Simpatico  v1.10
BondTensorAutoCorr.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 "BondTensorAutoCorr.h"
9 #include <ddMd/analyzers/AutoCorrAnalyzer.tpp>
10 #include <ddMd/storage/BondStorage.h>
11 #include <ddMd/storage/GroupIterator.h>
12 #include <simp/boundary/Boundary.h>
13 
14 namespace DdMd
15 {
16 
17  using namespace Util;
18  using namespace Simp;
19 
20  /*
21  * Constructor.
22  */
24  : AutoCorrAnalyzer<Tensor, double>(simulation),
25  bondTensor_()
26  { setClassName("BondTensorAutoCorr"); }
27 
28  /*
29  * Destructor.
30  */
32  { }
33 
34  /*
35  * Compute the bond tensor (Call on all processors).
36  */
38  {
39  MPI::Intracomm& communicator = simulation().domain().communicator();
40  BondStorage& storage = simulation().bondStorage();
41  Boundary& boundary = simulation().boundary();
42 
43  Tensor localTensor;
44  Vector dr;
45  double rsq;
46  GroupIterator<2> iter;
47  Atom* atom0Ptr;
48  Atom* atom1Ptr;
49  int isLocal0, isLocal1, i, j;
50 
51 
52  // Iterate over bonds
53  localTensor.zero();
54  storage.begin(iter);
55  for ( ; iter.notEnd(); ++iter) {
56  atom0Ptr = iter->atomPtr(0);
57  atom1Ptr = iter->atomPtr(1);
58  isLocal0 = !(atom0Ptr->isGhost());
59  isLocal1 = !(atom1Ptr->isGhost());
60  rsq = boundary.distanceSq(atom0Ptr->position(),
61  atom1Ptr->position(), dr);
62  if (rsq > 1.0E-6) {
63  dr /= sqrt(rsq);
64  assert(isLocal0 || isLocal1);
65  if (isLocal0 && isLocal1) {
66  // If both atoms are local
67  for (i = 0; i < Dimension; ++i) {
68  for (j = 0; j < Dimension; ++j) {
69  localTensor(i, j) += dr[i]*dr[j];
70  }
71  }
72  } else {
73  // If one atoms is local and one is a ghost
74  for (i = 0; i < Dimension; ++i) {
75  for (j = 0; j < Dimension; ++j) {
76  localTensor(i, j) += 0.5*dr[i]*dr[j];
77  }
78  }
79  }
80  }
81  }
82 
83  // Reduce partial sums from all processors, store on the master.
84  bondTensor_.zero();
85  communicator.Reduce(&localTensor(0,0), &bondTensor_(0,0),
86  Dimension*Dimension, MPI::DOUBLE, MPI::SUM, 0);
87 
88  if (communicator.Get_rank() != 0) {
89  bondTensor_.zero();
90  }
91  }
92 
93  /*
94  * Return the current bond tensor value.
95  */
97  {
98  // Remove trace
99  double trace = 0.0;
100  int i, j;
101  for (i = 0; i < Dimension; ++i) {
102  trace += bondTensor_(i,i);
103  }
104  trace = trace/double(Dimension);
105  for (i = 0; i < Dimension; ++i) {
106  bondTensor_(i,i) -= trace;
107  }
108 
109  // Scale traceless symmetric tensor
110  double factor = 1.0/sqrt(10.0*simulation().boundary().volume());
111  for (i = 0; i < Dimension; ++i) {
112  for (j = 0; j < Dimension; ++j) {
113  bondTensor_(i,j) *= factor;
114  }
115  }
116 
117  return bondTensor_;
118  }
119 
120 }
const int Dimension
Dimensionality of space.
Definition: Dimension.h:19
Simulation & simulation()
Get the parent Simulation by reference.
A Vector is a Cartesian vector.
Definition: Vector.h:75
Compute an autocorrelation function for a sequence of Data values.
double distanceSq(const Vector &r1, const Vector &r2) const
Return square distance between positions r1 and r2.
virtual void computeData()
Compute Data value, call on all processors.
An orthorhombic periodic unit cell.
Vector & position()
Get position Vector by reference.
Tensor & zero()
Set all elements of this tensor to zero.
Definition: Tensor.h:441
BondStorage & bondStorage()
Get the BondStorage by reference.
A point particle in an MD simulation.
Parallel domain decomposition (DD) MD simulation.
Classes used by all simpatico molecular simulations.
Main object for a domain-decomposition MD simulation.
A Tensor represents a Cartesian tensor.
Definition: Tensor.h:32
MPI::Intracomm & communicator() const
Return Cartesian communicator by reference.
Definition: Domain.h:257
bool isGhost() const
Is this atom a ghost?
Iterator for all Group < N > objects owned by a GroupStorage< N >.
Definition: GroupIterator.h:25
bool notEnd() const
Is the current pointer not at the end of the PArray?
Utility classes for scientific computation.
Definition: accumulators.mod:1
virtual Tensor data()
Get current Data value, call only on master.
void begin(GroupIterator< N > &iterator)
Set iterator to beginning of the set of groups.
BondTensorAutoCorr(Simulation &simulation)
Constructor.
void setClassName(const char *className)
Set class name string.
Boundary & boundary()
Get the Boundary by reference.
Domain & domain()
Get the Domain by reference.
virtual ~BondTensorAutoCorr()
Destructor.
Container for for Group<2> (bond) objects.
Definition: BondStorage.h:25