Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2014
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.46 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <string.h>
  5.  
  6.  
  7.  
  8. typedef struct {
  9. int x;
  10. int y;
  11. } Tuple;
  12.  
  13. void setBlackRed(int L, Tuple* blackCells, Tuple* redCells){
  14. int blackCount=0;
  15. int redCount=0;
  16. for(int i=1; i<L-1; i++){
  17. for(int j=1; j<L-1; j++){
  18. Tuple cell;
  19. cell.x = i;
  20. cell.y = j;
  21. if((i+j)%2 == 0){
  22. blackCells[blackCount] = cell;
  23. blackCount++;
  24. } else {
  25. redCells[redCount] = cell;
  26. redCount++;
  27. }
  28. }
  29. }
  30. }
  31.  
  32. void setPeriodicBoundary(int L, double m[L][L]){
  33. for(int i=1; i<L-1; i++){
  34. m[i][0] = m[i][L-2];
  35. m[i][L-1] = m[i][1];
  36. m[0][i] = m[L-2][i];
  37. m[L-1][i] = m[1][i];
  38. }
  39. }
  40.  
  41. double testFunction(int x, int y, int L){
  42. double xval = ((double) x);
  43. double yval = ((double) y);
  44. double dev = ((double)L-2)/10;
  45. //printf("%f\n", 4*exp(-(xval*xval+yval*yval)/(dev*dev)) * (-dev*dev+xval*xval+yval*yval)
  46. // / (dev*dev*dev*dev));
  47. //return 0;
  48. return 4*exp(-(xval*xval+yval*yval)/(dev*dev)) * (-dev*dev+xval*xval+yval*yval)
  49. / (dev*dev*dev*dev);
  50. }
  51.  
  52. double gausian(int x, int y, int L){
  53. double xval = ((double) x);
  54. double yval = ((double) y);
  55. double dev = ((double)L-2)/10;
  56. return exp(-(xval*xval + yval*yval)/(dev*dev));
  57. }
  58.  
  59.  
  60. double error(int L, double m[L][L], double m1[L][L]){
  61. double error = 0;
  62. for(int i=1; i<L-1; i++){
  63. for(int j=1; j<L-1; j++){
  64. //printf("%.12f\t%.12f\n", m[i][j], m1[i][j]);
  65. error += fabs(m[i][j]-m1[i][j]);
  66. }
  67. }
  68. return error/((L-2)*(L-2));
  69. }
  70.  
  71.  
  72.  
  73.  
  74. void SOR(int n, int L, double m[L][L], float w, double F[L][L]){
  75. for(int i=0; i<n; i++){
  76. setPeriodicBoundary(L, m);
  77. Tuple blackCells[(L-2)*(L-2)/2];
  78. Tuple redCells[(L-2)*(L-2)/2];
  79. setBlackRed(L, blackCells, redCells);
  80. for(int j=0; j<(L-2)*(L-2)/2; j++){
  81. int x = blackCells[j].x;
  82. int y = blackCells[j].y;
  83. m[x][y] = (1-w)*m[x][y] + w*.25*(m[x-1][y] + m[x+1][y] + m[x][y-1] + m[x][y+1]
  84. - F[x][y]/((L-2)*(L-2)));
  85. }
  86. setPeriodicBoundary(L, m);
  87. for(int j=0; j<(L-2)*(L-2)/2; j++){
  88. int x = redCells[j].x;
  89. int y = redCells[j].y;
  90. m[x][y] = (1-w)*m[x][y] + w*.25*(m[x-1][y] + m[x+1][y] + m[x][y-1] + m[x][y+1]
  91. - F[x][y]/((L-2)*(L-2)));
  92. }
  93. }
  94. setPeriodicBoundary(L, m);
  95. }
  96.  
  97. double calculateConvergence(int L, int startingIterations, int iterationInterval, double tolerance, double w, double (*f)(int, int, int)){
  98. double m[L][L];
  99. double m1[L][L]; // Used for testing error
  100. double F[L][L];
  101. for(int i=0; i<L; i++){
  102. for(int j=0; j<L; j++){
  103. m[i][j] = (double)rand()/(double)RAND_MAX;
  104. F[i][j] = (*f)(i, j, L);
  105. }
  106. }
  107.  
  108. SOR(startingIterations-1, L, m, w, F);
  109. for(int i=0; i<L; i++){for(int j=0; j<L; j++){m1[i][j] = m[i][j];}}
  110. SOR(1, L, m, w, F);
  111. double error1 = error(L, m, m1);
  112. double error2 = error1;
  113.  
  114. while(error2 > tolerance){
  115. //printf("%.12f\t%.12f\n", error1, error2);
  116. error1 = error2;
  117. SOR(iterationInterval-1, L, m, w, F);
  118. for(int i=0; i<L; i++){for(int j=0; j<L; j++){m1[i][j] = m[i][j];}}
  119. SOR(1, L, m, w, F);
  120. error2 = error(L, m, m1);
  121. }
  122.  
  123. return pow(error2/error1, 1./iterationInterval);
  124. }
  125.  
  126. void mgm(int level, int L, double phi[L][L], double F[L][L], int m1, int m2, int gamma){
  127. SOR(m1, L, phi, 1, F);
  128. if(level > 0){
  129. double residual[L][L];
  130. for(int i=1; i<L-1; i++){for(int j=1; j<L-1; j++){
  131. residual[i][j] = (phi[i-1][j] + phi[i+1][j] + phi[i][j-1] + phi[i][j+1] - 4*phi[i][j])
  132. - F[i][j]/((L-2)*(L-2));
  133. //residual[i][j] = -residual[i][j];
  134. }}
  135. setPeriodicBoundary(L, residual);
  136.  
  137. int Lnew = (L-2)/2 + 2;
  138. double psi[Lnew][Lnew];
  139. double d[Lnew][Lnew];
  140. for(int i=1; i<Lnew-1; i++){for(int j=1; j<Lnew-1; j++){
  141. psi[i][j] = 0;
  142. int x = 2*i-1;
  143. int y = 2*j-1;
  144. d[i][j] = .25 * (residual[x][y] + residual[x+1][y]
  145. + residual[x][y+1]+ residual[x+1][y+1]);
  146. }}
  147.  
  148.  
  149. for(int i=0; i<gamma; i++){
  150. setPeriodicBoundary(Lnew, d);
  151. setPeriodicBoundary(Lnew, psi);
  152. mgm(level-1, Lnew, psi, d, m1, m2, gamma);
  153. }
  154.  
  155. for(int i=1; i<Lnew-1; i++){for(int j=1; j<Lnew-1; j++){
  156. int x = 2*i-1;
  157. int y = 2*j-1;
  158. phi[x][y] = phi[x][y] + psi[i][j];
  159. phi[x+1][y] = phi[x+1][y] + psi[i][j];
  160. phi[x][y+1] = phi[x][y+1] + psi[i][j];
  161. phi[x+1][y+1] = phi[x+1][y+1] + psi[i][j];
  162. }}
  163.  
  164. }
  165. SOR(m2, L, phi, 1, F);
  166. }
  167.  
  168. double calculateMgmConvergence(int level, int m1, int m2, int gamma, int startingIterations, int iterationInterval, double tolerance){
  169. int L = pow(2, level) + 2;
  170.  
  171. double phi[L][L];
  172. double F[L][L];
  173. double testPhi[L][L];
  174. for(int i=1; i<L-1; i++){for(int j=1; j<L-1; j++){
  175. phi[i][j] = (double)rand()/(double)RAND_MAX;
  176. //phi[i][j] = i + j;
  177. F[i][j] = testFunction(i, j, L);
  178. }}
  179.  
  180. // Starting iterations
  181. for(int i=0; i<startingIterations-1; i++){ mgm(level, L, phi, F, m1, m2, gamma); }
  182. // Update test
  183. for(int x=1; x<L-1; x++){for(int y=1; y<L-1; y++){testPhi[x][y] = phi[x][y];}}
  184. // Extra iteration
  185. mgm(level, L, phi, F, m1, m2, gamma);
  186. double error1 = error(L, phi, testPhi);
  187. double error2 = error1;
  188.  
  189. while(error2 > tolerance){
  190. printf("%.12f\t%.12f\n", error1, error2);
  191. error1 = error2;
  192.  
  193. for(int i=0; i<iterationInterval-1; i++){ mgm(level, L, phi, F, m1, m2, gamma); }
  194. // Update test
  195. for(int x=1; x<L-1; x++){for(int y=1; y<L-1; y++){testPhi[x][y] = phi[x][y];}}
  196. // Extra iteration
  197. mgm(level, L, phi, F, m1, m2, gamma);
  198. error2 = error(L, phi, testPhi);
  199. }
  200.  
  201. return pow(error2/error1, 1./iterationInterval);
  202. }
  203.  
  204.  
  205. int main(){
  206.  
  207. // int m1 = 2;
  208. // int m2 = 2;
  209. // int startingIterations = 1;
  210. // int iterationInterval = 1;
  211. // double tolerance = .0000001;
  212.  
  213. // int start = 4;
  214. // int range = 4;
  215. // int Lrange[range];
  216. // double convergenceArr1[range];
  217. // double convergenceArr2[range];
  218. // for(int i=start; i<start+range; i++){
  219. // printf("levels: %i\n", i);
  220. // Lrange[i-start] = i;
  221. // convergenceArr1[i-start] = calculateMgmConvergence(i, m1, m2, 1, startingIterations, iterationInterval, tolerance);
  222. // convergenceArr2[i-start] = calculateMgmConvergence(i, m1, m2, 2, startingIterations, iterationInterval, tolerance);
  223. // }
  224.  
  225.  
  226.  
  227.  
  228. int N = 64;
  229. int L = N+2;
  230. int startingIterations = 100;
  231. int iterationInterval = 20;
  232. double tolerance = .0000001;
  233.  
  234.  
  235. int omegaLength = 100;
  236. double omegaArr[omegaLength];
  237. double convergenceArr[omegaLength];
  238. for(int i=0; i<omegaLength; i++){
  239. omegaArr[i] = 1 + ((double)i)/omegaLength;
  240. convergenceArr[i] = calculateConvergence(L, startingIterations, iterationInterval,
  241. tolerance, omegaArr[i], testFunction);
  242. printf("%.12f\t%.12f\n", omegaArr[i], convergenceArr[i]);
  243. }
  244.  
  245.  
  246. printf("Writing to file\n");
  247. FILE *f = fopen("../out/temp.txt", "w");
  248. if (f == NULL){
  249. printf("Error opening file!\n");
  250. exit(1);
  251. }
  252.  
  253. /* print some text */
  254. const char *text = "Plot1";
  255. fprintf(f, "%s\n", text);
  256.  
  257. /* print integers and floats */
  258. //for(int i=0; i<range; i++){
  259. for(int i=0; i<omegaLength; i++){
  260. //fprintf(f, "%i\t%.12f\t%.12f\n", Lrange[i], convergenceArr1[i], convergenceArr2[i]);
  261. fprintf(f, "%.12f\t%.12f\n", omegaArr[i], convergenceArr[i]);
  262. }
  263.  
  264. fclose(f);
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement