PageRenderTime 76ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 1ms

/Stokes3D.cpp

https://bitbucket.org/cuneytsert/cfd-with-cuda
C++ | 1751 lines | 1265 code | 315 blank | 171 comment | 278 complexity | 68b7412e7727b9a392fc1c580105e83e MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*****************************************************************
  2. * This code is a part of the CFD-with-CUDA project *
  3. * http://code.google.com/p/cfd-with-cuda *
  4. * *
  5. * Dr. Cuneyt Sert and Mahmut M. Gocmen *
  6. * *
  7. * Department of Mechanical Engineering *
  8. * Middle East Technical University *
  9. * Ankara, Turkey *
  10. * http://www.me.metu.edu.tr/people/cuneyt *
  11. *****************************************************************/
  12. #include <stdio.h>
  13. #include <string>
  14. #include <iostream>
  15. #include <iomanip>
  16. #include <fstream>
  17. #include <ctime>
  18. #include <cmath>
  19. #include <algorithm>
  20. using namespace std;
  21. #ifdef SINGLE
  22. typedef float real;
  23. #else
  24. typedef double real;
  25. #endif
  26. ifstream meshfile;
  27. ifstream problemFile;
  28. ofstream outputFile;
  29. ofstream outputControl;
  30. string problemNameFile, whichProblem;
  31. string problemName = "ProblemName.txt";
  32. string controlFile = "Control_Output.txt";
  33. string inputExtension = ".inp"; // Change this line to specify the extension of input file (with dot).
  34. string outputExtension = ".dat"; // Change this line to specify the extension of output file (with dot).
  35. int name, eType, NE, NN, NGP, NEU, Ndof;
  36. int NCN, NENv, NENp, nonlinearIterMax, solverIterMax; // nonlinearIterMax is not used by the Stokes solver.
  37. double density, viscosity, fx, fy, nonlinearTol, solverTol; // nonlinearTol is not used by the Stokes solver.
  38. int **LtoG, **velNodes, **pressureNodes;
  39. double **coord;
  40. int nBC, nVelNodes, nPressureNodes;
  41. double *BCtype, **BCstrings;
  42. double axyFunc, fxyFunc;
  43. double **GQpoint, *GQweight;
  44. double **Sp, ***DSp, **Sv, ***DSv;
  45. double **detJacob, ****gDSp, ****gDSv;
  46. real **K, *F, *u; // Can be float or double. K is the stiffness matrix in full
  47. // storage used Gauss Elimination solver.
  48. int bigNumber;
  49. int **GtoL, *rowStarts, *rowStartsSmall, *colSmall, *col, **KeKMapSmall, NNZ;
  50. real *val; // Can be float or double
  51. void readInput();
  52. void gaussQuad();
  53. void calcShape();
  54. void calcJacobian();
  55. void calcGlobalSys();
  56. void assemble(int e, double **Ke, double *Fe);
  57. void applyBC();
  58. void solve();
  59. void postProcess();
  60. void gaussElimination(int N, real **K, real *F, real *u, bool& err);
  61. void writeTecplotFile();
  62. void compressedSparseRowStorage();
  63. #ifdef CUSP
  64. extern void CUSPsolver();
  65. #endif
  66. //------------------------------------------------------------------------------
  67. int main()
  68. //------------------------------------------------------------------------------
  69. {
  70. cout << "\n *******************************************************";
  71. cout << "\n * Stokes 3D - Part of CFD with CUDA project *";
  72. cout << "\n * http://code.google.com/p/cfd-with-cuda *";
  73. cout << "\n *******************************************************\n\n";
  74. cout << "The program is started." << endl ;
  75. time_t start, end;
  76. time (&start); // Start measuring execution time.
  77. readInput(); cout << "Input file is read." << endl ;
  78. compressedSparseRowStorage(); cout << "CSR vectors are created." << endl ;
  79. gaussQuad();
  80. calcShape();
  81. calcJacobian();
  82. calcGlobalSys(); cout << "Global system is calculated." << endl ;
  83. applyBC(); cout << "Boundary conditions are applied." << endl ;
  84. solve(); cout << "Global system is solved." << endl ;
  85. //postProcess();
  86. writeTecplotFile(); cout << "A DAT file is created for Tecplot." << endl ;
  87. time (&end); // Stop measuring execution time.
  88. cout << endl << "Elapsed wall clock time is " << difftime (end,start) << " seconds." << endl;
  89. cout << endl << "The program is terminated successfully.\nPress a key to close this window...";
  90. cin.get();
  91. return 0;
  92. } // End of function main()
  93. //------------------------------------------------------------------------------
  94. void readInput()
  95. //------------------------------------------------------------------------------
  96. {
  97. string dummy, dummy2, dummy4, dummy5;
  98. int dummy3, i;
  99. problemFile.open(problemName.c_str(), ios::in); // Read problem name
  100. problemFile >> whichProblem;
  101. problemFile.close();
  102. meshfile.open((whichProblem + inputExtension).c_str(), ios::in);
  103. meshfile.ignore(256, '\n'); // Read and ignore the line
  104. meshfile.ignore(256, '\n'); // Read and ignore the line
  105. meshfile >> dummy >> dummy2 >> eType;
  106. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  107. meshfile >> dummy >> dummy2 >> NE;
  108. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  109. meshfile >> dummy >> dummy2 >> NCN;
  110. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  111. meshfile >> dummy >> dummy2 >> NN;
  112. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  113. meshfile >> dummy >> dummy2 >> NENv;
  114. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  115. meshfile >> dummy >> dummy2 >> NENp;
  116. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  117. meshfile >> dummy >> dummy2 >> NGP;
  118. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  119. meshfile >> dummy >> dummy2 >> nonlinearIterMax;
  120. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  121. meshfile >> dummy >> dummy2 >> nonlinearTol;
  122. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  123. meshfile >> dummy >> dummy2 >> solverIterMax;
  124. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  125. meshfile >> dummy >> dummy2 >> solverTol;
  126. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  127. meshfile >> dummy >> dummy2 >> density;
  128. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  129. meshfile >> dummy >> dummy2 >> viscosity;
  130. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  131. meshfile >> dummy >> dummy2 >> fx;
  132. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  133. meshfile >> dummy >> dummy2 >> fy;
  134. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  135. meshfile.ignore(256, '\n'); // Read and ignore the line
  136. meshfile.ignore(256, '\n'); // Read and ignore the line
  137. NEU = 3*NENv + NENp;
  138. Ndof = 3*NN + NCN;
  139. // Read node coordinates
  140. coord = new double*[NN];
  141. if (eType == 2 || eType == 1) {
  142. for (i = 0; i < NN; i++) {
  143. coord[i] = new double[2];
  144. }
  145. for (i=0; i<NN; i++){
  146. meshfile >> dummy3 >> coord[i][0] >> coord[i][1] ;
  147. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  148. }
  149. } else {
  150. for (i = 0; i < NN; i++) {
  151. coord[i] = new double[3];
  152. }
  153. for (i=0; i<NN; i++){
  154. meshfile >> dummy3 >> coord[i][0] >> coord[i][1] >> coord[i][2] ;
  155. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  156. }
  157. }
  158. meshfile.ignore(256, '\n'); // Read and ignore the line
  159. meshfile.ignore(256, '\n'); // Read and ignore the line
  160. // Read element connectivity, i.e. LtoG
  161. LtoG = new int*[NE];
  162. for (i=0; i<NE; i++) {
  163. LtoG[i] = new int[NENv];
  164. }
  165. for (int e = 0; e<NE; e++){
  166. meshfile >> dummy3;
  167. for (i = 0; i<NENv; i++){
  168. meshfile >> LtoG[e][i];
  169. }
  170. meshfile.ignore(256, '\n'); // Read and ignore the line
  171. }
  172. meshfile.ignore(256, '\n'); // Read and ignore the line
  173. meshfile.ignore(256, '\n'); // Read and ignore the line
  174. // Read number of different BC types and details of each BC
  175. meshfile >> dummy >> dummy2 >> nBC;
  176. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  177. BCtype = new double[nBC];
  178. BCstrings = new double*[nBC];
  179. for (i=0; i<nBC; i++) {
  180. BCstrings[i] = new double[3];
  181. }
  182. for (i = 0; i<nBC-1; i++){
  183. meshfile >> dummy >> BCtype[i] >> dummy2 >> dummy3 >> BCstrings[i][0] >> dummy4 >> BCstrings[i][1] >> dummy5 >> BCstrings[i][2];
  184. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  185. }
  186. meshfile >> dummy >> BCtype[2] >> dummy >> BCstrings[i][0];
  187. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  188. // Read EBC data
  189. meshfile.ignore(256, '\n'); // Read and ignore the line
  190. meshfile >> dummy >> dummy2 >> nVelNodes;
  191. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  192. meshfile >> dummy >> dummy2 >> nPressureNodes;
  193. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  194. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  195. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  196. if (nVelNodes!=0){
  197. velNodes = new int*[nVelNodes];
  198. for (i = 0; i < nVelNodes; i++){
  199. velNodes[i] = new int[2];
  200. }
  201. for (i = 0; i < nVelNodes; i++){
  202. meshfile >> velNodes[i][0] >> velNodes[i][1];
  203. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  204. }
  205. }
  206. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  207. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  208. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  209. if (nVelNodes!=0){
  210. pressureNodes = new int*[nPressureNodes];
  211. for (i = 0; i < nPressureNodes; i++){
  212. pressureNodes[i] = new int[2];
  213. }
  214. for (i = 0; i < nPressureNodes; i++){
  215. meshfile >> pressureNodes[i][0] >> pressureNodes[i][1];
  216. meshfile.ignore(256, '\n'); // Ignore the rest of the line
  217. }
  218. }
  219. meshfile.close();
  220. } // End of function readInput()
  221. //------------------------------------------------------------------------------
  222. void compressedSparseRowStorage()
  223. //------------------------------------------------------------------------------
  224. {
  225. //GtoL creation
  226. int i, j, k, m, x, y, valGtoL, check, temp, *checkCol, noOfColGtoL, *GtoLCounter;
  227. GtoL = new int*[NN]; // stores which elements connected to the node
  228. noOfColGtoL = 8; // for 3D meshes created by our mesh generator max 8 elements connect to one node,
  229. GtoLCounter = new int[NN]; // but for real 3D problems this must be a big enough value!
  230. for (i=0; i<NN; i++) {
  231. GtoL[i] = new int[noOfColGtoL];
  232. }
  233. for(i=0; i<NN; i++) {
  234. for(j=0; j<noOfColGtoL; j++) {
  235. GtoL[i][j] = -1; // for the nodes that didn't connect 4 nodes
  236. }
  237. GtoLCounter[i] = 0;
  238. }
  239. for (i=0; i<NE; i++) {
  240. for(j=0; j<NENv; j++) {
  241. GtoL[LtoG[i][j]][GtoLCounter[LtoG[i][j]]] = i;
  242. GtoLCounter[LtoG[i][j]] += 1;
  243. }
  244. }
  245. delete [] GtoLCounter;
  246. // Su anda gereksiz 0'lar oluþturuluyor. Ýleride düzeltilebilir.
  247. // for(i=0; i<nVelNodes; i++) { // extracting EBC values from GtoL with making them "-1"
  248. // for(j=0; j<noOfColGtoL; j++) {
  249. // GtoL[velNodes[i][0]][j] = -1;
  250. // }
  251. // }
  252. // Finding size of col vector, creation of rowStarts & rowStartsSmall
  253. rowStarts = new int[Ndof+1]; // how many non zeros at rows of [K]
  254. rowStartsSmall = new int[NN]; // rowStarts for a piece of K(only for "u" velocity in another words 1/16 of the K(if NENv==NENp))
  255. checkCol = new int[1000]; // for checking the non zero column overlaps
  256. // stores non-zero column number for rows (must be a large enough value)
  257. rowStarts[0] = 0;
  258. for(i=0; i<NN; i++) {
  259. NNZ = 0;
  260. if(GtoL[i][0] == -1) {
  261. NNZ = 1;
  262. } else {
  263. for(k=0; k<1000; k++) { // prepare checkCol for new row
  264. checkCol[k] = -1;
  265. }
  266. for(j=0; j<noOfColGtoL; j++) {
  267. valGtoL = GtoL[i][j];
  268. if(valGtoL != -1) {
  269. for(x=0; x<NENp; x++) {
  270. check = 1; // for checking if column overlap occurs or not
  271. for(y=0; y<NNZ; y++) {
  272. if(checkCol[y] == (LtoG[valGtoL][x])) { // this column was created
  273. check = 0;
  274. }
  275. }
  276. if (check) {
  277. checkCol[NNZ]=(LtoG[valGtoL][x]); // adding new non zero number to checkCol
  278. NNZ++;
  279. }
  280. }
  281. }
  282. }
  283. }
  284. rowStarts[i+1] = NNZ + rowStarts[i];
  285. }
  286. // Creation of rowStarts from rowStarsSmall
  287. for (i=0; i<=NN; i++) {
  288. rowStartsSmall[i] = rowStarts[i];
  289. }
  290. for (i=1; i<=NN; i++) {
  291. rowStarts[i] = rowStarts[i]*4;
  292. }
  293. for (i=1; i<=NN*3; i++) {
  294. rowStarts[NN+i] = rowStarts[NN] + rowStarts[i];
  295. }
  296. delete [] checkCol;
  297. // col & colSmall creation
  298. col = new int[rowStarts[Ndof]]; // stores which non zero columns at which row data
  299. colSmall = new int[rowStarts[NN]/4]; // col for a piece of K(only for "u" velocity in another words 1/16 of the K(if NENv==NENp))
  300. for(i=0; i<NN; i++) {
  301. NNZ = 0;
  302. if(GtoL[i][0] == -1) {
  303. colSmall[rowStartsSmall[i]] = i;
  304. } else {
  305. for(j=0; j<noOfColGtoL; j++) {
  306. valGtoL = GtoL[i][j];
  307. if(valGtoL != -1) {
  308. for(x=0; x<NENp; x++) {
  309. check = 1;
  310. for(y=0; y<NNZ; y++) {
  311. if(colSmall[rowStartsSmall[i]+y] == (LtoG[valGtoL][x])) { // for checking if column overlap occurs or not
  312. check = 0;
  313. }
  314. }
  315. if (check) {
  316. colSmall[rowStartsSmall[i]+NNZ] = (LtoG[valGtoL][x]);
  317. NNZ++;
  318. }
  319. }
  320. }
  321. }
  322. for(k=1; k<NNZ; k++) { // sorting the column vector values
  323. for(m=1; m<NNZ; m++) { // for each row from smaller to bigger
  324. if(colSmall[rowStartsSmall[i]+m] < colSmall[rowStartsSmall[i]+m-1]) {
  325. temp = colSmall[rowStartsSmall[i]+m];
  326. colSmall[rowStartsSmall[i]+m] = colSmall[rowStartsSmall[i]+m-1];
  327. colSmall[rowStartsSmall[i]+m-1] = temp;
  328. }
  329. }
  330. }
  331. }
  332. }
  333. // creation of col from colSmall
  334. m=0;
  335. for (i=0; i<NN; i++) {
  336. for (k=0; k<(4*NN); k=k+NN) {
  337. for (j=rowStartsSmall[i]; j<rowStartsSmall[i+1]; j++) {
  338. col[m]= colSmall[j] + k;
  339. m++;
  340. }
  341. }
  342. }
  343. for (i=0; i<rowStarts[NN]*3; i++) {
  344. col[i+rowStarts[NN]]=col[i];
  345. }
  346. ////----------------------CONTROL---------------------------------------
  347. //cout<<endl;
  348. //for (i=0; i<5; i++) {
  349. // for (j=rowStartsSmall[i]; j<rowStartsSmall[i+1]; j++) {
  350. // cout<< colSmall[j] << " " ;
  351. // }
  352. // cout<<endl;
  353. //}
  354. //cout<<endl;
  355. //cout<<endl;
  356. //for (i=0; i<5; i++) {
  357. // for (j=rowStarts[i]; j<rowStarts[i+1]; j++) {
  358. // cout<< col[j] << " " ;
  359. // }
  360. // cout<<endl;
  361. //}
  362. ////----------------------CONTROL---------------------------------------
  363. NNZ = rowStarts[Ndof];
  364. val = new real[NNZ];
  365. for(i=0; i<rowStarts[Ndof]; i++) {
  366. val[i] = 0;
  367. }
  368. for (i = 0; i<NN; i++) { //deleting the unnecessary arrays for future
  369. delete GtoL[i];
  370. }
  371. delete [] GtoL;
  372. } // End of function compressedSparseRowStorage()
  373. //------------------------------------------------------------------------------
  374. void gaussQuad()
  375. //------------------------------------------------------------------------------
  376. {
  377. // Generates the NGP-point Gauss quadrature points and weights.
  378. GQpoint = new double*[NGP];
  379. for (int i=0; i<NGP; i++) {
  380. GQpoint[i] = new double[3];
  381. }
  382. GQweight = new double[NGP];
  383. if (eType == 3) { // 3D Hexahedron element
  384. GQpoint[0][0] = -sqrt(1.0/3); GQpoint[0][1] = -sqrt(1.0/3); GQpoint[0][2] = -sqrt(1.0/3);
  385. GQpoint[1][0] = sqrt(1.0/3); GQpoint[1][1] = -sqrt(1.0/3); GQpoint[1][2] = -sqrt(1.0/3);
  386. GQpoint[2][0] = sqrt(1.0/3); GQpoint[2][1] = sqrt(1.0/3); GQpoint[2][2] = -sqrt(1.0/3);
  387. GQpoint[3][0] = -sqrt(1.0/3); GQpoint[3][1] = sqrt(1.0/3); GQpoint[3][2] = -sqrt(1.0/3);
  388. GQpoint[4][0] = -sqrt(1.0/3); GQpoint[4][1] = -sqrt(1.0/3); GQpoint[4][2] = sqrt(1.0/3);
  389. GQpoint[5][0] = sqrt(1.0/3); GQpoint[5][1] = -sqrt(1.0/3); GQpoint[5][2] = sqrt(1.0/3);
  390. GQpoint[6][0] = sqrt(1.0/3); GQpoint[6][1] = sqrt(1.0/3); GQpoint[6][2] = sqrt(1.0/3);
  391. GQpoint[7][0] = -sqrt(1.0/3); GQpoint[7][1] = sqrt(1.0/3); GQpoint[7][2] = sqrt(1.0/3);
  392. GQweight[0] = 1.0;
  393. GQweight[1] = 1.0;
  394. GQweight[2] = 1.0;
  395. GQweight[3] = 1.0;
  396. GQweight[4] = 1.0;
  397. GQweight[5] = 1.0;
  398. GQweight[6] = 1.0;
  399. GQweight[7] = 1.0;
  400. }
  401. else if (eType == 1) { // Quadrilateral element 3 ile 4 ün yeri deðiþmeyecek mi sor!
  402. if (NGP == 1) { // One-point quadrature
  403. GQpoint[0][0] = 0.0; GQpoint[0][1] = 0.0;
  404. GQweight[0] = 4.0;
  405. } else if (NGP == 4) { // Four-point quadrature
  406. GQpoint[0][0] = -sqrt(1.0/3); GQpoint[0][1] = -sqrt(1.0/3);
  407. GQpoint[1][0] = sqrt(1.0/3); GQpoint[1][1] = -sqrt(1.0/3);
  408. GQpoint[2][0] = -sqrt(1.0/3); GQpoint[2][1] = sqrt(1.0/3);
  409. GQpoint[3][0] = sqrt(1.0/3); GQpoint[3][1] = sqrt(1.0/3);
  410. GQweight[0] = 1.0;
  411. GQweight[1] = 1.0;
  412. GQweight[2] = 1.0;
  413. GQweight[3] = 1.0;
  414. } else if (NGP == 9) { // Nine-point quadrature
  415. GQpoint[0][0] = -sqrt(3.0/5); GQpoint[0][1] = -sqrt(3.0/5);
  416. GQpoint[1][0] = 0.0; GQpoint[1][1] = -sqrt(3.0/5);
  417. GQpoint[2][0] = sqrt(3.0/5); GQpoint[2][1] = -sqrt(3.0/5);
  418. GQpoint[3][0] = -sqrt(3.0/5); GQpoint[3][1] = 0.0;
  419. GQpoint[4][0] = 0.0; GQpoint[4][1] = 0.0;
  420. GQpoint[5][0] = sqrt(3.0/5); GQpoint[5][1] = 0.0;
  421. GQpoint[6][0] = -sqrt(3.0/5); GQpoint[6][1] = sqrt(3.0/5);
  422. GQpoint[7][0] = 0.0; GQpoint[7][1] = sqrt(3.0/5);
  423. GQpoint[8][0] = sqrt(3.0/5); GQpoint[8][1] = sqrt(3.0/5);
  424. GQweight[0] = 5.0/9 * 5.0/9;
  425. GQweight[1] = 8.0/9 * 5.0/9;
  426. GQweight[2] = 5.0/9 * 5.0/9;
  427. GQweight[3] = 5.0/9 * 8.0/9;
  428. GQweight[4] = 8.0/9 * 8.0/9;
  429. GQweight[5] = 5.0/9 * 8.0/9;
  430. GQweight[6] = 5.0/9 * 5.0/9;
  431. GQweight[7] = 8.0/9 * 5.0/9;
  432. GQweight[8] = 5.0/9 * 5.0/9;
  433. } else if (NGP == 16) { // Sixteen-point quadrature
  434. GQpoint[0][0] = -0.8611363116; GQpoint[0][1] = -0.8611363116;
  435. GQpoint[1][0] = -0.3399810435; GQpoint[1][1] = -0.8611363116;
  436. GQpoint[2][0] = 0.3399810435; GQpoint[2][1] = -0.8611363116;
  437. GQpoint[3][0] = 0.8611363116; GQpoint[3][1] = -0.8611363116;
  438. GQpoint[4][0] = -0.8611363116; GQpoint[4][1] = -0.3399810435;
  439. GQpoint[5][0] = -0.3399810435; GQpoint[5][1] = -0.3399810435;
  440. GQpoint[6][0] = 0.3399810435; GQpoint[6][1] = -0.3399810435;
  441. GQpoint[7][0] = 0.8611363116; GQpoint[7][1] = -0.3399810435;
  442. GQpoint[8][0] = -0.8611363116; GQpoint[8][1] = 0.3399810435;
  443. GQpoint[9][0] = -0.3399810435; GQpoint[9][1] = 0.3399810435;
  444. GQpoint[10][0]= 0.3399810435; GQpoint[10][1]= 0.3399810435;
  445. GQpoint[11][0]= 0.8611363116; GQpoint[11][1]= 0.3399810435;
  446. GQpoint[12][0]= -0.8611363116; GQpoint[12][1]= 0.8611363116;
  447. GQpoint[13][0]= -0.3399810435; GQpoint[13][1]= 0.8611363116;
  448. GQpoint[14][0]= 0.3399810435; GQpoint[14][1]= 0.8611363116;
  449. GQpoint[15][0]= 0.8611363116; GQpoint[15][1]= 0.8611363116;
  450. GQweight[0] = 0.3478548451 * 0.3478548451;
  451. GQweight[1] = 0.3478548451 * 0.6521451548;
  452. GQweight[2] = 0.3478548451 * 0.6521451548;
  453. GQweight[3] = 0.3478548451 * 0.3478548451;
  454. GQweight[4] = 0.6521451548 * 0.3478548451;
  455. GQweight[5] = 0.6521451548 * 0.6521451548;
  456. GQweight[6] = 0.6521451548 * 0.6521451548;
  457. GQweight[7] = 0.6521451548 * 0.3478548451;
  458. GQweight[8] = 0.6521451548 * 0.3478548451;
  459. GQweight[9] = 0.6521451548 * 0.6521451548;
  460. GQweight[10] = 0.6521451548 * 0.6521451548;
  461. GQweight[11] = 0.6521451548 * 0.3478548451;
  462. GQweight[12] = 0.3478548451 * 0.3478548451;
  463. GQweight[13] = 0.3478548451 * 0.6521451548;
  464. GQweight[14] = 0.3478548451 * 0.6521451548;
  465. GQweight[15] = 0.3478548451 * 0.3478548451;
  466. }
  467. } else if (eType == 2) { // Triangular element
  468. if (NGP == 1) { // One-point quadrature
  469. GQpoint[0][0] = 1.0/3; GQpoint[0][1] = 1.0/3;
  470. GQweight[0] = 0.5;
  471. } else if (NGP == 3) { // Two-point quadrature
  472. GQpoint[0][0] = 0.5; GQpoint[0][1] = 0.0;
  473. GQpoint[1][0] = 0.0; GQpoint[1][1] = 0.5;
  474. GQpoint[2][0] = 0.5; GQpoint[2][1] = 0.5;
  475. GQweight[0] = 1.0/6;
  476. GQweight[1] = 1.0/6;
  477. GQweight[2] = 1.0/6;
  478. } else if (NGP == 4) { // Four-point quadrature
  479. GQpoint[0][0] = 1.0/3; GQpoint[0][1] = 1.0/3;
  480. GQpoint[1][0] = 0.6; GQpoint[1][1] = 0.2;
  481. GQpoint[2][0] = 0.2; GQpoint[2][1] = 0.6;
  482. GQpoint[3][0] = 0.2; GQpoint[3][1] = 0.2;
  483. GQweight[0] = -27.0/96;
  484. GQweight[1] = 25.0/96;
  485. GQweight[2] = 25.0/96;
  486. GQweight[3] = 25.0/96;
  487. } else if (NGP == 7) { // Seven-point quadrature
  488. GQpoint[0][0] = 1.0/3; GQpoint[0][1] = 1.0/3;
  489. GQpoint[1][0] = 0.059715871789770; GQpoint[1][1] = 0.470142064105115;
  490. GQpoint[2][0] = 0.470142064105115; GQpoint[2][1] = 0.059715871789770;
  491. GQpoint[3][0] = 0.470142064105115; GQpoint[3][1] = 0.470142064105115;
  492. GQpoint[4][0] = 0.101286507323456; GQpoint[4][1] = 0.797426985353087;
  493. GQpoint[5][0] = 0.101286507323456; GQpoint[5][1] = 0.101286507323456;
  494. GQpoint[6][0] = 0.797426985353087; GQpoint[6][1] = 0.101286507323456;
  495. GQweight[0] = 0.225 / 2;
  496. GQweight[1] = 0.132394152788 / 2;
  497. GQweight[2] = 0.132394152788 / 2;
  498. GQweight[3] = 0.132394152788 / 2;
  499. GQweight[4] = 0.125939180544 / 2;
  500. GQweight[5] = 0.125939180544 / 2;
  501. GQweight[6] = 0.125939180544 / 2;
  502. }
  503. }
  504. } // End of function gaussQuad()
  505. //------------------------------------------------------------------------------
  506. void calcShape()
  507. //------------------------------------------------------------------------------
  508. {
  509. // Calculates the values of the shape functions and their derivatives with
  510. // respect to ksi and eta at GQ points.
  511. double ksi, eta, zeta;
  512. if (eType == 3) { // 3D Hexahedron Element
  513. if (NENp == 8) {
  514. Sp = new double*[8];
  515. for (int i=0; i<NGP; i++) {
  516. Sp[i] = new double[NGP];
  517. }
  518. DSp = new double **[3];
  519. for (int i=0; i<3; i++) {
  520. DSp[i] = new double *[8];
  521. for (int j=0; j<8; j++) {
  522. DSp[i][j] = new double[NGP];
  523. }
  524. }
  525. for (int k = 0; k<NGP; k++) {
  526. ksi = GQpoint[k][0];
  527. eta = GQpoint[k][1];
  528. zeta = GQpoint[k][2];
  529. Sp[0][k] = 0.25*(1-ksi)*(1-eta)*(1-zeta);
  530. Sp[1][k] = 0.25*(1+ksi)*(1-eta)*(1-zeta);
  531. Sp[2][k] = 0.25*(1+ksi)*(1+eta)*(1-zeta);
  532. Sp[3][k] = 0.25*(1-ksi)*(1+eta)*(1-zeta);
  533. Sp[4][k] = 0.25*(1-ksi)*(1-eta)*(1+zeta);
  534. Sp[5][k] = 0.25*(1+ksi)*(1-eta)*(1+zeta);
  535. Sp[6][k] = 0.25*(1+ksi)*(1+eta)*(1+zeta);
  536. Sp[7][k] = 0.25*(1-ksi)*(1+eta)*(1+zeta);
  537. DSp[0][0][k] = -0.25*(1-eta)*(1-zeta); // ksi derivative of the 1st shape funct. at k-th GQ point.
  538. DSp[1][0][k] = -0.25*(1-ksi)*(1-zeta); // eta derivative of the 1st shape funct. at k-th GQ point.
  539. DSp[2][0][k] = -0.25*(1-ksi)*(1-eta); // zeta derivative of the 1st shape funct. at k-th GQ point.
  540. DSp[0][1][k] = 0.25*(1-eta)*(1-zeta);
  541. DSp[1][1][k] = -0.25*(1+ksi)*(1-zeta);
  542. DSp[2][1][k] = -0.25*(1+ksi)*(1-eta);
  543. DSp[0][2][k] = 0.25*(1+eta)*(1-zeta);
  544. DSp[1][2][k] = 0.25*(1+ksi)*(1-zeta);
  545. DSp[2][2][k] = -0.25*(1+ksi)*(1+eta);
  546. DSp[0][3][k] = -0.25*(1+eta)*(1-zeta);
  547. DSp[1][3][k] = 0.25*(1-ksi)*(1-zeta);
  548. DSp[2][3][k] = -0.25*(1-ksi)*(1+eta);
  549. DSp[0][4][k] = -0.25*(1-eta)*(1+zeta); // ksi derivative of the 1st shape funct. at k-th GQ point.
  550. DSp[1][4][k] = -0.25*(1-ksi)*(1+zeta); // eta derivative of the 1st shape funct. at k-th GQ point.
  551. DSp[2][4][k] = 0.25*(1-ksi)*(1-eta); // zeta derivative of the 1st shape funct. at k-th GQ point.
  552. DSp[0][5][k] = 0.25*(1-eta)*(1+zeta);
  553. DSp[1][5][k] = -0.25*(1+ksi)*(1+zeta);
  554. DSp[2][5][k] = 0.25*(1+ksi)*(1-eta);
  555. DSp[0][6][k] = 0.25*(1+eta)*(1+zeta);
  556. DSp[1][6][k] = 0.25*(1+ksi)*(1+zeta);
  557. DSp[2][6][k] = 0.25*(1+ksi)*(1+eta);
  558. DSp[0][7][k] = -0.25*(1+eta)*(1+zeta);
  559. DSp[1][7][k] = 0.25*(1-ksi)*(1+zeta);
  560. DSp[2][7][k] = 0.25*(1-ksi)*(1+eta);
  561. }
  562. }
  563. if (NENv == 8) {
  564. Sv = new double*[8];
  565. for (int i=0; i<NGP; i++) {
  566. Sv[i] = new double[NGP];
  567. }
  568. DSv = new double **[3];
  569. for (int i=0; i<3; i++) {
  570. DSv[i] = new double *[8];
  571. for (int j=0; j<8; j++) {
  572. DSv[i][j] = new double[NGP];
  573. }
  574. }
  575. for (int i=0; i<NGP; i++) {
  576. Sv[i] = Sp[i];
  577. }
  578. for (int i=0; i<3; i++) {
  579. for (int j=0; j<8; j++) {
  580. DSv[i][j] = DSp[i][j];
  581. }
  582. }
  583. }
  584. }
  585. for (int i = 0; i<8; i++) { //deleting the unnecessary arrays for future
  586. delete GQpoint[i];
  587. }
  588. delete [] GQpoint;
  589. } // End of function calcShape()
  590. //------------------------------------------------------------------------------
  591. void calcJacobian()
  592. //------------------------------------------------------------------------------
  593. {
  594. // Calculates the Jacobian matrix, its inverse and determinant for all
  595. // elements at all GQ points. Also evaluates and stores derivatives of shape
  596. // functions wrt global coordinates x and y.
  597. int e, i, j, k, x, iG;
  598. double **e_coord;
  599. double **Jacob, **invJacob;
  600. double temp;
  601. if (eType == 3) {
  602. e_coord = new double*[NENp];
  603. for (i=0; i<NENp; i++) {
  604. e_coord[i] = new double[3];
  605. }
  606. Jacob = new double*[3];
  607. invJacob = new double*[3];
  608. for (i=0; i<3; i++) {
  609. Jacob[i] = new double[3];
  610. invJacob[i] = new double[3];
  611. }
  612. detJacob = new double*[NE];
  613. for (i=0; i<NE; i++) {
  614. detJacob[i] = new double[NGP];
  615. }
  616. gDSp = new double***[NE];
  617. for (i=0; i<NE; i++) {
  618. gDSp[i] = new double**[3];
  619. for(j=0; j<3; j++) {
  620. gDSp[i][j] = new double*[NENv];
  621. for(k=0; k<NENp; k++) {
  622. gDSp[i][j][k] = new double[NGP];
  623. }
  624. }
  625. }
  626. gDSv = new double***[NE];
  627. for (i=0; i<NE; i++) {
  628. gDSv[i] = new double**[3];
  629. for(j=0; j<3; j++) {
  630. gDSv[i][j] = new double*[NENv];
  631. for(k=0; k<NENv; k++) {
  632. gDSv[i][j][k] = new double[NGP];
  633. }
  634. }
  635. }
  636. for (e = 0; e<NE; e++){
  637. // To calculate Jacobian matrix of an element we need e_coord matrix of
  638. // size NEN*2. Each row of it stores x, y & z coordinates of the nodes of
  639. // an element.
  640. for (i = 0; i<NENp; i++){
  641. iG = LtoG[e][i];
  642. e_coord[i][0] = coord[iG][0];
  643. e_coord[i][1] = coord[iG][1];
  644. e_coord[i][2] = coord[iG][2];
  645. }
  646. // For each GQ point calculate 3*3 Jacobian matrix, its inverse and its
  647. // determinant. Also calculate derivatives of shape functions wrt global
  648. // coordinates x and y & z. These are the derivatives that we'll use in
  649. // evaluating K and F integrals.
  650. for (k = 0; k<NGP; k++) {
  651. for (i = 0; i<3; i++) {
  652. for (j = 0; j<3; j++) {
  653. temp = 0;
  654. for (x = 0; x<NENp; x++) {
  655. temp = DSp[i][x][k] * e_coord[x][j]+temp;
  656. }
  657. Jacob[i][j] = temp;
  658. }
  659. }
  660. invJacob[0][0] = Jacob[1][1]*Jacob[2][2]-Jacob[2][1]*Jacob[1][2];
  661. invJacob[0][1] = -(Jacob[0][1]*Jacob[2][2]-Jacob[0][2]*Jacob[2][1]);
  662. invJacob[0][2] = Jacob[0][1]*Jacob[1][2]-Jacob[1][1]*Jacob[0][2];
  663. invJacob[1][0] = -(Jacob[1][0]*Jacob[2][2]-Jacob[1][2]*Jacob[2][0]);
  664. invJacob[1][1] = Jacob[2][2]*Jacob[0][0]-Jacob[2][0]*Jacob[0][2];
  665. invJacob[1][2] = -(Jacob[1][2]*Jacob[0][0]-Jacob[1][0]*Jacob[0][2]);
  666. invJacob[2][0] = Jacob[1][0]*Jacob[2][1]-Jacob[2][0]*Jacob[1][1];
  667. invJacob[2][1] = -(Jacob[2][1]*Jacob[0][0]-Jacob[2][0]*Jacob[0][1]);
  668. invJacob[2][2] = Jacob[1][1]*Jacob[0][0]-Jacob[1][0]*Jacob[0][1];
  669. detJacob[e][k] = Jacob[0][0]*(Jacob[1][1]*Jacob[2][2]-Jacob[2][1]*Jacob[1][2]) +
  670. Jacob[0][1]*(Jacob[1][2]*Jacob[2][0]-Jacob[1][0]*Jacob[2][2]) +
  671. Jacob[0][2]*(Jacob[1][0]*Jacob[2][1]-Jacob[1][1]*Jacob[2][0]);
  672. for (i = 0; i<3; i++){
  673. for (j = 0; j<3; j++){
  674. invJacob[i][j] = invJacob[i][j]/detJacob[e][k];
  675. }
  676. }
  677. for (i = 0; i<3; i++){
  678. for (j = 0; j<8; j++){
  679. temp = 0;
  680. for (x = 0; x<3; x++){
  681. temp = invJacob[i][x] * DSp[x][j][k]+temp;
  682. }
  683. gDSp[e][i][j][k] = temp;
  684. gDSv[e][i][j][k] = gDSp[e][i][j][k];
  685. }
  686. }
  687. }
  688. }
  689. }
  690. } // End of function calcJacobian()
  691. //------------------------------------------------------------------------------
  692. void calcGlobalSys()
  693. //------------------------------------------------------------------------------
  694. {
  695. // Calculates Ke and Fe one by one for each element and assembles them into
  696. // the global K and F.
  697. int e, i, j, k, m, n;
  698. double Tau;
  699. // double x, y, axy, fxy;
  700. double *Fe, **Ke;
  701. double *Fe_1, *Fe_2, *Fe_3, *Fe_4;
  702. double **Ke_11, **Ke_12, **Ke_13, **Ke_14, **Ke_22, **Ke_23, **Ke_24, **Ke_33, **Ke_34, **Ke_44;
  703. double **Ke_11_add, **Ke_12_add, **Ke_13_add, **Ke_14_add, **Ke_22_add, **Ke_23_add, **Ke_24_add, **Ke_33_add, **Ke_34_add, **Ke_44_add;
  704. // Initialize the arrays
  705. F = new real[Ndof];
  706. K = new real*[Ndof];
  707. for (i=0; i<Ndof; i++) {
  708. K[i] = new real[Ndof];
  709. }
  710. for (i=0; i<Ndof; i++) {
  711. F[i] = 0;
  712. for (j=0; j<Ndof; j++) {
  713. K[i][j] = 0;
  714. }
  715. }
  716. Fe = new double[NEU];
  717. Ke = new double*[NEU];
  718. for (i=0; i<NEU; i++) {
  719. Ke[i] = new double[NEU];
  720. }
  721. Fe_1 = new double[NENv];
  722. Fe_2 = new double[NENv];
  723. Fe_3 = new double[NENv];
  724. Fe_4 = new double[NENp];
  725. Ke_11 = new double*[NENv];
  726. Ke_12 = new double*[NENv];
  727. Ke_13 = new double*[NENv];
  728. Ke_14 = new double*[NENv];
  729. // Ke_21 is the transpose of Ke_12
  730. Ke_22 = new double*[NENv];
  731. Ke_23 = new double*[NENv];
  732. Ke_24 = new double*[NENv];
  733. // Ke_31 is the transpose of Ke_13
  734. // Ke_32 is the transpose of Ke_23
  735. Ke_33 = new double*[NENv];
  736. Ke_34 = new double*[NENv];
  737. // Ke_41 is the transpose of Ke_14
  738. // Ke_42 is the transpose of Ke_24
  739. // Ke_43 is the transpose of Ke_34
  740. Ke_44 = new double*[NENp];
  741. Ke_11_add = new double*[NENv];
  742. Ke_12_add = new double*[NENv];
  743. Ke_13_add = new double*[NENv];
  744. Ke_14_add = new double*[NENv];
  745. Ke_22_add = new double*[NENv];
  746. Ke_23_add = new double*[NENv];
  747. Ke_24_add = new double*[NENv];
  748. Ke_33_add = new double*[NENv];
  749. Ke_34_add = new double*[NENv];
  750. Ke_44_add = new double*[NENp];
  751. for (i=0; i<NENv; i++) {
  752. Ke_11[i] = new double[NENv];
  753. Ke_12[i] = new double[NENv];
  754. Ke_13[i] = new double[NENv];
  755. Ke_14[i] = new double[NENp];
  756. Ke_22[i] = new double[NENv];
  757. Ke_23[i] = new double[NENv];
  758. Ke_24[i] = new double[NENp];
  759. Ke_33[i] = new double[NENv];
  760. Ke_34[i] = new double[NENp];
  761. Ke_11_add[i] = new double[NENv];
  762. Ke_12_add[i] = new double[NENv];
  763. Ke_13_add[i] = new double[NENv];
  764. Ke_14_add[i] = new double[NENp];
  765. Ke_22_add[i] = new double[NENv];
  766. Ke_23_add[i] = new double[NENv];
  767. Ke_24_add[i] = new double[NENp];
  768. Ke_33_add[i] = new double[NENv];
  769. Ke_34_add[i] = new double[NENp];
  770. }
  771. for (i=0; i<NENp; i++) {
  772. Ke_44[i] = new double[NENp];
  773. Ke_44_add[i] = new double[NENp];
  774. }
  775. // Calculating the elemental stiffness matrix(Ke) and force vector(Fe)
  776. for (e = 0; e<NE; e++) {
  777. // Intitialize Ke and Fe to zero.
  778. for (i=0; i<NEU; i++) {
  779. Fe[i] = 0;
  780. for (j=0; j<NEU; j++) {
  781. Ke[i][j] = 0;
  782. }
  783. }
  784. for (i=0; i<NENv; i++) {
  785. Fe_1[i] = 0;
  786. Fe_2[i] = 0;
  787. Fe_3[i] = 0;
  788. Fe_4[i] = 0;
  789. for (j=0; j<NENv; j++) {
  790. Ke_11[i][j] = 0;
  791. Ke_12[i][j] = 0;
  792. Ke_13[i][j] = 0;
  793. Ke_22[i][j] = 0;
  794. Ke_23[i][j] = 0;
  795. Ke_33[i][j] = 0;
  796. }
  797. for (j=0; j<NENp; j++) {
  798. Ke_14[i][j] = 0;
  799. Ke_24[i][j] = 0;
  800. Ke_34[i][j] = 0;
  801. }
  802. }
  803. for (i=0; i<NENp; i++) {
  804. for (j=0; j<NENp; j++) {
  805. Ke_44[i][j] = 0;
  806. }
  807. }
  808. for (k = 0; k<NGP; k++) { // Gauss quadrature loop
  809. for (i=0; i<NENv; i++) {
  810. for (j=0; j<NENv; j++) {
  811. Ke_11_add[i][j] = 0;
  812. Ke_12_add[i][j] = 0;
  813. Ke_13_add[i][j] = 0;
  814. Ke_22_add[i][j] = 0;
  815. Ke_23_add[i][j] = 0;
  816. Ke_33_add[i][j] = 0;
  817. }
  818. for (j=0; j<NENp; j++) {
  819. Ke_14_add[i][j] = 0;
  820. Ke_24_add[i][j] = 0;
  821. Ke_34_add[i][j] = 0;
  822. }
  823. }
  824. for (i=0; i<NENp; i++) {
  825. for (j=0; j<NENp; j++) {
  826. Ke_44_add[i][j] = 0;
  827. }
  828. }
  829. for (i=0; i<NENv; i++) {
  830. for (j=0; j<NENv; j++) {
  831. Ke_11_add[i][j] = Ke_11_add[i][j] + viscosity * (
  832. 2 * gDSv[e][0][i][k] * gDSv[e][0][j][k] +
  833. gDSv[e][1][i][k] * gDSv[e][1][j][k] +
  834. gDSv[e][2][i][k] * gDSv[e][2][j][k]) ;
  835. //density * Sv[i][k];
  836. Ke_12_add[i][j] = Ke_12_add[i][j] + viscosity * gDSv[e][1][i][k] * gDSv[e][0][j][k];
  837. Ke_13_add[i][j] = Ke_13_add[i][j] + viscosity * gDSv[e][2][i][k] * gDSv[e][0][j][k];
  838. Ke_22_add[i][j] = Ke_22_add[i][j] + viscosity * (
  839. gDSv[e][0][i][k] * gDSv[e][0][j][k] +
  840. 2 * gDSv[e][1][i][k] * gDSv[e][1][j][k] +
  841. gDSv[e][2][i][k] * gDSv[e][2][j][k]) ;
  842. // density * Sv[i][k];
  843. Ke_23_add[i][j] = Ke_23_add[i][j] + viscosity * gDSv[e][2][i][k] * gDSv[e][1][j][k];
  844. Ke_33_add[i][j] = Ke_33_add[i][j] + viscosity * (
  845. gDSv[e][0][i][k] * gDSv[e][0][j][k] +
  846. gDSv[e][1][i][k] * gDSv[e][1][j][k] +
  847. 2 * gDSv[e][2][i][k] * gDSv[e][2][j][k]) ;
  848. // density * Sv[i][k];
  849. }
  850. for (j=0; j<NENp; j++) {
  851. Ke_14_add[i][j] = Ke_14_add[i][j] - gDSv[e][0][i][k] * Sp[j][k];
  852. Ke_24_add[i][j] = Ke_24_add[i][j] - gDSv[e][1][i][k] * Sp[j][k];
  853. Ke_34_add[i][j] = Ke_34_add[i][j] - gDSv[e][2][i][k] * Sp[j][k];
  854. }
  855. }
  856. // Apply GLS stabilization for linear elements with NENv = NENp
  857. Tau = ((1.0/12.0)*2) / viscosity; // GLS parameter
  858. for (i=0; i<NENp; i++) {
  859. for (j=0; j<NENp; j++) {
  860. Ke_44_add[i][j] = Ke_44_add[i][j] - Tau * ( gDSv[e][0][i][k] * gDSv[e][0][j][k] + gDSv[e][1][i][k] * gDSv[e][1][j][k] + gDSv[e][2][i][k] * gDSv[e][2][j][k] );
  861. Ke_44_add[i][j] = Ke_44_add[i][j] - Tau * ( gDSv[e][0][i][k] * gDSv[e][0][j][k] + gDSv[e][1][i][k] * gDSv[e][1][j][k] + gDSv[e][2][i][k] * gDSv[e][2][j][k] );
  862. }
  863. }
  864. // Apply GLS stabilization for linear elements with NENv = NENp
  865. for (i=0; i<NENv; i++) {
  866. for (j=0; j<NENv; j++) {
  867. Ke_11[i][j] += Ke_11_add[i][j] * detJacob[e][k] * GQweight[k];
  868. Ke_12[i][j] += Ke_12_add[i][j] * detJacob[e][k] * GQweight[k];
  869. Ke_13[i][j] += Ke_13_add[i][j] * detJacob[e][k] * GQweight[k];
  870. Ke_22[i][j] += Ke_22_add[i][j] * detJacob[e][k] * GQweight[k];
  871. Ke_23[i][j] += Ke_23_add[i][j] * detJacob[e][k] * GQweight[k];
  872. Ke_33[i][j] += Ke_33_add[i][j] * detJacob[e][k] * GQweight[k];
  873. }
  874. for (j=0; j<NENp; j++) {
  875. Ke_14[i][j] += Ke_14_add[i][j] * detJacob[e][k] * GQweight[k];
  876. Ke_24[i][j] += Ke_24_add[i][j] * detJacob[e][k] * GQweight[k];
  877. Ke_34[i][j] += Ke_34_add[i][j] * detJacob[e][k] * GQweight[k];
  878. }
  879. }
  880. for (i=0; i<NENv; i++) {
  881. for (j=0; j<NENv; j++) {
  882. Ke_44[i][j] += Ke_44_add[i][j] * detJacob[e][k] * GQweight[k];
  883. }
  884. }
  885. } // End GQ loop
  886. // Assembly of Fe
  887. i=0;
  888. for (j=0; j<NENv; j++) {
  889. Fe[i]=Fe_1[j];
  890. i++;
  891. }
  892. for (j=0; j<NENv; j++) {
  893. Fe[i]=Fe_2[j];
  894. i++;
  895. }
  896. for (j=0; j<NENv; j++) {
  897. Fe[i]=Fe_3[j];
  898. i++;
  899. }
  900. for (j=0; j<NENp; j++) {
  901. Fe[i]=Fe_4[j];
  902. i++;
  903. }
  904. // Assembly of Ke
  905. i=0;
  906. j=0;
  907. for (m=0; m<NENv; m++) {
  908. j=0;
  909. for (n=0; n<NENv; n++) {
  910. Ke[i][j] = Ke_11[m][n];
  911. j++;
  912. }
  913. i++;
  914. }
  915. i=i-NENv;
  916. for (m=0; m<NENv; m++) {
  917. j=0;
  918. for (n=0; n<NENv; n++) {
  919. Ke[i][j+NENv] = Ke_12[m][n];
  920. j++;
  921. }
  922. i++;
  923. }
  924. i=i-NENv;
  925. for (m=0; m<NENv; m++) {
  926. j=0;
  927. for (n=0; n<NENv; n++) {
  928. Ke[i][j+2*NENv] = Ke_13[m][n];
  929. j++;
  930. }
  931. i++;
  932. }
  933. i=i-NENv;
  934. for (m=0; m<NENv; m++) {
  935. j=0;
  936. for (n=0; n<NENp; n++) {
  937. Ke[i][j+3*NENv] = Ke_14[m][n];
  938. j++;
  939. }
  940. i++;
  941. }
  942. for (m=0; m<NENv; m++) {
  943. j=0;
  944. for (n=0; n<NENv; n++) {
  945. Ke[i][j] = Ke_12[n][m];
  946. j++;
  947. }
  948. i++;
  949. }
  950. i=i-NENv;
  951. for (m=0; m<NENv; m++) {
  952. j=0;
  953. for (n=0; n<NENv; n++) {
  954. Ke[i][j+NENv] = Ke_22[m][n];
  955. j++;
  956. }
  957. i++;
  958. }
  959. i=i-NENv;
  960. for (m=0; m<NENv; m++) {
  961. j=0;
  962. for (n=0; n<NENv; n++) {
  963. Ke[i][j+2*NENv] = Ke_23[m][n];
  964. j++;
  965. }
  966. i++;
  967. }
  968. i=i-NENv;
  969. for (m=0; m<NENv; m++) {
  970. j=0;
  971. for (n=0; n<NENp; n++) {
  972. Ke[i][j+3*NENv] = Ke_24[m][n];
  973. j++;
  974. }
  975. i++;
  976. }
  977. for (m=0; m<NENv; m++) {
  978. j=0;
  979. for (n=0; n<NENv; n++) {
  980. Ke[i][j] = Ke_13[n][m];
  981. j++;
  982. }
  983. i++;
  984. }
  985. i=i-NENv;
  986. for (m=0; m<NENv; m++) {
  987. j=0;
  988. for (n=0; n<NENv; n++) {
  989. Ke[i][j+NENv] = Ke_23[n][m];
  990. j++;
  991. }
  992. i++;
  993. }
  994. i=i-NENv;
  995. for (m=0; m<NENv; m++) {
  996. j=0;
  997. for (n=0; n<NENv; n++) {
  998. Ke[i][j+2*NENv] = Ke_33[m][n];
  999. j++;
  1000. }
  1001. i++;
  1002. }
  1003. i=i-NENv;
  1004. for (m=0; m<NENv; m++) {
  1005. j=0;
  1006. for (n=0; n<NENp; n++) {
  1007. Ke[i][j+3*NENv] = Ke_34[m][n];
  1008. j++;
  1009. }
  1010. i++;
  1011. }
  1012. j=0;
  1013. for (m=0; m<NENv; m++) {
  1014. j=0;
  1015. for (n=0; n<NENp; n++) {
  1016. Ke[i][j] = Ke_14[n][m];
  1017. j++;
  1018. }
  1019. i++;
  1020. }
  1021. i=i-NENv;
  1022. for (m=0; m<NENv; m++) {
  1023. j=0;
  1024. for (n=0; n<NENp; n++) {
  1025. Ke[i][j+NENv] = Ke_24[n][m];
  1026. j++;
  1027. }
  1028. i++;
  1029. }
  1030. i=i-NENv;
  1031. for (m=0; m<NENv; m++) {
  1032. j=0;
  1033. for (n=0; n<NENp; n++) {
  1034. Ke[i][j+2*NENv] = Ke_34[n][m];
  1035. j++;
  1036. }
  1037. i++;
  1038. }
  1039. i=i-NENv;
  1040. for (m=0; m<NENp; m++) {
  1041. j=0;
  1042. for (n=0; n<NENp; n++) {
  1043. Ke[i][j+3*NENv] = Ke_44[m][n];
  1044. j++;
  1045. }
  1046. i++;
  1047. }
  1048. assemble(e, Ke, Fe); // sending Ke & Fe for assembly
  1049. } // End element loop
  1050. } // End of function calcGlobalSys()
  1051. //------------------------------------------------------------------------------
  1052. void assemble(int e, double **Ke, double *Fe)
  1053. //------------------------------------------------------------------------------
  1054. {
  1055. // Inserts Ke and Fe into proper locations of K and F.
  1056. int i, j, m, n, iG, jG;
  1057. // Inserts [Ke] and {Fe} into proper locations of [K] and {F} by the help of LtoG array.
  1058. for (i = 0; i<NEU; i++) {
  1059. iG = LtoG[e][i%NENv] + NN*(i/NENv);
  1060. F[iG] = F[iG] + Fe[i];
  1061. for (j = 0; j<NEU; j++) {
  1062. jG = LtoG[e][j%NENv] + NN*(j/NENv);
  1063. K[iG][jG] = K[iG][jG] + Ke[i][j];
  1064. }
  1065. }
  1066. // Assembly process for compressed sparse storage
  1067. // KeKMapSmall creation
  1068. int shiftRow, shiftCol;
  1069. int *nodeData, p, q, k;
  1070. // int *nodeDataEBC;
  1071. // nodeDataEBC = new int[NENv]; // Elemental node data(LtoG data) (modified with EBC) // BC implementationu sonraya býrak ineff ama bir anda zor
  1072. nodeData = new int[NENv]; // Stores sorted LtoG data
  1073. for(k=0; k<NENv; k++) {
  1074. nodeData[k] = (LtoG[e][k]); //takes node data from LtoG
  1075. }
  1076. // for(i=0; i<NEN; i++) {
  1077. // nodeData[i]=nodeDataEBC[i];
  1078. // if (GtoL[nodeDataEBC[i]][0] == -1) {
  1079. // val[rowStarts[nodeDataEBC[i]]] = 1*bigNumber; // Must be fixed, val[x] = 1 repeating for every element that contains the node!
  1080. // nodeDataEBC[i] = -1;
  1081. // }
  1082. // }
  1083. KeKMapSmall = new int*[NENv]; // NENv X NENv
  1084. for(j=0; j<NENv; j++) { // Stores map data between K elemental and value vector
  1085. KeKMapSmall[j] = new int[NENv];
  1086. }
  1087. for(i=0; i<NENv; i++) {
  1088. for(j=0; j<NENv; j++) {
  1089. q=0;
  1090. for(p=rowStartsSmall[nodeData[i]]; p<rowStartsSmall[nodeData[i]+1]; p++) { // p is the location of the col vector(col[x], p=x)
  1091. if(colSmall[p] == nodeData[j]) { // Selection process of the KeKMapSmall data from the col vector
  1092. KeKMapSmall[i][j] = q;
  1093. break;
  1094. }
  1095. q++;
  1096. }
  1097. }
  1098. }
  1099. // Creating val vector
  1100. for(shiftRow=1; shiftRow<5; shiftRow++) {
  1101. for(shiftCol=1; shiftCol<5; shiftCol++) {
  1102. for(i=0; i<NENv; i++) {
  1103. for(j=0; j<NENv; j++) {
  1104. val[ rowStarts[LtoG[ e ][ i ] + NN * (shiftRow-1)] + ((rowStartsSmall[LtoG[ e ][ i ]+1]-
  1105. rowStartsSmall[LtoG[ e ][ i ]]) * (shiftCol-1)) + KeKMapSmall[i][j]] +=
  1106. Ke[ i + ((shiftRow - 1) * NENv) ][ j + ((shiftCol - 1) * NENv) ] ;
  1107. }
  1108. }
  1109. }
  1110. }
  1111. } // End of function assemble()
  1112. //------------------------------------------------------------------------------
  1113. void applyBC()
  1114. //------------------------------------------------------------------------------
  1115. {
  1116. // For EBCs reduction is not applied. Instead K and F are modified as
  1117. // explained in class, which requires modification of both [K] and {F}.
  1118. // SV values specified for NBCs are added to {F}.
  1119. // Deleting the unnecessary arrays for future
  1120. delete [] GQweight;
  1121. for (int i=0; i<NGP; i++) {
  1122. delete Sp[i];
  1123. }
  1124. delete [] Sp;
  1125. //for (int i=0; i<NGP; i++) {
  1126. // delete Sv[i];
  1127. //}
  1128. //delete [] Sv;
  1129. for (int i=0; i<3; i++) {
  1130. for (int j=0; j<8; j++) {
  1131. delete DSp[i][j];
  1132. }
  1133. }
  1134. for (int i=0; i<3; i++) {
  1135. delete DSp[i];
  1136. }
  1137. delete [] DSp;
  1138. //for (int i=0; i<3; i++) {
  1139. // for (int j=0; j<8; j++) {
  1140. // delete DSv[i][j];
  1141. // }
  1142. //}
  1143. //for (int i=0; i<3; i++) {
  1144. // delete DSv[i];
  1145. //}
  1146. //delete [] DSv;
  1147. for (int i=0; i<NE; i++) {
  1148. delete detJacob[i];
  1149. }
  1150. delete [] detJacob;
  1151. for (int i=0; i<NE; i++) {
  1152. for(int j=0; j<3; j++) {
  1153. for(int k=0; k<NENp; k++) {
  1154. delete gDSp[i][j][k];
  1155. }
  1156. }
  1157. }
  1158. for (int i=0; i<NE; i++) {
  1159. for(int j=0; j<3; j++) {
  1160. delete gDSp[i][j];
  1161. }
  1162. }
  1163. for (int i=0; i<NE; i++) {
  1164. delete gDSp[i];
  1165. }
  1166. delete [] gDSp;
  1167. for (int i=0; i<NE; i++) {
  1168. for(int j=0; j<3; j++) {
  1169. for(int k=0; k<NENv; k++) {
  1170. delete gDSv[i][j][k];
  1171. }
  1172. }
  1173. }
  1174. for (int i=0; i<NE; i++) {
  1175. for(int j=0; j<3; j++) {
  1176. delete gDSv[i][j];
  1177. }
  1178. }
  1179. for (int i=0; i<NE; i++) {
  1180. delete gDSv[i];
  1181. }
  1182. delete [] gDSv;
  1183. int i, j, whichBC, node ;
  1184. double x, y, z;
  1185. bigNumber = 1000; // To make the sparse matrix diagonally dominant
  1186. // Modify [K] and {F} for velocity BCs. [FULL STORAGE]
  1187. for (i = 0; i<nVelNodes; i++) {
  1188. node = velNodes[i][0]; // Node at which this EBC is specified
  1189. x = coord[node][0]; // May be necessary for BCstring evaluation
  1190. y = coord[node][1];
  1191. z = coord[node][2];
  1192. whichBC = velNodes[i][1]-1; // Number of the specified BC
  1193. F[node] = BCstrings[whichBC][0]*bigNumber; // Specified value of the PV
  1194. for (j=0; j<Ndof; j++) {
  1195. K[node][j] = 0.0;
  1196. }
  1197. K[node][node] = 1.0*bigNumber;
  1198. F[node + NN] = BCstrings[whichBC][1]*bigNumber; // Specified value of the PV
  1199. for (j=0; j<Ndof; j++) {
  1200. K[node + NN][j] = 0.0;
  1201. }
  1202. K[node + NN][node + NN] = 1.0*bigNumber;
  1203. F[node + NN*2] = BCstrings[whichBC][2]*bigNumber; // Specified value of the PV
  1204. for (j=0; j<Ndof; j++) {
  1205. K[node + NN*2][j] = 0.0;
  1206. }
  1207. K[node + NN*2][node + NN*2] = 1.0*bigNumber;
  1208. }
  1209. // Modify [K] and {F} for pressure BCs.
  1210. for (i = 0; i<nPressureNodes; i++) {
  1211. node = pressureNodes[i][0]; // Node at which this EBC is specified
  1212. x = coord[node][0]; // May be necessary for BCstring evaluation
  1213. y = coord[node][1];
  1214. z = coord[node][2];
  1215. whichBC = pressureNodes[i][1]-1; // Number of the specified BC
  1216. F[node + NN*3] = BCstrings[whichBC][0]*bigNumber; // Specified value of the PV
  1217. for (j=0; j<Ndof; j++) {
  1218. K[node + NN*3][j] = 0.0;
  1219. }
  1220. K[node + NN*3][node + NN*3] = 1.0*bigNumber;
  1221. }
  1222. // Modify CSR vectors for BCs [CSR STORAGE]
  1223. int p, q;
  1224. // Modify CSR vectors for velocity and wall BCs
  1225. for (i = 0; i<nVelNodes; i++) {
  1226. node = velNodes[i][0]; // Node at which this EBC is specified
  1227. x = coord[node][0];

Large files files are truncated, but you can click here to view the full file