45#include "applications/staticProps/MultipoleSum.hpp"
52#include "types/MultipoleAdapter.hpp"
53#include "utils/simError.h"
57 MultipoleSum::MultipoleSum(SimInfo* info,
const std::string& filename,
58 const std::string& sele1, RealType rmax,
60 StaticAnalyser(info, filename, nrbins),
61 nRBins_(nrbins), rMax_(rmax), selectionScript1_(sele1), seleMan1_(info),
63 setOutputName(
getPrefix(filename) +
".multipoleSum");
65 evaluator1_.loadScriptString(sele1);
66 if (!evaluator1_.isDynamic()) {
67 seleMan1_.setSelectionSet(evaluator1_.evaluate());
71 aveDlength_.resize(nRBins_, 0.0);
73 aveQlength_.resize(nRBins_, 0.0);
75 aveDcount_.resize(nRBins_, 0.0);
77 aveQcount_.resize(nRBins_, 0.0);
79 aveDproj_.resize(nRBins_, 0.0);
80 deltaR_ = rMax_ / nRBins_;
83 void MultipoleSum::process() {
85 SimInfo::MoleculeIterator miter;
86 vector<Atom*>::iterator aiter;
92 std::vector<RealType> dipoleHist(nRBins_, 0.0);
93 std::vector<RealType> qpoleHist(nRBins_, 0.0);
94 std::vector<int> lengthCount(nRBins_, 0);
95 std::vector<Vector3d> totalDipole;
96 std::vector<Mat3x3d> totalQpole;
97 std::vector<int> dipoleCount;
98 std::vector<int> qpoleCount;
99 std::vector<RealType> dipoleProjection;
102 bool usePeriodicBoundaryConditions_ =
103 info_->getSimParams()->getUsePeriodicBoundaryConditions();
105 DumpReader reader(info_, dumpFilename_);
106 int nFrames = reader.getNFrames();
108 for (
int i = 0; i < nFrames; i += step_) {
110 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
112 if (evaluator1_.isDynamic()) {
113 seleMan1_.setSelectionSet(evaluator1_.evaluate());
116 for (sd1 = seleMan1_.beginSelected(i1); sd1 != NULL;
117 sd1 = seleMan1_.nextSelected(i1)) {
118 pos1 = sd1->getPos();
121 totalDipole.resize(nRBins_, V3Zero);
123 dipoleCount.resize(nRBins_, 0);
125 totalQpole.resize(nRBins_, M3Zero);
127 qpoleCount.resize(nRBins_, 0);
128 dipoleProjection.clear();
129 dipoleProjection.resize(nRBins_, 0.0);
131 for (mol = info_->beginMolecule(miter); mol != NULL;
132 mol = info_->nextMolecule(miter)) {
133 for (atom = mol->beginAtom(aiter); atom != NULL;
134 atom = mol->nextAtom(aiter)) {
136 ri = atom->getPos() - pos1;
138 if (usePeriodicBoundaryConditions_)
139 currentSnapshot_->wrapVector(ri);
143 AtomType* atype2 = atom->getAtomType();
144 MultipoleAdapter ma2 = MultipoleAdapter(atype2);
146 if (ma2.isDipole()) dipole = atom->getDipole();
147 if (ma2.isQuadrupole()) qpole = atom->getQuadrupole();
150 std::size_t bin = int(distance / deltaR_);
154 for (std::size_t j = bin; j < nRBins_; j++) {
155 totalDipole[j] += dipole;
157 totalQpole[j] += qpole;
163 Vector3d myDipole = sd1->getDipole();
165 for (std::size_t j = 0; j < nRBins_; j++) {
166 RealType myProjection =
167 dot(myDipole, totalDipole[j]) / myDipole.length();
169 RealType dipoleLength = totalDipole[j].length();
170 RealType Qtrace = totalQpole[j].trace();
171 RealType Qddot =
doubleDot(totalQpole[j], totalQpole[j]);
172 RealType qpoleLength = 2.0 * (3.0 * Qddot - Qtrace * Qtrace);
173 dipoleHist[j] += dipoleLength;
174 qpoleHist[j] += qpoleLength;
175 aveDcount_[j] += dipoleCount[j];
176 aveQcount_[j] += qpoleCount[j];
178 dipoleProjection[j] += myProjection;
183 int nSelected = seleMan1_.getSelectionCount();
184 for (std::size_t j = 0; j < nRBins_; j++) {
185 if (lengthCount[j] > 0) {
186 aveDlength_[j] = dipoleHist[j] / RealType(lengthCount[j]);
187 aveQlength_[j] = qpoleHist[j] / RealType(lengthCount[j]);
188 aveDcount_[j] /= RealType(nSelected);
189 aveQcount_[j] /= RealType(nSelected);
190 aveDproj_[j] = dipoleProjection[j] / RealType(lengthCount[j]);
192 aveDlength_[j] = 0.0;
193 aveQlength_[j] = 0.0;
202 void MultipoleSum::writeOut() {
203 ofstream os(getOutputFileName().c_str());
204 os <<
"#multipole sum\n";
205 os <<
"#selection1: (" << selectionScript1_ <<
")\t";
206 os <<
"#r\taveDlength\taveDdensity\taveDproj\taveQlength\taveQdensity\n";
208 for (std::size_t i = 0; i < nRBins_; ++i) {
209 RealType r = deltaR_ * i;
210 os << r <<
"\t" << aveDlength_[i] <<
"\t"
211 << aveDlength_[i] / aveDcount_[i] <<
"\t" << aveDproj_[i] <<
"\t"
212 << aveQlength_[i] <<
"\t" << aveQlength_[i] / aveQcount_[i] <<
"\n";
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.