53#include "applications/staticProps/CurrentDensity.hpp"
60#include "brains/Thermo.hpp"
63#include "types/FixedChargeAdapter.hpp"
64#include "types/FluctuatingChargeAdapter.hpp"
66#include "utils/simError.h"
70 CurrentDensity::CurrentDensity(
SimInfo* info,
const std::string& filename,
71 const std::string& sele,
int nbins,
int axis) :
73 selectionScript_(sele), evaluator_(info), seleMan_(info), thermo_(info),
75 evaluator_.loadScriptString(sele);
76 if (!evaluator_.isDynamic()) {
77 seleMan_.setSelectionSet(evaluator_.evaluate());
81 sliceSDLists_.resize(nBins_);
82 currentDensity_.resize(nBins_);
97 setOutputName(
getPrefix(filename) +
".Jc");
100 void CurrentDensity::process() {
104 bool usePeriodicBoundaryConditions_ =
105 info_->getSimParams()->getUsePeriodicBoundaryConditions();
107 DumpReader reader(info_, dumpFilename_);
108 int nFrames = reader.getNFrames();
109 nProcessed_ = nFrames / step_;
110 overallCurrentDensity_ = 0;
112 for (
int istep = 0; istep < nFrames; istep += step_) {
113 reader.readFrame(istep);
114 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
115 Vector3d COMvel = thermo_.getComVel();
117 for (
unsigned int i = 0; i < nBins_; i++) {
118 sliceSDLists_[i].clear();
121 RealType boxVolume = currentSnapshot_->getVolume();
122 RealType sliceVolume = boxVolume / nBins_;
123 Mat3x3d hmat = currentSnapshot_->getHmat();
124 zBox_.push_back(hmat(axis_, axis_));
126 if (evaluator_.isDynamic()) {
127 seleMan_.setSelectionSet(evaluator_.evaluate());
131 for (sd = seleMan_.beginSelected(ii); sd != NULL;
132 sd = seleMan_.nextSelected(ii)) {
134 Vector3d pos = sd->getPos();
136 if (usePeriodicBoundaryConditions_) {
137 currentSnapshot_->wrapVector(pos);
139 int(nBins_ * (pos[axis_] / hmat(axis_, axis_) + 0.5)) % nBins_;
140 sliceSDLists_[binNo].push_back(sd);
145 for (
unsigned int i = 0; i < nBins_; i++) {
148 for (
unsigned int j = 0; j < sliceSDLists_[i].size(); ++j) {
150 Atom* atom =
static_cast<Atom*
>(sliceSDLists_[i][j]);
152 AtomType* atomType = atom->getAtomType();
154 if (sliceSDLists_[i][j]->isAtom()) {
155 FixedChargeAdapter fca = FixedChargeAdapter(atomType);
156 if (fca.isFixedCharge()) q = fca.getCharge();
158 FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType);
159 if (fqa.isFluctuatingCharge()) q += atom->getFlucQPos();
161 Vector3d vel = sliceSDLists_[i][j]->getVel();
162 binJc += q * (vel[axis_] - COMvel[axis_]);
167 currentDensity_[i] += binJc / sliceVolume;
168 overallCurrentDensity_ += binJc / boxVolume;
172 writeCurrentDensity();
175 void CurrentDensity::writeCurrentDensity() {
177 std::vector<RealType>::iterator j;
179 for (j = zBox_.begin(); j != zBox_.end(); ++j) {
182 RealType zAve = zSum / zBox_.size();
184 std::ofstream rdfStream(outputFilename_.c_str());
185 if (rdfStream.is_open()) {
186 rdfStream <<
"#Current Density = "
187 << overallCurrentDensity_ / nProcessed_
188 <<
" e / Ang^2 / fs.\n";
189 rdfStream <<
"#J_c(" << axisLabel_ <<
")\n";
190 rdfStream <<
"#nFrames:\t" << nProcessed_ <<
"\n";
191 rdfStream <<
"#selection: (" << selectionScript_ <<
")\n";
192 rdfStream <<
"#" << axisLabel_ <<
"\tcurrent density\n";
194 for (
unsigned int i = 0; i < currentDensity_.size(); ++i) {
195 RealType z = zAve * (i + 0.5) / currentDensity_.size();
196 rdfStream << z <<
"\t" << currentDensity_[i] / nProcessed_ <<
"\n";
200 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
201 "CurrentDensity: unable to open %s\n", outputFilename_.c_str());
202 painCave.isFatal = 1;
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)