45#include "applications/staticProps/CoordinationNumber.hpp"
52#include "utils/Revision.hpp"
53#include "utils/simError.h"
57 CoordinationNumber::CoordinationNumber(SimInfo* info,
58 const std::string& filename,
59 const std::string& sele1,
60 const std::string& sele2,
61 RealType rCut,
int bins) :
62 StaticAnalyser(info, filename, bins),
63 rCut_(rCut), bins_(bins), sele1_(sele1), seleMan1_(info),
64 evaluator1_(info), sele2_(sele2), seleMan2_(info), evaluator2_(info) {
65 setAnalysisType(
"Coordination Number Distribution");
66 setOutputName(
getPrefix(filename) +
".cn");
69 RealType binMax_ = nnMax_ * 1.5;
70 delta_ = binMax_ / bins_;
72 std::stringstream params;
73 params <<
" rcut = " << rCut_ <<
", nbins = " << bins_
74 <<
", nnMax = " << nnMax_;
75 const std::string paramString = params.str();
76 setParameterString(paramString);
78 evaluator1_.loadScriptString(sele1);
79 if (!evaluator1_.isDynamic()) {
80 seleMan1_.setSelectionSet(evaluator1_.evaluate());
81 selectionCount1_ = seleMan1_.getSelectionCount();
83 evaluator2_.loadScriptString(sele2);
84 if (!evaluator2_.isDynamic()) {
85 seleMan2_.setSelectionSet(evaluator2_.evaluate());
86 selectionCount2_ = seleMan2_.getSelectionCount();
90 void CoordinationNumber::process() {
91 SelectionManager common(info_);
93 std::vector<std::vector<int>> listNN;
94 std::vector<int> globalToLocal;
99 Snapshot* currentSnapshot_;
100 bool usePeriodicBoundaryConditions_ =
101 info_->getSimParams()->getUsePeriodicBoundaryConditions();
105 unsigned int mapIndex1(0);
106 unsigned int mapIndex2(0);
107 unsigned int whichBin(0);
115 histogram_.resize(bins_, 0.0);
117 DumpReader reader(info_, dumpFilename_);
118 int nFrames = reader.getNFrames();
123 for (
int istep = 0; istep < nFrames; istep += step_) {
124 reader.readFrame(istep);
125 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
127 if (evaluator1_.isDynamic()) {
128 seleMan1_.setSelectionSet(evaluator1_.evaluate());
129 selectionCount1_ = seleMan1_.getSelectionCount();
131 if (evaluator2_.isDynamic()) {
132 seleMan2_.setSelectionSet(evaluator2_.evaluate());
133 selectionCount2_ = seleMan2_.getSelectionCount();
137 common = seleMan1_ | seleMan2_;
138 int commonCount = common.getSelectionCount();
140 globalToLocal.clear();
141 globalToLocal.resize(
142 info_->getNGlobalAtoms() + info_->getNGlobalRigidBodies(), -1);
143 for (
unsigned int i = 0; i < listNN.size(); i++)
144 listNN.at(i).clear();
146 listNN.resize(commonCount);
149 for (sd1 = common.beginSelected(iterator1); sd1 != NULL;
150 sd1 = common.nextSelected(iterator1)) {
151 globalToLocal.at(sd1->getGlobalIndex()) = mapIndex1;
153 pos1 = sd1->getPos();
156 for (sd2 = common.beginSelected(iterator2); sd2 != NULL;
157 sd2 = common.nextSelected(iterator2)) {
158 if (mapIndex1 < mapIndex2) {
159 pos2 = sd2->getPos();
161 if (usePeriodicBoundaryConditions_)
162 currentSnapshot_->wrapVector(diff);
164 if (distance < rCut_) {
165 listNN.at(mapIndex1).push_back(mapIndex2);
166 listNN.at(mapIndex2).push_back(mapIndex1);
176 for (sd1 = seleMan1_.beginSelected(iterator1); sd1 != NULL;
177 sd1 = seleMan1_.nextSelected(iterator1)) {
178 mapIndex1 = globalToLocal.at(sd1->getGlobalIndex());
180 cn = computeCoordination(mapIndex1, listNN);
181 whichBin = int(cn / delta_);
183 if (whichBin < histogram_.size()) {
184 histogram_[whichBin] += 1;
186 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
187 "Coordination Number: Error: "
188 "In frame, %d, object %d has CN %lf outside of range max.\n",
189 istep, sd1->getGlobalIndex(), cn);
190 painCave.isFatal = 1;
194 count_ += selectionCount1_;
197 for (
unsigned int n = 0; n < histogram_.size(); n++) {
199 histogram_[n] /= RealType(count_);
207 RealType CoordinationNumber::computeCoordination(
int a,
208 vector<vector<int>> nl) {
209 return RealType(nl.at(a).size());
212 void CoordinationNumber::writeOutput() {
213 std::ofstream ofs(outputFilename_.c_str(), std::ios::binary);
217 RealType binValue(0.0);
219 ofs <<
"# " << getAnalysisType() <<
"\n";
220 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
221 ofs <<
"# " << r.getBuildDate() <<
"\n";
222 ofs <<
"# selection script1: \"" << sele1_;
223 ofs <<
"\"\tselection script2: \"" << sele2_ <<
"\"\n";
224 if (!paramString_.empty())
225 ofs <<
"# parameters: " << paramString_ <<
"\n";
227 for (
unsigned int n = 0; n < histogram_.size(); n++) {
228 binValue = n * delta_;
229 ofs << binValue <<
"\t" << histogram_[n] / delta_ <<
"\n";
235 SCN::SCN(SimInfo* info,
const std::string& filename,
const std::string& sele1,
236 const std::string& sele2, RealType rCut,
int bins) :
237 CoordinationNumber(info, filename, sele1, sele2, rCut, bins) {
238 setOutputName(
getPrefix(filename) +
".scn");
239 setAnalysisType(
"Secondary Coordination Number");
242 RealType SCN::computeCoordination(
int a, vector<vector<int>> nl) {
246 if (nl.at(a).size() != 0) {
247 for (
unsigned int i = 0; i < nl.at(a).size(); i++) {
250 scn += nl.at(b).size();
252 return scn / RealType(nl.at(a).size());
258 GCN::GCN(SimInfo* info,
const std::string& filename,
const std::string& sele1,
259 const std::string& sele2, RealType rCut,
int bins) :
260 CoordinationNumber(info, filename, sele1, sele2, rCut, bins) {
261 setOutputName(
getPrefix(filename) +
".gcn");
262 setAnalysisType(
"Generalized Coordination Number");
265 RealType GCN::computeCoordination(
int a, vector<vector<int>> nl) {
268 for (
unsigned int i = 0; i < nl.at(a).size(); i++) {
271 gcn += nl.at(b).size();
273 return gcn / RealType(nnMax_);
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)
Real distance(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the distance between two DynamicVectors.