45#include "applications/staticProps/CoordinationNumber.hpp" 
   52#include "utils/Revision.hpp" 
   53#include "utils/simError.h" 
   57  CoordinationNumber::CoordinationNumber(SimInfo* info,
 
   58                                         const std::string& filename,
 
   59                                         const std::string& sele1,
 
   60                                         const std::string& sele2,
 
   61                                         RealType rCut, 
int bins) :
 
   62      StaticAnalyser(info, filename, bins),
 
   63      rCut_(rCut), bins_(bins), sele1_(sele1), seleMan1_(info),
 
   64      evaluator1_(info), sele2_(sele2), seleMan2_(info), evaluator2_(info) {
 
   65    setAnalysisType(
"Coordination Number Distribution");
 
   66    setOutputName(
getPrefix(filename) + 
".cn");
 
   69    RealType binMax_ = nnMax_ * 1.5;
 
   70    delta_           = binMax_ / bins_;
 
   72    std::stringstream params;
 
   73    params << 
" rcut = " << rCut_ << 
", nbins = " << bins_
 
   74           << 
", nnMax = " << nnMax_;
 
   75    const std::string paramString = params.str();
 
   76    setParameterString(paramString);
 
   78    evaluator1_.loadScriptString(sele1);
 
   79    if (!evaluator1_.isDynamic()) {
 
   80      seleMan1_.setSelectionSet(evaluator1_.evaluate());
 
   81      selectionCount1_ = seleMan1_.getSelectionCount();
 
   83    evaluator2_.loadScriptString(sele2);
 
   84    if (!evaluator2_.isDynamic()) {
 
   85      seleMan2_.setSelectionSet(evaluator2_.evaluate());
 
   86      selectionCount2_ = seleMan2_.getSelectionCount();
 
   90  void CoordinationNumber::process() {
 
   91    SelectionManager common(info_);
 
   93    std::vector<std::vector<int>> listNN;
 
   94    std::vector<int> globalToLocal;
 
   99    Snapshot* currentSnapshot_;
 
  100    bool usePeriodicBoundaryConditions_ =
 
  101        info_->getSimParams()->getUsePeriodicBoundaryConditions();
 
  105    unsigned int mapIndex1(0);
 
  106    unsigned int mapIndex2(0);
 
  107    unsigned int whichBin(0);
 
  115    histogram_.resize(bins_, 0.0);
 
  117    DumpReader reader(info_, dumpFilename_);
 
  118    int nFrames = reader.getNFrames();
 
  123    for (
int istep = 0; istep < nFrames; istep += step_) {
 
  124      reader.readFrame(istep);
 
  125      currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
 
  127      if (evaluator1_.isDynamic()) {
 
  128        seleMan1_.setSelectionSet(evaluator1_.evaluate());
 
  129        selectionCount1_ = seleMan1_.getSelectionCount();
 
  131      if (evaluator2_.isDynamic()) {
 
  132        seleMan2_.setSelectionSet(evaluator2_.evaluate());
 
  133        selectionCount2_ = seleMan2_.getSelectionCount();
 
  137      common          = seleMan1_ | seleMan2_;
 
  138      int commonCount = common.getSelectionCount();
 
  140      globalToLocal.clear();
 
  141      globalToLocal.resize(
 
  142          info_->getNGlobalAtoms() + info_->getNGlobalRigidBodies(), -1);
 
  143      for (
unsigned int i = 0; i < listNN.size(); i++)
 
  144        listNN.at(i).clear();
 
  146      listNN.resize(commonCount);
 
  149      for (sd1 = common.beginSelected(iterator1); sd1 != NULL;
 
  150           sd1 = common.nextSelected(iterator1)) {
 
  151        globalToLocal.at(sd1->getGlobalIndex()) = mapIndex1;
 
  153        pos1 = sd1->getPos();
 
  156        for (sd2 = common.beginSelected(iterator2); sd2 != NULL;
 
  157             sd2 = common.nextSelected(iterator2)) {
 
  158          if (mapIndex1 < mapIndex2) {
 
  159            pos2 = sd2->getPos();
 
  161            if (usePeriodicBoundaryConditions_)
 
  162              currentSnapshot_->wrapVector(diff);
 
  164            if (distance < rCut_) {
 
  165              listNN.at(mapIndex1).push_back(mapIndex2);
 
  166              listNN.at(mapIndex2).push_back(mapIndex1);
 
  176      for (sd1 = seleMan1_.beginSelected(iterator1); sd1 != NULL;
 
  177           sd1 = seleMan1_.nextSelected(iterator1)) {
 
  178        mapIndex1 = globalToLocal.at(sd1->getGlobalIndex());
 
  180        cn       = computeCoordination(mapIndex1, listNN);
 
  181        whichBin = int(cn / delta_);
 
  183        if (whichBin < histogram_.size()) {
 
  184          histogram_[whichBin] += 1;
 
  186          snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  187                   "Coordination Number: Error: " 
  188                   "In frame, %d, object %d has CN %lf outside of range max.\n",
 
  189                   istep, sd1->getGlobalIndex(), cn);
 
  190          painCave.isFatal = 1;
 
  194      count_ += selectionCount1_;
 
  197    for (
unsigned int n = 0; n < histogram_.size(); n++) {
 
  199        histogram_[n] /= RealType(count_);
 
  207  RealType CoordinationNumber::computeCoordination(
int a,
 
  208                                                   vector<vector<int>> nl) {
 
  209    return RealType(nl.at(a).size());
 
  212  void CoordinationNumber::writeOutput() {
 
  213    std::ofstream ofs(outputFilename_.c_str(), std::ios::binary);
 
  217      RealType binValue(0.0);
 
  219      ofs << 
"# " << getAnalysisType() << 
"\n";
 
  220      ofs << 
"# OpenMD " << r.getFullRevision() << 
"\n";
 
  221      ofs << 
"# " << r.getBuildDate() << 
"\n";
 
  222      ofs << 
"# selection script1: \"" << sele1_;
 
  223      ofs << 
"\"\tselection script2: \"" << sele2_ << 
"\"\n";
 
  224      if (!paramString_.empty())
 
  225        ofs << 
"# parameters: " << paramString_ << 
"\n";
 
  227      for (
unsigned int n = 0; n < histogram_.size(); n++) {
 
  228        binValue = n * delta_;
 
  229        ofs << binValue << 
"\t" << histogram_[n] / delta_ << 
"\n";
 
  235  SCN::SCN(SimInfo* info, 
const std::string& filename, 
const std::string& sele1,
 
  236           const std::string& sele2, RealType rCut, 
int bins) :
 
  237      CoordinationNumber(info, filename, sele1, sele2, rCut, bins) {
 
  238    setOutputName(
getPrefix(filename) + 
".scn");
 
  239    setAnalysisType(
"Secondary Coordination Number");
 
  242  RealType SCN::computeCoordination(
int a, vector<vector<int>> nl) {
 
  246    if (nl.at(a).size() != 0) {
 
  247      for (
unsigned int i = 0; i < nl.at(a).size(); i++) {
 
  250        scn += nl.at(b).size();
 
  252      return scn / RealType(nl.at(a).size());
 
  258  GCN::GCN(SimInfo* info, 
const std::string& filename, 
const std::string& sele1,
 
  259           const std::string& sele2, RealType rCut, 
int bins) :
 
  260      CoordinationNumber(info, filename, sele1, sele2, rCut, bins) {
 
  261    setOutputName(
getPrefix(filename) + 
".gcn");
 
  262    setAnalysisType(
"Generalized Coordination Number");
 
  265  RealType GCN::computeCoordination(
int a, vector<vector<int>> nl) {
 
  268    for (
unsigned int i = 0; i < nl.at(a).size(); i++) {
 
  271      gcn += nl.at(b).size();
 
  273    return gcn / RealType(nnMax_);
 
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
 
std::string getPrefix(const std::string &str)
 
Real distance(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the distance between two DynamicVectors.