45#include "applications/staticProps/Kirkwood.hpp"
51#include "types/MultipoleAdapter.hpp"
52#include "utils/Revision.hpp"
53#include "utils/simError.h"
57 Kirkwood::Kirkwood(SimInfo* info,
const std::string& filename,
58 const std::string& sele1,
const std::string& sele2,
59 RealType len,
int nrbins) :
60 RadialDistrFunc(info, filename, sele1, sele2, nrbins),
62 setAnalysisType(
"Distance-dependent Kirkwood G-factor");
63 setOutputName(
getPrefix(filename) +
".kirkwood");
65 deltaR_ = len_ / nBins_;
67 histogram_.resize(nBins_);
68 avgKirkwood_.resize(nBins_);
69 std::stringstream params;
70 params <<
" len = " << len_ <<
", nrbins = " << nBins_;
71 const std::string paramString = params.str();
72 setParameterString(paramString);
75 void Kirkwood::preProcess() {
76 std::fill(avgKirkwood_.begin(), avgKirkwood_.end(), 0.0);
79 void Kirkwood::initializeHistogram() {
80 std::fill(histogram_.begin(), histogram_.end(), 0);
83 void Kirkwood::processHistogram() {
84 int nSelected1 = seleMan1_.getSelectionCount();
85 for (
unsigned int i = 0; i < histogram_.size(); ++i) {
86 avgKirkwood_[i] += histogram_[i] / nSelected1;
90 void Kirkwood::collectHistogram(StuntDouble* sd1, StuntDouble* sd2) {
91 if (sd1 == sd2) {
return; }
92 bool usePeriodicBoundaryConditions_ =
93 info_->getSimParams()->getUsePeriodicBoundaryConditions();
95 Vector3d pos1 = sd1->getPos();
96 Vector3d pos2 = sd2->getPos();
97 Vector3d r12 = pos2 - pos1;
98 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(r12);
102 AtomType* atype1 =
static_cast<Atom*
>(sd1)->getAtomType();
103 AtomType* atype2 =
static_cast<Atom*
>(sd2)->getAtomType();
105 MultipoleAdapter ma1 = MultipoleAdapter(atype1);
106 MultipoleAdapter ma2 = MultipoleAdapter(atype2);
110 RealType dotProduct(0.0);
112 if (ma1.isDipole()) {
113 d1 = sd1->getDipole();
115 if (ma2.isDipole()) {
116 d2 = sd2->getDipole();
118 dotProduct =
dot(d1, d2);
122 if (distance < len_) {
123 int whichBin = int(distance / deltaR_);
125 for (
unsigned int i = whichBin; i < nBins_; i++) {
126 histogram_[i] += dotProduct;
131 void Kirkwood::writeRdf() {
132 std::ofstream ofs(outputFilename_.c_str());
135 ofs <<
"# " << getAnalysisType() <<
"\n";
136 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
137 ofs <<
"# " << r.getBuildDate() <<
"\n";
138 ofs <<
"# selection script1: \"" << selectionScript1_;
139 ofs <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
140 if (!paramString_.empty())
141 ofs <<
"# parameters: " << paramString_ <<
"\n";
143 ofs <<
"#r\tcorrValue\n";
144 for (
unsigned int i = 0; i < avgKirkwood_.size(); ++i) {
145 RealType r = deltaR_ * (i + 0.5);
146 ofs << r <<
"\t" << avgKirkwood_[i] / nProcessed_ <<
"\n";
149 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
150 "Kirkwood: unable to open %s\n", outputFilename_.c_str());
151 painCave.isFatal = 1;
157 KirkwoodQuadrupoles::KirkwoodQuadrupoles(SimInfo* info,
158 const std::string& filename,
159 const std::string& sele1,
160 const std::string& sele2,
161 RealType len,
int nrbins) :
162 Kirkwood(info, filename, sele1, sele2, len, nrbins) {
163 setAnalysisType(
"Distance-dependent Kirkwood G-factor for quadrupoles");
164 setOutputName(
getPrefix(filename) +
".kirkwoodQ");
167 void KirkwoodQuadrupoles::collectHistogram(StuntDouble* sd1,
169 if (sd1 == sd2) {
return; }
170 bool usePeriodicBoundaryConditions_ =
171 info_->getSimParams()->getUsePeriodicBoundaryConditions();
173 Vector3d pos1 = sd1->getPos();
174 Vector3d pos2 = sd2->getPos();
175 Vector3d r12 = pos2 - pos1;
176 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(r12);
180 AtomType* atype1 =
static_cast<Atom*
>(sd1)->getAtomType();
181 AtomType* atype2 =
static_cast<Atom*
>(sd2)->getAtomType();
183 MultipoleAdapter ma1 = MultipoleAdapter(atype1);
184 MultipoleAdapter ma2 = MultipoleAdapter(atype2);
193 RealType quadrupoleProduct(0.0);
201 if (ma1.isQuadrupole()) {
202 Q1 = sd1->getQuadrupole();
205 Q1 /= sqrt(3.0 * Q1dQ1 - trQ1 * trQ1);
209 if (ma2.isQuadrupole()) {
210 Q2 = sd2->getQuadrupole();
213 Q2 /= sqrt(3.0 * Q2dQ2 - trQ2 * trQ2);
217 quadrupoleProduct = 3.0 *
doubleDot(Q1, Q2) - trQ1 * trQ2;
221 if (distance < len_) {
222 int whichBin = int(distance / deltaR_);
224 for (
unsigned int i = whichBin; i < nBins_; i++) {
225 histogram_[i] += quadrupoleProduct;
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Real doubleDot(const RectMatrix< Real, Row, Col > &t1, const RectMatrix< Real, Row, Col > &t2)
Returns the tensor contraction (double dot product) of two rank 2 tensors (or Matrices)
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
std::string getPrefix(const std::string &str)
Real distance(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the distance between two DynamicVectors.