48#include "applications/staticProps/TetrahedralityParamRAngle.hpp"
56#include "utils/Revision.hpp"
57#include "utils/simError.h"
59#define HONKING_LARGE_VALUE 1.0e10
63 TetrahedralityParamRAngle::TetrahedralityParamRAngle(
64 SimInfo* info,
const std::string& filename,
const std::string& sele1,
65 const std::string& sele2,
const std::string& sele3,
const int seleOffset3,
66 RealType rCut, RealType len,
int nrbins,
int nangleBins) :
68 selectionScript1_(sele1), selectionScript2_(sele2),
69 selectionScript3_(sele3), seleMan1_(info), seleMan2_(info),
70 seleMan3_(info), evaluator1_(info), evaluator2_(info), evaluator3_(info),
71 seleOffset3_(seleOffset3), len_(len), nBins_(nrbins), nAngleBins_(nangleBins) {
73 setAnalysisType(
"Tetrahedrality Parameter(r, cos(theta))");
75 evaluator1_.loadScriptString(sele1);
76 if (!evaluator1_.isDynamic()) {
77 seleMan1_.setSelectionSet(evaluator1_.evaluate());
80 evaluator2_.loadScriptString(sele2);
81 if (!evaluator2_.isDynamic()) {
82 seleMan2_.setSelectionSet(evaluator2_.evaluate());
85 evaluator3_.loadScriptString(sele3);
86 if (!evaluator3_.isDynamic()) {
87 seleMan3_.setSelectionSet(evaluator3_.evaluate());
93 deltaR_ = len_ / nBins_;
94 deltaCosAngle_ = 2.0 / (double)nAngleBins_;
97 sliceQ_.resize(nBins_);
98 sliceCount_.resize(nBins_);
99 for (
unsigned int i = 0; i < nBins_; ++i) {
100 sliceQ_[i].resize(nAngleBins_);
101 sliceCount_[i].resize(nAngleBins_);
102 std::fill(sliceQ_[i].begin(), sliceQ_[i].end(), 0.0);
103 std::fill(sliceCount_[i].begin(), sliceCount_[i].end(), 0);
106 setOutputName(
getPrefix(filename) +
".Qrangle");
109 void TetrahedralityParamRAngle::process() {
117 Vector3d ri, rj, rk, rik, rkj;
122 std::vector<std::pair<RealType, StuntDouble*>> myNeighbors;
131 bool usePeriodicBoundaryConditions_ =
132 info_->getSimParams()->getUsePeriodicBoundaryConditions();
134 DumpReader reader(info_, dumpFilename_);
135 int nFrames = reader.getNFrames();
137 for (
int istep = 0; istep < nFrames; istep += step_) {
138 reader.readFrame(istep);
139 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
141 if (evaluator1_.isDynamic()) {
142 seleMan1_.setSelectionSet(evaluator1_.evaluate());
145 if (evaluator2_.isDynamic()) {
146 seleMan2_.setSelectionSet(evaluator2_.evaluate());
149 if (evaluator3_.isDynamic()) {
150 seleMan3_.setSelectionSet(evaluator3_.evaluate());
153 if (seleMan3_.getSelectionCount() == 0) {
154 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
155 "TetrahedralityParamRAngle:process: third selection has no "
156 "objects at frame %d, skipping frame.\n",
158 painCave.severity = OPENMD_WARNING;
159 painCave.isFatal = 0;
165 for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
166 sd = seleMan1_.nextSelected(isd1)) {
167 myIndex = sd->getGlobalIndex();
172 for (sd2 = seleMan2_.beginSelected(isd2); sd2 != NULL;
173 sd2 = seleMan2_.nextSelected(isd2)) {
174 if (sd2->getGlobalIndex() != myIndex) {
175 vec = sd->getPos() - sd2->getPos();
177 if (usePeriodicBoundaryConditions_)
178 currentSnapshot_->wrapVector(vec);
184 if (r < rCut_) { myNeighbors.push_back(std::make_pair(r, sd2)); }
189 std::sort(myNeighbors.begin(), myNeighbors.end());
193 int nbors = myNeighbors.size() > 4 ? 4 : myNeighbors.size();
194 int nang = int(0.5 * (nbors * (nbors - 1)));
198 for (
int i = 0; i < nbors - 1; i++) {
199 sdi = myNeighbors[i].second;
202 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(rik);
206 for (
int j = i + 1; j < nbors; j++) {
207 sdj = myNeighbors[j].second;
210 if (usePeriodicBoundaryConditions_)
211 currentSnapshot_->wrapVector(rkj);
214 cospsi =
dot(rik, rkj);
218 Qk -= (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);
223 RealType shortest = HONKING_LARGE_VALUE;
226 for (sd3 = seleMan3_.beginSelected(isd3); sd3 != NULL;
227 sd3 = seleMan3_.nextSelected(isd3)) {
229 vec = sd->getPos() - sd3->getPos();
231 if (usePeriodicBoundaryConditions_) {
232 currentSnapshot_->wrapVector(vec);
240 whichBin = int(r / deltaR_);
243 int sd4ind = sd3->getGlobalIndex() + seleOffset3_;
244 StuntDouble* sd4 = info_->getIOIndexToIntegrableObject(sd4ind);
245 r34 = sd4->getPos() - sd3->getPos();
246 if (usePeriodicBoundaryConditions_) {
247 currentSnapshot_->wrapVector(r34);
250 cosAngle =
dot(r34, vec);
252 halfBin = (nAngleBins_ - 1) * 0.5;
253 whichThetaBin = int(halfBin * (cosAngle + 1.0));
257 if (whichBin <
int(nBins_)) {
258 sliceQ_[whichBin][whichThetaBin] += Qk;
259 sliceCount_[whichBin][whichThetaBin] += 1;
267 void TetrahedralityParamRAngle::writeQrAngle() {
269 std::ofstream qRstream(outputFilename_.c_str());
270 if (qRstream.is_open()) {
271 qRstream <<
"# " << getAnalysisType() <<
"\n";
272 qRstream <<
"# OpenMD " << rev.getFullRevision() <<
"\n";
273 qRstream <<
"# " << rev.getBuildDate() <<
"\n";
274 qRstream <<
"#selection 1: (" << selectionScript1_ <<
")\n";
275 qRstream <<
"#selection 2: (" << selectionScript2_ <<
")\n";
276 qRstream <<
"#selection 3: (" << selectionScript3_ <<
")\n";
277 qRstream <<
"#selection 3 offset: " << seleOffset3_ <<
"\n";
278 if (!paramString_.empty())
279 qRstream <<
"# parameters: " << paramString_ <<
"\n";
281 for (
unsigned int i = 0; i < sliceQ_.size(); ++i) {
282 for (
unsigned int j = 0; j < sliceQ_[i].size(); ++j) {
283 if (sliceCount_[i][j] != 0) {
284 qRstream << sliceQ_[i][j] / (RealType)sliceCount_[i][j] <<
"\t";
286 qRstream << 0.0 <<
"\t";
293 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
294 "TetrahedralityParamRAngle: unable to open %s\n",
295 outputFilename_.c_str());
296 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)