47#include "applications/staticProps/Hxy.hpp" 
   58#include "types/LennardJonesAdapter.hpp" 
   59#include "utils/Accumulator.hpp" 
   60#include "utils/AccumulatorView.hpp" 
   61#include "utils/BaseAccumulator.hpp" 
   62#include "utils/Utility.hpp" 
   63#include "utils/simError.h" 
   65using namespace OpenMD::Utils;
 
   69  Hxy::Hxy(
SimInfo* info, 
const std::string& filename, 
const std::string& sele,
 
   70           int nbins_x, 
int nbins_y, 
int nbins_z, 
int nrbins) :
 
   72      selectionScript_(sele), evaluator_(info), seleMan_(info),
 
   73      nBinsX_(nbins_x), nBinsY_(nbins_y), nBinsZ_(nbins_z) {
 
   74    evaluator_.loadScriptString(sele);
 
   75    if (!evaluator_.isDynamic()) {
 
   76      seleMan_.setSelectionSet(evaluator_.evaluate());
 
   80    dens_.resize(nBinsX_);
 
   83    minHeight_.resize(nBinsX_);
 
   84    maxHeight_.resize(nBinsX_);
 
   86    for (
unsigned int i = 0; i < nBinsX_; i++) {
 
   87      dens_[i].resize(nBinsY_);
 
   88      minHeight_[i].resize(nBinsY_);
 
   89      maxHeight_[i].resize(nBinsY_);
 
   90      for (
unsigned int j = 0; j < nBinsY_; j++) {
 
   91        dens_[i][j].resize(nBinsZ_);
 
   95    mag1.resize(nBinsX_ * nBinsY_);
 
   96    newmag1.resize(nBinsX_ * nBinsY_);
 
   97    mag2.resize(nBinsX_ * nBinsY_);
 
   98    newmag2.resize(nBinsX_ * nBinsY_);
 
  101    data_.resize(Hxy::ENDINDEX);
 
  104    freq.units        = 
"Angstroms^-1";
 
  105    freq.title        = 
"Spatial Frequency";
 
  106    freq.dataHandling = DataHandling::Average;
 
  107    for (
unsigned int i = 0; i < nBins_; i++)
 
  108      freq.accumulator.push_back(
 
  110    data_[FREQUECY] = std::move(freq);
 
  113    top.units         = 
"Angstroms";
 
  114    top.title         = 
"Hxy (Upper surface)";
 
  115    freq.dataHandling = DataHandling::Max;
 
  116    for (
unsigned int i = 0; i < nBins_; i++)
 
  117      top.accumulator.push_back(
 
  119    data_[TOP] = std::move(top);
 
  122    bottom.units      = 
"Angstroms";
 
  123    bottom.title      = 
"Hxy (Lower surface)";
 
  124    freq.dataHandling = DataHandling::Max;
 
  125    for (
unsigned int i = 0; i < nBins_; i++)
 
  126      bottom.accumulator.push_back(
 
  128    data_[BOTTOM] = std::move(bottom);
 
  130    setOutputName(
getPrefix(filename) + 
".Hxy");
 
  133  void Hxy::process() {
 
  134#if defined(HAVE_FFTW_H) || defined(HAVE_DFFTW_H) || defined(HAVE_FFTW3_H) 
  137    bool usePeriodicBoundaryConditions_ =
 
  138        info_->getSimParams()->getUsePeriodicBoundaryConditions();
 
  139    std::cerr << 
"usePeriodicBoundaryConditions_ = " 
  140              << usePeriodicBoundaryConditions_ << 
"\n";
 
  143    int nFrames = reader.getNFrames();
 
  144    nProcessed_ = nFrames / step_;
 
  146    for (
int istep = 0; istep < nFrames; istep += step_) {
 
  147      for (
unsigned int i = 0; i < nBinsX_; i++) {
 
  148        std::fill(minHeight_[i].begin(), minHeight_[i].end(), 0.0);
 
  149        std::fill(maxHeight_[i].begin(), maxHeight_[i].end(), 0.0);
 
  150        for (
unsigned int j = 0; j < nBinsY_; j++) {
 
  151          std::fill(dens_[i][j].begin(), dens_[i][j].end(), 0.0);
 
  155      reader.readFrame(istep);
 
  156      currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
 
  157      if (evaluator_.isDynamic()) {
 
  158        seleMan_.setSelectionSet(evaluator_.evaluate());
 
  166      fftw_complex *in1, *in2, *out1, *out2;
 
  168      in1  = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) *
 
  169                                        (nBinsX_ * nBinsY_));
 
  170      out1 = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) *
 
  171                                        (nBinsX_ * nBinsY_));
 
  172      in2  = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) *
 
  173                                        (nBinsX_ * nBinsY_));
 
  174      out2 = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) *
 
  175                                        (nBinsX_ * nBinsY_));
 
  178      p1 = fftw_plan_dft_2d(nBinsX_, nBinsY_, in1, out1, FFTW_FORWARD,
 
  180      p2 = fftw_plan_dft_2d(nBinsX_, nBinsY_, in2, out2, FFTW_FORWARD,
 
  183      p1 = fftw2d_create_plan(nBinsX_, nBinsY_, FFTW_FORWARD, FFTW_ESTIMATE);
 
  184      p2 = fftw2d_create_plan(nBinsX_, nBinsY_, FFTW_FORWARD, FFTW_ESTIMATE);
 
  187      Mat3x3d hmat   = currentSnapshot_->getHmat();
 
  188      Mat3x3d invBox = currentSnapshot_->getInvHmat();
 
  189      RealType lenX_ = hmat(0, 0);
 
  190      RealType lenY_ = hmat(1, 1);
 
  191      RealType lenZ_ = hmat(2, 2);
 
  193      RealType x, y, z, dx, dy, dz;
 
  194      RealType sigma, rcut;
 
  195      int di, dj, dk, ibin, jbin, kbin;
 
  196      int igrid, jgrid, kgrid;
 
  199      dx = lenX_ / nBinsX_;
 
  200      dy = lenY_ / nBinsY_;
 
  201      dz = lenZ_ / nBinsZ_;
 
  203      for (sd = seleMan_.beginSelected(ii); sd != NULL;
 
  204           sd = seleMan_.nextSelected(ii)) {
 
  206          Atom* atom              = 
static_cast<Atom*
>(sd);
 
  211          sigma = lja.getSigma() * 0.758176459;
 
  217          scaled = invBox * pos;
 
  221          for (
int j = 0; j < 3; j++) {
 
  222            scaled[j] -= roundMe(scaled[j]);
 
  227            if (scaled[j] >= 1.0) scaled[j] -= 1.0;
 
  230          ibin = nBinsX_ * scaled.
x();
 
  231          jbin = nBinsY_ * scaled.
y();
 
  232          kbin = nBinsZ_ * scaled.
z();
 
  234          di = (int)(rcut / dx);
 
  235          dj = (int)(rcut / dy);
 
  236          dk = (int)(rcut / dz);
 
  238          for (
int i = -di; i <= di; i++) {
 
  240            while (igrid >= 
int(nBinsX_)) {
 
  241              igrid -= int(nBinsX_);
 
  244              igrid += int(nBinsX_);
 
  247            x = lenX_ * (RealType(i) / RealType(nBinsX_));
 
  249            for (
int j = -dj; j <= dj; j++) {
 
  251              while (jgrid >= 
int(nBinsY_)) {
 
  252                jgrid -= int(nBinsY_);
 
  255                jgrid += int(nBinsY_);
 
  258              y = lenY_ * (RealType(j) / RealType(nBinsY_));
 
  260              for (
int k = -dk; k <= dk; k++) {
 
  262                while (kgrid >= 
int(nBinsZ_)) {
 
  263                  kgrid -= int(nBinsZ_);
 
  266                  kgrid += int(nBinsZ_);
 
  269                z = lenZ_ * (RealType(k) / RealType(nBinsZ_));
 
  271                RealType dist = sqrt(x * x + y * y + z * z);
 
  273                dens_[igrid][jgrid][kgrid] += getDensity(dist, sigma, rcut);
 
  280      RealType maxDens(0.0);
 
  281      for (
unsigned int i = 0; i < nBinsX_; i++) {
 
  282        for (
unsigned int j = 0; j < nBinsY_; j++) {
 
  283          for (
unsigned int k = 0; k < nBinsZ_; k++) {
 
  284            if (dens_[i][j][k] > maxDens) maxDens = dens_[i][j][k];
 
  289      RealType threshold = maxDens / 2.0;
 
  290      RealType z0, z1, h0, h1;
 
  291      std::cerr << 
"maxDens = " 
  292                << 
"\t" << maxDens << 
"\n";
 
  293      std::cerr << 
"threshold value = " 
  294                << 
"\t" << threshold << 
"\n";
 
  296      for (
unsigned int i = 0; i < nBinsX_; i++) {
 
  297        for (
unsigned int j = 0; j < nBinsY_; j++) {
 
  307          bool minFound = 
false;
 
  308          bool maxFound = 
false;
 
  310          if (dens_[i][j][0] < threshold) {
 
  311            for (
unsigned int k = 0; k < nBinsZ_ - 1; k++) {
 
  312              z0 = lenZ_ * (RealType(k) / RealType(nBinsZ_));
 
  313              z1 = lenZ_ * (RealType(k + 1) / RealType(nBinsZ_));
 
  315              h1 = dens_[i][j][k + 1];
 
  317              if (h0 < threshold && h1 > threshold && !minFound) {
 
  320                    z0 + (z1 - z0) * (threshold - h0) / (h1 - h0);
 
  323              if (h0 > threshold && h1 < threshold && minFound) {
 
  326                    z0 + (z1 - z0) * (threshold - h0) / (h1 - h0);
 
  332            for (
unsigned int k = 0; k < nBinsZ_ - 1; k++) {
 
  333              z0 = lenZ_ * (RealType(k) / RealType(nBinsZ_));
 
  334              z1 = lenZ_ * (RealType(k + 1) / RealType(nBinsZ_));
 
  336              h1 = dens_[i][j][k + 1];
 
  338              if (h0 > threshold && h1 < threshold && !maxFound) {
 
  341                    z0 + (z1 - z0) * (threshold - h0) / (h1 - h0);
 
  344              if (h0 < threshold && h1 > threshold && maxFound) {
 
  347                    z0 + (z1 - z0) * (threshold - h0) / (h1 - h0);
 
  354      RealType minBar = 0.0;
 
  355      RealType maxBar = 0.0;
 
  357      for (
unsigned int i = 0; i < nBinsX_; i++) {
 
  358        for (
unsigned int j = 0; j < nBinsY_; j++) {
 
  362          minBar += minHeight_[i][j];
 
  363          maxBar += maxHeight_[i][j];
 
  370      std::cerr << 
"bottomSurf = " << minBar << 
"\ttopSurf = " << maxBar
 
  375      for (
unsigned int i = 0; i < nBinsX_; i++) {
 
  376        for (
unsigned int j = 0; j < nBinsY_; j++) {
 
  377          newindex = i * nBinsY_ + j;
 
  379          c_re(in1[newindex]) = maxHeight_[i][j] - maxBar;
 
  381          c_im(in1[newindex]) = 0.0;
 
  382          c_re(in2[newindex]) =
 
  383              minHeight_[i][j] - minBar;  
 
  385          c_im(in2[newindex]) = 0.0;
 
  393      fftwnd_one(p1, in1, out1);
 
  394      fftwnd_one(p2, in2, out2);
 
  397      for (
unsigned int i = 0; i < nBinsX_; i++) {
 
  398        for (
unsigned int j = 0; j < nBinsY_; j++) {
 
  399          newindex       = i * nBinsY_ + j;
 
  400          mag1[newindex] = sqrt(pow(c_re(out1[newindex]), 2) +
 
  401                                pow(c_im(out1[newindex]), 2)) /
 
  402                           (RealType(nBinsX_ * nBinsY_));
 
  403          mag2[newindex] = sqrt(pow(c_re(out2[newindex]), 2) +
 
  404                                pow(c_im(out2[newindex]), 2)) /
 
  405                           (RealType(nBinsX_ * nBinsY_));
 
  410      fftw_destroy_plan(p1);
 
  411      fftw_destroy_plan(p2);
 
  413      fftwnd_destroy_plan(p1);
 
  414      fftwnd_destroy_plan(p2);
 
  421      int index, new_i, new_j, new_index;
 
  422      for (
unsigned int i = 0; i < (nBinsX_ / 2); i++) {
 
  423        for (
unsigned int j = 0; j < (nBinsY_ / 2); j++) {
 
  424          index              = i * nBinsY_ + j;
 
  425          new_i              = i + (nBinsX_ / 2);
 
  426          new_j              = j + (nBinsY_ / 2);
 
  427          new_index          = new_i * nBinsY_ + new_j;
 
  428          newmag1[new_index] = mag1[index];
 
  429          newmag2[new_index] = mag2[index];
 
  433      for (
unsigned int i = (nBinsX_ / 2); i < nBinsX_; i++) {
 
  434        for (
unsigned int j = 0; j < (nBinsY_ / 2); j++) {
 
  435          index              = i * nBinsY_ + j;
 
  436          new_i              = i - (nBinsX_ / 2);
 
  437          new_j              = j + (nBinsY_ / 2);
 
  438          new_index          = new_i * nBinsY_ + new_j;
 
  439          newmag1[new_index] = mag1[index];
 
  440          newmag2[new_index] = mag2[index];
 
  444      for (
unsigned int i = 0; i < (nBinsX_ / 2); i++) {
 
  445        for (
unsigned int j = (nBinsY_ / 2); j < nBinsY_; j++) {
 
  446          index              = i * nBinsY_ + j;
 
  447          new_i              = i + (nBinsX_ / 2);
 
  448          new_j              = j - (nBinsY_ / 2);
 
  449          new_index          = new_i * nBinsY_ + new_j;
 
  450          newmag1[new_index] = mag1[index];
 
  451          newmag2[new_index] = mag2[index];
 
  455      for (
unsigned int i = (nBinsX_ / 2); i < nBinsX_; i++) {
 
  456        for (
unsigned int j = (nBinsY_ / 2); j < nBinsY_; j++) {
 
  457          index              = i * nBinsY_ + j;
 
  458          new_i              = i - (nBinsX_ / 2);
 
  459          new_j              = j - (nBinsY_ / 2);
 
  460          new_index          = new_i * nBinsY_ + new_j;
 
  461          newmag1[new_index] = mag1[index];
 
  462          newmag2[new_index] = mag2[index];
 
  476      RealType maxfreqx = RealType(nBinsX_) / lenX_;
 
  477      RealType maxfreqy = RealType(nBinsY_) / lenY_;
 
  479      RealType maxfreq = sqrt(maxfreqx * maxfreqx + maxfreqy * maxfreqy);
 
  480      dfreq_           = maxfreq / (RealType)(nBins_ - 1);
 
  482      int zero_freq_x = nBinsX_ / 2;
 
  483      int zero_freq_y = nBinsY_ / 2;
 
  485      for (
int i = 0; i < (int)nBinsX_; i++) {
 
  486        for (
int j = 0; j < (int)nBinsY_; j++) {
 
  488              (RealType)(i - zero_freq_x) * maxfreqx / (RealType)nBinsX_;
 
  490              (RealType)(j - zero_freq_y) * maxfreqy / (RealType)nBinsY_;
 
  492          RealType freq = sqrt(freq_x * freq_x + freq_y * freq_y);
 
  494          unsigned int whichbin = (
unsigned int)(freq / dfreq_);
 
  496          newindex = i * nBinsY_ + j;
 
  498          data_[FREQUECY].accumulator[whichbin]->add(freq);
 
  499          data_[TOP].accumulator[whichbin]->add(newmag1[newindex]);
 
  500          data_[BOTTOM].accumulator[whichbin]->add(newmag2[newindex]);
 
  508    snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  509             "Hxy: FFTW support was not compiled in!\n");
 
  510    painCave.isFatal = 1;
 
  516  RealType Hxy::getDensity(RealType r, RealType sigma, RealType rcut) {
 
  517    RealType sigma2 = sigma * sigma;
 
  519        exp(-r * r / (sigma2 * 2.0)) / (pow(2.0 * Constants::PI * sigma2, 3));
 
  520    RealType dcut = exp(-rcut * rcut / (sigma2 * 2.0)) /
 
  521                    (pow(2.0 * Constants::PI * sigma2, 3));
 
AtomType * getAtomType()
Returns the AtomType of this Atom.
 
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
 
"Don't move, or you're dead! Stand up! Captain, we've got them!"
 
Vector3d getPos()
Returns the current position of this stuntDouble.
 
bool isAtom()
Tests if this stuntDouble is an atom.
 
Real & z()
Returns reference of the third element of Vector3.
 
Real & x()
Returns reference of the first element of Vector3.
 
Real & y()
Returns reference of the second element of Vector3.
 
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
 
std::string getPrefix(const std::string &str)