Simpatico  v1.10
mcMd/configIos/LammpsConfigIo.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 "LammpsConfigIo.h"
9 #include <mcMd/simulation/System.h>
10 #include <mcMd/simulation/Simulation.h>
11 #include <mcMd/chemistry/Molecule.h>
12 #include <mcMd/chemistry/Atom.h>
13 
14 #include <simp/species/Species.h>
15 
16 #include <util/space/Vector.h>
17 #include <util/space/IntVector.h>
18 #include <util/param/Label.h>
19 #include <util/format/Format.h>
20 #include <util/format/Int.h>
21 #include <util/format/Dbl.h>
22 #include <util/misc/ioUtil.h>
23 
24 #include <vector>
25 
26 namespace McMd
27 {
28 
29  using namespace Util;
30  using namespace Simp;
31 
32  /*
33  * Constructor.
34  */
36  : ConfigIo(system)
37  {}
38 
39  /*
40  * Destructor.
41  */
43  {}
44 
45  void LammpsConfigIo::read(std::istream &in)
46  {
47  // Precondition
48  UTIL_CHECK(system().simulation().hasSpecies());
49 
50  // Calculate atomCapacity for entire simulation
51  int atomCapacity = 0;
52  int bondCapacity = 0;
53  int nSpecies = simulation().nSpecies();
54  int speciesCapacity = 0;
55  int iSpec, i;
56  Species* speciesPtr;
57  for (iSpec = 0; iSpec < nSpecies; ++iSpec) {
58  speciesPtr = &simulation().species(iSpec);
59  speciesCapacity = speciesPtr->capacity();
60  atomCapacity += speciesCapacity*speciesPtr->nAtom();
61  #ifdef SIMP_BOND
62  bondCapacity += speciesCapacity*speciesPtr->nBond();
63  #endif
64  }
65 
66  // Read and discard title line
67  std::string line;
68  std::getline(in, line);
69 
70  // Read numbers of atoms, bonds, etc.
71  int nAtom;
72  int nBond;
73  int nAngle;
74  int nDihedral;
75  int nImproper;
76  in >> nAtom >> Label("atoms");
77  in >> nBond >> Label("bonds");
78  in >> nAngle >> Label("angles");
79  in >> nDihedral >> Label("dihedrals");
80  in >> nImproper >> Label("impropers");
81 
82  /*
83  * Validate nAtom and nBond
84  * Lammps files can be read only if the number of atoms and bonds
85  * in the lammps file exactly matches the corresponding capacities.
86  */
87  if (nAtom != atomCapacity) {
88  UTIL_THROW("nAtom != atomCapacity");
89  }
90  if (nBond != bondCapacity) {
91  UTIL_THROW("nAtom != atomCapacity");
92  }
93 
94  // Read numbers of atom types, bond types, etc.
95  int nAtomType;
96  int nBondType;
97  int nAngleType;
98  int nDihedralType;
99  int nImproperType;
100  in >> nAtomType >> Label("atom") >> Label("types");
101  in >> nBondType >> Label("bond") >> Label("types");
102  in >> nAngleType >> Label("angle") >> Label("types");
103  in >> nDihedralType >> Label("dihedral") >> Label("types");
104  in >> nImproperType >> Label("improper") >> Label("types");
105 
106  if (nAtomType > simulation().nAtomType()) {
107  UTIL_THROW("nAtomType > simulation().nAtomType()");
108  }
109  // Read boundary dimensions
110  Vector lengths;
111  Vector min;
112  Vector max;
113  in >> min[0] >> max[0] >> Label("xlo") >> Label("xhi");
114  in >> min[1] >> max[1] >> Label("ylo") >> Label("yhi");
115  in >> min[2] >> max[2] >> Label("zlo") >> Label("zhi");
116  lengths.subtract(max, min);
117  boundary().setOrthorhombic(lengths);
118 
119  // Read particle masses (discard values)
120  double mass;
121  int atomTypeId;
122  in >> Label("Masses");
123  for (i = 0; i < nAtomType; ++i) {
124  in >> atomTypeId >> mass;
125  }
126 
127  /*
128  * Read atomic positions
129  *
130  * Atom tags must appear in order, numbered from 1
131  */
132  in >> Label("Atoms");
133  Molecule* molPtr;
134  Molecule::AtomIterator atomIter;
135  IntVector shift;
136  int atomId, molId, iMol, nMolecule;
137  for (iSpec=0; iSpec < nSpecies; ++iSpec) {
138  speciesPtr = &simulation().species(iSpec);
139  nMolecule = speciesPtr->capacity();
140  for (iMol = 0; iMol < nMolecule; ++iMol) {
141  molPtr = &(simulation().getMolecule(iSpec));
142  system().addMolecule(*molPtr);
143 
144  if (molPtr != &system().molecule(iSpec, iMol)) {
145  UTIL_THROW("Molecule index error");
146  }
147 
148  // Read positions, shift into primary cell
149  for (molPtr->begin(atomIter); atomIter.notEnd(); ++atomIter) {
150 
151  in >> atomId >> molId >> atomTypeId;
152  if (atomId != atomIter->id() + 1)
153  UTIL_THROW("Atom tags not ordered");
154 
155  in >> atomIter->position();
156 
157  // Shift coordinates to box (0, length(i));
158  atomIter->position() += min;
159 
160  in >> shift;
161 
162  }
163  }
164  }
165 
166  }
167 
168  void LammpsConfigIo::write(std::ostream &out)
169  {
170 
171  // Write first line (skipped) and a blank line.
172  out << "LAMMPS data file" << "\n";
173  out << "\n";
174 
175  // Count total numbers of atoms and bonds in all species.
176  Species* speciesPtr;
177  int iSpec, nMolecule;
178  int nAtom = 0;
179  int nBond = 0;
180  int nAngle = 0;
181  int nDihedral = 0;
182  for (iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
183  speciesPtr = &simulation().species(iSpec);
184  nMolecule = system().nMolecule(iSpec);
185  nAtom += nMolecule*(speciesPtr->nAtom());
186  #ifdef SIMP_BOND
187  nBond += nMolecule*(speciesPtr->nBond());
188  #endif
189  #ifdef SIMP_ANGLE
190  nAngle += nMolecule*(speciesPtr->nAngle());
191  #endif
192  #ifdef SIMP_DIHEDRAL
193  nDihedral += nMolecule*(speciesPtr->nDihedral());
194  #endif
195  }
196 
197  // Write numbers of atoms, bonds, etc.
199  out << Int(nAtom) << " atoms " << "\n";
200  out << Int(nBond) << " bonds " << "\n";
201  out << Int(nAngle) << " angles " << "\n";
202  out << Int(nDihedral) << " dihedrals" << "\n";
203  out << Int(0) << " impropers" << "\n";
204  out << "\n";
205 
206  // Write numbers of atom types, bond types, etc.
208  out << Int(simulation().nAtomType()) << " atom types" << "\n";
209  int nBondType = 0;
210  int nAngleType = 0;
211  int nDihedralType = 0;
212  #ifdef SIMP_BOND
213  nBondType = simulation().nBondType();
214  #endif
215  #ifdef SIMP_ANGLE
216  nAngleType = simulation().nAngleType();
217  #endif
218  #ifdef SIMP_DIHEDRAL
219  nDihedralType = simulation().nDihedralType();
220  #endif
221  out << Int(nBondType) << " bond types" << "\n";
222  out << Int(nAngleType) << " angle types" << "\n";
223  out << Int(nDihedralType) << " dihedral types" << "\n";
224  out << Int(0) << " improper types" << "\n";
225  out << "\n";
226 
227  // Write Boundary dimensions
228  Vector lengths = boundary().lengths();
231  out << Dbl(0.0) << Dbl(lengths[0]) << " xlo xhi" << "\n";
232  out << Dbl(0.0) << Dbl(lengths[1]) << " ylo yhi" << "\n";
233  out << Dbl(0.0) << Dbl(lengths[2]) << " zlo zhi" << "\n";
234  out << "\n";
235 
236  // Write masses (all set to 1.0 for now)
237  // lammps atom type = Simpatico atom type + 1
238  out << "Masses" << "\n";
239  out << "\n";
240  for (int iType = 0; iType < simulation().nAtomType(); ++iType) {
241  out << Int(iType+1, 5) << Dbl(1.0) << "\n";
242  }
243  out << "\n";
244 
245  // Write atomic positions
246  // lammps atom tag = Simpatico atom id + 1
247  // lammps molecule id = Simpatico molecule id + 1
248  out << "Atoms" << "\n";
249  out << "\n";
250  System::MoleculeIterator molIter;
251  Molecule::AtomIterator atomIter;
252  int i;
253  int shift = 0;
254  for (iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
255  for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
256  for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
257  out << Int( atomIter->id() + 1, 8 ) << Int( molIter->id() + 1, 8 );
258  out << Int( atomIter->typeId() + 1, 5 );
259  out << atomIter->position();
260  for (i = 0; i < Dimension; ++i) {
261  out << Int(shift, 4);
262  }
263  out << "\n";
264  }
265  }
266  }
267  out << "\n";
268 
269  #ifdef SIMP_BOND
270  if (nBond > 0) {
271  out << "Bonds" << "\n";
272  out << "\n";
273  Molecule::BondIterator bondIter;
274  int iBond = 1;
275  for (iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
276  for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
277  for (molIter->begin(bondIter); bondIter.notEnd(); ++bondIter) {
278  out << Int(iBond, 8 ) << Int(bondIter->typeId() + 1, 5);
279  out << Int(bondIter->atom(0).id() + 1, 8);
280  out << Int(bondIter->atom(1).id() + 1, 8);
281  out << "\n";
282  ++iBond;
283  }
284  }
285  }
286  out << "\n";
287  }
288  #endif
289 
290  #ifdef SIMP_ANGLE
291  if (nAngle > 0) {
292  out << "Angles" << "\n";
293  out << "\n";
294  Molecule::AngleIterator angleIter;
295  int iAngle = 1;
296  for (iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
297  for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
298  for (molIter->begin(angleIter); angleIter.notEnd(); ++angleIter) {
299  out << Int(iAngle, 8) << Int(angleIter->typeId() + 1, 5);
300  out << Int(angleIter->atom(0).id() + 1, 8);
301  out << Int(angleIter->atom(1).id() + 1, 8);
302  out << Int(angleIter->atom(2).id() + 1, 8);
303  out << "\n";
304  ++iAngle;
305  }
306  }
307  }
308  out << "\n";
309  }
310  #endif
311 
312  #ifdef SIMP_DIHEDRAL
313  if (nDihedral > 0) {
314  out << "Dihedrals" << "\n";
315  out << "\n";
316  Molecule::DihedralIterator dihedralIter;
317  int iDihedral = 1;
318  for (iSpec=0; iSpec < simulation().nSpecies(); ++iSpec) {
319  for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
320  molIter->begin(dihedralIter);
321  for ( ; dihedralIter.notEnd(); ++dihedralIter) {
322  out << Int(iDihedral, 8);
323  out << Int(dihedralIter->typeId() + 1, 5);
324  out << Int(dihedralIter->atom(0).id() + 1, 8);
325  out << Int(dihedralIter->atom(1).id() + 1, 8);
326  out << Int(dihedralIter->atom(2).id() + 1, 8);
327  out << Int(dihedralIter->atom(3).id() + 1, 8);
328  out << "\n";
329  ++iDihedral;
330  }
331  }
332  }
333  out << "\n";
334  }
335  #endif
336 
337  // Reset Format defaults to initialization values
339  }
340 
341 }
Boundary & boundary() const
Get the Boundary.
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
A Vector is a Cartesian vector.
Definition: Vector.h:75
virtual ~LammpsConfigIo()
Destructor.
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 setOrthorhombic(const Vector &lengths)
Set unit cell dimensions for orthorhombic boundary.
const Vector & lengths() const
Get Vector of unit cell lengths by const reference.
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
Wrapper for a double precision number, for formatted ostream output.
Definition: Dbl.h:39
Classes used by all simpatico molecular simulations.
Molecule & getMolecule(int speciesId)
Get a new molecule from a reservoir of unused Molecule objects.
int nDihedral() const
Get number of dihedrals per molecule for this Species.
int nBondType() const
Get the number of bond types.
int nMolecule(int speciesId) const
Get the number of molecules of one Species in this System.
Definition: System.h:1128
void read(std::istream &in)
Read configuration (particle positions) from file.
#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
bool notEnd() const
Is the current pointer not at the end of the PArray?
Utility classes for scientific computation.
Definition: accumulators.mod:1
System & system() const
Get a reference to the parent System.
Wrapper for an int, for formatted ostream output.
Definition: Int.h:36
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
Forward iterator for a PArray.
Definition: ArraySet.h:19
int nAngleType() const
Get the number of angle types.
static void setDefaultWidth(int width)
Set the default output field width.
Definition: Format.cpp:20
static void setDefaultPrecision(int precision)
Set the default output precision.
Definition: Format.cpp:26
A label string in a file format.
Definition: Label.h:36
Simulation & simulation() const
Get a reference to the parent Simulation.
int nDihedralType() const
Get the number of dihedral types.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
int nSpecies() const
Get the number of Species in this Simulation.
void write(std::ostream &out)
Write configuration (particle positions) to file.
Vector & subtract(const Vector &v1, const Vector &v2)
Subtract vector v2 from v1.
Definition: Vector.h:672
#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.
LammpsConfigIo(System &system)
Constructor.
A physical molecule (a set of covalently bonded Atoms).
int nAtomType() const
Get the number of atom types.
A Species represents a set of chemically similar molecules.
int nBond() const
Get number of bonds per molecule for this Species.
int nAngle() const
Get number of angles per molecule for this Species.
Species & species(int i)
Get a specific Species by reference.
static void initStatic()
Initialize or reset default width and precision values.
Definition: Format.cpp:47
System configuration file reader and writer.