48#include "applications/staticProps/CoordinationNumber.hpp"
55#include "utils/Revision.hpp"
56#include "utils/simError.h"
60 CoordinationNumber::CoordinationNumber(
SimInfo* info,
61 const std::string& filename,
62 const std::string& sele1,
63 const std::string& sele2,
64 RealType rCut,
int bins) :
66 rCut_(rCut), bins_(bins), sele1_(sele1), seleMan1_(info),
67 evaluator1_(info), sele2_(sele2), seleMan2_(info), evaluator2_(info) {
68 setAnalysisType(
"Coordination Number Distribution");
69 setOutputName(
getPrefix(filename) +
".cn");
72 RealType binMax_ = nnMax_ * 1.5;
73 delta_ = binMax_ / bins_;
75 std::stringstream params;
76 params <<
" rcut = " << rCut_ <<
", nbins = " << bins_
77 <<
", nnMax = " << nnMax_;
78 const std::string paramString = params.str();
79 setParameterString(paramString);
81 evaluator1_.loadScriptString(sele1);
82 if (!evaluator1_.isDynamic()) {
83 seleMan1_.setSelectionSet(evaluator1_.evaluate());
84 selectionCount1_ = seleMan1_.getSelectionCount();
86 evaluator2_.loadScriptString(sele2);
87 if (!evaluator2_.isDynamic()) {
88 seleMan2_.setSelectionSet(evaluator2_.evaluate());
89 selectionCount2_ = seleMan2_.getSelectionCount();
93 void CoordinationNumber::process() {
94 SelectionManager common(info_);
96 std::vector<std::vector<int>> listNN;
97 std::vector<int> globalToLocal;
102 Snapshot* currentSnapshot_;
103 bool usePeriodicBoundaryConditions_ =
104 info_->getSimParams()->getUsePeriodicBoundaryConditions();
108 unsigned int mapIndex1(0);
109 unsigned int mapIndex2(0);
110 unsigned int whichBin(0);
118 histogram_.resize(bins_, 0.0);
120 DumpReader reader(info_, dumpFilename_);
121 int nFrames = reader.getNFrames();
126 for (
int istep = 0; istep < nFrames; istep += step_) {
127 reader.readFrame(istep);
128 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
130 if (evaluator1_.isDynamic()) {
131 seleMan1_.setSelectionSet(evaluator1_.evaluate());
132 selectionCount1_ = seleMan1_.getSelectionCount();
134 if (evaluator2_.isDynamic()) {
135 seleMan2_.setSelectionSet(evaluator2_.evaluate());
136 selectionCount2_ = seleMan2_.getSelectionCount();
140 common = seleMan1_ | seleMan2_;
141 int commonCount = common.getSelectionCount();
143 globalToLocal.clear();
144 globalToLocal.resize(
145 info_->getNGlobalAtoms() + info_->getNGlobalRigidBodies(), -1);
146 for (
unsigned int i = 0; i < listNN.size(); i++)
147 listNN.at(i).clear();
149 listNN.resize(commonCount);
152 for (sd1 = common.beginSelected(iterator1); sd1 != NULL;
153 sd1 = common.nextSelected(iterator1)) {
154 globalToLocal.at(sd1->getGlobalIndex()) = mapIndex1;
156 pos1 = sd1->getPos();
159 for (sd2 = common.beginSelected(iterator2); sd2 != NULL;
160 sd2 = common.nextSelected(iterator2)) {
161 if (mapIndex1 < mapIndex2) {
162 pos2 = sd2->getPos();
164 if (usePeriodicBoundaryConditions_)
165 currentSnapshot_->wrapVector(diff);
167 if (distance < rCut_) {
168 listNN.at(mapIndex1).push_back(mapIndex2);
169 listNN.at(mapIndex2).push_back(mapIndex1);
179 for (sd1 = seleMan1_.beginSelected(iterator1); sd1 != NULL;
180 sd1 = seleMan1_.nextSelected(iterator1)) {
181 mapIndex1 = globalToLocal.at(sd1->getGlobalIndex());
183 cn = computeCoordination(mapIndex1, listNN);
184 whichBin = int(cn / delta_);
186 if (whichBin < histogram_.size()) {
187 histogram_[whichBin] += 1;
189 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
190 "Coordination Number: Error: "
191 "In frame, %d, object %d has CN %lf outside of range max.\n",
192 istep, sd1->getGlobalIndex(), cn);
193 painCave.isFatal = 1;
197 count_ += selectionCount1_;
200 for (
unsigned int n = 0; n < histogram_.size(); n++) {
202 histogram_[n] /= RealType(count_);
210 RealType CoordinationNumber::computeCoordination(
int a,
211 vector<vector<int>> nl) {
212 return RealType(nl.at(a).size());
215 void CoordinationNumber::writeOutput() {
216 std::ofstream ofs(outputFilename_.c_str(), std::ios::binary);
220 RealType binValue(0.0);
222 ofs <<
"# " << getAnalysisType() <<
"\n";
223 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
224 ofs <<
"# " << r.getBuildDate() <<
"\n";
225 ofs <<
"# selection script1: \"" << sele1_;
226 ofs <<
"\"\tselection script2: \"" << sele2_ <<
"\"\n";
227 if (!paramString_.empty())
228 ofs <<
"# parameters: " << paramString_ <<
"\n";
230 for (
unsigned int n = 0; n < histogram_.size(); n++) {
231 binValue = n * delta_;
232 ofs << binValue <<
"\t" << histogram_[n] / delta_ <<
"\n";
238 SCN::SCN(SimInfo* info,
const std::string& filename,
const std::string& sele1,
239 const std::string& sele2, RealType rCut,
int bins) :
240 CoordinationNumber(info, filename, sele1, sele2, rCut, bins) {
241 setOutputName(
getPrefix(filename) +
".scn");
242 setAnalysisType(
"Secondary Coordination Number");
245 RealType SCN::computeCoordination(
int a, vector<vector<int>> nl) {
249 if (nl.at(a).size() != 0) {
250 for (
unsigned int i = 0; i < nl.at(a).size(); i++) {
253 scn += nl.at(b).size();
255 return scn / RealType(nl.at(a).size());
261 GCN::GCN(SimInfo* info,
const std::string& filename,
const std::string& sele1,
262 const std::string& sele2, RealType rCut,
int bins) :
263 CoordinationNumber(info, filename, sele1, sele2, rCut, bins) {
264 setOutputName(
getPrefix(filename) +
".gcn");
265 setAnalysisType(
"Generalized Coordination Number");
268 RealType GCN::computeCoordination(
int a, vector<vector<int>> nl) {
271 for (
unsigned int i = 0; i < nl.at(a).size(); i++) {
274 gcn += nl.at(b).size();
276 return gcn / RealType(nnMax_);
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
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.