1. #include <iostream>
  2. #include <cmath>
  3. #include <cstdio>
  4. #include <fstream>
  5. #include <string>
  6. #include <sstream>
  7. #include <assert.h>
  8. #include <GLUT/glut.h>
  9.  
  10. using namespace std;
  11.  
  12. //Global constants
  13. const double PI = 4*atan(1.0);
  14. double* xArray_ptr;
  15. double* yArray_ptr;
  16. GLuint circle;
  17. string DIRECTORY = "/Users/rj/Desktop/";
  18.  
  19. //Math section
  20.  
  21. //Generate random trajectories
  22. /***********************************************************************/
  23. double linearCongruence(long int scale, unsigned long int& seed, unsigned long int offSet, unsigned long int modulo)
  24. {
  25. double randomNum = 0;
  26. seed = (scale*seed+offSet)%modulo;
  27. randomNum = (double)seed/(double)(modulo-1);
  28. return(randomNum);
  29. }
  30.  
  31. void genRandNum(double rand1[], double rand2[], int numRandomNums)
  32. {
  33. //Constants for random number generator, choices from Numerical Recipes
  34. const unsigned long int modulo = pow(2.0, 32.0);
  35. const long int scale = 1664525;
  36. const unsigned long int offSet = 1013904223;
  37.  
  38. //Random number generator seed and pointer
  39. unsigned long int seed1 = 1024;
  40. unsigned long int seed2 = 512;
  41.  
  42. for(int i = 0; numRandomNums > i; i++)
  43. {
  44. rand1[i] = (linearCongruence(scale,seed1,offSet,modulo));
  45. rand2[i] = (linearCongruence(scale,seed2,offSet,modulo));
  46. }
  47. }
  48.  
  49. void boxMuller(double gauss1[], double gauss2[], double rand1[], double rand2[])
  50. {
  51. for(int i = 0; 10000 > i; i++)
  52. {
  53. gauss1[i] = sqrt(-2*log(rand1[i]))*cos(2.0*PI*rand2[i]);
  54. gauss2[i] = sqrt(-2*log(rand1[i]))*sin(2*PI*rand2[i]);
  55. }
  56. }
  57. /***********************************************************************/
  58.  
  59. //Calculate classical dynamics
  60. /***********************************************************************/
  61. void posClassical( double posArray[], double gauss1[], double gauss2[], const double FIELD, double currentTime)
  62. {
  63. //mass is 1
  64.  
  65. for(int i = 0; 10000 > i; i++)
  66. {
  67. posArray[i] = (gauss1[i] + gauss2[i] * currentTime - 0.5 * FIELD * pow(currentTime, 2));
  68. }
  69. }
  70.  
  71. void momentumClassical(double momArray[], double gauss2[], const double FIELD, double currentTime)
  72. {
  73.  
  74. //mass is 1
  75.  
  76. for(int i = 0; 10000 > i; i++)
  77. {
  78. momArray[i] = (gauss2[i] - FIELD * currentTime);
  79. }
  80. }
  81. /***********************************************************************/
  82.  
  83. //Calculate probability densities analitically
  84. /***********************************************************************/
  85.  
  86. //Spatial probability density
  87. double rho_X_T(double pos, double spatialWidth0, double momWidth0, double atomicTime, double potential)
  88. {
  89. double spatialWidthT = sqrt(pow(spatialWidth0,2.0)+pow(momWidth0,2.0)*pow(atomicTime,2.0));
  90. double exponent = (-0.5)*pow(((pos+(potential/2.0)*pow(atomicTime,2.0))/spatialWidthT),2.0);
  91.  
  92. return((1/(sqrt(2.0)*PI))*(1/spatialWidthT)*exp(exponent));
  93. }
  94. /***********************************************************************/
  95.  
  96. //Statistics
  97. /***********************************************************************/
  98.  
  99.  
  100. double arrayAverage(double array[], int arraySize)
  101. {
  102. double sum = 0;
  103.  
  104. for(int i = 0; arraySize > i; i++)
  105. {
  106. sum = sum + array[i];
  107. }
  108. //cout << sum << endl;
  109. return(sum/(double)arraySize);
  110. }
  111.  
  112. double calculateAvgPosition(double posArray[], double arraySize)
  113. {
  114. return(arrayAverage(posArray, arraySize));
  115. }
  116.  
  117. double calculateAvgMomentum(double momArray[], double arraySize)
  118. {
  119. return(arrayAverage(momArray, arraySize));
  120. }
  121.  
  122. void writePhaseSpacePointToFile(double avgPosition, double avgMomentum, double currentTime)
  123. {
  124. string filename = DIRECTORY + "phaseSpaceData.txt";
  125. ofstream fout;
  126. fout.open(filename.c_str(), ios_base::app);
  127.  
  128. fout << avgPosition << ";" << avgMomentum << ";" << currentTime << endl;
  129.  
  130. fout.close();
  131. }
  132.  
  133.  
  134. //If I switch to vectors I can get rid of all this arraySize crap...
  135. void calculatAvgPhaseSpace(double totalTime, double numTimeSteps,
  136. double posArray[], double momArray[],
  137. int arraySize, const double FIELD, double gauss1[], double gauss2[])
  138. {
  139.  
  140. const double deltaT = totalTime/(double)numTimeSteps;
  141.  
  142. double currentTime = 0;
  143. double avgPosition = 0; //These two seem to be a waste of memory
  144. double avgMomentum = 0;
  145.  
  146. for(int i = 0; numTimeSteps > i; i++)
  147. {
  148. currentTime = deltaT * i;
  149.  
  150. //load the position and momentum values for each particle
  151. posClassical(posArray, gauss1, gauss2, FIELD, currentTime);
  152. momentumClassical(momArray, gauss2, FIELD, currentTime);
  153.  
  154. //calculate the averages
  155. avgPosition = calculateAvgPosition(posArray, arraySize);
  156. avgMomentum = calculateAvgMomentum(momArray, arraySize);
  157.  
  158. //Write data to file
  159. writePhaseSpacePointToFile(avgPosition, avgMomentum, currentTime);
  160. }
  161. }
  162.  
  163.  
  164. /***********************************************************************/
  165.  
  166. //Bookkeeping
  167. /***********************************************************************/
  168. void writeArrayToFile(double xArray[], double yArray[], ofstream* filePtr)
  169. {
  170. //Arrays must be same size, should add an assert here at some point.
  171. for(int i = 0; 10000 > i; i++)
  172. {
  173. *filePtr << xArray[i] << ";" << yArray[i] << endl;
  174. }
  175. }
  176.  
  177. void buildSequentialFileNameArray(string nameArray[], string directory, string prefix, string extenstion, const int numFiles)
  178. {
  179. stringstream ss;
  180. string suffix;
  181. for(int i = 0; numFiles > i; i++)
  182. {
  183. ss << i;
  184. suffix = "_" + ss.str() + "." + extenstion;
  185. nameArray[i] = directory + prefix + suffix;
  186. }
  187. }
  188.  
  189. void buildFileStreamArray(ofstream* streamArray[], string nameArray[], int numStreams)
  190. {
  191. for(int i = 0; numStreams > i; i++)
  192. {
  193. streamArray[i] = new ofstream(nameArray[i].c_str()) ;
  194. }
  195. }
  196.  
  197. /***********************************************************************/
  198.  
  199. //Graphics part
  200. /***********************************************************************/
  201. void createCircle()
  202. {
  203. float theta;
  204. int i;
  205. int div = 50;
  206.  
  207.  
  208. circle = glGenLists(1);
  209.  
  210. glNewList(circle,GL_COMPILE);
  211. glBegin(GL_TRIANGLE_FAN);
  212. glVertex2f(0,0);
  213. for (i=0;i<div;i++)
  214. {
  215. theta = (float)i*2*3.14159/div;
  216. glVertex2f(cos(theta),sin(theta));
  217. }
  218. glVertex2f(1,0);
  219. glEnd();
  220. glEndList();
  221. }
  222.  
  223. void drawAxis(int xSize, int ySize)
  224. {
  225. glBegin(GL_LINES);
  226. //x-axis
  227. glColor3f(0,0,0);
  228. glVertex3f(-xSize,0,0);
  229. glVertex3f(xSize,0,0);
  230.  
  231. //y-axis
  232. glColor3f(0,0,0);
  233. glVertex3f(0,-ySize,0);
  234. glVertex3f(0,ySize,0);
  235. glEnd();
  236. }
  237.  
  238. void drawBaorder(int xSize, int ySize)
  239. {
  240. glBegin(GL_LINES);
  241.  
  242. //Left boarder
  243. glColor3f(0,0,0);
  244. glVertex3f(-xSize,-ySize,0);
  245. glVertex3f(-xSize,ySize,0);
  246.  
  247. //Botom boarder
  248. glColor3f(0,0,0);
  249. glVertex3f(-xSize,-ySize,0);
  250. glVertex3f(xSize,-ySize,0);
  251.  
  252. //Right boarder
  253. glColor3f(0,0,0);
  254. glVertex3f(xSize,-ySize,0);
  255. glVertex3f(xSize,ySize,0);
  256.  
  257. //top boarder
  258. glColor3f(0,0,0);
  259. glVertex3f(-xSize,ySize,0);
  260. glVertex3f(xSize,ySize,0);
  261. glEnd();
  262. }
  263.  
  264. void display(void)
  265. {
  266. glClear(GL_COLOR_BUFFER_BIT);
  267. glMatrixMode(GL_MODELVIEW);
  268. glLoadIdentity();
  269.  
  270. glColor3f(1,0,0); //pure red
  271. glPointSize(2.0);
  272. /*
  273.   glBegin(GL_POINTS);
  274.   for (int i=0; i < 10000; i++)
  275.   {
  276.   glVertex2f(xArray_ptr[i],yArray_ptr[i]);
  277.   }
  278.   glEnd();
  279. */
  280. drawAxis(35,35);
  281. drawBaorder(35,35);
  282.  
  283.  
  284. glColor3f(1,0,0);
  285. for (int i=0; i < 10000; i++)
  286. {
  287. glPushMatrix();
  288. glTranslatef(xArray_ptr[i],yArray_ptr[i],0);
  289. glScalef(.05,.05,1);
  290. glCallList(circle);
  291. glPopMatrix();
  292. }
  293.  
  294. glutSwapBuffers();
  295. }
  296.  
  297. void reshape(int width, int height)
  298. {
  299. glMatrixMode(GL_PROJECTION);
  300. glClearColor(1,1,1,1);
  301. glLoadIdentity();
  302. gluOrtho2D(-40,40,-40,40); //you need to get these
  303. glViewport(0,0,width,height);
  304.  
  305. createCircle();
  306. }
  307.  
  308. void idle(void)
  309. {
  310. //Need to generate x and y
  311.  
  312. glutPostRedisplay();
  313. }
  314.  
  315. /***********************************************************************/
  316.  
  317. //main program
  318. /***********************************************************************/
  319. int main(int argc, char *argv[])
  320. {
  321. //OpenGL stuff
  322. glutInit(&argc, argv);
  323.  
  324. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  325. glutInitWindowSize(1024, 768);
  326.  
  327. glutCreateWindow("Classical Statistical Dynamics");
  328.  
  329. glutDisplayFunc(display);
  330. glutReshapeFunc(reshape);
  331. //glutIdleFunc(idle);
  332.  
  333. //Problem specific constants
  334. const int numRandomNums = 10000;
  335. const double EFIELD = 1.0;
  336. const double spatialWidth0 = 1.0;
  337. const double momWidth0 = 0.5;
  338. const double numTimeSteps = 100;
  339. double atomicTime[] = {0,2,4};
  340. double atomicTime_t0 = 0;
  341. double atomicTime_t1 = 2;
  342. double atomicTime_t2 = 4;
  343. const int numFiles = 3;
  344. string fileNameArray[numFiles];
  345. ofstream* streamArray[numFiles];
  346. string filename_t0 = DIRECTORY + "data_t0.txt";
  347. string filename_t1 = DIRECTORY + "data_t1.txt";
  348. string filename_t2 = DIRECTORY + "data_t2.txt";
  349.  
  350. buildSequentialFileNameArray(fileNameArray, DIRECTORY, "data_t", "txt", numFiles);
  351. buildFileStreamArray(streamArray, fileNameArray, numFiles);
  352.  
  353. //Stream variables for classical trajectories
  354. ofstream fout0(filename_t0.c_str());
  355. ofstream fout1(filename_t1.c_str());
  356. ofstream fout2(filename_t2.c_str());
  357.  
  358. //temp arrays for storing uniformly distributed random numbers
  359. double rand1[numRandomNums];
  360. double rand2[numRandomNums];
  361.  
  362. //temp arrays for storing gaussian distributed random numbers
  363. double gauss1[numRandomNums];
  364. double gauss2[numRandomNums];
  365.  
  366. //Arrays to hold classical position and momentum
  367. double posArray[numRandomNums];
  368. double momArray[numRandomNums];
  369.  
  370. //Array pointers
  371. xArray_ptr = &posArray[0];
  372. yArray_ptr = &momArray[0];
  373.  
  374. //Generate 10000 uniformly distributed random numbers
  375. genRandNum(rand1, rand2, numRandomNums);
  376.  
  377. //Convert to Gaussian distributed random numbers
  378. boxMuller(gauss1, gauss2, rand1, rand2);
  379.  
  380. //PROBLEM 1.2F
  381. /***********************************************************************/
  382. calculatAvgPhaseSpace(atomicTime_t2, numTimeSteps, posArray, momArray, numRandomNums, EFIELD, gauss1, gauss2);
  383.  
  384. /***********************************************************************/
  385.  
  386. for(int i = 0; numFiles > i; i++)
  387. {
  388. posClassical(posArray, gauss1, gauss2, EFIELD, atomicTime[i]);
  389. momentumClassical(momArray, gauss2, EFIELD, atomicTime[i]);
  390.  
  391. writeArrayToFile(posArray, momArray, streamArray[i]);
  392. }
  393. /*
  394.   //PROBLEM 1.2D T0
  395.   /***********************************************************************/
  396.  
  397. //Calculate first itteration of classical position and momentum for t = 0
  398. posClassical(posArray, gauss1, gauss2, EFIELD, atomicTime_t0);
  399. momentumClassical(momArray, gauss2, EFIELD, atomicTime_t0);
  400.  
  401. writeArrayToFile(posArray, momArray, &fout0);
  402. /***********************************************************************/
  403.  
  404. //Problem 1.2D T1
  405. /***********************************************************************/
  406. //Calculate first itteration of classical position and momentum for t = 2
  407. posClassical(posArray, gauss1, gauss2, EFIELD, atomicTime_t1);
  408. momentumClassical(momArray, gauss2, EFIELD, atomicTime_t1);
  409.  
  410. writeArrayToFile(posArray, momArray, &fout1);
  411. /***********************************************************************/
  412.  
  413. //Problem 1.2D T2
  414. /***********************************************************************/
  415. //Calculate first itteration of classical position and momentum for t = 4
  416. posClassical(posArray, gauss1, gauss2, EFIELD, atomicTime_t2);
  417. momentumClassical(momArray, gauss2, EFIELD, atomicTime_t2);
  418.  
  419. writeArrayToFile(posArray, momArray, &fout2);
  420. /***********************************************************************/
  421.  
  422. //Need to make sure arrays are assigned and changing correctly before this function is called.
  423. glutMainLoop();
  424.  
  425. return 0;
  426. }
  427.