From bb2e616c5fe204293ff8f008d8d687605ed62588 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Sat, 24 Oct 2020 12:56:02 -0400 Subject: [PATCH 1/6] molecule: use user-provided IDs in molecule files --- src/molecule.cpp | 52 +++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/molecule.cpp b/src/molecule.cpp index b4f16525e9..afa5296414 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -683,14 +683,15 @@ void Molecule::coords(char *line) ValueTokenizer values(line); if (values.count() != 4) error->one(FLERR,"Invalid Coords section in molecule file"); - values.next_int(); - x[i][0] = values.next_double(); - x[i][1] = values.next_double(); - x[i][2] = values.next_double(); + int iatom = values.next_int() - 1; + if (iatom >= natoms) error->one(FLERR,"Invalid Coords section in molecule file"); + x[iatom][0] = values.next_double(); + x[iatom][1] = values.next_double(); + x[iatom][2] = values.next_double(); - x[i][0] *= sizescale; - x[i][1] *= sizescale; - x[i][2] *= sizescale; + x[iatom][0] *= sizescale; + x[iatom][1] *= sizescale; + x[iatom][2] *= sizescale; } } catch (TokenizerException &e) { error->one(FLERR, fmt::format("Invalid Coords section in molecule file\n" @@ -718,9 +719,10 @@ void Molecule::types(char *line) ValueTokenizer values(line); if (values.count() != 2) error->one(FLERR,"Invalid Types section in molecule file"); - values.next_int(); - type[i] = values.next_int(); - type[i] += toffset; + int iatom = values.next_int() - 1; + if (iatom >= natoms) error->one(FLERR,"Invalid Types section in molecule file"); + type[iatom] = values.next_int(); + type[iatom] += toffset; } } catch (TokenizerException &e) { error->one(FLERR, fmt::format("Invalid Types section in molecule file\n" @@ -748,9 +750,10 @@ void Molecule::molecules(char *line) ValueTokenizer values(line); if (values.count() != 2) error->one(FLERR,"Invalid Molecules section in molecule file"); - values.next_int(); - molecule[i] = values.next_int(); - // molecule[i] += moffset; // placeholder for possible molecule offset + int iatom = values.next_int() - 1; + if (iatom >= natoms) error->one(FLERR,"Invalid Molecules section in molecule file"); + molecule[iatom] = values.next_int(); + // molecule[iatom] += moffset; // placeholder for possible molecule offset } } catch (TokenizerException &e) { error->one(FLERR, fmt::format("Invalid Molecules section in molecule file\n" @@ -808,8 +811,9 @@ void Molecule::charges(char *line) ValueTokenizer values(line); if ((int)values.count() != 2) error->one(FLERR,"Invalid Charges section in molecule file"); - values.next_int(); - q[i] = values.next_double(); + int iatom = values.next_int() - 1; + if (iatom >= natoms) error->one(FLERR,"Invalid Charges section in molecule file"); + q[iatom] = values.next_double(); } } catch (TokenizerException &e) { error->one(FLERR, fmt::format("Invalid Charges section in molecule file\n" @@ -831,11 +835,12 @@ void Molecule::diameters(char *line) ValueTokenizer values(line); if (values.count() != 2) error->one(FLERR,"Invalid Diameters section in molecule file"); - values.next_int(); - radius[i] = values.next_double(); - radius[i] *= sizescale; - radius[i] *= 0.5; - maxradius = MAX(maxradius,radius[i]); + int iatom = values.next_int() - 1; + if (iatom >= natoms) error->one(FLERR,"Invalid Diameters section in molecule file"); + radius[iatom] = values.next_double(); + radius[iatom] *= sizescale; + radius[iatom] *= 0.5; + maxradius = MAX(maxradius,radius[iatom]); } } catch (TokenizerException &e) { error->one(FLERR, fmt::format("Invalid Diameters section in molecule file\n" @@ -860,9 +865,10 @@ void Molecule::masses(char *line) ValueTokenizer values(line); if (values.count() != 2) error->one(FLERR,"Invalid Masses section in molecule file"); - values.next_int(); - rmass[i] = values.next_double(); - rmass[i] *= sizescale*sizescale*sizescale; + int iatom = values.next_int() - 1; + if (iatom >= natoms) error->one(FLERR,"Invalid Diameters section in molecule file"); + rmass[iatom] = values.next_double(); + rmass[iatom] *= sizescale*sizescale*sizescale; } } catch (TokenizerException &e) { error->one(FLERR, fmt::format("Invalid Masses section in molecule file\n" From 7df8b81af98f33f133d378704f1ff2a18c033682 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Sat, 24 Oct 2020 13:08:49 -0400 Subject: [PATCH 2/6] Update molecule.rst --- doc/src/molecule.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/doc/src/molecule.rst b/doc/src/molecule.rst index 7b316b9d24..2c20dc8856 100644 --- a/doc/src/molecule.rst +++ b/doc/src/molecule.rst @@ -201,11 +201,9 @@ bonds between nuclear cores and Drude electrons in a different manner. Each section is listed below in alphabetic order. The format of each section is described including the number of lines it must contain and -rules (if any) for whether it can appear in the data file. In each -case the ID is ignored; it is simply included for readability, and -should be a number from 1 to Nlines for the section, indicating which -atom (or bond, etc) the entry applies to. The lines are assumed to be -listed in order from 1 to Nlines, but LAMMPS does not check for this. +rules (if any) for whether it can appear in the data file. For per- +atom sections, entries should be numbered from 1 to Natoms, where +Natoms is the number of atoms in the template. ---------- From d09eb491f8e045b662f1c4c574e391cdeba68638 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Wed, 11 Nov 2020 13:00:10 -0500 Subject: [PATCH 3/6] molecule: add iatom < 0 check --- src/molecule.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/molecule.cpp b/src/molecule.cpp index afa5296414..104ad3dccf 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -684,7 +684,7 @@ void Molecule::coords(char *line) if (values.count() != 4) error->one(FLERR,"Invalid Coords section in molecule file"); int iatom = values.next_int() - 1; - if (iatom >= natoms) error->one(FLERR,"Invalid Coords section in molecule file"); + if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Coords section in molecule file"); x[iatom][0] = values.next_double(); x[iatom][1] = values.next_double(); x[iatom][2] = values.next_double(); @@ -720,7 +720,7 @@ void Molecule::types(char *line) if (values.count() != 2) error->one(FLERR,"Invalid Types section in molecule file"); int iatom = values.next_int() - 1; - if (iatom >= natoms) error->one(FLERR,"Invalid Types section in molecule file"); + if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Types section in molecule file"); type[iatom] = values.next_int(); type[iatom] += toffset; } @@ -751,7 +751,7 @@ void Molecule::molecules(char *line) if (values.count() != 2) error->one(FLERR,"Invalid Molecules section in molecule file"); int iatom = values.next_int() - 1; - if (iatom >= natoms) error->one(FLERR,"Invalid Molecules section in molecule file"); + if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Molecules section in molecule file"); molecule[iatom] = values.next_int(); // molecule[iatom] += moffset; // placeholder for possible molecule offset } @@ -812,7 +812,7 @@ void Molecule::charges(char *line) if ((int)values.count() != 2) error->one(FLERR,"Invalid Charges section in molecule file"); int iatom = values.next_int() - 1; - if (iatom >= natoms) error->one(FLERR,"Invalid Charges section in molecule file"); + if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Charges section in molecule file"); q[iatom] = values.next_double(); } } catch (TokenizerException &e) { @@ -836,7 +836,7 @@ void Molecule::diameters(char *line) if (values.count() != 2) error->one(FLERR,"Invalid Diameters section in molecule file"); int iatom = values.next_int() - 1; - if (iatom >= natoms) error->one(FLERR,"Invalid Diameters section in molecule file"); + if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Diameters section in molecule file"); radius[iatom] = values.next_double(); radius[iatom] *= sizescale; radius[iatom] *= 0.5; @@ -866,7 +866,7 @@ void Molecule::masses(char *line) if (values.count() != 2) error->one(FLERR,"Invalid Masses section in molecule file"); int iatom = values.next_int() - 1; - if (iatom >= natoms) error->one(FLERR,"Invalid Diameters section in molecule file"); + if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Masses section in molecule file"); rmass[iatom] = values.next_double(); rmass[iatom] *= sizescale*sizescale*sizescale; } From 8b9f2e0539fa6cb5e2428ebf7a8e674a0f801d11 Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Sat, 14 Nov 2020 15:51:26 -0500 Subject: [PATCH 4/6] molecule: add atom ID completeness check --- src/molecule.cpp | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/molecule.cpp b/src/molecule.cpp index 57fadfaca4..77fa9c82df 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -509,7 +509,6 @@ void Molecule::read(int flag) // count = vector for tallying bonds,angles,etc per atom if (flag == 0) memory->create(count,natoms,"molecule:count"); - else count = nullptr; // grab keyword and skip next line @@ -616,10 +615,6 @@ void Molecule::read(int flag) parse_keyword(1,line,keyword); } - // clean up - - memory->destroy(count); - // error check if (flag == 0) { @@ -665,6 +660,10 @@ void Molecule::read(int flag) maxradius = radius[0]; } } + + // clean up + + if (flag) memory->destroy(count); } /* ---------------------------------------------------------------------- @@ -673,6 +672,7 @@ void Molecule::read(int flag) void Molecule::coords(char *line) { + for (int i = 0; i < natoms; i++) count[i] = 0; try { for (int i = 0; i < natoms; i++) { readline(line); @@ -682,6 +682,7 @@ void Molecule::coords(char *line) int iatom = values.next_int() - 1; if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Coords section in molecule file"); + count[iatom]++; x[iatom][0] = values.next_double(); x[iatom][1] = values.next_double(); x[iatom][2] = values.next_double(); @@ -695,6 +696,9 @@ void Molecule::coords(char *line) "{}", e.what())); } + for (int i = 0; i < natoms; i++) + if (count[i] == 0) error->all(FLERR,"Invalid Coords section in molecule file"); + if (domain->dimension == 2) { for (int i = 0; i < natoms; i++) if (x[i][2] != 0.0) @@ -709,6 +713,7 @@ void Molecule::coords(char *line) void Molecule::types(char *line) { + for (int i = 0; i < natoms; i++) count[i] = 0; try { for (int i = 0; i < natoms; i++) { readline(line); @@ -718,6 +723,7 @@ void Molecule::types(char *line) int iatom = values.next_int() - 1; if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Types section in molecule file"); + count[iatom]++; type[iatom] = values.next_int(); type[iatom] += toffset; } @@ -726,6 +732,9 @@ void Molecule::types(char *line) "{}", e.what())); } + for (int i = 0; i < natoms; i++) + if (count[i] == 0) error->all(FLERR,"Invalid Types section in molecule file"); + for (int i = 0; i < natoms; i++) if ((type[i] <= 0) || (domain->box_exist && (type[i] > atom->ntypes))) error->all(FLERR,"Invalid atom type in molecule file"); @@ -741,6 +750,7 @@ void Molecule::types(char *line) void Molecule::molecules(char *line) { + for (int i = 0; i < natoms; i++) count[i] = 0; try { for (int i = 0; i < natoms; i++) { readline(line); @@ -749,6 +759,7 @@ void Molecule::molecules(char *line) int iatom = values.next_int() - 1; if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Molecules section in molecule file"); + count[iatom]++; molecule[iatom] = values.next_int(); // molecule[iatom] += moffset; // placeholder for possible molecule offset } @@ -757,6 +768,9 @@ void Molecule::molecules(char *line) "{}", e.what())); } + for (int i = 0; i < natoms; i++) + if (count[i] == 0) error->all(FLERR,"Invalid Molecules section in molecule file"); + for (int i = 0; i < natoms; i++) if (molecule[i] <= 0) error->all(FLERR,"Invalid molecule ID in molecule file"); @@ -801,6 +815,7 @@ void Molecule::fragments(char *line) void Molecule::charges(char *line) { + for (int i = 0; i < natoms; i++) count[i] = 0; try { for (int i = 0; i < natoms; i++) { readline(line); @@ -810,12 +825,16 @@ void Molecule::charges(char *line) int iatom = values.next_int() - 1; if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Charges section in molecule file"); + count[iatom]++; q[iatom] = values.next_double(); } } catch (TokenizerException &e) { error->one(FLERR, fmt::format("Invalid Charges section in molecule file\n" "{}", e.what())); } + + for (int i = 0; i < natoms; i++) + if (count[i] == 0) error->all(FLERR,"Invalid Charges section in molecule file"); } /* ---------------------------------------------------------------------- @@ -824,6 +843,7 @@ void Molecule::charges(char *line) void Molecule::diameters(char *line) { + for (int i = 0; i < natoms; i++) count[i] = 0; try { maxradius = 0.0; for (int i = 0; i < natoms; i++) { @@ -834,6 +854,7 @@ void Molecule::diameters(char *line) int iatom = values.next_int() - 1; if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Diameters section in molecule file"); + count[iatom]++; radius[iatom] = values.next_double(); radius[iatom] *= sizescale; radius[iatom] *= 0.5; @@ -844,6 +865,9 @@ void Molecule::diameters(char *line) "{}", e.what())); } + for (int i = 0; i < natoms; i++) + if (count[i] == 0) error->all(FLERR,"Invalid Diameters section in molecule file"); + for (int i = 0; i < natoms; i++) if (radius[i] < 0.0) error->all(FLERR,"Invalid atom diameter in molecule file"); @@ -855,6 +879,7 @@ void Molecule::diameters(char *line) void Molecule::masses(char *line) { + for (int i = 0; i < natoms; i++) count[i] = 0; try { for (int i = 0; i < natoms; i++) { readline(line); @@ -864,6 +889,7 @@ void Molecule::masses(char *line) int iatom = values.next_int() - 1; if (iatom < 0 || iatom >= natoms) error->one(FLERR,"Invalid Masses section in molecule file"); + count[iatom]++; rmass[iatom] = values.next_double(); rmass[iatom] *= sizescale*sizescale*sizescale; } @@ -872,6 +898,9 @@ void Molecule::masses(char *line) "{}", e.what())); } + for (int i = 0; i < natoms; i++) + if (count[i] == 0) error->all(FLERR,"Invalid Masses section in molecule file"); + for (int i = 0; i < natoms; i++) if (rmass[i] <= 0.0) error->all(FLERR,"Invalid atom mass in molecule file"); } @@ -1302,7 +1331,6 @@ void Molecule::special_generate() { int newton_bond = force->newton_bond; tagint atom1,atom2; - int *count = new int[natoms]; // temporary array for special atoms @@ -1388,7 +1416,6 @@ void Molecule::special_generate() } } } - delete[] count; maxspecial = 0; for (int i = 0; i < natoms; i++) From d287e116106bdb77bb3b705f82872a5b8e20acc2 Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Sat, 14 Nov 2020 16:04:39 -0500 Subject: [PATCH 5/6] clarify docs --- doc/src/molecule.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/src/molecule.rst b/doc/src/molecule.rst index 06dc010038..01f7e539d0 100644 --- a/doc/src/molecule.rst +++ b/doc/src/molecule.rst @@ -202,8 +202,9 @@ bonds between nuclear cores and Drude electrons in a different manner. Each section is listed below in alphabetic order. The format of each section is described including the number of lines it must contain and rules (if any) for whether it can appear in the data file. For per- -atom sections, entries should be numbered from 1 to Natoms, where -Natoms is the number of atoms in the template. +atom sections, entries should be numbered from 1 to Natoms (where +Natoms is the number of atoms in the template), indicating which atom +(or bond, etc) the entry applies to. ---------- From 145d688fa4cdf38b72454fcee959eb6251243a44 Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Mon, 16 Nov 2020 15:09:17 -0500 Subject: [PATCH 6/6] clairfy docs --- doc/src/molecule.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/src/molecule.rst b/doc/src/molecule.rst index 01f7e539d0..b86983766d 100644 --- a/doc/src/molecule.rst +++ b/doc/src/molecule.rst @@ -204,7 +204,9 @@ section is described including the number of lines it must contain and rules (if any) for whether it can appear in the data file. For per- atom sections, entries should be numbered from 1 to Natoms (where Natoms is the number of atoms in the template), indicating which atom -(or bond, etc) the entry applies to. +(or bond, etc) the entry applies to. Per-atom sections need to +include a setting for every atom, but the atoms can be listed in any +order. ----------