48#include "applications/staticProps/TetrahedralityParamXYZ.hpp"
56#include "utils/Constants.hpp"
57#include "utils/simError.h"
61 TetrahedralityParamXYZ::TetrahedralityParamXYZ(
62 SimInfo* info,
const std::string& filename,
const std::string& sele1,
63 const std::string& sele2, RealType rCut, RealType voxelSize,
64 RealType gaussWidth) :
66 selectionScript1_(sele1), selectionScript2_(sele2), seleMan1_(info),
67 seleMan2_(info), evaluator1_(info), evaluator2_(info), rCut_(rCut),
68 voxelSize_(voxelSize), gaussWidth_(gaussWidth) {
69 evaluator1_.loadScriptString(sele1);
70 if (!evaluator1_.isDynamic()) {
71 seleMan1_.setSelectionSet(evaluator1_.evaluate());
73 evaluator2_.loadScriptString(sele2);
74 if (!evaluator2_.isDynamic()) {
75 seleMan2_.setSelectionSet(evaluator2_.evaluate());
78 Mat3x3d hmat = info->getSnapshotManager()->getCurrentSnapshot()->getHmat();
80 nBins_(0) =
int(hmat(0, 0) / voxelSize);
81 nBins_(1) = int(hmat(1, 1) / voxelSize);
82 nBins_(2) = int(hmat(2, 2) / voxelSize);
84 hist_.resize(nBins_(0));
85 count_.resize(nBins_(0));
86 for (
int i = 0; i < nBins_(0); ++i) {
87 hist_[i].resize(nBins_(1));
88 count_[i].resize(nBins_(1));
89 for (
int j = 0; j < nBins_(1); ++j) {
90 hist_[i][j].resize(nBins_(2));
91 count_[i][j].resize(nBins_(2));
92 std::fill(hist_[i][j].begin(), hist_[i][j].end(), 0.0);
93 std::fill(count_[i][j].begin(), count_[i][j].end(), 0.0);
97 setOutputName(
getPrefix(filename) +
".Qxyz");
100 void TetrahedralityParamXYZ::process() {
107 Vector3d ri, rj, rk, rik, rkj;
111 std::vector<std::pair<RealType, StuntDouble*>> myNeighbors;
116 bool usePeriodicBoundaryConditions_ =
117 info_->getSimParams()->getUsePeriodicBoundaryConditions();
119 int kMax = int(5.0 * gaussWidth_ / voxelSize_);
120 int kSqLim = kMax * kMax;
121 cerr <<
"gw = " << gaussWidth_ <<
" vS = " << voxelSize_
122 <<
" kMax = " << kMax <<
" kSqLim = " << kSqLim <<
"\n";
124 DumpReader reader(info_, dumpFilename_);
125 int nFrames = reader.getNFrames();
127 for (
int istep = 0; istep < nFrames; istep += step_) {
128 reader.readFrame(istep);
130 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
131 Mat3x3d hmat = currentSnapshot_->getHmat();
132 Vector3d halfBox = Vector3d(hmat(0, 0), hmat(1, 1), hmat(2, 2)) / 2.0;
134 if (evaluator1_.isDynamic()) {
135 seleMan1_.setSelectionSet(evaluator1_.evaluate());
138 if (evaluator2_.isDynamic()) {
139 seleMan2_.setSelectionSet(evaluator2_.evaluate());
145 for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
146 sd = seleMan1_.nextSelected(isd1)) {
147 myIndex = sd->getGlobalIndex();
152 for (sd2 = seleMan2_.beginSelected(isd2); sd2 != NULL;
153 sd2 = seleMan2_.nextSelected(isd2)) {
154 if (sd2->getGlobalIndex() != myIndex) {
155 vec = sd->getPos() - sd2->getPos();
157 if (usePeriodicBoundaryConditions_)
158 currentSnapshot_->wrapVector(vec);
164 if (r < rCut_) { myNeighbors.push_back(std::make_pair(r, sd2)); }
169 std::sort(myNeighbors.begin(), myNeighbors.end());
173 int nbors = myNeighbors.size() > 4 ? 4 : myNeighbors.size();
174 int nang = int(0.5 * (nbors * (nbors - 1)));
178 for (
int i = 0; i < nbors - 1; i++) {
179 sdi = myNeighbors[i].second;
182 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(rik);
186 for (
int j = i + 1; j < nbors; j++) {
187 sdj = myNeighbors[j].second;
190 if (usePeriodicBoundaryConditions_)
191 currentSnapshot_->wrapVector(rkj);
194 cospsi =
dot(rik, rkj);
198 Qk -= (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);
203 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(rk);
206 Vector3d pos = rk + halfBox;
208 Vector3i whichVoxel(
int(pos[0] / voxelSize_),
209 int(pos[1] / voxelSize_),
210 int(pos[2] / voxelSize_));
212 for (
int l = -kMax; l <= kMax; l++) {
213 for (
int m = -kMax; m <= kMax; m++) {
214 for (
int n = -kMax; n <= kMax; n++) {
215 int kk = l * l + m * m + n * n;
217 int ll = (whichVoxel[0] + l) % nBins_(0);
218 ll = ll < 0 ? nBins_(0) + ll : ll;
219 int mm = (whichVoxel[1] + m) % nBins_(1);
220 mm = mm < 0 ? nBins_(1) + mm : mm;
221 int nn = (whichVoxel[2] + n) % nBins_(2);
222 nn = nn < 0 ? nBins_(2) + nn : nn;
224 Vector3d bPos = Vector3d(ll, mm, nn) * voxelSize_ - halfBox;
225 Vector3d d = bPos - rk;
226 currentSnapshot_->wrapVector(d);
228 pow(2.0 * sqrt(Constants::PI) * gaussWidth_, 3);
229 RealType exponent = -
dot(d, d) / pow(2.0 * gaussWidth_, 2);
230 RealType weight = exp(exponent) / denom;
231 count_[ll][mm][nn] += weight;
232 hist_[ll][mm][nn] += weight * Qk;
261 void TetrahedralityParamXYZ::writeVTKGrid() {
262 Mat3x3d hmat = info_->getSnapshotManager()->getCurrentSnapshot()->getHmat();
265 for (
unsigned int i = 0; i < hist_.size(); ++i) {
266 for (
unsigned int j = 0; j < hist_[i].size(); ++j) {
267 for (
unsigned int k = 0; k < hist_[i][j].size(); ++k) {
268 hist_[i][j][k] = hist_[i][j][k] / count_[i][j][k];
273 std::ofstream qXYZstream(outputFilename_.c_str());
274 if (qXYZstream.is_open()) {
275 qXYZstream <<
"# vtk DataFile Version 2.0\n";
276 qXYZstream <<
"Tetrahedrality Parameter volume rendering\n";
277 qXYZstream <<
"ASCII\n";
278 qXYZstream <<
"DATASET RECTILINEAR_GRID\n";
279 qXYZstream <<
"DIMENSIONS " << hist_.size() <<
" " << hist_[0].size()
280 <<
" " << hist_[0][0].size() <<
"\n";
281 qXYZstream <<
"X_COORDINATES " << hist_.size() <<
" float\n";
282 for (std::size_t i = 0; i < hist_.size(); ++i) {
283 qXYZstream << (RealType(i) / nBins_.x()) * hmat(0, 0) <<
" ";
286 qXYZstream <<
"Y_COORDINATES " << hist_[0].size() <<
" float\n";
287 for (std::size_t j = 0; j < hist_[0].size(); ++j) {
288 qXYZstream << (RealType(j) / nBins_.y()) * hmat(1, 1) <<
" ";
291 qXYZstream <<
"Z_COORDINATES " << hist_[0][0].size() <<
" float\n";
292 for (std::size_t k = 0; k < hist_[0][0].size(); ++k) {
293 qXYZstream << (RealType(k) / nBins_.z()) * hmat(2, 2) <<
" ";
296 qXYZstream <<
"POINT_DATA "
297 << hist_.size() * hist_[0].size() * hist_[0][0].size() <<
"\n";
298 qXYZstream <<
"SCALARS scalars float\n";
299 qXYZstream <<
"LOOKUP_TABLE default\n";
301 for (std::size_t k = 0; k < hist_[0][0].size(); ++k) {
302 for (std::size_t j = 0; j < hist_[0].size(); ++j) {
303 for (std::size_t i = 0; i < hist_.size(); ++i) {
304 qXYZstream << hist_[i][j][k] <<
" ";
313 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
314 "TetrahedralityParamXYZ: unable to open %s\n",
315 outputFilename_.c_str());
316 painCave.isFatal = 1;
322 void TetrahedralityParamXYZ::writeQxyz() {
323 Mat3x3d hmat = info_->getSnapshotManager()->getCurrentSnapshot()->getHmat();
326 for (
unsigned int i = 0; i < hist_.size(); ++i) {
327 for (
unsigned int j = 0; j < hist_[i].size(); ++j) {
328 for (
unsigned int k = 0; k < hist_[i][j].size(); ++k) {
329 hist_[i][j][k] = hist_[i][j][k] / count_[i][j][k];
334 std::ofstream qXYZstream(outputFilename_.c_str());
335 if (qXYZstream.is_open()) {
336 qXYZstream <<
"# AmiraMesh ASCII 1.0\n\n";
337 qXYZstream <<
"# Dimensions in x-, y-, and z-direction\n";
338 qXYZstream <<
" define Lattice " << hist_.size() <<
" "
339 << hist_[0].size() <<
" " << hist_[0][0].size() <<
"\n";
341 qXYZstream <<
"Parameters {\n";
342 qXYZstream <<
" CoordType \"uniform\",\n";
343 qXYZstream <<
" # BoundingBox is xmin xmax ymin ymax zmin zmax\n";
344 qXYZstream <<
" BoundingBox 0.0 " << hmat(0, 0) <<
" 0.0 "
345 << hmat(1, 1) <<
" 0.0 " << hmat(2, 2) <<
"\n";
348 qXYZstream <<
"Lattice { double ScalarField } = @1\n";
350 qXYZstream <<
"@1\n";
352 for (std::size_t k = 0; k < hist_[0][0].size(); ++k) {
353 for (std::size_t j = 0; j < hist_[0].size(); ++j) {
354 for (std::size_t i = 0; i < hist_.size(); ++i) {
355 qXYZstream << hist_[i][j][k] <<
" ";
364 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
365 "TetrahedralityParamXYZ: unable to open %s\n",
366 outputFilename_.c_str());
367 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)