Simpatico  v1.10
mcMd/simulation/Simulation.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 "Simulation.h"
9 
10 // namespace McMd
11 #include <mcMd/analyzers/AnalyzerManager.h>
12 #include <mcMd/species/SpeciesManager.h>
13 #include <mcMd/chemistry/Activate.h>
14 
15 // namespace Simp
16 #include <simp/species/Species.h>
17 #include <simp/species/SpeciesGroup.tpp>
18 
19 // namespace Util
20 #include <util/containers/ArraySet.h>
21 #include <util/param/Factory.h>
22 #include <util/space/Vector.h>
23 #include <util/misc/initStatic.h>
24 
25 #ifdef UTIL_MPI
26 #include "McMd_mpi.h"
27 #endif
28 
29 namespace McMd
30 {
31 
32  using namespace Util;
33  using namespace Simp;
34 
35  /*
36  * Constructor.
37  */
38  #ifdef UTIL_MPI
39  Simulation::Simulation(MPI::Intracomm& communicator)
40  : iStep_(0),
41  nSystem_(1),
42  speciesManagerPtr_(0),
43  analyzerManagerPtr_(0),
44  commandManagerPtr_(0),
45  moleculeCapacity_(0),
46  nAtomType_(-1),
47  atomCapacity_(0)
48  #ifndef SIMP_NOPAIR
49  , maskedPairPolicy_(MaskBonded)
50  #endif
51  #ifdef SIMP_BOND
52  , nBondType_(-1)
53  , bondCapacity_(0)
54  #endif
55  #ifdef SIMP_ANGLE
56  , nAngleType_(-1)
57  , angleCapacity_(0)
58  #endif
59  #ifdef SIMP_DIHEDRAL
60  , nDihedralType_(-1)
61  , dihedralCapacity_(0)
62  #endif
63  #ifdef SIMP_COULOMB
64  , hasCoulomb_(-1)
65  #endif
66  #ifdef SIMP_EXTERNAL
67  , hasExternal_(-1)
68  #endif
69  #ifdef MCMD_LINK
70  , nLinkType_(-1)
71  #endif
72  #ifdef SIMP_TETHER
73  , hasTether_(-1)
74  #endif
75  #ifdef SIMP_SPECIAL
76  , hasSpecial_(-1)
77  #endif
78  , hasSpecies_(false)
79  , communicatorPtr_(&communicator)
80  {
81  setClassName("Simulation");
85 
86  if (!MPI::Is_initialized()) {
87  UTIL_THROW("MPI not initialized on entry");
88  }
90 
91  // Set directory Id in FileMaster to MPI processor rank.
92  int rank = communicatorPtr_->Get_rank();
93  fileMaster_.setDirectoryId(rank);
94 
95  // Set log file for processor n to a new file named "n/log"
96  // Relies on initialization of FileMaster outputPrefix to "" (empty).
97  fileMaster_.openOutputFile("log", logFile_);
98  Log::setFile(logFile_);
99 
100  speciesManagerPtr_ = new SpeciesManager;
101  }
102  #endif
103 
104  /*
105  * Constructor.
106  */
108  : iStep_(0),
109  nSystem_(1),
110  speciesManagerPtr_(0),
111  analyzerManagerPtr_(0),
112  commandManagerPtr_(0),
113  moleculeCapacity_(0),
114  nAtomType_(-1),
115  atomCapacity_(0)
116  #ifndef SIMP_NOPAIR
117  , maskedPairPolicy_(MaskBonded)
118  #endif
119  #ifdef SIMP_BOND
120  , nBondType_(-1)
121  , bondCapacity_(0)
122  #endif
123  #ifdef SIMP_ANGLE
124  , nAngleType_(-1)
125  , angleCapacity_(0)
126  #endif
127  #ifdef SIMP_DIHEDRAL
128  , nDihedralType_(-1)
129  , dihedralCapacity_(0)
130  #endif
131  #ifdef SIMP_COULOMB
132  , hasCoulomb_(-1)
133  #endif
134  #ifdef SIMP_EXTERNAL
135  , hasExternal_(-1)
136  #endif
137  #ifdef MCMD_LINK
138  , nLinkType_(-1)
139  #endif
140  #ifdef SIMP_TETHER
141  , hasTether_(-1)
142  #endif
143  #ifdef SIMP_SPECIAL
144  , hasSpecial_(-1)
145  #endif
146  , hasSpecies_(false)
147  #ifdef UTIL_MPI
148  , communicatorPtr_(0)
149  #endif
150  {
151  setClassName("Simulation");
155  speciesManagerPtr_ = new SpeciesManager;
156  }
157 
158  /*
159  * Destructor.
160  */
162  {
163  if (speciesManagerPtr_) {
164  delete speciesManagerPtr_;
165  }
166 
168 
169  #ifdef UTIL_MPI
170  if (logFile_.is_open()) logFile_.close();
171  #endif
172  }
173 
174  /*
175  * Set AnalyzerManager - protected, called by subclass constructor.
176  */
178  { analyzerManagerPtr_ = ptr; }
179 
180  /*
181  * Set CommandManager - protected, called by subclass constructor.
182  */
184  { commandManagerPtr_ = ptr; }
185 
186  #ifdef UTIL_MPI
187  /*
188  * Set an MPI job to read a single parameter file, from std::cin.
189  */
191  {
192  if (!hasCommunicator()) {
193  UTIL_THROW("No communicator was passed to constructor");
194  } else
195  if (communicatorPtr_ != &communicator) {
196  UTIL_THROW("ParamCommunicator must be the one passed to constructor");
197  }
198  fileMaster_.setCommonControl();
199  ParamComponent::setIoCommunicator(communicator);
200  }
201 
202  /*
203  * Set an MPI job to read a single parameter file, from std::cin.
204  */
207  #endif
208 
209  /*
210  * Read parameter file.
211  */
212  void Simulation::readParameters(std::istream& in)
213  {
214  // Preconditions
215  assert(speciesManagerPtr_);
216 
217  readParamComposite(in, fileMaster_);
218 
219  read<int>(in, "nAtomType", nAtomType_);
220  if (nAtomType_ <= 0) {
221  UTIL_THROW("nAtomType must be > 0");
222  }
223  #ifdef SIMP_BOND
224  nBondType_ = 0; // Default value
225  readOptional<int>(in, "nBondType", nBondType_);
226  if (nBondType_ < 0) {
227  UTIL_THROW("nBondType must be >= 0");
228  }
229  #endif
230  #ifdef SIMP_ANGLE
231  nAngleType_ = 0; // Default value
232  readOptional<int>(in, "nAngleType", nAngleType_);
233  if (nAngleType_ < 0) {
234  UTIL_THROW("nAngleType must be >= 0");
235  }
236  #endif
237  #ifdef SIMP_DIHEDRAL
238  nDihedralType_ = 0; // Default value
239  readOptional<int>(in, "nDihedralType", nDihedralType_);
240  if (nDihedralType_ < 0) {
241  UTIL_THROW("nDihedralType must be >= 0");
242  }
243  #endif
244  #ifdef SIMP_COULOMB
245  hasCoulomb_ = 0;
246  readOptional<int>(in, "hasCoulomb", hasCoulomb_);
247  if ((hasCoulomb_ != 0) && (hasCoulomb_ != 1)) {
248  UTIL_THROW("hasCoulomb must be 0 or 1");
249  }
250  #endif
251  #ifdef SIMP_EXTERNAL
252  hasExternal_ = 0; // Default value
253  readOptional<int>(in, "hasExternal", hasExternal_);
254  if (hasExternal_ < 0) {
255  UTIL_THROW("hasExternal must be >= 0");
256  }
257  #endif
258  #ifdef MCMD_LINK
259  nLinkType_ = 0; // Default value
260  readOptional<int>(in, "nLinkType", nLinkType_);
261  if (nLinkType_ < 0) {
262  UTIL_THROW("nLinkType must be >= 0");
263  }
264  #endif
265  #ifdef SIMP_TETHER
266  hasTether_ = 0; // Default value
267  readOptional<int>(in, "hasTether", hasTether_);
268  if (hasTether_ < 0) {
269  UTIL_THROW("hasTether must be >= 0");
270  }
271  #endif
272  #ifdef SIMP_SPECIAL
273  hasSpecial_ = 0; // Default value
274  readOptional<int>(in, "hasSpecial", hasSpecial_);
275  if (hasSpecial_ < 0) {
276  UTIL_THROW("hasSpecial must be >= 0");
277  }
278  #endif
279 
280  // Allocate and initialize array of AtomType objects
281  atomTypes_.allocate(nAtomType_);
282  for (int i = 0; i < nAtomType_; ++i) {
283  atomTypes_[i].setId(i);
284  #ifdef SIMP_COULOMB
285  atomTypes_[i].setHasCharge(hasCoulomb_);
286  #endif
287  }
288 
289  // Read AtomType data from file
290  readDArray<AtomType>(in, "atomTypes", atomTypes_, nAtomType_);
291 
292  #ifndef SIMP_NOPAIR
293  read<MaskPolicy>(in, "maskedPairPolicy", maskedPairPolicy_);
294  #endif
295 
296  readParamComposite(in, *speciesManagerPtr_);
297  for (int iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) {
298  species(iSpecies).setId(iSpecies);
299  }
300 
301  readParamComposite(in, random_);
302 
303  // Allocate, initialize arrays that require Species data.
304  initializeSpeciesData();
305 
307  }
308 
309 
310  /*
311  * Open, write and close a parameter file.
312  */
313  void Simulation::writeParam(std::string filename)
314  {
315  std::ofstream file;
316  fileMaster().openOutputFile(filename, file);
317  writeParam(file);
318  file.close();
319  }
320 
321  /*
322  * Load internal state from an archive.
323  */
325  {
326  loadParamComposite(ar, fileMaster_);
327 
328  loadParameter<int>(ar, "nAtomType", nAtomType_);
329  #ifdef SIMP_BOND
330  loadParameter<int>(ar, "nBondType", nBondType_);
331  #endif
332  #ifdef SIMP_ANGLE
333  nAngleType_ = 0;
334  loadParameter<int>(ar, "nAngleType", nAngleType_, false);
335  #endif
336  #ifdef SIMP_DIHEDRAL
337  nDihedralType_ = 0;
338  loadParameter<int>(ar, "nDihedralType", nDihedralType_, false);
339  #endif
340  #ifdef SIMP_COULOMB
341  hasCoulomb_ = 0;
342  loadParameter<int>(ar, "hasCoulomb", hasCoulomb_, false);
343  #endif
344  #ifdef SIMP_EXTERNAL
345  hasExternal_ = 0;
346  loadParameter<int>(ar, "hasExternal", hasExternal_, false);
347  #endif
348  #ifdef MCMD_LINK
349  nLinkType_ = 0;
350  loadParameter<int>(ar, "nLinkType", nLinkType_, false);
351  #endif
352  #ifdef SIMP_TETHER
353  hasTether_ = false;
354  loadParameter<int>(ar, "hasTether", hasTether_, false);
355  #endif
356  #ifdef SIMP_SPECIAL
357  hasSpecial_ = 0;
358  loadParameter<int>(ar, "hasSpecial", hasSpecial_, false);
359  #endif
360 
361  // Allocate and load an array of AtomType objects
362  atomTypes_.allocate(nAtomType_);
363  for (int i = 0; i < nAtomType_; ++i) {
364  atomTypes_[i].setId(i);
365  }
366  loadDArray<AtomType>(ar, "atomTypes", atomTypes_, nAtomType_);
367 
368  #ifndef SIMP_NOPAIR
369  loadParameter<MaskPolicy>(ar, "maskedPairPolicy", maskedPairPolicy_);
370  #endif
371  loadParamComposite(ar, *speciesManagerPtr_);
372  for (int iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) {
373  species(iSpecies).setId(iSpecies);
374  }
375  loadParamComposite(ar, random_);
376 
377  // Allocate and initialize all private arrays.
378  initializeSpeciesData();
379 
381  }
382 
383  /*
384  * Load internal state from an archive.
385  */
387  {
388  fileMaster_.save(ar);
389  ar << nAtomType_;
390  #ifdef SIMP_BOND
391  ar << nBondType_;
392  #endif
393  #ifdef SIMP_ANGLE
394  Parameter::saveOptional(ar, nAngleType_, (bool)nAngleType_);
395  #endif
396  #ifdef SIMP_DIHEDRAL
397  Parameter::saveOptional(ar, nDihedralType_, (bool)nDihedralType_);
398  #endif
399  #ifdef SIMP_COULOMB
400  Parameter::saveOptional(ar, hasCoulomb_, hasCoulomb_);
401  #endif
402  #ifdef SIMP_EXTERNAL
403  Parameter::saveOptional(ar, hasExternal_, hasExternal_);
404  #endif
405  #ifdef MCMD_LINK
406  Parameter::saveOptional(ar, nLinkType_, (bool)nLinkType_);
407  #endif
408  #ifdef SIMP_TETHER
409  ar << hasTether_;
410  Parameter::saveOptional(ar, hasTether_, hasTether_);
411  #endif
412  #ifdef SIMP_SPECIAL
413  Parameter::saveOptional(ar, hasSpecial_, hasSpecial_);
414  #endif
415 
416  ar << atomTypes_;
417  #ifndef SIMP_NOPAIR
418  ar & maskedPairPolicy_;
419  #endif
420  (*speciesManagerPtr_).save(ar);
421  random_.save(ar);
422  }
423 
424  /*
425  * Allocate, initialize private arrays that require Species data (private).
426  *
427  * Allocates global arrays (molecules_, atoms_, bonds_, angles_) and the
428  * arrays first<class>Ids_ of integers to species blocks. Initializes:
429  *
430  * - Capacity values and first<class>Ptr_ addresses.
431  * - Integer ids for Species and Molecule objects.
432  * - Pointers between Species, Molecule, and Atom objects
433  * - Atom typeIds and all Bond and Angle objects.
434  */
435  void Simulation::initializeSpeciesData()
436  {
437  //Preconditions
438  assert(nSpecies() > 0);
439  if (nSpecies() <= 0) {
440  UTIL_THROW("Error: nSpecies() <= 0 in Simulation::initialize()");
441  }
442  #ifdef SIMP_BOND
443  if (nBondType_ < 0) {
444  UTIL_THROW("Error: nBondType < 0 in Simulation::initialize()");
445  }
446  #endif
447  #ifdef SIMP_ANGLE
448  if (nAngleType_ < 0) {
449  UTIL_THROW("Error: nAngleType < 0 in Simulation::initialize()");
450  }
451  #endif
452  #ifdef SIMP_DIHEDRAL
453  if (nDihedralType_ < 0) {
454  UTIL_THROW("Error: nDihedralType < 0 in Simulation::initialize()");
455  }
456  #endif
457  #ifdef MCMD_LINK
458  if (nLinkType_ < 0) {
459  UTIL_THROW("Error: nLinkType_ < 0 in Simulation::initialize()");
460  }
461  #endif
462  if (hasSpecies_) {
463  UTIL_THROW("Attempt to re-initialize species data arrays");
464  }
465 
466  Species *speciesPtr;
467  int nAtom, iSpecies;
468  int capacity;
469  #ifdef SIMP_BOND
470  int nBond;
471  #endif
472  #ifdef SIMP_ANGLE
473  int nAngle;
474  #endif
475  #ifdef SIMP_DIHEDRAL
476  int nDihedral;
477  #endif
478 
479  // Allocate arrays dimensioned by nSpecies().
480  reservoirs_.allocate(nSpecies());
481  firstMoleculeIds_.allocate(nSpecies());
482  firstAtomIds_.allocate(nSpecies());
483  #ifdef SIMP_BOND
484  if (nBondType_ > 0) {
485  firstBondIds_.allocate(nSpecies());
486  }
487  #endif
488  #ifdef SIMP_ANGLE
489  if (nAngleType_ > 0) {
490  firstAngleIds_.allocate(nSpecies());
491  }
492  #endif
493  #ifdef SIMP_DIHEDRAL
494  if (nDihedralType_ > 0) {
495  firstDihedralIds_.allocate(nSpecies());
496  }
497  #endif
498 
499  // Count Molecules, Atoms and Groups.
500  moleculeCapacity_ = 0;
501  atomCapacity_ = 0;
502  #ifdef SIMP_BOND
503  bondCapacity_ = 0;
504  #endif
505  #ifdef SIMP_ANGLE
506  angleCapacity_ = 0;
507  #endif
508  #ifdef SIMP_DIHEDRAL
509  dihedralCapacity_ = 0;
510  #endif
511  for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) {
512  speciesPtr = &species(iSpecies);
513 
514  // Check species id
515  if (speciesPtr->id() != iSpecies) {
516  UTIL_THROW("Inconsistent species ids");
517  }
518  //speciesPtr->setId(iSpecies);
519 
520  // Allocate reservoir for this species
521  reservoirs_[iSpecies].allocate(speciesPtr->capacity());
522 
523  // Set indexes of first objects of the blocks for this species
524  firstMoleculeIds_[iSpecies] = moleculeCapacity_;
525  firstAtomIds_[iSpecies] = atomCapacity_;
526  #ifdef SIMP_BOND
527  if (nBondType_ > 0) {
528  firstBondIds_[iSpecies] = bondCapacity_;
529  }
530  #endif
531  #ifdef SIMP_ANGLE
532  if (nAngleType_ > 0) {
533  firstAngleIds_[iSpecies] = angleCapacity_;
534  }
535  #endif
536  #ifdef SIMP_DIHEDRAL
537  if (nDihedralType_ > 0) {
538  firstDihedralIds_[iSpecies] = dihedralCapacity_;
539  }
540  #endif
541 
542  // Increment total capacity values
543  capacity = speciesPtr->capacity();
544  nAtom = speciesPtr->nAtom();
545  moleculeCapacity_ += capacity;
546  atomCapacity_ += capacity*nAtom;
547  #ifdef SIMP_BOND
548  if (nBondType_ > 0) {
549  nBond = speciesPtr->nBond();
550  bondCapacity_ += capacity*nBond;
551  }
552  #endif
553  #ifdef SIMP_ANGLE
554  if (nAngleType_ > 0) {
555  nAngle = speciesPtr->nAngle();
556  angleCapacity_ += capacity*nAngle;
557  }
558  #endif
559  #ifdef SIMP_DIHEDRAL
560  if (nDihedralType_ > 0) {
561  nDihedral = speciesPtr->nDihedral();
562  dihedralCapacity_ += capacity*nDihedral;
563  }
564  #endif
565  }
566 
567  // Allocate global array of atoms (static member of Atom class).
568  Atom::allocate(atomCapacity_, atoms_);
569 
570  // Allocate other global arrays (members of Simulation).
571  molecules_.allocate(moleculeCapacity_);
572 
573  // Initialize all Molecule and atom objects.
574  for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) {
575  speciesPtr = &species(iSpecies);
576  initializeSpeciesMolecules(iSpecies);
577  }
578 
579  #ifdef SIMP_BOND
580  // Initialize bonds.
581  if (nBondType_ > 0) {
582  if (bondCapacity_ > 0) {
583  bonds_.allocate(bondCapacity_);
584  } else {
585  bonds_.allocate(1);
586  }
587  for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) {
588  initializeSpeciesBonds(iSpecies);
589  }
590  }
591  #endif
592 
593  #ifdef SIMP_ANGLE
594  // Initialize angles.
595  if (nAngleType_ > 0) {
596  if (angleCapacity_ > 0) {
597  angles_.allocate(angleCapacity_);
598  } else {
599  angles_.allocate(1);
600  }
601  for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) {
602  initializeSpeciesAngles(iSpecies);
603  }
604  }
605  #endif
606 
607  #ifdef SIMP_DIHEDRAL
608  // Initialize dihedrals.
609  if (nDihedralType_ > 0) {
610  if (dihedralCapacity_ > 0) {
611  dihedrals_.allocate(dihedralCapacity_);
612  } else {
613  dihedrals_.allocate(1);
614  }
615  for (iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) {
616  initializeSpeciesDihedrals(iSpecies);
617  }
618  }
619  #endif
620 
621  // Assert: arrays that depends on Species info are initialized
622  hasSpecies_ = true;
623  }
624 
625  /*
626  * Initialize all Molecule and Atom objects for one Species (private).
627  *
628  * This function creates associations between Species, Molecule, and
629  * Atom objects for all molecules of one species, & sets atom typeIds.
630  *
631  * For each molecule, it sets the id, species pointer, nAtom, and the
632  * firstAtom pointer. The molecule id is only unique within a species.
633  *
634  * For each atom, it sets the molecule pointer and an integer typeId.
635  *
636  * This function also pushes all molecules of the species onto the
637  * reservoir, pushing them in order of decreasing molecule id.
638  */
639  void Simulation::initializeSpeciesMolecules(int iSpecies)
640  {
641 
642  Species* speciesPtr;
643  Molecule* moleculePtr;
644  Atom* atomPtr;
645  int iMol, iAtom;
646  int capacity, nAtom;
647 
648  speciesPtr = &species(iSpecies);
649  capacity = speciesPtr->capacity();
650  nAtom = speciesPtr->nAtom();
651 
652  // Initialize pointers before loop
653  moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]];
654  atomPtr = &atoms_[firstAtomIds_[iSpecies]];
655 
656  // Loop over all molecules in Species
657  for (iMol = 0; iMol < capacity; ++iMol) {
658 
659  // Initialize a Molecule
660  moleculePtr->setId(iMol);
661  moleculePtr->setSpecies(*speciesPtr);
662  moleculePtr->setNAtom(nAtom);
663  moleculePtr->setFirstAtom(*atomPtr);
664 
665  // Loop over atoms in a molecule, set molecule and atom TypeId
666  for (iAtom = 0; iAtom < nAtom; ++iAtom) {
667  atomPtr->setMolecule(*moleculePtr);
668  atomPtr->setTypeId(speciesPtr->atomTypeId(iAtom));
669  ++atomPtr;
670  }
671 
672  ++moleculePtr;
673  }
674 
675  // Push all molecules of this species onto the reservoir stack
676  // Push on in reverse order, so that they pop off in sequence
677  moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]
678  + capacity - 1];
679  for (iMol = 0; iMol < capacity; ++iMol) {
680  reservoirs_[iSpecies].push(*moleculePtr);
681  --moleculePtr;
682  }
683 
684  }
685 
686  #ifdef SIMP_BOND
687  /*
688  * Initialize Bond objects for Molecules of one Species. (private)
689  *
690  * This functions assigns Atom pointers and bond types ids within
691  * a contiguous block of Bond objects, and sets a pointer in each
692  * Molecule to the first Bond in the associated block.
693  */
694  void Simulation::initializeSpeciesBonds(int iSpecies)
695  {
696  if (nBondType_ <= 0) {
697  UTIL_THROW("nBondType_ must be positive");
698  }
699 
700  Species* speciesPtr = 0;
701  Molecule* moleculePtr = 0;
702  Bond* bondPtr = 0;
703  Atom* firstAtomPtr;
704  Atom* atom0Ptr;
705  Atom* atom1Ptr;
706  int iMol, iBond, atom0Id, atom1Id, type;
707  int capacity, nBond;
708 
709  speciesPtr = &species(iSpecies);
710  nBond = speciesPtr->nBond();
711  capacity = speciesPtr->capacity();
712 
713  // Initialize pointers before loop
714  moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]];
715  // bondPtr = &bonds_[firstBondIds_[iSpecies]];
716  bondPtr = &bonds_[0] + firstBondIds_[iSpecies];
717 
718  // Loop over molecules in Species
719  for (iMol = 0; iMol < capacity; ++iMol) {
720 
721  firstAtomPtr = &(moleculePtr->atom(0));
722  moleculePtr->setFirstBond(*bondPtr);
723  moleculePtr->setNBond(nBond);
724 
725  if (nBond > 0) {
726 
727  // Create bonds for a molecule
728  for (iBond = 0; iBond < nBond; ++iBond) {
729 
730  // Get pointers to bonded atoms and bond type
731  atom0Id = speciesPtr->speciesBond(iBond).atomId(0);
732  atom1Id = speciesPtr->speciesBond(iBond).atomId(1);
733  type = speciesPtr->speciesBond(iBond).typeId();
734  atom0Ptr = firstAtomPtr + atom0Id;
735  atom1Ptr = firstAtomPtr + atom1Id;
736 
737  // Set fields of the Bond object
738  bondPtr->setAtom(0, *atom0Ptr);
739  bondPtr->setAtom(1, *atom1Ptr);
740  bondPtr->setTypeId(type);
741 
742  #ifndef SIMP_NOPAIR
743  // If MaskBonded, add each atom to its partner's Mask
744  if (maskedPairPolicy_ == MaskBonded) {
745  atom0Ptr->mask().append(*atom1Ptr);
746  atom1Ptr->mask().append(*atom0Ptr);
747  }
748  #endif
749 
750  ++bondPtr;
751  }
752 
753  }
754  ++moleculePtr;
755  }
756 
757  }
758  #endif
759 
760  #ifdef SIMP_ANGLE
761  /*
762  * Initialize all Angle objects for Molecules of one Species.
763  *
764  * This functions assigns Atom pointers and angle types ids within
765  * a contiguous block of Angle objects, and sets a pointer in each
766  * Molecule to the first Angle in the associated block.
767  */
768  void Simulation::initializeSpeciesAngles(int iSpecies)
769  {
770 
771  if (nAngleType_ <= 0) {
772  UTIL_THROW("nAngleType must be positive");
773  }
774 
775  Species* speciesPtr = 0;
776  Molecule* moleculePtr = 0;
777  Angle* anglePtr = 0;
778  Atom* firstAtomPtr, *atom0Ptr, *atom1Ptr, *atom2Ptr;
779  int iMol, iAngle, atom0Id, atom1Id, atom2Id, type;
780  int capacity, nAngle;
781 
782  speciesPtr = &species(iSpecies);
783  capacity = speciesPtr->capacity();
784  nAngle = speciesPtr->nAngle();
785 
786  // Initialize pointers before loop
787  moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]];
788  // anglePtr = &angles_[firstAngleIds_[iSpecies]];
789  anglePtr = &angles_[0] + firstAngleIds_[iSpecies];
790 
791  // Loop over molecules in Species
792  for (iMol = 0; iMol < capacity; ++iMol) {
793 
794  firstAtomPtr = &(moleculePtr->atom(0));
795  moleculePtr->setFirstAngle(*anglePtr);
796  moleculePtr->setNAngle(nAngle);
797 
798  if (nAngle > 0) {
799 
800  // Create angles for a molecule
801  for (iAngle = 0; iAngle < nAngle; ++iAngle) {
802 
803  // Get pointers to 3 atoms and an angle type
804  atom0Id = speciesPtr->speciesAngle(iAngle).atomId(0);
805  atom1Id = speciesPtr->speciesAngle(iAngle).atomId(1);
806  atom2Id = speciesPtr->speciesAngle(iAngle).atomId(2);
807  type = speciesPtr->speciesAngle(iAngle).typeId();
808  atom0Ptr = firstAtomPtr + atom0Id;
809  atom1Ptr = firstAtomPtr + atom1Id;
810  atom2Ptr = firstAtomPtr + atom2Id;
811 
812  // Set fields of the Angle object
813  anglePtr->setAtom(0, *atom0Ptr);
814  anglePtr->setAtom(1, *atom1Ptr);
815  anglePtr->setAtom(2, *atom2Ptr);
816  anglePtr->setTypeId(type);
817 
818  ++anglePtr;
819 
820  }
821 
822  }
823 
824  ++moleculePtr;
825  }
826 
827  }
828  #endif
829 
830  #ifdef SIMP_DIHEDRAL
831  /*
832  * Initialize all Dihedral objects for Molecules of one Species.
833  *
834  * This functions assigns Atom pointers dihedral types ids within
835  * a contiguous block of Dihedral objects, and sets a pointer in
836  * each Molecule to the first Dihedral in the associated block.
837  */
838  void Simulation::initializeSpeciesDihedrals(int iSpecies)
839  {
840 
841  Species* speciesPtr = 0;
842  Molecule* moleculePtr = 0;
843  Dihedral* dihedralPtr = 0;
844  Atom *firstAtomPtr, *atom0Ptr, *atom1Ptr, *atom2Ptr, *atom3Ptr;
845  int iMol, iDihedral, atom0Id, atom1Id, atom2Id, atom3Id, type;
846  int capacity, nDihedral;
847 
848  speciesPtr = &species(iSpecies);
849  capacity = speciesPtr->capacity();
850  nDihedral = speciesPtr->nDihedral();
851 
852  // Initialize pointers before loop
853  moleculePtr = &molecules_[firstMoleculeIds_[iSpecies]];
854  //dihedralPtr = &dihedrals_[firstDihedralIds_[iSpecies]];
855  dihedralPtr = &dihedrals_[0] + firstDihedralIds_[iSpecies];
856 
857  // Loop over molecules in Species
858  for (iMol = 0; iMol < capacity; ++iMol) {
859 
860  firstAtomPtr = &(moleculePtr->atom(0));
861  moleculePtr->setFirstDihedral(*dihedralPtr);
862  moleculePtr->setNDihedral(nDihedral);
863 
864  if (nDihedral > 0) {
865 
866  // Create dihedrals for a molecule
867  for (iDihedral = 0; iDihedral < nDihedral; ++iDihedral) {
868 
869  // Get local indices for atoms and dihedral type
870  atom0Id = speciesPtr->speciesDihedral(iDihedral).atomId(0);
871  atom1Id = speciesPtr->speciesDihedral(iDihedral).atomId(1);
872  atom2Id = speciesPtr->speciesDihedral(iDihedral).atomId(2);
873  atom3Id = speciesPtr->speciesDihedral(iDihedral).atomId(3);
874  type = speciesPtr->speciesDihedral(iDihedral).typeId();
875 
876  // Compute atom pointers
877  atom0Ptr = firstAtomPtr + atom0Id;
878  atom1Ptr = firstAtomPtr + atom1Id;
879  atom2Ptr = firstAtomPtr + atom2Id;
880  atom3Ptr = firstAtomPtr + atom3Id;
881 
882  // Set fields of the Dihedral object
883  dihedralPtr->setAtom(0, *atom0Ptr);
884  dihedralPtr->setAtom(1, *atom1Ptr);
885  dihedralPtr->setAtom(2, *atom2Ptr);
886  dihedralPtr->setAtom(3, *atom3Ptr);
887  dihedralPtr->setTypeId(type);
888 
889  ++dihedralPtr;
890  }
891  }
892  ++moleculePtr;
893  }
894 
895  }
896  #endif
897 
898  /*
899  * Associate and allocate a System MoleculeSet for a specified Species.
900  */
902  int speciesId) const
903  {
904  const Molecule* molecules = &molecules_[firstMoleculeIds_[speciesId]];
905  int capacity = species(speciesId).capacity();
906  set.allocate(molecules, capacity);
907  }
908 
909  /*
910  * Get a new molecule from a reservoir of unused Molecule objects.
911  */
913  {
914  Molecule* ptr = &reservoirs_[speciesId].pop();
915  Activate::activate(*ptr); // activate all atoms in molecule
916  return *ptr;
917  }
918 
919  /*
920  * Return a molecule to a reservoir of unused molecules.
921  */
923  {
924  int speciesId = molecule.species().id();
925  reservoirs_[speciesId].push(molecule);
926  }
927 
928  // Accessors
929 
930  /*
931  * Get number of Species in this Simulation.
932  */
934  { return speciesManagerPtr_->size(); }
935 
936  /*
937  * Get a reference to a Species object, identified by index.
938  */
940  { return (*speciesManagerPtr_)[i]; }
941 
942  /*
943  * Get a const reference to a Species object, identified by index.
944  */
945  const Species& Simulation::species(int i) const
946  { return (*speciesManagerPtr_)[i]; }
947 
948  /*
949  * Return true if valid, or throw an Exception.
950  */
951  bool Simulation::isValid() const
952  {
953  // Check indices of all Atom objects
954  for (int iAtom = 0; iAtom < atomCapacity_; ++iAtom) {
955  if (atoms_[iAtom].id() != iAtom) {
956  UTIL_THROW("Error in atom Ids");
957  }
958  }
959 
960  // Check validity of all Species objects.
961  for (int iSpecies=0; iSpecies < nSpecies(); ++iSpecies) {
962  species(iSpecies).isValid();
963  }
964 
965  // Declare and initialize pointers to atoms, bonds, etc.
966  const Atom* atomPtr = &(atoms_[0]);
967  #ifdef SIMP_BOND
968  const Bond* bondPtr = 0;
969  if (nBondType_ > 0) {
970  bondPtr = &(bonds_[0]);
971  }
972  #endif
973  #ifdef SIMP_ANGLE
974  const Angle* anglePtr = 0;
975  if (nAngleType_ > 0) {
976  anglePtr = &(angles_[0]);
977  }
978  #endif
979  #ifdef SIMP_DIHEDRAL
980  const Dihedral* dihedralPtr = 0;
981  if (nDihedralType_ > 0) {
982  dihedralPtr = &(dihedrals_[0]);
983  }
984  #endif
985  const Molecule* moleculePtr = &(atomPtr->molecule());
986 
987  // Loop over molecular species
988  for (int iSpecies = 0; iSpecies < nSpecies(); ++iSpecies) {
989 
990  // Declare / initialize variables for this Species
991  const Species* speciesPtr = &(species(iSpecies));
992  const int capacity = speciesPtr->capacity();
993  const int nAtom = speciesPtr->nAtom();
994  #ifdef SIMP_BOND
995  int nBond = 0;
996  if (nBondType_ > 0) {
997  nBond = speciesPtr->nBond();
998  }
999  #endif
1000  #ifdef SIMP_ANGLE
1001  int nAngle = 0;
1002  if (nAngleType_ > 0) {
1003  nAngle = speciesPtr->nAngle();
1004  }
1005  #endif
1006  #ifdef SIMP_DIHEDRAL
1007  int nDihedral = 0;
1008  if (nDihedralType_ > 0) {
1009  nDihedral = speciesPtr->nDihedral();
1010  }
1011  #endif
1012 
1013  // Loop over molecules allocated for a species
1014  for (int iMol = 0; iMol < capacity; ++iMol) {
1015 
1016  // Validate molecule
1017  if (&moleculePtr->species() != speciesPtr) {
1018  UTIL_THROW("Inconsistent molecule.species()");
1019  }
1020  if (moleculePtr->id() != iMol) {
1021  UTIL_THROW("Inconsistent molecule.id()");
1022  }
1023 
1024  // Validate atoms within a molecule
1025  {
1026  if (&moleculePtr->atom(0) != atomPtr) {
1027  UTIL_THROW("Error in molecule::bond()");
1028  }
1029 
1030  int type;
1031  for (int iAtom = 0; iAtom < nAtom; ++iAtom) {
1032 
1033  // Validate pointers linking atom and molecule
1034  if (&(atomPtr->molecule()) != moleculePtr) {
1035  UTIL_THROW("Inconsistent atom.molecule()");
1036  }
1037  if (atomPtr != &(moleculePtr->atom(iAtom))) {
1038  UTIL_THROW("Inconsistent molecule.atom()");
1039  }
1040 
1041  // Require that atom be active
1042  if (!atomPtr->isActive()) {
1043  UTIL_THROW("Atom is inactive");
1044  }
1045 
1046  // Validate atom type, if species is not mutable
1047  if (!speciesPtr->isMutable()) {
1048  type = atomPtr->typeId();
1049  if (type < 0 || type >= nAtomType_) {
1050  UTIL_THROW("Invalid atom type id");
1051  }
1052  if (type != speciesPtr->atomTypeId(iAtom)) {
1053  UTIL_THROW("Inconsistent atom type");
1054  }
1055  }
1056 
1057 
1058  ++atomPtr;
1059  }
1060  }
1061 
1062  #ifdef SIMP_BOND
1063  if (nBondType_ > 0 && nBond > 0) {
1064 
1065  if (&moleculePtr->bond(0) != bondPtr) {
1066  UTIL_THROW("Error in molecule::bond()");
1067  }
1068  if (moleculePtr->nBond() != nBond) {
1069  UTIL_THROW("Inconsistent values of nBond");
1070  }
1071 
1072  const Atom* atom0Ptr;
1073  const Atom* atom1Ptr;
1074  int id0, id1, bondType;
1075 
1076  // Validate bonds within a molecule
1077  for (int iBond = 0; iBond < nBond; ++iBond) {
1078 
1079  // Get data from associated SpeciesBond
1080  id0 = speciesPtr->speciesBond(iBond).atomId(0);
1081  id1 = speciesPtr->speciesBond(iBond).atomId(1);
1082  bondType = speciesPtr->speciesBond(iBond).typeId();
1083 
1084  // Validate SpeciesBond
1085  if (id0 < 0 || id0 >= nAtom) {
1086  UTIL_THROW("Invalid local atom id in a SpeciesBond");
1087  }
1088  if (id1 < 0 || id1 >= nAtom) {
1089  UTIL_THROW("Invalid local atom id in a SpeciesBond");
1090  }
1091  if (bondType < 0 || bondType >= nBondType_) {
1092  std::cout << "bondType = " << bondType
1093  << std::endl;
1094  std::cout << "nBondType_ = " << nBondType_
1095  << std::endl;
1096  UTIL_THROW("Invalid bondType in a SpeciesBond");
1097  }
1098 
1099  // Validate consistency of Bond and SpeciesBond
1100  atom0Ptr = &(bondPtr->atom(0));
1101  atom1Ptr = &(bondPtr->atom(1));
1102  if (atom0Ptr != &(moleculePtr->atom(id0))) {
1103  UTIL_THROW("Inconsistent atom handle for a Bond");
1104  }
1105  if (atom1Ptr != &(moleculePtr->atom(id1))) {
1106  UTIL_THROW("Inconsistent atom handle for a Bond");
1107  }
1108  if (bondPtr->typeId() != bondType) {
1109  UTIL_THROW("Inconsistent bond type index");
1110  }
1111 
1112  // Require that bond be active
1113  if (!bondPtr->isActive()) {
1114  UTIL_THROW("Bond is inactive");
1115  }
1116 
1117  #ifndef SIMP_NOPAIR
1118  // If MaskBonded, check that bonded atoms are masked
1119  if (maskedPairPolicy_ == MaskBonded) {
1120 
1121  if (!atom0Ptr->mask().isMasked(*atom1Ptr)) {
1122  UTIL_THROW("Missing masked partner");
1123  }
1124  if (!atom1Ptr->mask().isMasked(*atom0Ptr)) {
1125  UTIL_THROW("Missing masked partner");
1126  }
1127 
1128  }
1129  #endif
1130 
1131  ++bondPtr;
1132  }
1133  }
1134  #endif
1135 
1136  #ifdef SIMP_ANGLE
1137  if (nAngleType_ > 0 && nAngle > 0) {
1138 
1139  if (&moleculePtr->angle(0) != anglePtr) {
1140  UTIL_THROW("Error in molecule::angle()");
1141  }
1142  if (moleculePtr->nAngle() != nAngle) {
1143  UTIL_THROW("Inconsistent values of nAngle");
1144  }
1145 
1146  const Atom* atom0Ptr = 0;
1147  const Atom* atom1Ptr = 0;
1148  const Atom* atom2Ptr = 0;
1149  int id0, id1, id2, angleType;
1150 
1151  // Validate angles within a molecule
1152  for (int iAngle = 0; iAngle < nAngle; ++iAngle) {
1153 
1154  // Get data from associated SpeciesAngle
1155  id0 = speciesPtr->speciesAngle(iAngle).atomId(0);
1156  id1 = speciesPtr->speciesAngle(iAngle).atomId(1);
1157  id2 = speciesPtr->speciesAngle(iAngle).atomId(2);
1158  angleType = speciesPtr->speciesAngle(iAngle).typeId();
1159 
1160  // Validate SpeciesAngle object
1161  if (id0 < 0 || id0 >= nAtom) {
1162  UTIL_THROW("Invalid local atom id in a SpeciesAngle");
1163  }
1164  if (id1 < 0 || id1 >= nAtom) {
1165  UTIL_THROW("Invalid local atom id in a SpeciesAngle");
1166  }
1167  if (id2 < 0 || id2 >= nAtom) {
1168  UTIL_THROW("Invalid local atom id in a SpeciesAngle");
1169  }
1170  if (angleType < 0 || angleType >= nAngleType_) {
1171  UTIL_THROW("Invalid local atom id in a SpeciesAngle");
1172  }
1173 
1174  // Validate consistency of Angle and SpeciesAngle
1175  atom0Ptr = &(anglePtr->atom(0));
1176  atom1Ptr = &(anglePtr->atom(1));
1177  atom2Ptr = &(anglePtr->atom(2));
1178 
1179  if (atom0Ptr != &(moleculePtr->atom(id0))) {
1180  UTIL_THROW("Inconsistent atom handle for an Angle");
1181  }
1182  if (atom1Ptr != &(moleculePtr->atom(id1))) {
1183  UTIL_THROW("Inconsistent atom handle for an Angle");
1184  }
1185  if (atom2Ptr != &(moleculePtr->atom(id2))) {
1186  UTIL_THROW("Inconsistent atom handle for an Angle");
1187  }
1188  if (anglePtr->typeId() != angleType) {
1189  UTIL_THROW("Inconsistent angle type index");
1190  }
1191 
1192  // Require that angle be active
1193  if (!anglePtr->isActive()) {
1194  UTIL_THROW("Angle is inactive");
1195  }
1196 
1197  ++anglePtr;
1198  }
1199  }
1200  #endif
1201 
1202  #ifdef SIMP_DIHEDRAL
1203  if (nDihedralType_ > 0 && nDihedral > 0) {
1204 
1205  const Atom* tAtomPtr;
1206  int tAtomId, dihedralType;
1207 
1208  if (&moleculePtr->dihedral(0) != dihedralPtr) {
1209  UTIL_THROW("Error in molecule::dihedral()");
1210  }
1211  if (moleculePtr->nDihedral() != nDihedral) {
1212  UTIL_THROW("Inconsistent values of nDihedral");
1213  }
1214 
1215  // Validate dihedrals within a molecule
1216  for (int iDihedral = 0; iDihedral < nDihedral; ++iDihedral) {
1217 
1218  // Validate data from SpeciesDihedral
1219  for (int tId = 0; tId < 4; ++tId) {
1220  tAtomId =
1221  speciesPtr->speciesDihedral(iDihedral).atomId(tId);
1222  if (tId < 0 || tId >= nAtom)
1223  UTIL_THROW("Invalid local atom id in SpeciesDihedral");
1224 
1225  tAtomPtr = &(dihedralPtr->atom(tId));
1226  if (tAtomPtr != &(moleculePtr->atom(tAtomId))) {
1227  UTIL_THROW("Inconsistent atom handle for an Dihedral");
1228  }
1229  }
1230  dihedralType =
1231  speciesPtr->speciesDihedral(iDihedral).typeId();
1232  if (dihedralType < 0 || dihedralType >= nDihedralType_) {
1233  UTIL_THROW("Invalid local atom id in a SpeciesDihedral");
1234  }
1235  if (dihedralType != dihedralPtr->typeId()) {
1236  UTIL_THROW("Inconsistent dihedral type index");
1237  }
1238 
1239  // Require that dihedral be active
1240  if (!dihedralPtr->isActive()) {
1241  UTIL_THROW("Dihedral is inactive");
1242  }
1243 
1244  ++dihedralPtr;
1245  }
1246 
1247  }
1248  #endif
1249 
1250  ++moleculePtr;
1251  }
1252  }
1253 
1254  return true;
1255  }
1256 
1257  void Simulation::outputOptions(std::ostream& out) const
1258  {
1259  #ifdef UTIL_DEBUG
1260  out << "-g Debugging ON " << std::endl;
1261  #else
1262  out << "-g Debugging OFF" << std::endl;
1263  #endif
1264  #ifdef UTIL_MPI
1265  out << "-m MPI ON " << std::endl;
1266  #else
1267  out << "-m MPI OFF" << std::endl;
1268  #endif
1269  #ifdef SIMP_COULOMB
1270  out << "-c Coulomb ON " << std::endl;
1271  #else
1272  out << "-c Coulomb OFF" << std::endl;
1273  #endif
1274  #ifndef SIMP_NOPAIR
1275  out << "-np Pairs ON " << std::endl;
1276  #else
1277  out << "-np Pairs OFF" << std::endl;
1278  #endif
1279  #ifdef SIMP_BOND
1280  out << "-b Bonds ON " << std::endl;
1281  #else
1282  out << "-b Bonds OFF" << std::endl;
1283  #endif
1284  #ifdef SIMP_ANGLE
1285  out << "-a Angles ON " << std::endl;
1286  #else
1287  out << "-a Angles OFF" << std::endl;
1288  #endif
1289  #ifdef SIMP_DIHEDRAL
1290  out << "-d Dihedrals ON " << std::endl;
1291  #else
1292  out << "-d Dihedrals OFF" << std::endl;
1293  #endif
1294  #ifdef SIMP_EXTERNAL
1295  out << "-e External ON " << std::endl;
1296  #else
1297  out << "-e External OFF" << std::endl;
1298  #endif
1299  #ifdef SIMP_SPECIAL
1300  out << "-s Special ON " << std::endl;
1301  #else
1302  out << "-s Special OFF" << std::endl;
1303  #endif
1304  #ifdef MCMD_LINK
1305  out << "-l Link ON " << std::endl;
1306  #else
1307  out << "-l Link OFF" << std::endl;
1308  #endif
1309  #ifdef MCMD_SHIFT
1310  out << "-i Shift ON " << std::endl;
1311  #else
1312  out << "-i Shift OFF" << std::endl;
1313  #endif
1314  }
1315 
1316  // Mutators / Setters
1317 
1318  /*
1319  * Return the Species factory by reference.
1320  */
1322  {
1323  UTIL_CHECK(speciesManagerPtr_);
1324  return speciesManagerPtr_->factory();
1325  }
1326 
1327  /*
1328  * Return the Analyzer factory by reference.
1329  */
1331  {
1332  UTIL_CHECK(analyzerManagerPtr_);
1333  return analyzerManagerPtr_->factory();
1334  }
1335 
1336 }
void setNAtom(int nAtom)
Set the number of Atoms per molecule.
Manager for Command objects in an MdSimulation.
static void initStatic()
Define and initialize baseInterval.
Bond & bond(int localId)
Get a specific Bond in this Molecule by non-const reference.
void setSpecies(Species &species)
Set the parent Species.
void setAtom(int i, Atom &atom)
Add an atom to this group.
void commitMpiTypes()
Commit all MPI data types needed for Mc and Md simulations.
Definition: McMd_mpi.cpp:31
int iStep_
Step index for main MC or MD loop.
Molecule & molecule() const
Get the parent Molecule by reference.
virtual void readParameters(std::istream &in)
Read parameter file block and initialize simulation.
const SpeciesDihedral & speciesDihedral(int iDihedral) const
Get a specific SpeciesDihedral object, by local angle index.
static void deallocate()
Delete all static arrays.
void setDirectoryId(int directoryId)
Set an integer directory identifier for this processor.
Definition: FileMaster.cpp:76
int nDihedral() const
Get the number of Dihedrals in this Molecule.
void setIoCommunicator(MPI::Intracomm &communicator)
Set the communicator.
Definition: MpiFileIo.cpp:36
int nAngle() const
Get the number of Angles in this Molecule.
int nAtom() const
Get number of atoms per molecule for this Species.
Factory< Analyzer > & analyzerFactory()
Return the Analyzer factory by reference.
void outputOptions(std::ostream &out) const
Output a list of options enabled and disabled during compilation.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
void setId(int id)
Set the integer index for this molecule.
Dihedral & dihedral(int localId)
Get a specific Dihedral in this Molecule by reference.
virtual ~Simulation()
Destructor.
Factory< Data > & factory()
Return a reference to the factory.
Definition: Manager.h:265
void setFirstBond(Bond &bond)
Set the first Bond.
void setTypeId(int typeId)
Set the group type id for this group.
void openOutputFile(const std::string &filename, std::ofstream &out, std::ios_base::openmode mode=std::ios_base::out) const
Open an output file.
Definition: FileMaster.cpp:290
void loadParamComposite(Serializable::IArchive &ar, ParamComposite &child, bool next=true)
Add and load a required child ParamComposite.
Mask & mask()
Get the associated Mask by reference.
bool isActive() const
Is this group active?
Species & species() const
Get the molecular Species by reference.
void setMolecule(Molecule &molecule)
Set the parent molecule.
int typeId() const
Get the typeId for this covalent group.
void allocateMoleculeSet(Util::ArraySet< Molecule > &set, int speciesId) const
Allocate and initialize a molecule set for one Species.
static void activate(Molecule &molecule)
Activate all atoms and groups in one molecule.
Definition: Activate.cpp:126
virtual bool isValid() const
Return true if Simulation is valid, or throw an Exception.
Classes used by all simpatico molecular simulations.
int nSystem_
Number of Systems of interacting molecules (> 1 in Gibbs ensemble).
void initStatic()
Guarantee initialization of all static class members in Util namespace.
Molecule & getMolecule(int speciesId)
Get a new molecule from a reservoir of unused Molecule objects.
int id() const
Get the index for this Molecule (unique in species).
void setNAngle(int nAngle)
Set the number of Angles per molecule.
void returnMolecule(Molecule &molecule)
Return a molecule to a reservoir of unused molecules.
static void setFile(std::ofstream &file)
Set the log ostream to a file.
Definition: Log.cpp:36
Saving / output archive for binary ostream.
void setFirstAtom(Atom &atom)
Set the first Atom.
const SpeciesBond & speciesBond(int iBond) const
Get a specific SpeciesBond object, by local bond index.
int nDihedral() const
Get number of dihedrals per molecule for this Species.
bool isMasked(const Atom &atom) const
True if the atom is in the masked set for the target Atom.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
bool isActive() const
Get the isActive flag.
static void initStatic()
Method to guarantee initialization of static data.
int typeId() const
Get type index for this Atom.
static void allocate(int capacity, RArray< Atom > &atoms)
Allocate a static array of Atom objects.
int nBond() const
Get the number of Bonds in this Molecule.
virtual void save(Serializable::OArchive &ar)
Save internal state to file.
Definition: Random.cpp:46
A container for pointers to a subset of elements of an associated array.
Definition: ArraySet.h:46
void setNBond(int nBond)
Set the number of Bonds per molecule.
bool hasSpecies() const
Has data for all species structures and capacities.
A point particle within a Molecule.
Utility classes for scientific computation.
Definition: accumulators.mod:1
void setAnalyzerManager(AnalyzerManager *ptr)
Set the associated AnalyzerManager.
void setCommandManager(CommandManager *ptr)
Set the associated CommandManager.
const SpeciesAngle & speciesAngle(int iAngle) const
Get a specific SpeciesAngle object, by local angle index.
int typeId() const
Get the type id for this covalent group.
Definition: SpeciesGroup.h:189
void setFirstDihedral(Dihedral &dihedral)
Set the first Dihedral.
int atomTypeId(int iAtom) const
Get atom type index for a specific atom, by local atom index.
MPI::Intracomm & communicator()
Get the MPI communicator by reference.
Atom & atom(int i)
Get a specific Atom in the Group by reference.
bool isValid() const
Return true if Species is valid, or throw an Exception.
virtual void save(Serializable::OArchive &ar)
Save internal state to file.
Definition: FileMaster.cpp:145
void setId(int id)
Set integer id for this Species.
void setCommonControl()
Enable "replicated" mode in multi-system simulations.
Definition: FileMaster.cpp:88
Manager for a list of Analyzer objects.
void setTypeId(int typeId)
Set the atomic type index.
int id() const
Get integer id of this Species.
Saving archive for binary istream.
int atomId(int i) const
Get the local id for a specific Atom.
Definition: SpeciesGroup.h:182
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
int nSpecies() const
Get the number of Species in this Simulation.
A sequence of NAtom covalently interacting atoms.
bool isMutable() const
Is this a mutable Species?
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
void setClassName(const char *className)
Set class name string.
const Atom & atom(int localId) const
Get a specific Atom in this Molecule.
int capacity() const
Maximum allowed number of molecules for this Species.
Factory< Species > & speciesFactory()
Return the Species Factory by reference.
bool hasCommunicator() const
Does the simulation have an associated MPI communicator?
void readParamComposite(std::istream &in, ParamComposite &child, bool next=true)
Add and read a required child ParamComposite.
A Manager for a set of Species objects.
void setIoCommunicator()
Set MPI job to read one parameter file and one command file.
Factory template.
Definition: Factory.h:32
void setNDihedral(int nDihedral)
Set the number of Dihedrals per molecule.
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
int size() const
Get logical size.
Definition: Manager.h:494
A physical molecule (a set of covalently bonded Atoms).
A Species represents a set of chemically similar molecules.
static void saveOptional(Serializable::OArchive &ar, Type &value, bool isActive)
Save an optional parameter value to an output archive.
Definition: Parameter.h:224
int nBond() const
Get number of bonds per molecule for this Species.
int nAngle() const
Get number of angles per molecule for this Species.
Angle & angle(int localId)
Get a specific Angle in this Molecule by non-const reference.
Species & species(int i)
Get a specific Species by reference.
#define UTIL_ASSERT(condition)
Assertion macro suitable for debugging serial or parallel code.
Definition: global.h:75
void setFirstAngle(Angle &angle)
Set the first Angle.
void writeParam(std::string filename)
Open output, write and close an output parameter file.
FileMaster & fileMaster()
Get the FileMaster object.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
void append(const Atom &atom)
Add an Atom to the masked set.