45#include "applications/staticProps/ChargeDensityZ.hpp" 
   50#include "brains/Thermo.hpp" 
   53#include "types/FixedChargeAdapter.hpp" 
   54#include "types/FluctuatingChargeAdapter.hpp" 
   55#include "utils/Constants.hpp" 
   56#include "utils/simError.h" 
   60  ChargeDensityZ::ChargeDensityZ(
SimInfo* info, 
const std::string& filename,
 
   61                                 const std::string& sele, 
int nzbins,
 
   62                                 RealType vRadius, std::string atomName,
 
   63                                 bool xyzGen, 
int axis) :
 
   65      selectionScript_(sele), evaluator_(info), seleMan_(info), thermo_(info),
 
   66      axis_(axis), vRadius_(vRadius), fileName_(filename),
 
   67      atomFlucCharge_(atomName), genXYZ_(xyzGen) {
 
   68    evaluator_.loadScriptString(sele);
 
   69    if (!evaluator_.isDynamic()) {
 
   70      seleMan_.setSelectionSet(evaluator_.evaluate());
 
   75    densityZAverageAllFrame_.resize(nBins_);
 
   76    densityFlucZAverageAllFrame_.resize(nBins_);
 
   77    absDensityFlucZAverageAllFrame_.resize(nBins_);
 
   78    averageDensityZ_.resize(nBins_);
 
   79    flucDensityZAverageAllFrame_.resize(nBins_);
 
   80    std::fill(densityFlucZAverageAllFrame_.begin(),
 
   81              densityFlucZAverageAllFrame_.end(), 0);
 
   82    std::fill(densityZAverageAllFrame_.begin(), densityZAverageAllFrame_.end(),
 
   84    std::fill(absDensityFlucZAverageAllFrame_.begin(),
 
   85              absDensityFlucZAverageAllFrame_.end(), 0);
 
   86    std::fill(averageDensityZ_.begin(), averageDensityZ_.end(), 0);
 
   87    std::fill(flucDensityZAverageAllFrame_.begin(),
 
   88              flucDensityZAverageAllFrame_.end(), 0);
 
   90    densityFlucZAverageFirstFrame_.resize(nBins_);
 
   91    absDensityFlucZAverageFirstFrame_.resize(nBins_);
 
   92    std::fill(densityFlucZAverageFirstFrame_.begin(),
 
   93              densityFlucZAverageFirstFrame_.end(), 0);
 
   94    std::fill(absDensityFlucZAverageFirstFrame_.begin(),
 
   95              absDensityFlucZAverageFirstFrame_.end(), 0);
 
  110    setOutputName(
getPrefix(filename) + 
".ChargeDensityZ");
 
  112  void ChargeDensityZ::process() {
 
  113    bool usePeriodicBoundaryConditions_ =
 
  114        info_->getSimParams()->getUsePeriodicBoundaryConditions();
 
  117    int nFrames_ = reader.getNFrames();
 
  118    nProcessed_  = nFrames_ / step_;
 
  125    hmat_ = currentSnapshot_->
getHmat();
 
  126    zBox_.push_back(hmat_(axis_, axis_));
 
  128    std::vector<RealType>::iterator j;
 
  130    for (j = zBox_.begin(); j != zBox_.end(); ++j) {
 
  134    RealType zAve = zSum / zBox_.size();
 
  136    axisValues.insert(0);
 
  137    axisValues.insert(1);
 
  138    axisValues.insert(2);
 
  139    axisValues.erase(axis_);
 
  140    set<int>::iterator axis_it;
 
  141    std::vector<int> cartesian_axis;
 
  142    for (axis_it = axisValues.begin(); axis_it != axisValues.end(); ++axis_it) {
 
  143      cartesian_axis.push_back(*axis_it);
 
  145    x_                   = cartesian_axis[0];
 
  146    y_                   = cartesian_axis[1];
 
  147    RealType area        = hmat_(x_, x_) * hmat_(y_, y_);
 
  148    RealType sliceVolume = zAve / densityZAverageAllFrame_.size() * area;
 
  150    for (
int i = 1; i < nFrames_; i += step_) {
 
  155        seleMan_.setSelectionSet(evaluator_.evaluate());
 
  162          snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  163                   "Can not calculate charge density distribution if it is not " 
  165          painCave.severity = OPENMD_ERROR;
 
  166          painCave.isFatal  = 1;
 
  171        Atom* atom = 
static_cast<Atom*
>(sd);
 
  177          if (fca.isFixedCharge()) { q += fca.getCharge(); }
 
  180          if (fqa.isFluctuatingCharge()) { q += atom->
getFlucQPos(); }
 
  184        std::string atomName;
 
  185        std::vector<AtomType*> atChain = atomType->allYourBase();
 
  186        std::vector<AtomType*>::iterator i;
 
  187        for (i = atChain.begin(); i != atChain.end(); ++i) {
 
  188          atomName = (*i)->getName().c_str();
 
  195        if (obanum == 0) { sigma = vRadius_; }
 
  198        if (usePeriodicBoundaryConditions_) currentSnapshot_->
wrapVector(pos);
 
  203        int globalIndex = sd->getGlobalIndex();
 
  205        atomNameGlobalIndex_[globalIndex] = atomName;
 
  206        averageChargeUsingGlobalIndex_[globalIndex] =
 
  207            (countUsingGlobalIndex_[globalIndex] *
 
  208                 averageChargeUsingGlobalIndex_[globalIndex] +
 
  210            (countUsingGlobalIndex_[globalIndex] + 1);
 
  211        totalChargeUsingGlobalIndex_[globalIndex].push_back(q);
 
  212        zPosUsingGlobalIndex_[globalIndex].push_back(pos[axis_]);
 
  213        xPosUsingGlobalIndex_[globalIndex].push_back(pos[x_]);
 
  214        yPosUsingGlobalIndex_[globalIndex].push_back(pos[y_]);
 
  216        vanderRUsingGlobalIndex_[globalIndex] = sigma;
 
  217        countUsingGlobalIndex_[globalIndex]++;
 
  220      for (std::map<int, std::string>::iterator it =
 
  221               atomNameGlobalIndex_.begin();
 
  222           it != atomNameGlobalIndex_.end(); ++it) {
 
  223        int g_Index        = it->first;
 
  224        std::string a_name = it->second;
 
  225        averageChargeForEachType_[a_name] =
 
  226            (SDCount_[a_name] * averageChargeForEachType_[a_name] +
 
  227             totalChargeUsingGlobalIndex_[g_Index].front()) /
 
  228            (SDCount_[a_name] + 1);
 
  232    RealType epsilon = 1e-10;
 
  233    for (std::map<int, std::string>::iterator it = atomNameGlobalIndex_.begin();
 
  234         it != atomNameGlobalIndex_.end(); ++it) {
 
  236      std::string a_name = it->second;
 
  238      RealType averageCharge = averageChargeUsingGlobalIndex_[key];
 
  239      RealType averageChargeUsingFirstFrame = averageChargeForEachType_[a_name];
 
  240      RealType v_radius                     = vanderRUsingGlobalIndex_[key];
 
  241      RealType v_radius2                    = v_radius * v_radius;
 
  242      for (
size_t index = 0; index < zPosUsingGlobalIndex_[key].size();
 
  244        RealType z_pos  = zPosUsingGlobalIndex_[key][index];
 
  245        RealType charge = totalChargeUsingGlobalIndex_[key][index];
 
  246        RealType chargeDiff =
 
  247            fabs(charge - averageCharge) > epsilon ? charge - averageCharge : 0;
 
  248        RealType chargeDiffUsingFirstFrameAverage =
 
  249            fabs(charge - averageChargeUsingFirstFrame) > epsilon ?
 
  250                charge - averageChargeUsingFirstFrame :
 
  253        for (
size_t i = 0; i < densityFlucZAverageAllFrame_.size(); ++i) {
 
  254          RealType z = -zAve / 2 + i * zAve / densityZAverageAllFrame_.size();
 
  255          RealType zdist = z_pos - z;
 
  257          RealType gaussian_scale =
 
  258              exp(-zdist * zdist / (v_radius2 * 2.0)) /
 
  259              (sliceVolume * (sqrt(2 * Constants::PI * v_radius * v_radius)));
 
  260          densityZAverageAllFrame_[i] += charge * gaussian_scale;
 
  262          densityFlucZAverageAllFrame_[i] += chargeDiff * gaussian_scale;
 
  263          absDensityFlucZAverageAllFrame_[i] +=
 
  264              abs(chargeDiff) * abs(chargeDiff) * gaussian_scale;
 
  266          densityFlucZAverageFirstFrame_[i] +=
 
  267              chargeDiffUsingFirstFrameAverage * gaussian_scale;
 
  268          absDensityFlucZAverageFirstFrame_[i] +=
 
  269              abs(chargeDiffUsingFirstFrameAverage) *
 
  270              abs(chargeDiffUsingFirstFrameAverage) * gaussian_scale;
 
  277    if (genXYZ_) generateXYZForLastFrame();
 
  280  void ChargeDensityZ::writeDensity() {
 
  282    std::vector<RealType>::iterator j;
 
  284    for (j = zBox_.begin(); j != zBox_.end(); ++j) {
 
  287    RealType zAve = zSum / zBox_.size();
 
  289    std::ofstream rdfStream(outputFilename_.c_str());
 
  290    if (rdfStream.is_open()) {
 
  291      rdfStream << 
"#ChargeDensityZ " 
  293      rdfStream << 
"#selection: (" << selectionScript_ << 
")\n";
 
  296          << 
"\tchargeDensity\tchargeDensityFluctuations_Average_on_all_frame\t" 
  297          << 
"Absolute_chargeDensityFluctuations_Average_on_all_frame\t" 
  298          << 
"chargeDensityFluctuations_Average_On_first_frame\t" 
  299          << 
"Absolute_chargeDensityFluctuations_Average_on_first_frame\n";
 
  301      for (
unsigned int i = 0; i < densityFlucZAverageAllFrame_.size(); ++i) {
 
  302        RealType z = zAve * (i + 0.5) / densityFlucZAverageAllFrame_.size();
 
  303        rdfStream << z << 
"\t" << densityZAverageAllFrame_[i] / nProcessed_
 
  304                  << 
"\t" << densityFlucZAverageAllFrame_[i] / (nProcessed_)
 
  305                  << 
"\t" << absDensityFlucZAverageAllFrame_[i] / (nProcessed_)
 
  306                  << 
"\t" << densityFlucZAverageFirstFrame_[i] / (nProcessed_)
 
  308                  << absDensityFlucZAverageFirstFrame_[i] / (nProcessed_)
 
  313      snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  314               "ChargeDensityZ: unable to open %s\n", outputFilename_.c_str());
 
  315      painCave.isFatal = 1;
 
  322  void ChargeDensityZ::generateXYZForLastFrame() {
 
  323    std::string XYZFile(
getPrefix(fileName_) + 
".xyz");
 
  324    std::ofstream rdfStream(XYZFile.c_str());
 
  325    int nAtoms = zPosUsingGlobalIndex_.size();
 
  327    if (rdfStream.is_open()) {
 
  328      rdfStream << nAtoms << 
"\n";
 
  329      rdfStream << 1 << 
";\t" << hmat_(x_, x_) << 
"\t" << hmat_(x_, y_) << 
"\t" 
  330                << hmat_(x_, axis_) << 
"\t" << hmat_(y_, x_) << 
"\t" 
  331                << hmat_(y_, y_) << 
"\t" << hmat_(y_, axis_) << 
"\t" 
  332                << hmat_(axis_, x_) << 
"\t" << hmat_(axis_, y_) << 
"\t" 
  333                << hmat_(axis_, axis_) << 
"\n";
 
  335      for (std::map<int, std::string>::iterator it =
 
  336               atomNameGlobalIndex_.begin();
 
  337           it != atomNameGlobalIndex_.end(); ++it) {
 
  339        std::string a_name = it->second;
 
  340        RealType x         = zPosUsingGlobalIndex_[key].back();
 
  341        RealType y         = xPosUsingGlobalIndex_[key].back();
 
  342        RealType z         = yPosUsingGlobalIndex_[key].back();
 
  345        if (a_name == atomFlucCharge_) {
 
  346          for (std::map<int, std::string>::iterator it1 =
 
  347                   atomNameGlobalIndex_.begin();
 
  348               it1 != atomNameGlobalIndex_.end(); ++it1) {
 
  349            int key1            = it1->first;
 
  350            std::string a_name1 = it1->second;
 
  352            RealType v_radius      = vanderRUsingGlobalIndex_[key1];
 
  353            RealType v_radius2     = v_radius * v_radius;
 
  354            RealType averageCharge = averageChargeUsingGlobalIndex_[key1];
 
  356            for (
size_t index = 0; index < zPosUsingGlobalIndex_[key1].size();
 
  358              RealType xt = xPosUsingGlobalIndex_[key][index];
 
  359              RealType yt = yPosUsingGlobalIndex_[key][index];
 
  360              RealType zt = zPosUsingGlobalIndex_[key][index];
 
  362              RealType z_pos = zPosUsingGlobalIndex_[key1][index];
 
  363              RealType x_pos = xPosUsingGlobalIndex_[key1][index];
 
  364              RealType y_pos = yPosUsingGlobalIndex_[key1][index];
 
  365              RealType r2    = (xt - x_pos) * (xt - x_pos) +
 
  366                            (yt - y_pos) * (yt - y_pos) +
 
  367                            (zt - z_pos) * (zt - z_pos);
 
  369              RealType charge_for_atom =
 
  370                  totalChargeUsingGlobalIndex_[key1][index];
 
  371              RealType chargeDiff =
 
  372                  fabs(charge_for_atom - averageCharge) > epsilon ?
 
  373                      charge_for_atom - averageCharge :
 
  375              RealType gaussian_scale =
 
  376                  exp(-r2 / (v_radius2 * 2.0)) /
 
  377                  (sqrt(2 * Constants::PI * v_radius * v_radius));
 
  381              charge += chargeDiff * gaussian_scale;
 
  384          charge /= (nProcessed_ * atomNameGlobalIndex_.size());
 
  387          charge = totalChargeUsingGlobalIndex_[key].back();
 
  390        rdfStream << a_name << 
"\t" << x << 
"\t" << y << 
"\t" << z << 
"\t" 
  395      snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  396               "XYZ file: unable to open %s\n", outputFilename_.c_str());
 
  397      painCave.isFatal = 1;
 
AtomType * getAtomType()
Returns the AtomType of this Atom.
 
AtomType is what OpenMD looks to for unchanging data about an atom.
 
RealType GetVdwRad(int atomicnum)
 
int GetAtomicNum(const char *str)
 
bool isDynamic()
Tests if the result from evaluation of script is dynamic.
 
StuntDouble * nextSelected(int &i)
Finds the next selected StuntDouble in the selection.
 
StuntDouble * beginSelected(int &i)
Finds the first selected StuntDouble in the selection.
 
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
 
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
 
Mat3x3d getHmat()
Returns the H-Matrix.
 
void wrapVector(Vector3d &v)
Wrapping the vector according to periodic boundary condition.
 
Snapshot * getCurrentSnapshot()
Returns the pointer of current snapshot.
 
"Don't move, or you're dead! Stand up! Captain, we've got them!"
 
RealType getFlucQPos()
Returns the current fluctuating charge of this stuntDouble.
 
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
 
std::string getPrefix(const std::string &str)