9 #define _USE_MATH_DEFINES 14 #include "../utils/message.h" 25 new GenDict({{
"Targets", targets}, {
"Box", box}})));
31 const Vec<std::pair<ElPtr,ElPtr>> &pairs)
35 for (
const auto &pair : pairs)
38 new GenDict({{
"Targets", pair.first}, {
"Box", pair.second}})));
53 auto el_atoms =
generators[index]->get_element(
"Targets");
55 el_atoms->check_required_keys({
"x",
"y",
"z",
"id"});
57 auto &atoms = el_atoms->get_data();
59 auto special_bonds_exist = el_atoms->check_optional_keys(
"special-bonds");
61 auto el_box =
generators[index]->get_element(
"Box");
63 el_box->check_required_keys({
"lo_x",
"lo_y",
"lo_z",
"hi_x",
"hi_y",
"hi_z"});
65 auto &box = el_box->get_data();
68 el_atoms->make_2darray_from_data(rs, {
"x",
"y",
"z"});
71 box_length << box[
"hi_x"].get<
double>() - box[
"lo_x"].get<double>(),
72 box[
"hi_y"].get<
double>() - box[
"lo_y"].get<double>(),
73 box[
"hi_z"].get<
double>() - box[
"lo_z"].get<double>();
79 const auto r2_max = r_max*r_max;
81 for (
int i = 0; i != 3; ++i)
83 if (neighbor_limits(i) < r_max)
86 "Box length is too short in " +
Str(
"xyz").substr(i, 1));
90 const std::pair<int,int> image_range_x = box.value(
"pbc_x",
false) ?
91 std::make_pair(-1, 1) : std::make_pair(0, 0);
92 const std::pair<int,int> image_range_y = box.value(
"pbc_y",
false) ?
93 std::make_pair(-1, 1) : std::make_pair(0, 0);
94 const std::pair<int,int> image_range_z = box.value(
"pbc_z",
false) ?
95 std::make_pair(-1, 1) : std::make_pair(0, 0);
97 const auto reciprocal_bin_width = 1.0 /
bin_width;
99 const auto n_atoms = atoms.size();
107 for (
int i = 0; i != n_atoms; ++i)
109 auto sbonds_i = special_bonds_exist ?
112 auto r_i = rs.row(i);
114 for (
int j = i+1; j != n_atoms; ++j)
116 if (!sbonds_i.empty() && sbonds_i.find(
117 atoms[j][
"id"].get<int>()) != sbonds_i.cend())
continue;
119 auto dr_original = rs.row(j) - r_i;
121 for (
int ix = image_range_x.first; ix <= image_range_x.second; ++ix)
123 auto dx = dr_original(0) + ix*box_length(0);
125 if (neighbor_limits(0) < abs(dx))
continue;
127 for (
int iy = image_range_y.first; iy <= image_range_y.second; ++iy)
129 auto dy = dr_original(1) + iy*box_length(1);
131 if (neighbor_limits(1) < abs(dy))
continue;
133 for (
int iz = image_range_z.first; iz <= image_range_z.second; ++iz)
135 auto dz = dr_original(2) + iz*box_length(2);
137 if (neighbor_limits(2) < abs(dz))
continue;
139 auto r2 = dx*dx + dy*dy + dz*dz;
141 if (r2_max <= r2)
continue;
146 floor(r*reciprocal_bin_width) : round(r*reciprocal_bin_width);
152 counts(r_index) += 2;
176 const double ball_coeff = 4.0 * M_PI / 3.0;
178 for (
int i = 0; i !=
n_bins; ++i)
185 shell_volume(i) = ball_coeff * (pow(r_outer, 3) - pow(r_inner, 3));
189 double volume_sum = 0.0;
200 auto density_tmp = number_tmp / volume_tmp;
201 auto number_distribution_tmp
202 = counts_tmp.cast<
double>() /
double(number_tmp);
205 number_distribution_tmp / (density_tmp*shell_volume));
207 number_sum += number_tmp;
208 volume_sum += volume_tmp;
209 counts_sum += counts_tmp;
212 auto density = number_sum / volume_sum;
213 auto number_distribution
214 = counts_sum.cast<
double>() /
double(number_sum);
216 rdf = number_distribution / (density*shell_volume);
258 for (
int i = 0; i !=
n_bins; ++i)
Vec< ArrayXi > counts_traj
Vec< ShPtr< Generator > > generators
const Vec< ArrayXd > & get_rdf_traj()
Get a sequence of radial distribution functions as list of one-dimensional arrays.
ShPtr< Element > ElPtr
An alias for a shared pointer of Element class.
virtual void run_impl(const int index) override
Implementation of analysis using an element of generators.
ProRadialDistributionFunction(const ElPtr &targets, const ElPtr &box)
Constructor of ProRadialDistributionFunction class for a snapshot of simulation.
virtual void finish() override
Compute rdf and rdf_traj from number_traj, volume_traj and counts_traj.
Eigen::Array< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > ArrayXXd
ArrayXXd is an alias for a two-dimensional array of float numbers.
This file has a definition of ProRadialDistributionFunction class, which is a subclass of Processor c...
std::string Str
Str is an alias for string.
const ArrayXd & get_rdf()
Get the radial distribution function as a one-dimensional array.
void bin_from_r_to_r_plus_dr(bool bin_from_r_=true)
By default, the bins are [0, 0.5*dr), [0.5*dr, 1.5*dr), ... . If this method is called without a para...
std::unordered_set< T > Set
Set is an alias for unordered set (same as set in Python).
std::vector< T > Vec
Vec is an alias for vector (same as list in Python).
virtual void prepare() override
Resize number_traj, volume_traj and counts_traj.
void register_generator(const ShPtr< GEN > &gen)
Vec< double > volume_traj
const ArrayXd get_r_axis()
Get a one-dimensional array of distance, [0, dr, 2*dr, ... ], where dr is width of a bin...
Eigen::Array< int, Eigen::Dynamic, 1 > ArrayXi
ArrayXi is an alias for a column array of integers.
void warning(const Str &msg)
Waning with a message.
GenDict is a dictionary (or map) of Generator objects.
Namespace for utility functions.
void beyond_half_box_length(bool beyond_half_=true)
Use a sample including particles of which distance from a reference particle are larger than half the...
Eigen::Array< double, Eigen::Dynamic, 1 > ArrayXd
ArrayXd is an alias for a column array of float numbers.
std::shared_ptr< T > ShPtr
ShPtr is an alias for shared pointer.
void set_bin(double bin_width_, int n_bins_)
Set width and number of bins in the distance axis. Each bin is a spherical shell of which center is p...
void register_generators(const Vec< ShPtr< GEN >> &gens)