mcpele  1.0.0
The Monte Carlo Python Energy Landscape Explorer
mcpele/pair_dist_histogram.h
00001 #ifndef _MCPELE_PAIR_DIST_HISTOGRAM_H
00002 #define _MCPELE_PAIR_DIST_HISTOGRAM_H
00003 
00004 #include <algorithm>
00005 #include <stdexcept>
00006 #include <cmath>
00007 #include <utility>
00008 
00009 #include "pele/distance.h"
00010 
00011 #include "mcpele/histogram.h"
00012 
00013 namespace mcpele{
00014 
00015 template<size_t BOXDIM>
00016 class PairDistHistogram{
00017 private:
00018     pele::periodic_distance<BOXDIM> m_distance;
00019     const size_t m_nr_bins;
00020     const double m_min_dist;
00021     const double m_max_dist;
00022     const double m_delta_bin;
00023     mcpele::Histogram m_hist;
00024     size_t m_nr_configs;
00025 public:
00026     PairDistHistogram(pele::Array<double> boxvector, const size_t nr_bins)
00027         : m_distance(boxvector),
00028           m_nr_bins(nr_bins),
00029           m_min_dist(0),
00030           m_max_dist(0.5 * *std::min_element(boxvector.data(), boxvector.data() + BOXDIM)),
00031           m_delta_bin((m_max_dist - m_min_dist) / static_cast<double>(m_nr_bins)),
00032           m_hist(m_min_dist, m_max_dist, m_delta_bin),
00033           m_nr_configs(0)
00034     {
00035         if (BOXDIM != boxvector.size()) {
00036             throw std::runtime_error("PairDistHistogram: illegal boxvector size");
00037         }
00038     }
00039     virtual ~PairDistHistogram() {}
00040     void add_configuration(pele::Array<double> coords)
00041     {
00042         ++m_nr_configs;
00043         const size_t nr_particles(coords.size() / BOXDIM);
00044         for (size_t i = 0; i < nr_particles; ++i) {
00045             for (size_t j = i + 1; j < nr_particles; ++j) {
00046                 add_distance(i, j, coords.data());
00047             }
00048         }
00049     }
00050     void add_distance(const size_t i, const size_t j, const double* coor)
00051     {
00052         double* rij = new double[BOXDIM];
00053         m_distance.get_rij(rij, coor + i * BOXDIM, coor + j * BOXDIM);
00054         double r2 = 0;
00055         for (size_t k = 0; k < BOXDIM; ++k) {
00056             r2 += rij[k] * rij[k];
00057         }
00058         delete[] rij;
00059         const double r = sqrt(r2);
00060         if (r > m_max_dist) {
00061             // here, g(r) measurement is resticted to a disc domain of radius
00062             // m_max_dist in distance space; could be done differently
00063             return;
00064         }
00065         m_hist.add_entry(r);
00066     }
00067     double volume_nball(const double radius, const size_t ndim) const
00068     {
00069         return pow(M_PI, 0.5 * ndim) * pow(radius, ndim) / tgamma(0.5 * ndim + 1);
00070     }
00071     std::vector<double> get_vecdata_r() const
00072     {
00073         std::vector<double> result(m_hist.size());
00074         for (size_t i = 0; i < m_hist.size(); ++i) {
00075             const double r = m_hist.get_position(i);
00076             result.at(i) = r;
00077         }
00078         return result;
00079     }
00080     std::vector<double> get_vecdata_gr(const double number_density, const size_t nr_particles) const
00081     {
00082         std::vector<double> result(m_hist.size());
00083         for (size_t i = 0; i < m_hist.size(); ++i) {
00084             const double r = m_hist.get_position(i);
00085             const double delta_r = m_hist.bin();
00086             const double shell_volume_r = volume_nball(r + 0.5 * delta_r, BOXDIM) - volume_nball(r - 0.5 * delta_r, BOXDIM);
00087             const double nid = shell_volume_r * number_density;
00088             const double normalization = 2.0 / (static_cast<double>(m_nr_configs) * static_cast<double>(nr_particles) * nid);
00089             const double g_of_r = normalization * static_cast<double>(m_hist.get_entry(i));
00090             result.at(i) = g_of_r;
00091         }
00092         return result;
00093     }
00094 };
00095 
00096 } //namespace mcpele
00097 
00098 #endif//#ifndef _MCPELE_PAIR_DIST_HISTOGRAM_H
 All Classes Namespaces Functions Variables Typedefs