Simpatico  v1.10
HoomdConfigReader.cpp
1 /*
2 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
3 *
4 * Copyright 2010 - 2017, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include "HoomdConfigReader.h"
9 
10 #include <tools/chemistry/Atom.h>
11 #include <tools/chemistry/Group.h>
12 #include <tools/chemistry/Species.h>
13 //#include <tools/chemistry/MaskPolicy.h>
14 #include <tools/storage/Configuration.h>
15 
16 #include <util/space/Vector.h>
17 #include <util/xmltag/XmlXmlTag.h>
18 #include <util/xmltag/XmlStartTag.h>
19 #include <util/xmltag/XmlAttribute.h>
20 #include <util/xmltag/XmlEndTag.h>
21 #include <util/misc/ioUtil.h>
22 
23 namespace Tools
24 {
25 
26  using namespace Util;
27 
28  /*
29  * Constructor.
30  */
32  : ConfigReader(configuration, true),
33  hasTypeMaps_(false)
34  { setClassName("HoomdConfigReader"); }
35 
36  /*
37  * Read auxiliary type map file.
38  */
39  void HoomdConfigReader::readAuxiliaryFile(std::ifstream& file)
40  {
41  bool notEnd;
42  std::stringstream line;
43 
44  notEnd = getNextLine(file, line);
45  if (notEnd) {
46  checkString(line, "ATOM");
47  checkString(line, "TYPES:");
48  atomTypeMap_.read(file);
49  }
50 
51  notEnd = getNextLine(file, line);
52  if (notEnd) {
53  checkString(line, "BOND");
54  checkString(line, "TYPES:");
55  bondTypeMap_.read(file);
56  }
57 
58  notEnd = getNextLine(file, line);
59  if (notEnd) {
60  checkString(line, "ANGLE");
61  checkString(line, "TYPES:");
62  angleTypeMap_.read(file);
63  }
64 
65  hasTypeMaps_ = true;
66  }
67 
68  /*
69  * Read a configuration file.
70  */
71  void HoomdConfigReader::readConfig(std::ifstream& file)
72  {
73  // Preconditions
74  if (!file.is_open()) {
75  UTIL_THROW("Error: File is not open");
76  }
77  if (!hasTypeMaps_) {
78  UTIL_THROW("Error: A type map file must be read before config");
79  }
80 
81  // Set flags
82 
83  std::string line;
84 
85  // Read XML tag
86  getNextLine(file, line);
87  XmlXmlTag xmlTag;
88  if (!xmlTag.match(line, 0)) {
89  UTIL_THROW("Missing XML tag");
90  }
91 
92  // Read hoom_xml start tag
93  getNextLine(file, line);
94  XmlStartTag start;
95  start.matchLabel("hoomd_xml", line, 0);
96  XmlAttribute attribute;
97  std::string version;
98  while (start.matchAttribute(attribute)) {
99  if (attribute.label() == "version") {
100  attribute.value() >> version;
101  } else {
102  Log::file() << "attribute = " << attribute.label() << std::endl;
103  UTIL_THROW("Unknown attribute of hoomd_xml tag");
104  }
105  }
106 
107  // Read configuration start tag
108  getNextLine(file, line);
109  start.matchLabel("configuration", line, 0);
110  int timestep;
111  int dimensions;
112  int natoms;
113  double vizsigma;
114  while (start.matchAttribute(attribute)) {
115  if (attribute.label() == "time_step") {
116  attribute.value() >> timestep;
117  } else
118  if (attribute.label() == "dimensions") {
119  attribute.value() >> dimensions;
120  if (dimensions != 3) {
121  UTIL_THROW("hoomd_xml dimensions attribute not equal to 3");
122  }
123  } else
124  if (attribute.label() == "natoms") {
125  attribute.value() >> natoms;
126  } else
127  if (attribute.label() == "vizsigma") {
128  attribute.value() >> vizsigma;
129  } else {
130  Log::file() << "attribute = " << attribute.label() << std::endl;
131  UTIL_THROW("Unknown attribute of hoomd_xml tag");
132  }
133  }
134  start.finish();
135 
136  // Read data nodes
137  XmlEndTag end;
138  std::string name;
139  bool finish = false;
140  while (!finish) {
141 
142  getNextLine(file, line);
143 
144  // Attempt to match hoomd_xml end tag
145  if (end.match(line, 0)) {
146 
147  if (end.label() != "configuration") {
148  Log::file() << "End label = " << end.label() << std::endl;
149  UTIL_THROW("Incorrect configuration end tag label");
150  }
151  finish = true;
152 
153  } else // Attempt to match a data node
154  if (start.matchLabel(line, 0)) {
155 
156  name = start.label();
157  // Log::file() << std::endl;
158  // Log::file() << "node name = " << start.label() << std::endl;
159 
160  // Select node type
161  if (name == "box") {
162  readBox(start, file);
163  } else
164  if (name == "position") {
165  readPosition(start, file);
166  } else
167  if (name == "velocity") {
168  readVelocity(start, file);
169  } else
170  if (name == "type") {
171  readType(start, file);
172  } else
173  if (name == "mass") {
174  readAtomIgnore(start, file);
175  } else
176  if (name == "charge") {
177  readAtomIgnore(start, file);
178  } else
179  if (name == "diameter") {
180  readAtomIgnore(start, file);
181  } else
182  if (name == "body") {
183  readAtomIgnore(start, file);
184  } else
185  if (name == "bond") {
186  readGroups<2>(start, file, configuration().bonds(),
187  bondTypeMap_);
188  }
189  #ifdef SIMP_ANGLE
190  else if (name == "angle") {
191  readGroups<3>(start, file, configuration().angles(),
192  angleTypeMap_);
193  }
194  #endif
195  #ifdef SIMP_DIHEDRAL
196  else if (name == "dihedral") {
197  readGroups<4>(start, file, configuration().dihedrals(),
198  dihedralTypeMap_);
199  } else if (name == "improper") {
200  readGroups<4>(start, file, configuration().impropers(),
201  improperTypeMap_);
202  }
203  #endif
204  else {
205  UTIL_THROW("Unknown node name");
206  }
207 
208  } else {
209 
210  Log::file() << line << std::endl;
211  UTIL_THROW("Expected data node start tag or configuration end tag");
212 
213  }
214 
215  }
216 
217  // Read hoomd_xml end line
218  getNextLine(file, line);
219  end.match("hoomd_xml", line, 0);
220 
221  // If species are declared, attempt to set atom context info,
222  // assuming that atom ids are ordered by molecule and species.
223 
224  if (configuration().nSpecies() > 0) {
225  bool success;
226  success = setAtomContexts();
227  if (success) {
229  }
230  }
231 
232  }
233 
234 
235 
236 
237 
238  void HoomdConfigReader::readBox(Util::XmlStartTag& start,
239  std::istream& file)
240  {
241  // Process data node start tag
242  XmlAttribute attribute;
243  Vector lengths;
244  double xy, xz, yz;
245  while (start.matchAttribute(attribute)) {
246  if (attribute.label() == "lx") {
247  attribute.value() >> lengths[0];
248  } else
249  if (attribute.label() == "ly") {
250  attribute.value() >> lengths[1];
251  } else
252  if (attribute.label() == "lz") {
253  attribute.value() >> lengths[2];
254  } else
255  if (attribute.label() == "xy") {
256  attribute.value() >> xy;
257  } else
258  if (attribute.label() == "xz") {
259  attribute.value() >> xz;
260  } else
261  if (attribute.label() == "yz") {
262  attribute.value() >> yz;
263  } else {
264  Log::file() << attribute.label() << std::endl;
265  UTIL_THROW("Unknown attribute");
266  }
267  }
268  start.finish();
269 
271 
272  }
273 
274  /*
275  * Finish processing start tag.
276  */
277  int HoomdConfigReader::readNumberAttribute(Util::XmlStartTag& start, int nAtom)
278  {
279  XmlAttribute attribute;
280  while (start.matchAttribute(attribute)) {
281  if (attribute.label() == "num") {
282  int num;
283  attribute.value() >> num;
284  if (nAtom > 0 && num != nAtom) {
285  UTIL_THROW("Inconsistent number of atoms");
286  }
287  if (nAtom == 0) {
288  nAtom = num;
289  }
290  } else {
291  Log::file() << attribute.label() << std::endl;
292  UTIL_THROW("Unknown attribute");
293  }
294  }
295  start.finish();
296  return nAtom;
297  }
298 
299  /*
300  * Check end tag.
301  */
302  void HoomdConfigReader::endTag(std::istream& file, const std::string& name)
303  {
304  std::string line;
305  XmlEndTag end;
306  getNextLine(file, line);
307  end.match(name, line, 0);
308  }
309 
310  /*
311  * Read position data node.
312  */
313  void HoomdConfigReader::readPosition(Util::XmlStartTag& start,
314  std::istream& file)
315  {
316  AtomStorage& storage = configuration().atoms();
317  Boundary& boundary = configuration().boundary();
318  int nAtom = storage.size();
319  int n = readNumberAttribute(start, nAtom);
320 
321  Atom* atomPtr;
322  if (nAtom > 0) {
323  for (int i = 0; i < n; ++i) {
324  atomPtr = storage.ptr(i);
325  if (!atomPtr) {
326  UTIL_THROW("Atom not found");
327  }
328  file >> atomPtr->position;
329  boundary.shift(atomPtr->position);
330  }
331  } else {
332  for (int i = 0; i < n; ++i) {
333  atomPtr = storage.newPtr();
334  atomPtr->id = i;
335  file >> atomPtr->position;
336  boundary.shift(atomPtr->position);
337  storage.add();
338  }
339  }
340  endTag(file, "position");
341  }
342 
343  /*
344  * Read velocity data node.
345  */
346  void HoomdConfigReader::readVelocity(Util::XmlStartTag& start,
347  std::istream& file)
348  {
349  AtomStorage& storage = configuration().atoms();
350  int nAtom = storage.size();
351  int n = readNumberAttribute(start, nAtom);
352 
353  Atom* atomPtr;
354  if (nAtom > 0) {
355  for (int i = 0; i < n; ++i) {
356  atomPtr = storage.ptr(i);
357  if (!atomPtr) {
358  UTIL_THROW("Atom not found");
359  }
360  file >> atomPtr->velocity;
361  }
362  } else {
363  for (int i = 0; i < n; ++i) {
364  atomPtr = storage.newPtr();
365  atomPtr->id = i;
366  file >> atomPtr->velocity;
367  storage.add();
368  }
369  }
370  endTag(file, "velocity");
371  }
372 
373  /*
374  * Read type data node.
375  */
376  void HoomdConfigReader::readType(Util::XmlStartTag& start,
377  std::istream& file)
378  {
379  AtomStorage& storage = configuration().atoms();
380  int nAtom = storage.size();
381  int n = readNumberAttribute(start, nAtom);
382  int typeId;
383  std::string typeName;
384 
385  Atom* atomPtr;
386  if (nAtom > 0) {
387  for (int i = 0; i < n; ++i) {
388  atomPtr = storage.ptr(i);
389  if (!atomPtr) {
390  UTIL_THROW("Atom not found");
391  }
392  file >> typeName;
393  typeId = atomTypeMap_.id(typeName);
394  atomPtr->typeId = typeId;
395  }
396  } else {
397  for (int i = 0; i < n; ++i) {
398  atomPtr = storage.newPtr();
399  atomPtr->id = i;
400  file >> typeName;
401  typeId = atomTypeMap_.id(typeName);
402  atomPtr->typeId = typeId;
403  storage.add();
404  }
405  }
406  endTag(file, "type");
407  }
408 
409  /*
410  * Read and discard atom data
411  */
412  void HoomdConfigReader::readAtomIgnore(Util::XmlStartTag& start,
413  std::istream& file)
414  {
415  AtomStorage& storage = configuration().atoms();
416  int nAtom = storage.size();
417  int n = readNumberAttribute(start, nAtom);
418 
419  std::string dummy;
420  for (int i = 0; i < n; ++i) {
421  file >> dummy;
422  }
423 
424  endTag(file, start.label());
425  #if 0
426  XmlEndTag end;
427  std::string line;
428  getNextLine(file, line);
429  if (!end.match(line, 0)) {
430  UTIL_THROW("No end tag");
431  }
432  #endif
433  }
434 
435  /*
436  * Read type data node.
437  */
438  void HoomdConfigReader::readBond(Util::XmlStartTag& start,
439  std::istream& file)
440  {
441  GroupStorage < 2> & storage = configuration().bonds();
442  int nGroup = storage.size();
443  if (nGroup > 0) {
444  UTIL_THROW("Group storage not empty");
445  }
446  int n = readNumberAttribute(start, nGroup);
447  int typeId;
448  std::string typeName;
449 
450  int i, j;
451  Group<2>* groupPtr;
452  for (i = 0; i < n; ++i) {
453  groupPtr = storage.newPtr();
454  groupPtr->id = i;
455  file >> typeName;
456  typeId = bondTypeMap_.id(typeName);
457  groupPtr->typeId = typeId;
458  for (j = 0; j < 2; ++j) {
459  file >> groupPtr->atomIds[j];
460  }
461  }
462  endTag(file, start.label());
463  }
464 
465  /*
466  * Read group data node.
467  */
468  template <int N>
469  void HoomdConfigReader::readGroups(Util::XmlStartTag& start,
470  std::istream& file,
471  GroupStorage<N>& storage,
472  const TypeMap& map)
473  {
474  int nGroup = storage.size();
475  if (nGroup > 0) {
476  UTIL_THROW("Group storage not empty");
477  }
478  int n = readNumberAttribute(start, nGroup);
479  int typeId;
480  std::string typeName;
481 
482  if (n > 0) {
483  int i, j;
484  Group<N>* groupPtr;
485  for (i = 0; i < n; ++i) {
486  groupPtr = storage.newPtr();
487  groupPtr->id = i;
488  file >> typeName;
489  typeId = map.id(typeName);
490  groupPtr->typeId = typeId;
491  for (j = 0; j < 2; ++j) {
492  file >> groupPtr->atomIds[j];
493  }
494  }
495  }
496  endTag(file, start.label());
497  }
498 
499 }
bool matchLabel(const std::string &string, int begin)
Match opening bracket and any label.
Definition: XmlStartTag.cpp:21
Vector velocity
Atom velocity.
int size() const
Return logical size of this array (i.e., number of elements).
Definition: DSArray.h:388
bool matchAttribute(XmlAttribute &attribute)
Attempt to match an attribute.
Definition: XmlStartTag.cpp:71
Parser for an XML start tag.
Definition: XmlStartTag.h:36
Map between type names and type ids.
Definition: TypeMap.h:26
A Vector is a Cartesian vector.
Definition: Vector.h:75
int id
Unique global index (tag)
Abstract reader/writer for configuration files.
Definition: ConfigReader.h:27
std::stringstream & value()
Return value string, without quotes.
Definition: XmlAttribute.h:59
int typeId
Integer index for the type of group.
Container for a set of atoms.
virtual void readAuxiliaryFile(std::ifstream &file)
Read auxiliary file with type map information.
void setOrthorhombic(const Vector &lengths)
Set unit cell dimensions for orthorhombic boundary.
An orthorhombic periodic unit cell.
void read(std::istream &in)
Read pairs from file.
Definition: TypeMap.cpp:42
Parser for an XML attribute.
Definition: XmlAttribute.h:23
int size() const
Get number of atoms.
Group< N > * newPtr()
Append a new element to container and return its address.
Atom * ptr(int id)
Get a pointer to an atom by global id.
Parser for an XML file declaration tag (first line in file).
Definition: XmlXmlTag.h:27
const std::string & label()
Return label string.
Definition: XmlAttribute.h:53
AtomStorage & atoms()
Get the AtomStorage.
An instantaneous molecular dynamics configuration.
Definition: Configuration.h:40
bool setAtomContexts()
Set atom context data for all atoms, assuming consecutive ids.
bool getNextLine(std::istream &in, std::string &line)
Read the next non-empty line into a string, strip trailing whitespace.
Definition: ioUtil.cpp:79
const std::string label()
Label string.
Definition: XmlEndTag.h:64
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
bool match(const std::string &string, int begin)
Attempt to match entire xml tag.
Definition: XmlXmlTag.cpp:21
Parser for an XML end tag.
Definition: XmlEndTag.h:24
int typeId
Atom type index.
int id(const std::string &name) const
Get type id associated with a type name.
Definition: TypeMap.h:82
int atomIds[N]
Array of integer ids of atoms in this group.
Utility classes for scientific computation.
Definition: accumulators.mod:1
void add()
Finalize addition of atom (allows lookup by id).
void shift(Vector &r) const
Shift Cartesian Vector r to its primary image.
void checkString(std::istream &in, const std::string &expected)
Extract string from stream, and compare to expected value.
Definition: ioUtil.cpp:37
Single-processor classes for pre- and post-processing MD trajectories.
GroupStorage< 4 > & impropers()
Get the Improper dihedral storage.
const std::string label()
Label string.
Definition: XmlStartTag.h:90
A point particle in an MD simulation.
static std::ostream & file()
Get log ostream by reference.
Definition: Log.cpp:57
GroupStorage< 3 > & angles()
Get the Angle storage.
GroupStorage< 4 > & dihedrals()
Get the Dihedral storage.
A group of covalently interacting atoms.
HoomdConfigReader()
Default constructor.
virtual void readConfig(std::ifstream &file)
Read configuration file in DdMd default format.
Atom * newPtr()
Return pointer to location for new atom.
Boundary & boundary()
Get the Boundary by non-const reference.
void addAtomsToSpecies()
Add all atoms to Species containers and associated molecules.
void setClassName(const char *className)
Set class name string.
Vector position
Atom position.
int id
Global id for this group.
void finish()
Check if end bracket was found.
Definition: XmlStartTag.cpp:93
Configuration & configuration()
Get parent Configuration by reference.
Definition: ConfigReader.h:89
GroupStorage< 2 > & bonds()
Get the Bond storage.
bool match(const std::string &string, int begin)
Attempt to match any end tag.
Definition: XmlEndTag.cpp:20