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.