Simpatico  v1.10
VelProf.cpp
1 #ifndef VEL_PROF_CPP
2 #define VEL_PROF_CPP
3 
4 /*
5 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
6 *
7 * Copyright 2010 - 2014, The Regents of the University of Minnesota
8 * Distributed under the terms of the GNU General Public License.
9 */
10 
11 #include "VelProf.h"
12 #include <mcMd/simulation/Simulation.h>
13 #include <simp/species/Species.h>
14 #include <mcMd/chemistry/Molecule.h>
15 #include <mcMd/chemistry/Atom.h>
16 #include <simp/boundary/Boundary.h>
17 #include <util/misc/FileMaster.h>
18 
19 
20 namespace McMd
21 {
22 
23  using namespace Util;
24  using namespace Simp;
25 
28  : SystemAnalyzer<System>(system),
29  outputFile_(),
30  accumulator_(),
31  totalMomentum_(0.0),
32  velx_(),
33  nSpec_(0),
34  slabWidth_(0.0)
35  { setClassName("VelProf"); }
36 
38  void VelProf::readParameters(std::istream& in)
39  {
40 
41  readInterval(in);
43  read<int>(in,"numberOfSlabs", nSlabs_);
44  if (nSlabs_ <= 0) {
45  UTIL_THROW("Invalid number of slabs");
46  }
47 
48  //Allocate acumulator_ array.
49  accumulator_. allocate(nSlabs_);
50 
51  read<int>(in,"nSamplePerBlock", nSamplePerBlock_);
52 
53  int i;
54  for (i=0; i < nSlabs_; ++i){
55  accumulator_[i].setNSamplePerBlock(nSamplePerBlock_);
56  }
57  // If nSamplePerBlock != 0, open an output file for block averages.
58  if (nSamplePerBlock_ != 0) {
59  fileMaster().openOutputFile(outputFileName(".dat"), outputFile_);
60  }
61 
62  // Allocate arrays
63  velx_.allocate(nSlabs_);
64  nAtomi_.allocate(nSlabs_);
65  }
66 
67 
70  {
71  nSpec_ = system().simulation().nSpecies();
72  slabWidth_ = system().boundary().lengths()[2]/(double)nSlabs_;
73  totalMomentum_ = 0.0;
74  int i;
75  for (i=0; i < nSlabs_; ++i){
76  accumulator_[i].clear();
77  }
78  iBlock_ = 0;
79  }
80 
82  void VelProf::sample(long iStep)
83  {
84  if (isAtInterval(iStep)) {
85  int i, iSpec;
87  Molecule::AtomIterator atomIter;
88  double Lz = system().boundary().lengths()[2];
89  double zcoord;
90  int imed=int(Lz/(2.0*slabWidth_));
91  double vx, maxvx=-10.0, minvx=10.0, deltaP;
92  Atom* atomPtrmax=0;
93  Atom* atomPtrmin=0;
94 
95  for (i=0; i < nSlabs_; ++i){
96  velx_[i] = 0.0;
97  nAtomi_[i] = 0;
98  }
99 
100  // Loop over all atoms
101  for (iSpec = 0; iSpec < nSpec_; ++iSpec) {
102  for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
103  for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
104  zcoord = (atomIter->position())[2];
105  i = int(zcoord/slabWidth_);
106  if(zcoord == Lz) i = nSlabs_-1;
107  vx = (atomIter->velocity())[0];
108  velx_[i] += vx;
109  nAtomi_[i] += 1;
110  if(iStep > 0){
111  if (i == 0) {
112  if (vx < minvx){
113  minvx = vx;
114  atomPtrmin = &(*atomIter);
115  }
116  }
117  if (i == imed){
118  if (vx > maxvx){
119  maxvx = vx;
120  atomPtrmax = &(*atomIter);
121  }
122  }
123  }
124  }
125  }
126  }
127 
128  // Calculate mean velocity for each slab.
129  if(iStep > 0){
130  iBlock_ += 1;
131 
132  for (i=0; i < nSlabs_; ++i){
133  if (nAtomi_[i] != 0 ){
134  velx_[i] = velx_[i]/(double)nAtomi_[i];
135  }
136  else {
137  velx_[i] = 0.0;
138  }
139  accumulator_[i].sample(velx_[i], outputFile_);
140  }
141 
142  if (iBlock_ == nSamplePerBlock_) {
143  outputFile_ << std::endl;
144  iBlock_ = 0;
145  }
146 
147  if(atomPtrmin!=0 && atomPtrmax!=0){
148  (atomPtrmin->velocity())[0] = maxvx;
149  (atomPtrmax->velocity())[0] = minvx;
150  deltaP = maxvx-minvx;
151  totalMomentum_ += deltaP;
152  }
153  }
154 
155  } // if isAtInterval
156 
157  }
158 
159  /*
160  * Output param file after simulation is completed.
161  */
163  {
164  // If outputFile_ was used to write block averages, close it.
165  if (nSamplePerBlock_ != 0) {
166  outputFile_.close();
167  }
168 
169  // Write parameters to file
170  fileMaster().openOutputFile(outputFileName(".prm"), outputFile_);
171  ParamComposite::writeParam(outputFile_);
172  outputFile_.close();
173 
174  // Write average to file
175  fileMaster().openOutputFile(outputFileName(".ave"), outputFile_);
176  int i;
177  for(i=0; i<nSlabs_; ++i){
178  accumulator_[i].output(outputFile_);
179  }
180  double A = system().boundary().lengths()[0] * system().boundary().lengths()[1];
181  double nSteps = (double)system().simulation().iStep();
182  outputFile_ << std::endl;
183  outputFile_ << "Total transferred momentum: " << totalMomentum_ << std::endl;
184  outputFile_ << "Total number of steps: " << nSteps << std::endl;
185  outputFile_ << "Momentum flux: " << totalMomentum_/(2.0*A*nSteps) << std::endl;
186  outputFile_.close();
187  }
188 
189 }
190 #endif
Vector & velocity()
Get atomic velocity Vector by reference.
bool notEnd() const
Is the current pointer not at the end of the array?
Definition: ArrayIterator.h:83
const Vector & lengths() const
Get Vector of unit cell lengths by const reference.
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
A set of interacting Molecules enclosed by a Boundary.
Definition: System.h:115
System & system()
Return reference to parent system.
Classes used by all simpatico molecular simulations.
void readOutputFileName(std::istream &in)
Read outputFileName from file.
virtual void sample(long iStep)
Evaluate and output x-velocity profile as a function of z.
Definition: VelProf.cpp:82
virtual void readParameters(std::istream &in)
Read parameters from file, and allocate data arrays.
Definition: VelProf.cpp:38
virtual void setup()
Empty.
Definition: VelProf.cpp:69
virtual void output()
Output param file at end of simulation.
Definition: VelProf.cpp:162
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Simulation & simulation() const
Get the parent Simulation by reference.
Definition: System.h:1055
virtual void writeParam(std::ostream &out)
Write all parameters to an output stream.
void readInterval(std::istream &in)
Read interval from file, with error checking.
A point particle within a Molecule.
bool notEnd() const
Is the current pointer not at the end of the PArray?
Utility classes for scientific computation.
Definition: accumulators.mod:1
Forward iterator for an Array or a C array.
Definition: ArrayIterator.h:39
Forward iterator for a PArray.
Definition: ArraySet.h:19
Template for Analyzer associated with one System.
int iStep() const
Get value of step index for main MC or MD loop.
Boundary & boundary() const
Get the Boundary by reference.
Definition: System.h:1064
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
int nSpecies() const
Get the number of Species in this Simulation.
VelProf(System &system)
Constructor.
Definition: VelProf.cpp:27
void setClassName(const char *className)
Set class name string.
FileMaster & fileMaster()
Get the FileMaster by reference.
bool isAtInterval(long counter) const
Return true iff counter is a multiple of the interval.
const std::string & outputFileName() const
Return outputFileName string.
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191