48#include "applications/staticProps/MultipoleSum.hpp"
55#include "types/MultipoleAdapter.hpp"
56#include "utils/simError.h"
60 MultipoleSum::MultipoleSum(
SimInfo* info,
const std::string& filename,
61 const std::string& sele1, RealType rmax,
64 nRBins_(nrbins), rMax_(rmax), selectionScript1_(sele1), seleMan1_(info),
66 setOutputName(
getPrefix(filename) +
".multipoleSum");
68 evaluator1_.loadScriptString(sele1);
69 if (!evaluator1_.isDynamic()) {
70 seleMan1_.setSelectionSet(evaluator1_.evaluate());
74 aveDlength_.resize(nRBins_, 0.0);
76 aveQlength_.resize(nRBins_, 0.0);
78 aveDcount_.resize(nRBins_, 0.0);
80 aveQcount_.resize(nRBins_, 0.0);
82 aveDproj_.resize(nRBins_, 0.0);
83 deltaR_ = rMax_ / nRBins_;
86 void MultipoleSum::process() {
88 SimInfo::MoleculeIterator miter;
89 vector<Atom*>::iterator aiter;
95 std::vector<RealType> dipoleHist(nRBins_, 0.0);
96 std::vector<RealType> qpoleHist(nRBins_, 0.0);
97 std::vector<int> lengthCount(nRBins_, 0);
98 std::vector<Vector3d> totalDipole;
99 std::vector<Mat3x3d> totalQpole;
100 std::vector<int> dipoleCount;
101 std::vector<int> qpoleCount;
102 std::vector<RealType> dipoleProjection;
105 bool usePeriodicBoundaryConditions_ =
106 info_->getSimParams()->getUsePeriodicBoundaryConditions();
108 DumpReader reader(info_, dumpFilename_);
109 int nFrames = reader.getNFrames();
111 for (
int i = 0; i < nFrames; i += step_) {
113 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
115 if (evaluator1_.isDynamic()) {
116 seleMan1_.setSelectionSet(evaluator1_.evaluate());
119 for (sd1 = seleMan1_.beginSelected(i1); sd1 != NULL;
120 sd1 = seleMan1_.nextSelected(i1)) {
121 pos1 = sd1->getPos();
124 totalDipole.resize(nRBins_, V3Zero);
126 dipoleCount.resize(nRBins_, 0);
128 totalQpole.resize(nRBins_, M3Zero);
130 qpoleCount.resize(nRBins_, 0);
131 dipoleProjection.clear();
132 dipoleProjection.resize(nRBins_, 0.0);
134 for (mol = info_->beginMolecule(miter); mol != NULL;
135 mol = info_->nextMolecule(miter)) {
136 for (atom = mol->beginAtom(aiter); atom != NULL;
137 atom = mol->nextAtom(aiter)) {
139 ri = atom->getPos() - pos1;
141 if (usePeriodicBoundaryConditions_)
142 currentSnapshot_->wrapVector(ri);
146 AtomType* atype2 = atom->getAtomType();
147 MultipoleAdapter ma2 = MultipoleAdapter(atype2);
149 if (ma2.isDipole()) dipole = atom->getDipole();
150 if (ma2.isQuadrupole()) qpole = atom->getQuadrupole();
153 std::size_t bin = int(distance / deltaR_);
157 for (std::size_t j = bin; j < nRBins_; j++) {
158 totalDipole[j] += dipole;
160 totalQpole[j] += qpole;
166 Vector3d myDipole = sd1->getDipole();
168 for (std::size_t j = 0; j < nRBins_; j++) {
169 RealType myProjection =
170 dot(myDipole, totalDipole[j]) / myDipole.length();
172 RealType dipoleLength = totalDipole[j].length();
173 RealType Qtrace = totalQpole[j].trace();
174 RealType Qddot =
doubleDot(totalQpole[j], totalQpole[j]);
175 RealType qpoleLength = 2.0 * (3.0 * Qddot - Qtrace * Qtrace);
176 dipoleHist[j] += dipoleLength;
177 qpoleHist[j] += qpoleLength;
178 aveDcount_[j] += dipoleCount[j];
179 aveQcount_[j] += qpoleCount[j];
181 dipoleProjection[j] += myProjection;
186 int nSelected = seleMan1_.getSelectionCount();
187 for (std::size_t j = 0; j < nRBins_; j++) {
188 if (lengthCount[j] > 0) {
189 aveDlength_[j] = dipoleHist[j] / RealType(lengthCount[j]);
190 aveQlength_[j] = qpoleHist[j] / RealType(lengthCount[j]);
191 aveDcount_[j] /= RealType(nSelected);
192 aveQcount_[j] /= RealType(nSelected);
193 aveDproj_[j] = dipoleProjection[j] / RealType(lengthCount[j]);
195 aveDlength_[j] = 0.0;
196 aveQlength_[j] = 0.0;
205 void MultipoleSum::writeOut() {
206 ofstream os(getOutputFileName().c_str());
207 os <<
"#multipole sum\n";
208 os <<
"#selection1: (" << selectionScript1_ <<
")\t";
209 os <<
"#r\taveDlength\taveDdensity\taveDproj\taveQlength\taveQdensity\n";
211 for (std::size_t i = 0; i < nRBins_; ++i) {
212 RealType r = deltaR_ * i;
213 os << r <<
"\t" << aveDlength_[i] <<
"\t"
214 << aveDlength_[i] / aveDcount_[i] <<
"\t" << aveDproj_[i] <<
"\t"
215 << aveQlength_[i] <<
"\t" << aveQlength_[i] / aveQcount_[i] <<
"\n";
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 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.