ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/SurfaceDiffusion.cpp
Revision: 2032
Committed: Fri Oct 31 18:57:19 2014 UTC (10 years, 6 months ago) by jmichalk
File size: 9649 byte(s)
Log Message:
Forgot to svn add the files. Additionally, examined the files where changes were committed that I didn't realize were going to be changed. Primary one to examine SimplePreprocessor, bufferSize=8192 instead of 1024... everything else was commented cerr/cout or line spacing issues

File Contents

# User Rev Content
1 jmichalk 2032 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright
10     * notice, this list of conditions and the following disclaimer.
11     *
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31     *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
39     * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40     * [4] , Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011). *
41     * Created by Joseph R. Michalka on Oct 12 2012
42     * @author Joseph R. Michalka
43     * @version $Id: RhoZ.cpp 1665 2011-11-22 20:38:56Z gezelter $
44     *
45     */
46    
47     /* Surface Diffusion
48     * Attempting to track/measure the surface diffusion rates of particles on... wait for it..
49     * a surface.
50     * This program was initially created to track Platinum particles moving around a 557 surface.
51     * Hence why we are trying to keep the x and y movement separate.
52     *
53     */
54    
55     #include <algorithm>
56     #include <fstream>
57     #include "applications/staticProps/SurfaceDiffusion.hpp"
58     #include "utils/simError.h"
59     #include "io/DumpReader.hpp"
60     #include "primitives/Molecule.hpp"
61     namespace OpenMD {
62    
63     SurfaceDiffusion::SurfaceDiffusion(SimInfo* info, const std::string& filename, const std::string& sele, RealType len)
64     : StaticAnalyser(info, filename), selectionScript_(sele), evaluator_(info), seleMan1_(info){
65    
66     evaluator_.loadScriptString(sele);
67     if (!evaluator_.isDynamic()) {
68     seleMan1_.setSelectionSet(evaluator_.evaluate());
69     }
70    
71     //Depending on the selection 'sele1="select Pt"' need a vector equal to the
72     //number of Platinums in the system (for this specific case)
73     selectionCount_ = seleMan1_.getSelectionCount();
74     cout << "SelectionCount_: " << selectionCount_ << "\n";
75    
76     moBool_.resize(selectionCount_);
77     positions_.resize(selectionCount_);
78    
79     filename_ = filename;
80     singleMoveDistance_ = 2.0;
81     }
82    
83     SurfaceDiffusion::~SurfaceDiffusion(){
84    
85     }
86    
87     void SurfaceDiffusion::process() {
88     Molecule* mol;
89     RigidBody* rb;
90     StuntDouble* sd;
91     SimInfo::MoleculeIterator mi;
92     Molecule::RigidBodyIterator rbIter;
93    
94     DumpReader reader(info_, dumpFilename_);
95     int nFrames = reader.getNFrames();
96     frames_ = 0;
97     nProcessed_ = nFrames/step_;
98    
99     //positions_ and moBool_ are 2D arrays, need the second dimension filled as well
100     for(int i = 0; i < selectionCount_; i++){
101     moBool_[i].resize(nFrames);
102     positions_[i].resize(nFrames);
103     }
104    
105     int iterator;
106     int index = 0;
107     /* Loop over all frames storing the positions in a vec< vec<pos> >
108     * At the end, positions.length() should equal seleMan1_.size() or w/e
109     * And positions[index].length() should equal nFrames (or nFrames/istep)
110     */
111     for(int istep = 0; istep < nFrames; istep += step_){
112     frames_++;
113     reader.readFrame(istep);
114     currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
115    
116     for(mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)){
117     //change the positions of atoms which belong to the rigidbodies
118     for(rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)){
119     rb->updateAtoms();
120     }
121     }
122    
123     index = 0; //count over atoms since iterators aren't the most friendly for such plebian things
124     for(sd = seleMan1_.beginSelected(iterator); sd != NULL; sd = seleMan1_.nextSelected(iterator)){
125     Vector3d pos = sd->getPos();
126     positions_[index][istep] = pos;
127     index++;
128     }
129     }
130    
131    
132     cout << "Position Array size: " << positions_.size() << "\n";
133     cout << "Frames analyzed: " << positions_[0].size() << "\n";
134    
135    
136     for(int i = 0; i < positions_.size(); i++){
137     int frameIndex = positions_[i].size();
138     for(int j = 1; j < frameIndex; j++){
139     Vector3d posF1 = positions_[i][j-1];
140     Vector3d posF2 = positions_[i][j];
141     Vector3d diff = posF2 - posF1;
142     if(usePeriodicBoundaryConditions_){
143     currentSnapshot_->wrapVector(diff);
144     }
145     double dist = diff.length();
146     if(dist > singleMoveDistance_){
147     moBool_[i][j] = true;
148     }else{
149     moBool_[i][j] = false;
150     }
151     }
152     }
153    
154     int mobileAtomCount = 0;
155     for(int i = 0; i < moBool_.size(); i++){
156     int frameIndex = moBool_[i].size();
157     bool mobileAtom = false;
158     for(int j = 0; j < frameIndex; j++){
159     mobileAtom = mobileAtom || moBool_[i][j];
160     }
161     moBool_[i][0] = mobileAtom; //is true if any value later in the array is true, false otherwise
162     if(mobileAtom){
163     mobileAtomCount++;
164     }
165     }
166    
167     cout << "Mobile atom count: " << mobileAtomCount << "\n";
168    
169     //Here I shrink the size of the arrays, why look through 3888, when you only need ~800.
170     //Additionally, all of these are mobile at some point in time, the others aren't, dead weight and
171     //memory
172     positions2_.resize(mobileAtomCount);
173     moBool2_.resize(mobileAtomCount);
174     int pos2index = 0;
175     for(int i = 0; i < positions_.size(); i++){
176     int frameCount = positions_[i].size();
177     if(moBool_[i][0]){
178     for(int j = 0; j < frameCount; j++){
179     positions2_[pos2index].push_back(positions_[i][j]);
180     moBool2_[pos2index].push_back(moBool_[i][j]);
181     }
182     pos2index++;
183     }
184     }
185    
186     positions_.clear();
187     moBool_.clear();
188    
189     cout << "positions_ has been cleared: " << positions_.size() << "\n";
190     cout << "positions2_ has been filled: " << positions2_.size() << "\n";
191     cout << "positions2_ has " << positions2_[0].size() << " frames\n";
192    
193     //The important one!
194     positionCorrelation();
195    
196    
197     //Write out my data
198     std::ofstream diffStream;
199     setOutputName(getPrefix(filename_) + ".Mdiffusion");
200     diffStream.open(outputFilename_.c_str());
201     diffStream << "#X&Y diffusion amounts\n";
202     diffStream << "#singleMoveDistance_: " << singleMoveDistance_ << "\n";
203    
204     diffStream << "#Number of mobile atoms: " << positions2_.size() << "\n";
205    
206     diffStream << "#time, <x(t)-x(0)>, <y(t)-y(0)>, <r(t)-r(0)>\n";
207     for(int i = 0; i < xHist_.size(); i++){
208     diffStream << i << ", " << xHist_[i] << ", " << yHist_[i] << ", " << rHist_[i] << "\n";
209     }
210     diffStream.close();
211    
212     }
213    
214     void SurfaceDiffusion::positionCorrelation(){
215     RealType xDist = 0.0;
216     RealType yDist = 0.0;
217     RealType rDist = 0.0;
218     int timeShift = 0;
219     Vector3d kPos;
220     Vector3d jPos;
221     //biggest timeShift is positions2_[0].size() - 1?
222     xHist_.clear();
223     yHist_.clear();
224     rHist_.clear();
225     count_.clear();
226     int frameResize = positions2_[0].size();
227     xHist_.resize(frameResize);
228     yHist_.resize(frameResize);
229     rHist_.resize(frameResize);
230     count_.resize(frameResize);
231     //loop over particles
232     // loop over frames starting at j
233     // loop over frames starting at k = j (time shift of 0)
234     for(int i = 0; i < positions2_.size(); i++){
235     int frames = positions2_[i].size() - 1; //for counting properly, otherwise moBool2_[i][j+1] will
236     // go over
237     for(int j = 0; j < frames; j++){
238     //if the particle is mobile between j and j + 1, then count it for all timeShifts
239     if(moBool2_[i][j+1]){
240     for(int k = j; k < positions2_[0].size(); k++){
241     //<x(t)-x(0)> <y(t)-y(0)> <r(t)-r(0)>
242     //The positions stored are not wrapped, thus I don't need to worry about pbc
243     //Mean square displacement
244     //So I do want the squared distances
245    
246     kPos = positions2_[i][k];
247     jPos = positions2_[i][j];
248     xDist = kPos.x() - jPos.x();
249     xDist = xDist*xDist;
250    
251     yDist = kPos.y() - jPos.y();
252     yDist = yDist*yDist;
253    
254     rDist = (kPos - jPos).lengthSquare();
255    
256    
257     timeShift = k - j;
258     xHist_[timeShift] += xDist;
259     yHist_[timeShift] += yDist;
260     rHist_[timeShift] += rDist;
261     count_[timeShift]++;
262     }
263     }
264     }
265     }
266     cout << "X, Y, R calculated\n";
267    
268     for(int i = 0; i < xHist_.size(); i++){
269     xHist_[i] = xHist_[i]/(count_[i]);
270     yHist_[i] = yHist_[i]/(count_[i]);
271     rHist_[i] = rHist_[i]/(count_[i]);
272     }
273     cout << "X, Y, R normalized\n";
274     }
275    
276     }