rdf2d.cpp
Go to the documentation of this file.
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 
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 
162 int 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 
213  molSys::PointCloud<molSys::Point<double>, double> *yCloud) {
214  //
215  std::vector<double> lengths; // Volume lengths
217  rMax; // Max of the coordinates {0 is for x, 1 is for y and 2 is for z}
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 
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
T begin(T... args)
T close(T... args)
T end(T... args)
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
T min_element(T... args)
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.
T open(T... args)
T push_back(T... args)
File containing functions used to calculate the in-plane radial distribution functions.
T resize(T... args)
T reverse(T... args)
T sort(T... args)
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