PageRenderTime 64ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/2d/MeshIterate.cpp

https://bitbucket.org/imsejae/meshgencpp
C++ | 272 lines | 216 code | 26 blank | 30 comment | 33 complexity | 50120ea1e7cb6b0ab1d571128278b58c MD5 | raw file
  1. #include "meshdefs.h"
  2. #include <cstdio>
  3. #include <cstdlib>
  4. //
  5. // Takes initial point distribution "p", triangulates with "t", and then
  6. // iterates on the point distribution and triangulation until an equilibrium
  7. // mesh is created (or until the number of iterations exceeds "maxiters").
  8. //
  9. void MeshIterate(int maxiters, double geps, double ttol, double dptol, double Fscale,
  10. double deltat, double deps, double h0, int numfixpts, int& numpts, int& numtri,
  11. point*& p, triangle*& t,double (*SignedDistance)(point),
  12. double (*GridSpacing)(point))
  13. {
  14. // Sorting function
  15. void QuickSort_bar(bar* b, int* key, int i, int j);
  16. // Set up all needed variables and dynamic arrays for while-loop iteration
  17. bool retriang = true; // force initial retriangulation
  18. bool terminate = false; // end when termination criterion satisfied
  19. // create and allocate dynamic arrays
  20. point* pold;
  21. triangle* ttemp;
  22. point* pmid;
  23. bar* bartemp;
  24. bar* bars;
  25. int* priority;
  26. point* barvec;
  27. double* L;
  28. point* midpt;
  29. double* hbars;
  30. double* L0;
  31. double* F;
  32. point* Fvec;
  33. point* Ftot;
  34. double* dist;
  35. pold = new point[numpts];
  36. ttemp = new triangle[2*numpts];
  37. pmid = new point[2*numpts];
  38. t = new triangle[2*numpts];
  39. bartemp = new bar[6*numpts];
  40. bars = new bar[6*numpts];
  41. priority = new int[6*numpts];
  42. barvec = new point[6*numpts];
  43. L = new double[6*numpts];
  44. midpt = new point[6*numpts];
  45. hbars = new double[6*numpts];
  46. L0 = new double[6*numpts];
  47. F = new double[6*numpts];
  48. Fvec = new point[6*numpts];
  49. Ftot = new point[numpts];
  50. dist = new double[numpts];
  51. //*************************************************************************
  52. //*** Iterate until maxiterations reached or termination criterion met ****
  53. //*************************************************************************
  54. int counter = 0;
  55. int retris = 0;
  56. int numbar = 0;
  57. while (terminate == false && counter < maxiters) //***********
  58. {
  59. counter++; // ***************************
  60. printf(" Iteration %i\n",counter);
  61. // retriangulate if necessary
  62. if (retriang == true)
  63. {
  64. retris++; // ***************************
  65. // if retriangulating, save old positions
  66. for (int i=0; i<numpts; i++)
  67. {
  68. pold[i].x = p[i].x;
  69. pold[i].y = p[i].y;
  70. }
  71. FILE* pointfile = fopen("pointfile.txt","w");
  72. fprintf(pointfile,"%8i\n%8i\n",2,numpts);
  73. for (int i=0; i<numpts; i++)
  74. { fprintf(pointfile,"%24.16e %24.16e\n",p[i].x,p[i].y); }
  75. fclose(pointfile);
  76. // System call for Delaunay triangulation
  77. printf(" Retriangulating ... \n\n");
  78. int exit_status = system("$QHULL/bin/qdelaunay Qt i < ./pointfile.txt > ./trifile.txt");
  79. // Read-in triangulation from qhull
  80. int numtritemp;
  81. FILE* trifile = fopen("trifile.txt","r");
  82. int garbage=fscanf(trifile,"%i",&numtritemp);
  83. triangle* ttemp = new triangle[numtritemp];
  84. point* pmid = new point[numtritemp];
  85. for (int i=0; i<numtritemp; i++)
  86. { garbage=fscanf(trifile,"%i %i %i",&ttemp[i].n1,&ttemp[i].n2,&ttemp[i].n3); }
  87. fclose(trifile);
  88. // Remove files
  89. exit_status = system("rm -f pointfile.txt trifile.txt");
  90. retriang = false;
  91. numtri = 0;
  92. for (int i=0; i<numtritemp; i++)
  93. {
  94. pmid[i].x = (p[ttemp[i].n1].x + p[ttemp[i].n2].x + p[ttemp[i].n3].x) / 3;
  95. pmid[i].y = (p[ttemp[i].n1].y + p[ttemp[i].n2].y + p[ttemp[i].n3].y) / 3;
  96. if (SignedDistance(pmid[i]) < -geps)
  97. {
  98. t[numtri].n1 = ttemp[i].n1;
  99. t[numtri].n2 = ttemp[i].n2;
  100. t[numtri].n3 = ttemp[i].n3;
  101. numtri++;
  102. }
  103. }
  104. // find unique listing of bars
  105. numbar = 0;
  106. for (int i=0; i<numtri; i++)
  107. {
  108. bartemp[3*i].n1 = t[i].n1;
  109. bartemp[3*i].n2 = t[i].n2;
  110. bartemp[3*i+1].n1 = t[i].n1;
  111. bartemp[3*i+1].n2 = t[i].n3;
  112. bartemp[3*i+2].n1 = t[i].n2;
  113. bartemp[3*i+2].n2 = t[i].n3;
  114. }
  115. for (int i=0; i<3*numtri; i++)
  116. {
  117. // sort each bar so that n1 < n2
  118. if (bartemp[i].n1 > bartemp[i].n2)
  119. {
  120. int temp = bartemp[i].n1;
  121. bartemp[i].n1 = bartemp[i].n2;
  122. bartemp[i].n2 = temp;
  123. }
  124. // assign priority for sorting list of bars
  125. priority[i] = numpts*bartemp[i].n1 + bartemp[i].n2;
  126. }
  127. QuickSort_bar(bartemp, priority, 0, 3*numtri - 1);
  128. // keep only unique bars
  129. int value = 0;
  130. for (int i=0; i<3*numtri; i++)
  131. if (priority[i] != value)
  132. {
  133. bars[numbar].n1 = bartemp[i].n1;
  134. bars[numbar].n2 = bartemp[i].n2;
  135. value = priority[i];
  136. numbar++;
  137. }
  138. }
  139. // ********************************************************************
  140. // **************** Move mesh points by computed forces ***************
  141. // ********************************************************************
  142. // create list of bar vectors "barvec" and bar lengths "L"
  143. double sumL2 = 0.0;
  144. double sumhbars2 = 0.0;
  145. for (int i=0; i<numbar; i++)
  146. {
  147. barvec[i].x = p[bars[i].n1].x - p[bars[i].n2].x;
  148. barvec[i].y = p[bars[i].n1].y - p[bars[i].n2].y;
  149. L[i] = sqrt(static_cast<double>(barvec[i].x*barvec[i].x + barvec[i].y*barvec[i].y));
  150. midpt[i].x = (p[bars[i].n1].x + p[bars[i].n2].x)/2.0;
  151. midpt[i].y = (p[bars[i].n1].y + p[bars[i].n2].y)/2.0;
  152. hbars[i] = GridSpacing(midpt[i]);
  153. sumL2 += (L[i]*L[i]);
  154. sumhbars2 += (hbars[i]*hbars[i]);
  155. }
  156. for (int i=0; i<numbar; i++)
  157. {
  158. L0[i] = hbars[i] * Fscale * sqrt(static_cast<double>(sumL2 / sumhbars2));
  159. F[i] = L0[i] - L[i];
  160. if (F[i] < 0)
  161. F[i] = 0;
  162. Fvec[i].x = F[i]/L[i] * barvec[i].x;
  163. Fvec[i].y = F[i]/L[i] * barvec[i].y;
  164. }
  165. // find forces on each point (reset Ftot to 0, then add Fvec components)
  166. for (int i=0; i<numpts; i++)
  167. Ftot[i].x = Ftot[i].y = 0;
  168. for (int i=0; i<numbar; i++)
  169. {
  170. Ftot[bars[i].n1].x += Fvec[i].x;
  171. Ftot[bars[i].n1].y += Fvec[i].y;
  172. Ftot[bars[i].n2].x -= Fvec[i].x;
  173. Ftot[bars[i].n2].y -= Fvec[i].y;
  174. }
  175. // set forces on fixed points to 0
  176. for (int i=0; i<numfixpts; i++)
  177. Ftot[i].x = Ftot[i].y = 0;
  178. // update node positions
  179. for (int i=0; i<numpts; i++)
  180. {
  181. p[i].x += deltat * Ftot[i].x;
  182. p[i].y += deltat * Ftot[i].y;
  183. }
  184. // move outside points back to the boundary
  185. for (int i=0; i<numpts; i++)
  186. {
  187. dist[i] = SignedDistance(p[i]);
  188. if (dist[i] > 0.0)
  189. {
  190. int mm=0;
  191. double tmp = fabs(dist[i]);
  192. while (tmp>1.0e-14)
  193. {
  194. point ptemp = p[i];
  195. ptemp.x += deps;
  196. double dgradx = (SignedDistance(ptemp)-SignedDistance(p[i])) / deps;
  197. ptemp = p[i];
  198. ptemp.y += deps;
  199. double dgrady = (SignedDistance(ptemp)-SignedDistance(p[i])) / deps;
  200. double norm = sqrt(pow(dgradx,2)+pow(dgrady,2));
  201. p[i].x -= dist[i]*dgradx/norm;
  202. p[i].y -= dist[i]*dgrady/norm;
  203. dist[i] = SignedDistance(p[i]);
  204. tmp = fabs(dist[i]);
  205. mm=mm+1;
  206. }
  207. }
  208. }
  209. // check to retriangulate
  210. double bigmove = 0.0;
  211. for (int i=0; i<numpts; i++)
  212. {
  213. double pmove = sqrt(static_cast<double>((p[i].x-pold[i].x)*(p[i].x-pold[i].x)
  214. + (p[i].y-pold[i].y)*(p[i].y-pold[i].y)));
  215. if (pmove > bigmove)
  216. bigmove = pmove;
  217. }
  218. if ((bigmove / h0) > ttol)
  219. retriang = true;
  220. // check to terminate
  221. bigmove = 0.0;
  222. for (int i=0; i<numpts; i++)
  223. if (dist[i] < -geps)
  224. {
  225. double pmove = sqrt(static_cast<double>((deltat*Ftot[i].x *Ftot[i].x)
  226. + (deltat*Ftot[i].y *Ftot[i].y)));
  227. if (pmove > bigmove)
  228. bigmove = pmove;
  229. }
  230. if ((bigmove / h0) < dptol)
  231. terminate = true;
  232. }
  233. delete [] pmid;
  234. delete [] priority;
  235. delete [] bartemp;
  236. delete [] midpt;
  237. delete [] barvec;
  238. delete [] L;
  239. delete [] hbars;
  240. delete [] L0;
  241. delete [] F;
  242. delete [] bars;
  243. delete [] Fvec;
  244. delete [] Ftot;
  245. delete [] dist;
  246. }