rdf.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // Copyright (c) 2021 NVIDIA Corporation. All rights reserved.
  2. #include <stdio.h>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <cmath>
  6. #include <cstring>
  7. #include <cstdio>
  8. #include <iomanip>
  9. #include "dcdread.h"
  10. #include <assert.h>
  11. #include <algorithm>
  12. #include <vector>
  13. #include <atomic>
  14. #include <execution>
  15. #include <nvtx3/nvToolsExt.h>
  16. #ifdef USE_COUNTING_ITERATOR
  17. #include <thrust/iterator/counting_iterator.h>
  18. #endif
  19. void pair_gpu(double *d_x, double *d_y, double *d_z,
  20. std::atomic<int> *d_g2, int numatm, int nconf,
  21. const double xbox, const double ybox, const double zbox, int d_bin);
  22. int main(int argc, char *argv[])
  23. {
  24. double xbox, ybox, zbox;
  25. int nbin;
  26. int numatm, nconf, inconf;
  27. string file;
  28. ///////////////////////////////////////////////////////////////
  29. inconf = 10;
  30. nbin = 2000;
  31. file = "../input/alk.traj.dcd";
  32. ///////////////////////////////////////
  33. std::ifstream infile;
  34. infile.open(file.c_str());
  35. if (!infile)
  36. {
  37. cout << "file " << file.c_str() << " not found\n";
  38. return 1;
  39. }
  40. assert(infile);
  41. ofstream pairfile, stwo;
  42. pairfile.open("RDF.dat");
  43. stwo.open("Pair_entropy.dat");
  44. /////////////////////////////////////////////////////////
  45. dcdreadhead(&numatm, &nconf, infile);
  46. cout << "Dcd file has " << numatm << " atoms and " << nconf << " frames" << endl;
  47. if (inconf > nconf)
  48. cout << "nconf is reset to " << nconf << endl;
  49. else
  50. {
  51. nconf = inconf;
  52. }
  53. cout << "Calculating RDF for " << nconf << " frames" << endl;
  54. ////////////////////////////////////////////////////////
  55. double *h_x = new double[nconf * numatm];
  56. double *h_y = new double[nconf * numatm];
  57. double *h_z = new double[nconf * numatm];
  58. //Note
  59. std::atomic<int> *h_g2 = new std::atomic<int>[nbin];
  60. std::fill(std::execution::par, h_g2, h_g2 + nbin, 0);
  61. /////////reading cordinates//////////////////////////////////////////////
  62. nvtxRangePush("Read_File");
  63. double ax[numatm], ay[numatm], az[numatm];
  64. for (int i = 0; i < nconf; i++)
  65. {
  66. dcdreadframe(ax, ay, az, infile, numatm, xbox, ybox, zbox);
  67. for (int j = 0; j < numatm; j++)
  68. {
  69. h_x[i * numatm + j] = ax[j];
  70. h_y[i * numatm + j] = ay[j];
  71. h_z[i * numatm + j] = az[j];
  72. }
  73. }
  74. nvtxRangePop(); //pop for Reading file
  75. cout << "Reading of input file is completed" << endl;
  76. //////////////////////////////////////////////////////////////////////////
  77. nvtxRangePush("Pair_Calculation");
  78. pair_gpu(h_x, h_y, h_z, h_g2, numatm, nconf, xbox, ybox, zbox, nbin);
  79. nvtxRangePop(); //Pop for Pair Calculation
  80. double pi = acos(-1.0l);
  81. double rho = (numatm) / (xbox * ybox * zbox);
  82. double norm = (4.0l * pi * rho) / 3.0l;
  83. double rl, ru, nideal;
  84. double g2[nbin];
  85. double r, gr, lngr, lngrbond, s2 = 0.0l, s2bond = 0.0l;
  86. double box = min(xbox, ybox);
  87. box = min(box, zbox);
  88. double del = box / (2.0l * nbin);
  89. nvtxRangePush("Entropy_Calculation");
  90. for (int i = 0; i < nbin; i++)
  91. {
  92. // cout<<i+1<<" "<<h_g2[i]<<endl;
  93. rl = (i)*del;
  94. ru = rl + del;
  95. nideal = norm * (ru * ru * ru - rl * rl * rl);
  96. g2[i] = (double)h_g2[i] / ((double)nconf * (double)numatm * nideal);
  97. r = (i)*del;
  98. pairfile << (i + 0.5l) * del << " " << g2[i] << endl;
  99. if (r < 2.0l)
  100. {
  101. gr = 0.0l;
  102. }
  103. else
  104. {
  105. gr = g2[i];
  106. }
  107. if (gr < 1e-5)
  108. {
  109. lngr = 0.0l;
  110. }
  111. else
  112. {
  113. lngr = log(gr);
  114. }
  115. if (g2[i] < 1e-6)
  116. {
  117. lngrbond = 0.0l;
  118. }
  119. else
  120. {
  121. lngrbond = log(g2[i]);
  122. }
  123. s2 = s2 - 2.0l * pi * rho * ((gr * lngr) - gr + 1.0l) * del * r * r;
  124. s2bond = s2bond - 2.0l * pi * rho * ((g2[i] * lngrbond) - g2[i] + 1.0l) * del * r * r;
  125. }
  126. nvtxRangePop(); //Pop for Entropy Calculation
  127. stwo << "s2 value is " << s2 << endl;
  128. stwo << "s2bond value is " << s2bond << endl;
  129. cout << "#Freeing Host memory" << endl;
  130. delete[] h_x;
  131. delete[] h_y;
  132. delete[] h_z;
  133. delete[] h_g2;
  134. cout << "#Number of atoms processed: " << numatm << endl
  135. << endl;
  136. cout << "#Number of confs processed: " << nconf << endl
  137. << endl;
  138. return 0;
  139. }
  140. int round(float num)
  141. {
  142. return num < 0 ? num - 0.5 : num + 0.5;
  143. }
  144. void pair_gpu(double *d_x, double *d_y, double *d_z,
  145. std::atomic<int> *d_g2, int numatm, int nconf,
  146. const double xbox, const double ybox, const double zbox, int d_bin)
  147. {
  148. double cut;
  149. double box;
  150. box = min(xbox, ybox);
  151. box = min(box, zbox);
  152. double del = box / (2.0 * d_bin);
  153. cut = box * 0.5;
  154. #ifndef USE_COUNTING_ITERATOR
  155. std::vector<unsigned int> indices(numatm * numatm);
  156. std::generate(indices.begin(), indices.end(), [n = 0]() mutable { return n++; });
  157. #endif
  158. printf("\n %d %d ", nconf, numatm);
  159. for (int frame = 0; frame < nconf; frame++)
  160. {
  161. printf("\n %d ", frame);
  162. #ifdef USE_COUNTING_ITERATOR
  163. std::for_each(std::execution::par, thrust::counting_iterator<unsigned int>(0u), thrust::counting_iterator<unsigned int>(numatm * numatm),
  164. #else
  165. std::for_each(std::execution::par, indices.begin(), indices.end(),
  166. #endif
  167. [d_x, d_y, d_z, d_g2, numatm, frame, xbox, ybox, zbox, cut, del](unsigned int index) {
  168. int id1 = index / numatm;
  169. int id2 = index % numatm;
  170. double dx = d_x[frame * numatm + id1] - d_x[frame * numatm + id2];
  171. double dy = d_y[frame * numatm + id1] - d_y[frame * numatm + id2];
  172. double dz = d_z[frame * numatm + id1] - d_z[frame * numatm + id2];
  173. dx = dx - xbox * (round(dx / xbox));
  174. dy = dy - ybox * (round(dy / ybox));
  175. dz = dz - zbox * (round(dz / zbox));
  176. double r = sqrtf(dx * dx + dy * dy + dz * dz);
  177. if (r < cut)
  178. {
  179. int ig2 = (int)(r / del);
  180. ++d_g2[ig2];
  181. }
  182. });
  183. }
  184. }