45#include "applications/staticProps/TetrahedralityParam.hpp" 
   51#include "utils/simError.h" 
   55  TetrahedralityParam::TetrahedralityParam(SimInfo* info,
 
   56                                           const std::string& filename,
 
   57                                           const std::string& sele, 
double rCut,
 
   59      StaticAnalyser(info, filename, nbins),
 
   60      selectionScript_(sele), seleMan_(info), evaluator_(info) {
 
   61    setOutputName(
getPrefix(filename) + 
".q");
 
   63    evaluator_.loadScriptString(sele);
 
   64    if (!evaluator_.isDynamic()) {
 
   65      seleMan_.setSelectionSet(evaluator_.evaluate());
 
   72    Q_histogram_.resize(nBins_);
 
   78    deltaQ_ = (MaxQ_ - MinQ_) / nBins_;
 
   81  void TetrahedralityParam::initializeHistogram() {
 
   82    std::fill(Q_histogram_.begin(), Q_histogram_.end(), 0);
 
   85  void TetrahedralityParam::process() {
 
   92    SimInfo::MoleculeIterator mi;
 
   93    Molecule::IntegrableObjectIterator ioi;
 
   95    Vector3d ri, rj, rk, rik, rkj, dposition, tposition;
 
   99    std::vector<std::pair<RealType, StuntDouble*>> myNeighbors;
 
  101    bool usePeriodicBoundaryConditions_ =
 
  102        info_->getSimParams()->getUsePeriodicBoundaryConditions();
 
  104    DumpReader reader(info_, dumpFilename_);
 
  105    int nFrames   = reader.getNFrames();
 
  109    Tetrahedral_.clear();
 
  111    for (
int istep = 0; istep < nFrames; istep += step_) {
 
  112      reader.readFrame(istep);
 
  114      currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
 
  116      if (evaluator_.isDynamic()) {
 
  117        seleMan_.setSelectionSet(evaluator_.evaluate());
 
  122      for (sd = seleMan_.beginSelected(isd); sd != NULL;
 
  123           sd = seleMan_.nextSelected(isd)) {
 
  124        myIndex = sd->getGlobalIndex();
 
  131        for (mol = info_->beginMolecule(mi); mol != NULL;
 
  132             mol = info_->nextMolecule(mi)) {
 
  133          for (sd2 = mol->beginIntegrableObject(ioi); sd2 != NULL;
 
  134               sd2 = mol->nextIntegrableObject(ioi)) {
 
  135            if (sd2->getGlobalIndex() != myIndex) {
 
  136              vec = sd->getPos() - sd2->getPos();
 
  138              if (usePeriodicBoundaryConditions_)
 
  139                currentSnapshot_->wrapVector(vec);
 
  145              if (r < rCut_) { myNeighbors.push_back(std::make_pair(r, sd2)); }
 
  151        std::sort(myNeighbors.begin(), myNeighbors.end());
 
  158        int nbors = myNeighbors.size() > 4 ? 4 : myNeighbors.size();
 
  159        int nang  = int(0.5 * (nbors * (nbors - 1)));
 
  163        for (
int i = 0; i < nbors - 1; i++) {
 
  164          sdi = myNeighbors[i].second;
 
  167          if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(rik);
 
  171          for (
int j = i + 1; j < nbors; j++) {
 
  172            sdj = myNeighbors[j].second;
 
  175            if (usePeriodicBoundaryConditions_)
 
  176              currentSnapshot_->wrapVector(rkj);
 
  179            cospsi = 
dot(rik, rkj);
 
  185            Qk = Qk - (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);
 
  191          collectHistogram(Qk);
 
  195          if ((Qk < 0.55) && (Qk > 0.45)) {
 
  197            Distorted_.push_back(sd);
 
  199            dposition = sd->getPos();
 
  206            Tetrahedral_.push_back(sd);
 
  208            tposition = sd->getPos();
 
  217    writeOrderParameter();
 
  218    std::cerr << 
"number of distorted StuntDoubles = " << Distorted_.size()
 
  220    std::cerr << 
"number of tetrahedral StuntDoubles = " << Tetrahedral_.size()
 
  224  void TetrahedralityParam::collectHistogram(RealType Qk) {
 
  225    if (Qk > MinQ_ && Qk < MaxQ_) {
 
  226      int whichBin = int((Qk - MinQ_) / deltaQ_);
 
  227      Q_histogram_[whichBin] += 1;
 
  231  void TetrahedralityParam::writeOrderParameter() {
 
  234    for (
int i = 0; i < nBins_; ++i) {
 
  235      nSelected = nSelected + int(Q_histogram_[i] * deltaQ_);
 
  238    std::ofstream osq((getOutputFileName() + 
"Q").c_str());
 
  241      osq << 
"# Tetrahedrality Parameters\n";
 
  242      osq << 
"# selection: (" << selectionScript_ << 
")\n";
 
  245      for (
int i = 0; i < nBins_; ++i) {
 
  246        RealType Qval = MinQ_ + (i + 0.5) * deltaQ_;
 
  248        osq << 
"\t" << (RealType)(Q_histogram_[i] / deltaQ_) / nSelected;
 
  255      snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  256               "TetrahedralityParam: unable to open %s\n",
 
  257               (getOutputFileName() + 
"q").c_str());
 
  258      painCave.isFatal = 1;
 
  262    DumpReader reader(info_, dumpFilename_);
 
  263    int nFrames = reader.getNFrames();
 
  266      std::vector<StuntDouble*>::iterator iter;
 
  267      std::ofstream osd((getOutputFileName() + 
"dxyz").c_str());
 
  270        osd << Distorted_.size() << 
"\n";
 
  273        for (iter = Distorted_.begin(); iter != Distorted_.end(); ++iter) {
 
  275          position = (*iter)->getPos();
 
  278          for (
unsigned int z = 0; z < position.size(); z++) {
 
  279            osd << position[z] << 
"  " 
  287      std::ofstream ost((getOutputFileName() + 
"txyz").c_str());
 
  290        ost << Tetrahedral_.size() << 
"\n";
 
  293        for (iter = Tetrahedral_.begin(); iter != Tetrahedral_.end(); ++iter) {
 
  295          position = (*iter)->getPos();
 
  300          for (
unsigned int z = 0; z < position.size(); z++) {
 
  301            ost << position[z] << 
"  " 
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)