PageRenderTime 78ms CodeModel.GetById 39ms RepoModel.GetById 1ms app.codeStats 0ms

/navierStokes3D.cpp

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

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