45#include "applications/staticProps/TetrahedralityParamR.hpp" 
   53#include "utils/Revision.hpp" 
   54#include "utils/simError.h" 
   56#define HONKING_LARGE_VALUE 1.0e10 
   60  TetrahedralityParamR::TetrahedralityParamR(
 
   61      SimInfo* info, 
const std::string& filename, 
const std::string& sele1,
 
   62      const std::string& sele2, 
const std::string& sele3, RealType rCut,
 
   63      RealType len, 
int nrbins) :
 
   64      StaticAnalyser(info, filename, nrbins),
 
   65      selectionScript1_(sele1), selectionScript2_(sele2),
 
   66      selectionScript3_(sele3), seleMan1_(info), seleMan2_(info),
 
   67      seleMan3_(info), evaluator1_(info), evaluator2_(info), evaluator3_(info),
 
   68      len_(len), nBins_(nrbins) {
 
   69    setAnalysisType(
"Tetrahedrality Parameter(r)");
 
   71    evaluator1_.loadScriptString(sele1);
 
   72    if (!evaluator1_.isDynamic()) {
 
   73      seleMan1_.setSelectionSet(evaluator1_.evaluate());
 
   76    evaluator2_.loadScriptString(sele2);
 
   77    if (!evaluator2_.isDynamic()) {
 
   78      seleMan2_.setSelectionSet(evaluator2_.evaluate());
 
   81    evaluator3_.loadScriptString(sele3);
 
   82    if (!evaluator3_.isDynamic()) {
 
   83      seleMan3_.setSelectionSet(evaluator3_.evaluate());
 
   89    deltaR_ = len_ / nBins_;
 
   92    sliceQ_.resize(nBins_);
 
   93    sliceCount_.resize(nBins_);
 
   94    std::fill(sliceQ_.begin(), sliceQ_.end(), 0.0);
 
   95    std::fill(sliceCount_.begin(), sliceCount_.end(), 0);
 
   97    setOutputName(
getPrefix(filename) + 
".Qr");
 
  100  void TetrahedralityParamR::process() {
 
  108    Vector3d ri, rj, rk, rik, rkj;
 
  112    std::vector<std::pair<RealType, StuntDouble*>> myNeighbors;
 
  116    bool usePeriodicBoundaryConditions_ =
 
  117        info_->getSimParams()->getUsePeriodicBoundaryConditions();
 
  119    DumpReader reader(info_, dumpFilename_);
 
  120    int nFrames = reader.getNFrames();
 
  122    for (
int istep = 0; istep < nFrames; istep += step_) {
 
  123      reader.readFrame(istep);
 
  124      currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
 
  126      if (evaluator1_.isDynamic()) {
 
  127        seleMan1_.setSelectionSet(evaluator1_.evaluate());
 
  130      if (evaluator2_.isDynamic()) {
 
  131        seleMan2_.setSelectionSet(evaluator2_.evaluate());
 
  134      if (evaluator3_.isDynamic()) {
 
  135        seleMan3_.setSelectionSet(evaluator3_.evaluate());
 
  139      for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
 
  140           sd = seleMan1_.nextSelected(isd1)) {
 
  141        myIndex = sd->getGlobalIndex();
 
  146        for (sd2 = seleMan2_.beginSelected(isd2); sd2 != NULL;
 
  147             sd2 = seleMan2_.nextSelected(isd2)) {
 
  148          if (sd2->getGlobalIndex() != myIndex) {
 
  149            vec = sd->getPos() - sd2->getPos();
 
  151            if (usePeriodicBoundaryConditions_)
 
  152              currentSnapshot_->wrapVector(vec);
 
  158            if (r < rCut_) { myNeighbors.push_back(std::make_pair(r, sd2)); }
 
  163        std::sort(myNeighbors.begin(), myNeighbors.end());
 
  167        int nbors = myNeighbors.size() > 4 ? 4 : myNeighbors.size();
 
  168        int nang  = int(0.5 * (nbors * (nbors - 1)));
 
  172        for (
int i = 0; i < nbors - 1; i++) {
 
  173          sdi = myNeighbors[i].second;
 
  176          if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(rik);
 
  180          for (
int j = i + 1; j < nbors; j++) {
 
  181            sdj = myNeighbors[j].second;
 
  184            if (usePeriodicBoundaryConditions_)
 
  185              currentSnapshot_->wrapVector(rkj);
 
  188            cospsi = 
dot(rik, rkj);
 
  192            Qk -= (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);
 
  197          RealType shortest = HONKING_LARGE_VALUE;
 
  200          for (sd3 = seleMan3_.beginSelected(isd3); sd3 != NULL;
 
  201               sd3 = seleMan3_.nextSelected(isd3)) {
 
  202            vec = sd->getPos() - sd3->getPos();
 
  204            if (usePeriodicBoundaryConditions_)
 
  205              currentSnapshot_->wrapVector(vec);
 
  209            if (r < shortest) shortest = r;
 
  212          int whichBin = int(shortest / deltaR_);
 
  213          if (whichBin < 
int(nBins_)) {
 
  214            sliceQ_[whichBin] += Qk;
 
  215            sliceCount_[whichBin] += 1;
 
  223  void TetrahedralityParamR::writeQr() {
 
  225    std::ofstream qRstream(outputFilename_.c_str());
 
  226    if (qRstream.is_open()) {
 
  227      qRstream << 
"# " << getAnalysisType() << 
"\n";
 
  228      qRstream << 
"# OpenMD " << rev.getFullRevision() << 
"\n";
 
  229      qRstream << 
"# " << rev.getBuildDate() << 
"\n";
 
  230      qRstream << 
"#selection 1: (" << selectionScript1_ << 
")\n";
 
  231      qRstream << 
"#selection 2: (" << selectionScript2_ << 
")\n";
 
  232      qRstream << 
"#selection 3: (" << selectionScript3_ << 
")\n";
 
  233      if (!paramString_.empty())
 
  234        qRstream << 
"# parameters: " << paramString_ << 
"\n";
 
  236      qRstream << 
"#distance" 
  238      for (
unsigned int i = 0; i < sliceQ_.size(); ++i) {
 
  239        RealType Rval = (i + 0.5) * deltaR_;
 
  240        if (sliceCount_[i] != 0) {
 
  241          qRstream << Rval << 
"\t" << sliceQ_[i] / (RealType)sliceCount_[i]
 
  247      snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  248               "TetrahedralityParamR: unable to open %s\n",
 
  249               outputFilename_.c_str());
 
  250      painCave.isFatal = 1;
 
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)