Simpatico  v1.10
SmpConfigIo.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 "SmpConfigIo.h"
9 #include <mcMd/simulation/Simulation.h>
10 #include <mcMd/simulation/System.h>
11 #include <mcMd/species/SpeciesMutator.h>
12 #include <mcMd/chemistry/Molecule.h>
13 #include <mcMd/chemistry/Atom.h>
14 #ifdef SIMP_TETHER
15 #include <mcMd/tethers/TetherMaster.h>
16 #endif
17 #ifdef MCMD_LINK
18 #include <mcMd/links/LinkMaster.h>
19 #endif
20 #include <simp/species/Species.h>
21 #include <util/param/Label.h>
22 #include <util/misc/FlagSet.h>
23 #include <util/format/Int.h>
24 
25 namespace McMd
26 {
27 
28  using namespace Util;
29  using namespace Simp;
30 
31  /*
32  * Constructor.
33  */
35  : ConfigIo(system)
36  {}
37 
38  /*
39  * Destructor.
40  */
42  {}
43 
44  /*
45  * Read the configuration file.
46  */
47  void SmpConfigIo::read(std::istream &in)
48  {
49  // Make sure Label static buffer is clean on entry
51 
52  using std::endl;
53 
54  // Allocate arrays
55  int nSpecies = simulation().nSpecies();
56  UTIL_CHECK(nSpecies > 0);
57  DArray<int> nMoleculeSpecies;
58  DArray<int> firstAtomIds;
59  nMoleculeSpecies.allocate(nSpecies);
60  firstAtomIds.allocate(nSpecies);
61  firstAtomIds[0] = 0;
62 
63  // Read SPECIES block
64  Species* speciesPtr;
65  int nAtomSpecies, nAtomMolecule;
66  int nAtomTot = 0;
67  Label speciesLabel("SPECIES", false); // optional label
68  if (speciesLabel.match(in)) {
69 
70  /*
71  * If SPECIES block is present, check consistency with data
72  * in Species objects, which was read from a parameter file
73  * or loaded from an archive upon a restart. Initialize the
74  * arrays nMoleculeSpecies and firstAtomIds.
75  */
76 
77  int nSpeciesIn, iSpeciesIn;
78  in >> Label("nSpecies") >> nSpeciesIn;
79  UTIL_CHECK(nSpeciesIn > 0);
80  UTIL_CHECK(nSpeciesIn == nSpecies);
81  Label speciesLabel("species");
82  Label nMoleculeLabel("nMolecule");
83  for (int iSpecies = 0; iSpecies < nSpecies; ++iSpecies) {
84  in >> Label("species") >> iSpeciesIn;
85  UTIL_CHECK(iSpeciesIn == iSpecies);
86  in >> Label("nMolecule") >> nMoleculeSpecies[iSpecies];
87  UTIL_CHECK(nMoleculeSpecies[iSpecies] >= 0);
88  speciesPtr = &simulation().species(iSpecies);
89  UTIL_CHECK(nMoleculeSpecies[iSpecies] <=
90  speciesPtr->capacity());
91  bool match = speciesPtr->matchStructure(in);
92  if (!match) {
93  UTIL_THROW("Structure mismatch");
94  }
95  firstAtomIds[iSpecies] = nAtomTot;
96  nAtomMolecule = speciesPtr->nAtom();
97  nAtomSpecies = nMoleculeSpecies[iSpecies]*nAtomMolecule;
98  nAtomTot += nAtomSpecies;
99  }
100 
101  } else {
102 
103  /*
104  * If the SPECIES block is absent, use the structures already
105  * defined in the Species objects, and set the nMoleculeSpecies
106  * for each species equal to Species::capacity(). Also initialize
107  * firstAtomIds array.
108  */
109 
110  for (int iSpecies = 0; iSpecies < nSpecies; ++iSpecies) {
111  speciesPtr = &simulation().species(iSpecies);
112  nMoleculeSpecies[iSpecies] = speciesPtr->capacity();
113  firstAtomIds[iSpecies+1] = nAtomTot;
114  nAtomMolecule = speciesPtr->nAtom();
115  nAtomSpecies = nMoleculeSpecies[iSpecies]*nAtomMolecule;
116  nAtomTot += nAtomSpecies;
117  }
118  }
119 
120  // Read BOUNDARY block
121  in >> Label("BOUNDARY");
122  in >> boundary();
123 
124  // Read ATOM block header
125  in >> Label("ATOM");
126  Label orderedLabel("ordered", false); // optional label
127  bool isOrdered = orderedLabel.match(in);
128  std::string formatString;
129  in >> Label("format") >> formatString;
130  UTIL_CHECK(formatString.size() > 0);
131  int nAtom;
132  in >> Label("nAtom") >> nAtom;
133  UTIL_CHECK(nAtom == nAtomTot);
134 
135  // Parse atom format string
136  FlagSet atomFormat("imtpvs");
137  atomFormat.setActualOrdered(formatString);
138  bool hasAtomIndex = atomFormat.isActive('i');
139  bool hasAtomContext = atomFormat.isActive('m');
140  bool hasAtomTypeId = atomFormat.isActive('t');
141  bool hasAtomPosition = atomFormat.isActive('p');
142  bool hasAtomVelocity = atomFormat.isActive('v');
143  bool hasAtomShift = atomFormat.isActive('s');
144  UTIL_CHECK(hasAtomPosition);
145  if (!isOrdered) {
146  UTIL_CHECK(hasAtomContext);
147  }
148 
149  // Read all atoms
150  Molecule* molPtr;
151  Molecule::AtomIterator atomIter;
152  int iSpecies, iMol;
153  int atomIndex, iAtom, count, atomTypeId;
154  int cSpeciesId, cMoleculeId, cAtomId;
155  IntVector shift;
156  if (isOrdered) {
157  count = 0;
158  for (iSpecies = 0; iSpecies < nSpecies; ++iSpecies) {
159  speciesPtr = &simulation().species(iSpecies);
160  nAtomMolecule = speciesPtr->nAtom();
161  for (iMol = 0; iMol < nMoleculeSpecies[iSpecies]; ++iMol) {
162 
163  // Add molecule
164  molPtr = &(simulation().getMolecule(iSpecies));
165  system().addMolecule(*molPtr);
166  if (molPtr != &system().molecule(iSpecies, iMol)) {
167  UTIL_THROW("Molecule index error");
168  }
169 
170  // Loop over atoms
171  iAtom = 0;
172  molPtr->begin(atomIter);
173  for ( ; atomIter.notEnd(); ++atomIter) {
174 
175  // Log::file() << endl;
176  if (hasAtomIndex) {
177  in >> atomIndex;
178  UTIL_CHECK(atomIndex == count);
179  // Log::file() << atomIndex << " ";
180  }
181  if (hasAtomContext) {
182  in >> cSpeciesId;
183  UTIL_CHECK(cSpeciesId == iSpecies);
184  // Log::file() << cSpeciesId << " ";
185  in >> cMoleculeId;
186  UTIL_CHECK(cMoleculeId == iMol);
187  // Log::file() << cMoleculeId << " ";
188  in >> cAtomId;
189  UTIL_CHECK(cAtomId == iAtom);
190  // Log::file() << cAtomId << " ";
191  }
192  if (hasAtomTypeId) {
193  in >> atomTypeId;
194  UTIL_CHECK(atomTypeId
195  == speciesPtr->atomTypeId(iAtom));
196  // Log::file() << atomTypeId << " ";
197  } else {
198  atomTypeId = speciesPtr->atomTypeId(iAtom);
199  }
200  atomIter->setTypeId(atomTypeId);
201 
202  in >> atomIter->position();
203  // Log::file() << endl << atomIter->position();
204  if (hasAtomVelocity) {
205  in >> atomIter->velocity();
206  // Log::file() << endl << atomIter->velocity();
207  }
208  if (hasAtomShift) {
209  in >> shift;
210  #ifdef MCMD_SHIFT
211  atomIter->shift() = shift;
212  #endif
213  }
214 
215  // Shift atom positions to primary cell
216  #ifdef MCMD_SHIFT
217  in >> atomIter->shift();
218  boundary().shift(atomIter->position(), atomIter.shift());
219  #else
220  boundary().shift(atomIter->position());
221  #endif
222 
223  iAtom++;
224  count++;
225  } // atom loop
226  } // molecule loop
227  } // species loop
228  } // if (isOrdered)
229 
230  // Make sure static Label buffer is clean on exit
232  }
233 
234  /*
235  * Write the configuration file.
236  */
237  void SmpConfigIo::write(std::ostream &out)
238  {
239  using std::endl;
240 
241  // Species atom info
242  out << "SPECIES";
243  int nSpecies = simulation().nSpecies();
244  out << endl << "nSpecies " << nSpecies;
245  int iMolecule, nMolecule;
246  int nAtom, nAtomTot;
247  nAtomTot = 0;
248  Species* speciesPtr;
249  out << endl;
250  for (int iSpecies = 0; iSpecies < nSpecies; ++iSpecies) {
251  out << endl << "species " << iSpecies;
252  nMolecule = system().nMolecule(iSpecies);
253  out << endl << " nMolecule " << nMolecule;
254  speciesPtr = &simulation().species(iSpecies);
255  speciesPtr->writeStructure(out, " ");
256  nAtom = speciesPtr->nAtom();
257  nAtomTot += nMolecule*nAtom;
258  out << endl;
259  }
260 
261  // Write Boundary dimensions
262  out << endl << "BOUNDARY";
263  out << endl << boundary() << endl;
264 
265  // Write ATOM information
266  out << endl << "ATOM";
267  out << endl << "ordered";
268  out << endl << "format imtpv";
269  out << endl << "nAtom " << nAtomTot;
272  int atomId, iAtom;
273  atomId = 0;
274  for (int iSpecies = 0; iSpecies < nSpecies; ++iSpecies) {
275  speciesPtr = &simulation().species(iSpecies);
276  system().begin(iSpecies, molIter);
277  iMolecule = 0;
278  for ( ; molIter.notEnd(); ++molIter) {
279  iAtom = 0;
280  for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
281  out << endl;
282  out << atomId << " ";
283  out << iSpecies << " " << iMolecule << " " << iAtom << " ";
284  out << atomIter->typeId();
285  out << endl << atomIter->position();
286  out << endl << atomIter->velocity();
287  ++iAtom;
288  ++atomId;
289  }
290  ++iMolecule;
291  }
292  }
293 
295  }
296 
297 }
virtual void read(std::istream &in)
Read configuration (particle positions) from file.
Definition: SmpConfigIo.cpp:47
Boundary & boundary() const
Get the Boundary.
void begin(int speciesId, MoleculeIterator &iterator)
Initialize an iterator for molecules of one species in this System.
Definition: System.h:1147
int nAtom() const
Get number of atoms per molecule for this Species.
bool notEnd() const
Is the current pointer not at the end of the array?
Definition: ArrayIterator.h:83
void writeStructure(std::ostream &out, std::string indent=std::string())
Write molecular structure in config/topology file format.
void begin(AtomIterator &iterator)
Set an Molecule::AtomIterator to first Atom in this Molecule.
A set of interacting Molecules enclosed by a Boundary.
Definition: System.h:115
Forward iterator for a PArray.
Classes used by all simpatico molecular simulations.
Molecule & getMolecule(int speciesId)
Get a new molecule from a reservoir of unused Molecule objects.
static bool isClear()
Is the input buffer clear?
Definition: Label.cpp:37
bool isActive(char c) const
Is the flag associated with character c active?
Definition: FlagSet.h:110
Forward const iterator for an Array or a C array.
int nMolecule(int speciesId) const
Get the number of molecules of one Species in this System.
Definition: System.h:1128
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
void addMolecule(Molecule &molecule)
Add a Molecule to this System.
Definition: System.cpp:1111
virtual ~SmpConfigIo()
Destructor.
Definition: SmpConfigIo.cpp:41
Utility classes for scientific computation.
Definition: accumulators.mod:1
System & system() const
Get a reference to the parent System.
SmpConfigIo(System &system)
Constructor.
Definition: SmpConfigIo.cpp:34
bool matchStructure(std::istream &in)
Read structure, return true iff it matches existing structure.
void shift(Vector &r) const
Shift Cartesian Vector r to its primary image.
int atomTypeId(int iAtom) const
Get atom type index for a specific atom, by local atom index.
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
A label string in a file format.
Definition: Label.h:36
Simulation & simulation() const
Get a reference to the parent Simulation.
bool notEnd() const
Is the current pointer not at the end of the array?
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
int nSpecies() const
Get the number of Species in this Simulation.
bool match(std::istream &in)
Read and attempt to match next word in an input stream.
Definition: Label.cpp:95
void setActualOrdered(std::string actual)
Set the string of actual flag characters.
Definition: FlagSet.cpp:47
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
int capacity() const
Maximum allowed number of molecules for this Species.
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
A physical molecule (a set of covalently bonded Atoms).
bool notEnd() const
Is this not the end of the array?
A Species represents a set of chemically similar molecules.
Species & species(int i)
Get a specific Species by reference.
virtual void write(std::ostream &out)
Write configuration (particle positions) to file.
A set of boolean variables represented by characters.
Definition: FlagSet.h:28
System configuration file reader and writer.