rdf2d.cpp
Go to the documentation of this file.
Code
1//-----------------------------------------------------------------------------------
2// d-SEAMS - Deferred Structural Elucidation Analysis for Molecular Simulations
3//
4// Copyright (c) 2018--present d-SEAMS core team
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the MIT License as published by
8// the Open Source Initiative.
9//
10// A copy of the MIT License is included in the LICENSE file of this repository.
11// You should have received a copy of the MIT License along with this program.
12// If not, see <https://opensource.org/licenses/MIT>.
13//-----------------------------------------------------------------------------------
14
15#include <rdf2d.hpp>
16
17// -----------------------------------------------------------------------------------------------------
18// IN-PLANE RDF
19// -----------------------------------------------------------------------------------------------------
20
46 std::string path, std::vector<double> *rdfValues,
47 molSys::PointCloud<molSys::Point<double>, double> *yCloud, double cutoff,
48 double binwidth, int firstFrame, int finalFrame) {
49 //
50 int nopA = yCloud->nop; // Number of particles of type A in the current frame.
51 int currentFrame = yCloud->currentFrame; // The current frame
52 int nbin; // Number of bins
53 std::vector<double> volumeLengths; // Lengths of the volume of the
54 // quasi-two-dimensional system
55 std::vector<int> histogram; // Histogram for the RDF, at every step
56 int nIter = finalFrame - firstFrame + 1; // Number of iterations
57 // ----------------------------------------------
58 // INITIALIZATION
59 if (currentFrame == firstFrame) {
60 // -----------------
61 // Checks and balances?
62 // -----------------
63 nbin = 1 + int(cutoff / binwidth); // Number of bins
64 (*rdfValues).resize(nbin); // RDF initialized to 0
65 } // end of initialization
66 // ----------------------------------------------
67 // SAMPLING
68 // Get the volume lengths of the quasi-two-dimensional system
69 volumeLengths = rdf2::getSystemLengths(yCloud);
70 // Update cutoff if required? later
71 nbin = int(cutoff / binwidth); // Number of bins
72 // Sample for the current frame!!
73 histogram = rdf2::sampleRDF_AA(yCloud, cutoff, binwidth, nbin);
74 // ----------------------------------------------
75 // NORMALIZATION
76 rdf2::normalizeRDF(nopA, rdfValues, histogram, binwidth, nbin, volumeLengths,
77 nIter);
78 // ----------------------------------------------
79 // PRINT OUT
80 if (currentFrame == finalFrame) {
81 // Create folder if required
82 sout::makePath(path);
83 std::string outputDirName = path + "topoMonolayer";
84 sout::makePath(outputDirName);
85 //
86 std::string fileName = path + "topoMonolayer/rdf.dat";
87 //
88 // Comment line
89 std::ofstream outputFile; // For the output file
90 outputFile.open(fileName, std::ios_base::app | std::ios_base::out);
91 outputFile << "# r g(r)\n";
92 outputFile.close();
93 //
94 //
95 sout::printRDF(fileName, rdfValues, binwidth, nbin);
96 } // end of print out
97 // ----------------------------------------------
98
99 return 0;
100} // end of function
101
114std::vector<int>
116 double cutoff, double binwidth, int nbin) {
117 //
118 std::vector<int> histogram; // Histogram for the RDF
119 double r_ij; // Unwrapped distance between iatom and jatom
120 int ibin; // Index of the bin in which the distance r_ij falls
121
122 // Init the histogram to 0
123 histogram.resize(nbin);
124
125 // Loop through pairs of atoms
126 for (int iatom = 0; iatom < yCloud->nop - 1; iatom++) {
127 //
128 // Loop through the next atom in the atom pair
129 for (int jatom = iatom + 1; jatom < yCloud->nop; jatom++) {
130 // Calculate the distance between iatom and jatom
131 r_ij = gen::periodicDist(yCloud, iatom, jatom);
132 // Check if the distance is within the cutoff. Update the histogram if
133 // r_ij is within the cutoff
134 if (r_ij <= cutoff) {
135 ibin = int(r_ij / binwidth); // Bin in which r_ij falls
136 histogram[ibin] += 2; // Update for iatom and jatom both
137 } // end of histogram update
138 } // end of loop through jatom
139 } // end of loop through iatom
140
141 // Return the histogram
142 return histogram;
143
144} // end of function
145
162int rdf2::normalizeRDF(int nopA, std::vector<double> *rdfValues,
163 std::vector<int> histogram, double binwidth, int nbin,
164 std::vector<double> volumeLengths, int nIter) {
165 //
166 auto height = *std::min_element(
167 volumeLengths.begin(),
168 volumeLengths.end()); // The height or the smallest dimension
169 // double planeArea = rdf2::getPlaneArea(
170 // volumeLengths); // The area of the quasi-two-dimensional water
171 double r; // Distance for the current bin
172 double factor; // Factor for accounting for the two-dimensional slab
173 double binVolume; // Volume of the current bin
174 double volumeDensity =
175 nopA / (volumeLengths[0] * volumeLengths[1] * volumeLengths[2]);
176
177 // Loop through every bin
178 for (int ibin = 0; ibin < nbin; ibin++) {
179 //
180 r = binwidth * (ibin + 0.5);
181 // ----------------------
182 // Factor calculation
183 factor = 1;
184 if (r > height) {
185 // FACTOR = HEIGHT/(2*R)
186 factor = height / (2 * r);
187 } // r>height
188 else {
189 // FACTOR = 1 - R/(2*HEIGHT)
190 factor = 1 - r / (2 * height);
191 } // r<=height
192 // ----------------------
193 // binVolume = 4.0*PI*(DELTA_R**3)*((I_BIN+1)**3-I_BIN**3)/3.0
194 binVolume = 4 * gen::pi * pow(binwidth, 3.0) *
195 (pow(ibin + 1, 3.0) - pow(ibin, 3.0)) / 3.0;
196 // Update the RDF
197 (*rdfValues)[ibin] +=
198 histogram[ibin] / (nIter * binVolume * nopA * volumeDensity * factor);
199 } // end of loop through every bin
200
201 return 0;
202
203} // end of function
204
212std::vector<double> rdf2::getSystemLengths(
213 molSys::PointCloud<molSys::Point<double>, double> *yCloud) {
214 //
215 std::vector<double> lengths; // Volume lengths
216 std::vector<double>
217 rMax; // Max of the coordinates {0 is for x, 1 is for y and 2 is for z}
218 std::vector<double>
219 rMin; // Min of the coordinates {0 is for x, 1 is for y and 2 is for z}
220 std::vector<double> r_iatom; // Current point coordinates
221 int dim = 3;
222
223 // Init
224 r_iatom.push_back(yCloud->pts[0].x);
225 r_iatom.push_back(yCloud->pts[0].y);
226 r_iatom.push_back(yCloud->pts[0].z);
227 rMin = r_iatom;
228 rMax = r_iatom;
229
230 // Loop through the entire PointCloud
231 for (int iatom = 1; iatom < yCloud->nop; iatom++) {
232 r_iatom[0] = yCloud->pts[iatom].x; // x coordinate of iatom
233 r_iatom[1] = yCloud->pts[iatom].y; // y coordinate of iatom
234 r_iatom[2] = yCloud->pts[iatom].z; // z coordinate of iatom
235 // Loop through every dimension
236 for (int k = 0; k < dim; k++) {
237 // Update rMin
238 if (r_iatom[k] < rMin[k]) {
239 rMin[k] = r_iatom[k];
240 } // end of rMin update
241 // Update rMax
242 if (r_iatom[k] > rMax[k]) {
243 rMax[k] = r_iatom[k];
244 } // end of rMax update
245 } // end of looping through every dimension
246 } // end of loop through all the atoms
247
248 // Get the lengths
249 for (int k = 0; k < dim; k++) {
250 lengths.push_back(rMax[k] - rMin[k]);
251 } // end of updating lengths
252
253 return lengths;
254} // end of function
255
264double rdf2::getPlaneArea(std::vector<double> volumeLengths) {
265 //
266 // Sort the vector in descending order
267 std::sort(volumeLengths.begin(), volumeLengths.end());
268 std::reverse(volumeLengths.begin(), volumeLengths.end());
269
270 return volumeLengths[0] * volumeLengths[1];
271
272} // end of function
double periodicDist(molSys::PointCloud< molSys::Point< double >, double > *yCloud, int iatom, int jatom)
Inline generic function for obtaining the unwrapped periodic distance between two particles,...
Definition generic.hpp:108
const double pi
Definition generic.hpp:54
std::vector< double > getSystemLengths(molSys::PointCloud< molSys::Point< double >, double > *yCloud)
Gets the lengths of the volume slice of the quasi-two-dimensional system.
Definition rdf2d.cpp:212
std::vector< int > sampleRDF_AA(molSys::PointCloud< molSys::Point< double >, double > *yCloud, double cutoff, double binwidth, int nbin)
Samples the RDF histogram at every step.
Definition rdf2d.cpp:115
double getPlaneArea(std::vector< double > volumeLengths)
Gets the plane area from the volume lengths vector.
Definition rdf2d.cpp:264
int rdf2Danalysis_AA(std::string path, std::vector< double > *rdfValues, molSys::PointCloud< molSys::Point< double >, double > *yCloud, double cutoff, double binwidth, int firstFrame, int finalFrame)
Definition rdf2d.cpp:45
int normalizeRDF(int nopA, std::vector< double > *rdfValues, std::vector< int > histogram, double binwidth, int nbin, std::vector< double > volumeLengths, int nIter)
Normalize the histogram.
Definition rdf2d.cpp:162
int makePath(const std::string &path)
int printRDF(std::string fileName, std::vector< double > *rdfValues, double binwidth, int nbin)
Function for printing out the RDF, given the filename.
File containing functions used to calculate the in-plane radial distribution functions.
This contains a collection of points; contains information for a particular frame.
Definition mol_sys.hpp:170
This contains per-particle information.
Definition mol_sys.hpp:149