48#include "applications/staticProps/TetrahedralityParamR.hpp"
56#include "utils/Revision.hpp"
57#include "utils/simError.h"
59#define HONKING_LARGE_VALUE 1.0e10
63 TetrahedralityParamR::TetrahedralityParamR(
64 SimInfo* info,
const std::string& filename,
const std::string& sele1,
65 const std::string& sele2,
const std::string& sele3, RealType rCut,
66 RealType len,
int nrbins) :
68 selectionScript1_(sele1), selectionScript2_(sele2),
69 selectionScript3_(sele3), seleMan1_(info), seleMan2_(info),
70 seleMan3_(info), evaluator1_(info), evaluator2_(info), evaluator3_(info),
71 len_(len), nBins_(nrbins) {
72 setAnalysisType(
"Tetrahedrality Parameter(r)");
74 evaluator1_.loadScriptString(sele1);
75 if (!evaluator1_.isDynamic()) {
76 seleMan1_.setSelectionSet(evaluator1_.evaluate());
79 evaluator2_.loadScriptString(sele2);
80 if (!evaluator2_.isDynamic()) {
81 seleMan2_.setSelectionSet(evaluator2_.evaluate());
84 evaluator3_.loadScriptString(sele3);
85 if (!evaluator3_.isDynamic()) {
86 seleMan3_.setSelectionSet(evaluator3_.evaluate());
92 deltaR_ = len_ / nBins_;
95 sliceQ_.resize(nBins_);
96 sliceCount_.resize(nBins_);
97 std::fill(sliceQ_.begin(), sliceQ_.end(), 0.0);
98 std::fill(sliceCount_.begin(), sliceCount_.end(), 0);
100 setOutputName(
getPrefix(filename) +
".Qr");
103 void TetrahedralityParamR::process() {
111 Vector3d ri, rj, rk, rik, rkj;
115 std::vector<std::pair<RealType, StuntDouble*>> myNeighbors;
119 bool usePeriodicBoundaryConditions_ =
120 info_->getSimParams()->getUsePeriodicBoundaryConditions();
122 DumpReader reader(info_, dumpFilename_);
123 int nFrames = reader.getNFrames();
125 for (
int istep = 0; istep < nFrames; istep += step_) {
126 reader.readFrame(istep);
127 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
129 if (evaluator1_.isDynamic()) {
130 seleMan1_.setSelectionSet(evaluator1_.evaluate());
133 if (evaluator2_.isDynamic()) {
134 seleMan2_.setSelectionSet(evaluator2_.evaluate());
137 if (evaluator3_.isDynamic()) {
138 seleMan3_.setSelectionSet(evaluator3_.evaluate());
141 if (seleMan3_.getSelectionCount() == 0) {
142 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
143 "TetrahedralityParamR:process: third selection has no objects"
144 "at frame %d, skipping frame.\n",
146 painCave.severity = OPENMD_WARNING;
147 painCave.isFatal = 0;
153 for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
154 sd = seleMan1_.nextSelected(isd1)) {
155 myIndex = sd->getGlobalIndex();
160 for (sd2 = seleMan2_.beginSelected(isd2); sd2 != NULL;
161 sd2 = seleMan2_.nextSelected(isd2)) {
162 if (sd2->getGlobalIndex() != myIndex) {
163 vec = sd->getPos() - sd2->getPos();
165 if (usePeriodicBoundaryConditions_)
166 currentSnapshot_->wrapVector(vec);
172 if (r < rCut_) { myNeighbors.push_back(std::make_pair(r, sd2)); }
177 std::sort(myNeighbors.begin(), myNeighbors.end());
181 int nbors = myNeighbors.size() > 4 ? 4 : myNeighbors.size();
182 int nang = int(0.5 * (nbors * (nbors - 1)));
186 for (
int i = 0; i < nbors - 1; i++) {
187 sdi = myNeighbors[i].second;
190 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(rik);
194 for (
int j = i + 1; j < nbors; j++) {
195 sdj = myNeighbors[j].second;
198 if (usePeriodicBoundaryConditions_)
199 currentSnapshot_->wrapVector(rkj);
202 cospsi =
dot(rik, rkj);
206 Qk -= (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);
211 RealType shortest = HONKING_LARGE_VALUE;
214 for (sd3 = seleMan3_.beginSelected(isd3); sd3 != NULL;
215 sd3 = seleMan3_.nextSelected(isd3)) {
216 vec = sd->getPos() - sd3->getPos();
218 if (usePeriodicBoundaryConditions_)
219 currentSnapshot_->wrapVector(vec);
223 if (r < shortest) shortest = r;
226 int whichBin = int(shortest / deltaR_);
227 if (whichBin <
int(nBins_)) {
228 sliceQ_[whichBin] += Qk;
229 sliceCount_[whichBin] += 1;
237 void TetrahedralityParamR::writeQr() {
239 std::ofstream qRstream(outputFilename_.c_str());
240 if (qRstream.is_open()) {
241 qRstream <<
"# " << getAnalysisType() <<
"\n";
242 qRstream <<
"# OpenMD " << rev.getFullRevision() <<
"\n";
243 qRstream <<
"# " << rev.getBuildDate() <<
"\n";
244 qRstream <<
"#selection 1: (" << selectionScript1_ <<
")\n";
245 qRstream <<
"#selection 2: (" << selectionScript2_ <<
")\n";
246 qRstream <<
"#selection 3: (" << selectionScript3_ <<
")\n";
247 if (!paramString_.empty())
248 qRstream <<
"# parameters: " << paramString_ <<
"\n";
250 qRstream <<
"#distance"
252 for (
unsigned int i = 0; i < sliceQ_.size(); ++i) {
253 RealType Rval = (i + 0.5) * deltaR_;
254 if (sliceCount_[i] != 0) {
255 qRstream << Rval <<
"\t" << sliceQ_[i] / (RealType)sliceCount_[i]
261 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
262 "TetrahedralityParamR: unable to open %s\n",
263 outputFilename_.c_str());
264 painCave.isFatal = 1;
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.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
std::string getPrefix(const std::string &str)