53#include "applications/staticProps/SurfaceDiffusion.hpp"
60#include "utils/simError.h"
64 SurfaceDiffusion::SurfaceDiffusion(SimInfo* info,
const std::string& filename,
65 const std::string& sele, RealType) :
66 StaticAnalyser(info, filename, 1),
67 selectionScript_(sele), evaluator_(info), seleMan1_(info) {
68 evaluator_.loadScriptString(sele);
69 if (!evaluator_.isDynamic()) {
70 seleMan1_.setSelectionSet(evaluator_.evaluate());
75 selectionCount_ = seleMan1_.getSelectionCount();
76 cout <<
"SelectionCount_: " << selectionCount_ <<
"\n";
78 moBool_.resize(selectionCount_);
79 positions_.resize(selectionCount_);
82 singleMoveDistance_ = 2.0;
85 void SurfaceDiffusion::process() {
87 bool usePeriodicBoundaryConditions_ =
88 info_->getSimParams()->getUsePeriodicBoundaryConditions();
90 DumpReader reader(info_, dumpFilename_);
91 int nFrames = reader.getNFrames();
93 nProcessed_ = nFrames / step_;
97 for (
int i = 0; i < selectionCount_; i++) {
98 moBool_[i].resize(nFrames);
99 positions_[i].resize(nFrames);
109 for (
int istep = 0; istep < nFrames; istep += step_) {
111 reader.readFrame(istep);
112 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
116 for (sd = seleMan1_.beginSelected(iterator); sd != NULL;
117 sd = seleMan1_.nextSelected(iterator)) {
118 Vector3d pos = sd->getPos();
119 positions_[index][istep] = pos;
124 cout <<
"Position Array size: " << positions_.size() <<
"\n";
125 cout <<
"Frames analyzed: " << positions_[0].size() <<
"\n";
127 for (std::size_t i = 0; i < positions_.size(); i++) {
128 int frameIndex = positions_[i].size();
129 for (
int j = 1; j < frameIndex; j++) {
130 Vector3d posF1 = positions_[i][j - 1];
131 Vector3d posF2 = positions_[i][j];
132 Vector3d diff = posF2 - posF1;
133 if (usePeriodicBoundaryConditions_) {
134 currentSnapshot_->wrapVector(diff);
136 double dist = diff.
length();
137 if (dist > singleMoveDistance_) {
138 moBool_[i][j] =
true;
140 moBool_[i][j] =
false;
145 int mobileAtomCount = 0;
146 for (std::size_t i = 0; i < moBool_.size(); i++) {
147 int frameIndex = moBool_[i].size();
148 bool mobileAtom =
false;
149 for (
int j = 0; j < frameIndex; j++) {
150 mobileAtom = mobileAtom || moBool_[i][j];
152 moBool_[i][0] = mobileAtom;
154 if (mobileAtom) { mobileAtomCount++; }
157 cout <<
"Mobile atom count: " << mobileAtomCount <<
"\n";
163 positions2_.resize(mobileAtomCount);
164 moBool2_.resize(mobileAtomCount);
166 for (std::size_t i = 0; i < positions_.size(); i++) {
167 int frameCount = positions_[i].size();
169 for (
int j = 0; j < frameCount; j++) {
170 positions2_[pos2index].push_back(positions_[i][j]);
171 moBool2_[pos2index].push_back(moBool_[i][j]);
180 cout <<
"positions_ has been cleared: " << positions_.size() <<
"\n";
181 cout <<
"positions2_ has been filled: " << positions2_.size() <<
"\n";
182 cout <<
"positions2_ has " << positions2_[0].size() <<
" frames\n";
185 positionCorrelation();
188 std::ofstream diffStream;
189 setOutputName(
getPrefix(filename_) +
".Mdiffusion");
190 diffStream.open(outputFilename_.c_str());
191 diffStream <<
"#X&Y diffusion amounts\n";
192 diffStream <<
"#singleMoveDistance_: " << singleMoveDistance_ <<
"\n";
193 diffStream <<
"#Number of mobile atoms: " << positions2_.size() <<
"\n";
194 diffStream <<
"#time, <x(t)-x(0)>, <y(t)-y(0)>, <r(t)-r(0)>\n";
196 for (std::size_t i = 0; i < xHist_.size(); i++) {
197 diffStream << i <<
", " << xHist_[i] <<
", " << yHist_[i] <<
", "
198 << rHist_[i] <<
"\n";
203 void SurfaceDiffusion::positionCorrelation() {
204 RealType xDist = 0.0;
205 RealType yDist = 0.0;
206 RealType rDist = 0.0;
215 int frameResize = positions2_[0].size();
216 xHist_.resize(frameResize);
217 yHist_.resize(frameResize);
218 rHist_.resize(frameResize);
219 count_.resize(frameResize);
223 for (std::size_t i = 0; i < positions2_.size(); i++) {
224 int frames = positions2_[i].size() - 1;
228 for (
int j = 0; j < frames; j++) {
231 if (moBool2_[i][j + 1]) {
232 for (std::size_t k = j; k < positions2_[0].size(); k++) {
239 kPos = positions2_[i][k];
240 jPos = positions2_[i][j];
241 xDist = kPos.x() - jPos.x();
242 xDist = xDist * xDist;
244 yDist = kPos.y() - jPos.y();
245 yDist = yDist * yDist;
247 rDist = (kPos - jPos).lengthSquare();
250 xHist_[timeShift] += xDist;
251 yHist_[timeShift] += yDist;
252 rHist_[timeShift] += rDist;
258 cout <<
"X, Y, R calculated\n";
260 for (std::size_t i = 0; i < xHist_.size(); i++) {
261 xHist_[i] = xHist_[i] / (count_[i]);
262 yHist_[i] = yHist_[i] / (count_[i]);
263 rHist_[i] = rHist_[i] / (count_[i]);
265 cout <<
"X, Y, R normalized\n";
Real length()
Returns the length of this vector.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)