LifeV
FastAssembler.cpp
Go to the documentation of this file.
1 #include <lifev/core/fem/FastAssembler.hpp>
2 #include <chrono>
3 
4 #ifdef EPETRA_HAVE_OMP
5 #include <omp.h>
6 #endif
7 
8 using namespace std::chrono;
9 
10 using namespace std;
11 
12 using namespace LifeV;
13 
14 //=========================================================================
15 // Constructor //
16 FastAssembler::FastAssembler( const meshPtr_Type& mesh, const commPtr_Type& comm, const ReferenceFE* refFE, const qr_Type* qr ) :
17  M_mesh ( mesh ),
18  M_comm ( comm ),
19  M_referenceFE ( refFE ),
20  M_qr ( qr ),
21  M_useSUPG ( false )
22 {
23 }
24 //=========================================================================
25 // Destructor //
27 {
28  //---------------------
29 
30  delete[] M_detJacobian;
31 
32  //---------------------
33 
34  for( int i = 0 ; i < M_numElements ; i++ )
35  {
36  for ( int j = 0; j < 3; j++ )
37  {
38  delete [] M_invJacobian[i][j];
39  }
40  delete [] M_invJacobian[i];
41  }
42  delete [] M_invJacobian;
43 
44  //---------------------
45 
46  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
47  {
48  delete [] M_phi[i];
49  }
50 
51  delete [] M_phi;
52 
53  //---------------------
54 
55  for( int i = 0 ; i < M_referenceFE->nbDof() ; i++ )
56  {
57  for ( int j = 0; j < M_qr->nbQuadPt(); j++ )
58  {
59  delete [] M_dphi[i][j];
60  }
61  delete [] M_dphi[i];
62  }
63  delete [] M_dphi;
64 
65  //---------------------
66 
67  for( int i = 0 ; i < M_referenceFE->nbDof() ; i++ )
68  {
69  for ( int j = 0; j < M_qr->nbQuadPt(); j++ )
70  {
71  for ( int k = 0; k < 3; k++ )
72  {
73  delete [] M_d2phi[i][j][k];
74  }
75  delete [] M_d2phi[i][j];
76  }
77  delete [] M_d2phi[i];
78  }
79  delete [] M_d2phi;
80 
81  //---------------------
82 
83  for( int i = 0 ; i < M_numElements ; i++ )
84  {
85  delete [] M_elements[i];
86  }
87  delete [] M_elements;
88 
89  //---------------------
90 
91  for( int i = 0 ; i < M_numElements ; i++ )
92  {
93  for ( int j = 0; j < M_referenceFE->nbDof(); j++ )
94  {
95  delete [] M_vals[i][j];
96  }
97  delete [] M_vals[i];
98  }
99  delete [] M_vals;
100 
101  //---------------------
102 
103  for( int i = 0 ; i < M_numElements ; i++ )
104  {
105  delete [] M_rows[i];
106  delete [] M_cols[i];
107  }
108  delete [] M_rows;
109  delete [] M_cols;
110 
111  //---------------------
112  if ( M_useSUPG )
113  {
114  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
115  {
116  for ( int k = 0; k < 3; k++ )
117  {
118  for ( int z = 0; z < 3; z++ )
119  {
120  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
121  {
122  delete [] M_vals_supg[i_elem][k][z][i];
123  }
124  delete [] M_vals_supg[i_elem][k][z];
125  }
126  delete [] M_vals_supg[i_elem][k];
127  }
128  delete [] M_vals_supg[i_elem];
129  }
130  delete [] M_vals_supg;
131 
132  for( int i = 0 ; i < M_numElements ; i++ )
133  {
134  delete [] M_rows_tmp[i];
135  delete [] M_cols_tmp[i];
136  }
137  delete [] M_rows_tmp;
138  delete [] M_cols_tmp;
139 
140 
141  for( int i = 0 ; i < M_numElements ; i++ )
142  {
143  for ( int j = 0; j < 3; j++ )
144  {
145  delete [] M_G[i][j];
146  }
147  delete [] M_G[i];
148  delete [] M_g[i];
149  delete [] M_Tau_M[i];
150  delete [] M_Tau_C[i];
151  }
152  delete [] M_G;
153  delete [] M_g;
154  delete [] M_Tau_M;
155  delete [] M_Tau_C;
156  }
157 
158 
159 }
160 //=========================================================================
161 void
162 FastAssembler::allocateSpace ( const int& numElements, CurrentFE* fe, const fespacePtr_Type& fespace )
163 {
164  M_numElements = numElements;
165 
166  M_numScalarDofs = fespace->dof().numTotalDof();
167 
168  M_detJacobian = new double[ M_numElements ];
169 
170  M_invJacobian = new double** [ M_numElements ];
171 
172  //-------------------------------------------------------------------------------------------------
173 
174  M_invJacobian = new double** [ M_numElements];
175 
176  for ( int i = 0; i < M_numElements; i++ )
177  {
178  M_invJacobian[i] = new double* [ 3 ];
179  for ( int j = 0; j < 3 ; j++ )
180  {
181  M_invJacobian[i][j] = new double [ 3 ];
182  }
183  }
184 
185  for ( int i = 0; i < M_numElements; i++ )
186  {
187  fe->update( M_mesh->element (i), UPDATE_D2PHI );
189  for ( int j = 0; j < 3; j++ )
190  {
191  for ( int k = 0; k < 3; k++ )
192  {
193  M_invJacobian[i][j][k] = fe->tInverseJacobian(j,k,2);
194  }
195  }
196  }
197 
198  //-------------------------------------------------------------------------------------------------
199 
200  M_phi = new double* [ M_referenceFE->nbDof() ];
201  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
202  {
203  M_phi[i] = new double [ M_qr->nbQuadPt() ];
204  }
205 
206  // PHI REF
207  for (UInt q (0); q < M_qr->nbQuadPt(); ++q)
208  {
209  for (UInt j (0); j < M_referenceFE->nbDof(); ++j)
210  {
211  M_phi[j][q] = M_referenceFE->phi (j, M_qr->quadPointCoor (q) );
212  }
213  }
214 
215  //-------------------------------------------------------------------------------------------------
216 
217  M_dphi = new double** [ M_referenceFE->nbDof() ];
218 
219  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
220  {
221  M_dphi[i] = new double* [ M_qr->nbQuadPt() ];
222  for ( int j = 0; j < M_qr->nbQuadPt() ; j++ )
223  {
224  M_dphi[i][j] = new double [ 3 ];
225  }
226  }
227 
228  //DPHI REF
229  for (UInt q (0); q < M_qr->nbQuadPt(); ++q)
230  {
231  for (UInt i (0); i < M_referenceFE->nbDof(); ++i)
232  {
233  for (UInt j (0); j < 3; ++j)
234  {
235  M_dphi[i][q][j] = M_referenceFE->dPhi (i, j, M_qr->quadPointCoor (q) );
236  }
237  }
238  }
239 
240  //-------------------------------------------------------------------------------------------------
241 
242  M_d2phi = new double*** [ M_referenceFE->nbDof() ];
243 
244  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
245  {
246  M_d2phi[i] = new double** [ M_qr->nbQuadPt() ];
247  for ( int j = 0; j < M_qr->nbQuadPt() ; j++ )
248  {
249  M_d2phi[i][j] = new double* [ 3 ];
250  for ( int k = 0; k < 3 ; k++ )
251  {
252  M_d2phi[i][j][k] = new double [ 3 ];
253  }
254  }
255  }
256 
257  //D2PHI REF
258  for (UInt q (0); q < M_qr->nbQuadPt(); ++q)
259  {
260  for (UInt i (0); i < M_referenceFE->nbDof(); ++i)
261  {
262  for (UInt j (0); j < 3; ++j)
263  {
264  for (UInt k (0); k < 3; ++k)
265  {
266  M_d2phi[i][q][j][k] = M_referenceFE->d2Phi (i, j, k, M_qr->quadPointCoor (q) );
267  }
268  }
269  }
270  }
271 
272  //-------------------------------------------------------------------------------------------------
273 
274  M_elements = new double* [ M_numElements ];
275 
276  for ( int i = 0; i < M_numElements; i++ )
277  {
278  M_elements[i] = new double [ M_referenceFE->nbDof() ];
279  }
280 
281  for ( int i = 0; i < M_numElements; i++ )
282  {
283  for ( int j = 0; j < M_referenceFE->nbDof(); j++ )
284  {
285  M_elements[i][j] = fespace->dof().localToGlobalMap (i, j);
286  }
287  }
288 
289  //-------------------------------------------------------------------------------------------------
290 
291  // Allocate space for M_rows, M_cols and M_vals
292 
293  M_vals = new double** [M_numElements];
294 
295  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
296  {
297  M_vals[i_elem] = new double* [ M_referenceFE->nbDof() ];
298  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
299  {
300  M_vals[i_elem][i] = new double [ M_referenceFE->nbDof() ];
301  }
302  }
303 
304  M_rows = new int* [M_numElements];
305 
306  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
307  {
308  M_rows[i_elem] = new int [ M_referenceFE->nbDof() ];
309  }
310 
311  M_cols = new int* [M_numElements];
312 
313  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
314  {
315  M_cols[i_elem] = new int [ M_referenceFE->nbDof() ];
316  }
317 }
318 //=========================================================================
319 void
321 {
322  M_useSUPG = true;
323 
324  M_vals_supg = new double**** [M_numElements];
325 
326  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
327  {
328  M_vals_supg[i_elem] = new double*** [ 3 ];
329  for ( int k = 0; k < 3; k++ )
330  {
331  M_vals_supg[i_elem][k] = new double** [ 3 ];
332  for ( int z = 0; z < 3; z++ )
333  {
334  M_vals_supg[i_elem][k][z] = new double* [ M_referenceFE->nbDof() ];
335  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
336  {
337  M_vals_supg[i_elem][k][z][i] = new double [ M_referenceFE->nbDof() ];
338  for ( int j = 0; j < M_referenceFE->nbDof(); j++ )
339  {
340  M_vals_supg[i_elem][k][z][i][j] = 0.0;
341  }
342  }
343  }
344  }
345  }
346 
347  M_rows_tmp = new int* [M_numElements];
348 
349  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
350  {
351  M_rows_tmp[i_elem] = new int [ M_referenceFE->nbDof() ];
352  }
353 
354  M_cols_tmp = new int* [M_numElements];
355 
356  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
357  {
358  M_cols_tmp[i_elem] = new int [ M_referenceFE->nbDof() ];
359  }
360 
361  //-------------------------------------------------------------------------------------------------
362 
363  M_G = new double** [ M_numElements];
364  M_g = new double* [ M_numElements];
365 
366  for ( int i = 0; i < M_numElements; i++ )
367  {
368  M_G[i] = new double* [ 3 ];
369  M_g[i] = new double [ 3 ];
370  for ( int j = 0; j < 3 ; j++ )
371  {
372  M_G[i][j] = new double [ 3 ];
373  }
374  }
375 
376  //-------------------------------------------------------------------------------------------------
377 
378  M_Tau_M = new double* [ M_numElements];
379  M_Tau_C = new double* [ M_numElements];
380  for ( int i = 0; i < M_numElements; i++ )
381  {
382  M_Tau_M[i] = new double [ M_qr->nbQuadPt() ];
383  M_Tau_C[i] = new double [ M_qr->nbQuadPt() ];
384  }
385 
386  //-------------------------------------------------------------------------------------------------
387 
388  for ( int i = 0; i < M_numElements; i++ )
389  {
390  M_G[i][0][0] = M_invJacobian[i][0][0]*M_invJacobian[i][0][0] + M_invJacobian[i][0][1]*M_invJacobian[i][0][1] + M_invJacobian[i][0][2]*M_invJacobian[i][0][2];
391  M_G[i][0][1] = M_invJacobian[i][0][0]*M_invJacobian[i][1][0] + M_invJacobian[i][0][1]*M_invJacobian[i][1][1] + M_invJacobian[i][0][2]*M_invJacobian[i][1][2];
392  M_G[i][0][2] = M_invJacobian[i][0][0]*M_invJacobian[i][2][0] + M_invJacobian[i][0][1]*M_invJacobian[i][2][1] + M_invJacobian[i][0][2]*M_invJacobian[i][2][2];
393 
394  M_G[i][1][0] = M_invJacobian[i][1][0]*M_invJacobian[i][0][0] + M_invJacobian[i][1][1]*M_invJacobian[i][0][1] + M_invJacobian[i][1][2]*M_invJacobian[i][0][2];
395  M_G[i][1][1] = M_invJacobian[i][1][0]*M_invJacobian[i][1][0] + M_invJacobian[i][1][1]*M_invJacobian[i][1][1] + M_invJacobian[i][1][2]*M_invJacobian[i][1][2];
396  M_G[i][1][2] = M_invJacobian[i][1][0]*M_invJacobian[i][2][0] + M_invJacobian[i][1][1]*M_invJacobian[i][2][1] + M_invJacobian[i][1][2]*M_invJacobian[i][2][2];
397 
398  M_G[i][2][0] = M_invJacobian[i][2][0]*M_invJacobian[i][0][0] + M_invJacobian[i][2][1]*M_invJacobian[i][0][1] + M_invJacobian[i][2][2]*M_invJacobian[i][0][2];
399  M_G[i][2][1] = M_invJacobian[i][2][0]*M_invJacobian[i][1][0] + M_invJacobian[i][2][1]*M_invJacobian[i][1][1] + M_invJacobian[i][2][2]*M_invJacobian[i][1][2];
400  M_G[i][2][2] = M_invJacobian[i][2][0]*M_invJacobian[i][2][0] + M_invJacobian[i][2][1]*M_invJacobian[i][2][1] + M_invJacobian[i][2][2]*M_invJacobian[i][2][2];
401 
402  M_g[i][0] = M_invJacobian[i][0][0] + M_invJacobian[i][0][1] + M_invJacobian[i][0][2];
403  M_g[i][1] = M_invJacobian[i][1][0] + M_invJacobian[i][1][1] + M_invJacobian[i][1][2];
404  M_g[i][2] = M_invJacobian[i][2][0] + M_invJacobian[i][2][1] + M_invJacobian[i][2][2];
405  }
406 
407 }
408 //=========================================================================
409 void
410 FastAssembler::allocateSpace( const int& numElements, CurrentFE* fe, const fespacePtr_Type& fespace, const UInt* meshSub_elements )
411 {
412  M_numElements = numElements;
413 
414  M_numScalarDofs = fespace->dof().numTotalDof();
415 
416  M_detJacobian = new double[ M_numElements ];
417 
418  M_invJacobian = new double** [ M_numElements ];
419 
420  //-------------------------------------------------------------------------------------------------
421 
422  M_invJacobian = new double** [ M_numElements];
423 
424  for ( int i = 0; i < M_numElements; i++ )
425  {
426  M_invJacobian[i] = new double* [ 3 ];
427  for ( int j = 0; j < 3 ; j++ )
428  {
429  M_invJacobian[i][j] = new double [ 3 ];
430  }
431  }
432 
433  for ( int i = 0; i < M_numElements; i++ )
434  {
435  fe->update( M_mesh->element (meshSub_elements[i]), UPDATE_DPHI );
437  for ( int j = 0; j < 3; j++ )
438  {
439  for ( int k = 0; k < 3; k++ )
440  {
441  M_invJacobian[i][j][k] = fe->tInverseJacobian(j,k,0);
442  }
443  }
444  }
445 
446  //-------------------------------------------------------------------------------------------------
447 
448  M_phi = new double* [ M_referenceFE->nbDof() ];
449  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
450  {
451  M_phi[i] = new double [ M_qr->nbQuadPt() ];
452  }
453 
454  // PHI REF
455  for (UInt q (0); q < M_qr->nbQuadPt(); ++q)
456  {
457  for (UInt j (0); j < M_referenceFE->nbDof(); ++j)
458  {
459  M_phi[j][q] = M_referenceFE->phi (j, M_qr->quadPointCoor (q) );
460  }
461  }
462 
463  //-------------------------------------------------------------------------------------------------
464 
465  M_dphi = new double** [ M_referenceFE->nbDof() ];
466 
467  for ( int i = 0; i < M_referenceFE->nbDof(); i++ )
468  {
469  M_dphi[i] = new double* [ M_qr->nbQuadPt() ];
470  for ( int j = 0; j < M_qr->nbQuadPt() ; j++ )
471  {
472  M_dphi[i][j] = new double [ 3 ];
473  }
474  }
475 
476  //DPHI REF
477  for (UInt q (0); q < M_qr->nbQuadPt(); ++q)
478  {
479  for (UInt i (0); i < M_referenceFE->nbDof(); ++i)
480  {
481  for (UInt j (0); j < 3; ++j)
482  {
483  M_dphi[i][q][j] = M_referenceFE->dPhi (i, j, M_qr->quadPointCoor (q) );
484  }
485  }
486  }
487 
488  //-------------------------------------------------------------------------------------------------
489 
490  M_elements = new double* [ M_numElements ];
491 
492  for ( int i = 0; i < M_numElements; i++ )
493  {
494  M_elements[i] = new double [ M_referenceFE->nbDof() ];
495  }
496 
497  for ( int i = 0; i < M_numElements; i++ )
498  {
499  for ( int j = 0; j < M_referenceFE->nbDof(); j++ )
500  {
501  M_elements[i][j] = fespace->dof().localToGlobalMap (meshSub_elements[i], j);
502  }
503  }
504 
505 }
506 
507 //=========================================================================
508 void
510 {
511  int ndof = M_referenceFE->nbDof();
512  int NumQuadPoints = M_qr->nbQuadPt();
513 
514  double w_quad[NumQuadPoints];
515  for ( int q = 0; q < NumQuadPoints ; q++ )
516  {
517  w_quad[q] = M_qr->weight(q);
518  }
519 
520  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
521  {
522  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial;
523  double integral;
524 
525  double dphi_phys[ndof][NumQuadPoints][3];
526 
527  // ELEMENTI
528  #pragma omp for
529  for ( i_el = 0; i_el < M_numElements ; i_el++ )
530  {
531  i_elem = i_el;
532 
533  // DOF
534  for ( i_dof = 0; i_dof < ndof; i_dof++ )
535  {
536  // QUAD
537  for ( q = 0; q < NumQuadPoints ; q++ )
538  {
539  // DIM 1
540  for ( d1 = 0; d1 < 3 ; d1++ )
541  {
542  dphi_phys[i_dof][q][d1] = 0.0;
543 
544  // DIM 2
545  for ( d2 = 0; d2 < 3 ; d2++ )
546  {
547  dphi_phys[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi[i_dof][q][d2];
548  }
549  }
550  }
551  }
552 
553  // DOF - test
554  for ( i_test = 0; i_test < ndof; i_test++ )
555  {
556  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
557 
558  // DOF - trial
559  for ( i_trial = 0; i_trial < ndof; i_trial++ )
560  {
561  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
562 
563  integral = 0.0;
564  // QUAD
565  for ( q = 0; q < NumQuadPoints ; q++ )
566  {
567  // DIM 1
568  for ( d1 = 0; d1 < 3 ; d1++ )
569  {
570  integral += dphi_phys[i_test][q][d1] * dphi_phys[i_trial][q][d1]*w_quad[q];
571  }
572  }
573  M_vals[i_elem][i_test][i_trial] = integral * M_detJacobian[i_elem];
574  }
575  }
576  }
577  }
578 
579  for ( int k = 0; k < M_numElements; ++k )
580  {
581  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
582  }
583 
584 }
585 //=========================================================================
586 void
588 {
589  int ndof = M_referenceFE->nbDof();
590  int NumQuadPoints = M_qr->nbQuadPt();
591 
592  double w_quad[NumQuadPoints];
593  for ( int q = 0; q < NumQuadPoints ; q++ )
594  {
595  w_quad[q] = M_qr->weight(q);
596  }
597 
598  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
599  {
600  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial;
601  double integral;
602 
603  double dphi_phys[ndof][NumQuadPoints][3];
604 
605  // ELEMENTI
606  #pragma omp for
607  for ( i_el = 0; i_el < M_numElements ; i_el++ )
608  {
609  i_elem = i_el;
610 
611  // DOF
612  for ( i_dof = 0; i_dof < ndof; i_dof++ )
613  {
614  // QUAD
615  for ( q = 0; q < NumQuadPoints ; q++ )
616  {
617  // DIM 1
618  for ( d1 = 0; d1 < 3 ; d1++ )
619  {
620  dphi_phys[i_dof][q][d1] = 0.0;
621 
622  // DIM 2
623  for ( d2 = 0; d2 < 3 ; d2++ )
624  {
625  dphi_phys[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi[i_dof][q][d2];
626  }
627  }
628  }
629  }
630 
631  // DOF - test
632  for ( i_test = 0; i_test < ndof; i_test++ )
633  {
634  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
635 
636  // DOF - trial
637  for ( i_trial = 0; i_trial < ndof; i_trial++ )
638  {
639  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
640 
641  integral = 0.0;
642  // QUAD
643  for ( q = 0; q < NumQuadPoints ; q++ )
644  {
645  // DIM 1
646  for ( d1 = 0; d1 < 3 ; d1++ )
647  {
648  integral += dphi_phys[i_test][q][d1] * dphi_phys[i_trial][q][d1]*w_quad[q];
649  }
650  }
651  M_vals[i_elem][i_test][i_trial] = integral * M_detJacobian[i_elem];
652  }
653  }
654  }
655  }
656 
657  for ( int k = 0; k < M_numElements; ++k )
658  {
659  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
660  }
661 
662  for ( UInt d1 = 1; d1 < 3 ; d1++ )
663  {
664  for ( int k = 0; k < M_numElements; ++k )
665  {
666  for ( UInt i = 0; i < ndof; i++ )
667  {
668  M_rows[k][i] += M_numScalarDofs;
669  M_cols[k][i] += M_numScalarDofs;
670  }
671  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
672  }
673  }
674 
675 }
676 //=========================================================================
677 void
679 {
680  int ndof = M_referenceFE->nbDof();
681  int NumQuadPoints = M_qr->nbQuadPt();
682 
683  double w_quad[NumQuadPoints];
684  for ( int q = 0; q < NumQuadPoints ; q++ )
685  {
686  w_quad[q] = M_qr->weight(q);
687  }
688 
689  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
690  {
691  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial;
692  double integral;
693 
694  double dphi_phys[ndof][NumQuadPoints][3];
695 
696  // ELEMENTI
697  #pragma omp for
698  for ( i_el = 0; i_el < M_numElements ; i_el++ )
699  {
700  i_elem = i_el;
701 
702  // DOF - test
703  for ( i_test = 0; i_test < ndof; i_test++ )
704  {
705  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
706 
707  // DOF - trial
708  for ( i_trial = 0; i_trial < ndof; i_trial++ )
709  {
710  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
711 
712  integral = 0.0;
713  // QUAD
714  for ( q = 0; q < NumQuadPoints ; q++ )
715  {
716  integral += M_phi[i_test][q] * M_phi[i_trial][q]*w_quad[q];
717  }
718  M_vals[i_elem][i_test][i_trial] = integral * M_detJacobian[i_elem];
719  }
720  }
721  }
722  }
723 
724  for ( int k = 0; k < M_numElements; ++k )
725  {
726  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
727  }
728 
729  for ( UInt d1 = 1; d1 < 3 ; d1++ )
730  {
731  for ( int k = 0; k < M_numElements; ++k )
732  {
733  for ( UInt i = 0; i < ndof; i++ )
734  {
735  M_rows[k][i] += M_numScalarDofs;
736  M_cols[k][i] += M_numScalarDofs;
737  }
738  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
739  }
740  }
741 }
742 //=========================================================================
743 void
745 {
746  int ndof = M_referenceFE->nbDof();
747  int NumQuadPoints = M_qr->nbQuadPt();
748 
749  double w_quad[NumQuadPoints];
750  for ( int q = 0; q < NumQuadPoints ; q++ )
751  {
752  w_quad[q] = M_qr->weight(q);
753  }
754 
755  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
756  {
757  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial;
758  double integral;
759 
760  double dphi_phys[ndof][NumQuadPoints][3];
761 
762  // ELEMENTI
763  #pragma omp for
764  for ( i_el = 0; i_el < M_numElements ; i_el++ )
765  {
766  i_elem = i_el;
767 
768  // DOF - test
769  for ( i_test = 0; i_test < ndof; i_test++ )
770  {
771  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
772 
773  // DOF - trial
774  for ( i_trial = 0; i_trial < ndof; i_trial++ )
775  {
776  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
777 
778  integral = 0.0;
779  // QUAD
780  for ( q = 0; q < NumQuadPoints ; q++ )
781  {
782  integral += M_phi[i_test][q] * M_phi[i_trial][q]*w_quad[q];
783  }
784  M_vals[i_elem][i_test][i_trial] = integral * M_detJacobian[i_elem];
785  }
786  }
787  }
788  }
789 
790  for ( int k = 0; k < M_numElements; ++k )
791  {
792  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
793  }
794 
795 }
796 //=========================================================================
797 void
799 {
800  assembleConvective( *matrix, u_h );
801 }
802 //=========================================================================
803 void
805 {
806  int ndof = M_referenceFE->nbDof();
807  int NumQuadPoints = M_qr->nbQuadPt();
808  int ndof_vec = M_referenceFE->nbDof()*3;
809 
810  double w_quad[NumQuadPoints];
811  for ( int q = 0; q < NumQuadPoints ; q++ )
812  {
813  w_quad[q] = M_qr->weight(q);
814  }
815 
816  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
817  {
818  int i_elem, i_dof, q, d1, d2, i_test, i_trial, e_idof;
819  double integral;
820 
821  double dphi_phys[ndof][NumQuadPoints][3];
822 
823  double uhq[3][NumQuadPoints];
824 
825  // ELEMENTI,
826  #pragma omp for
827  for ( i_elem = 0; i_elem < M_numElements; i_elem++ )
828  {
829  // DOF
830  for ( i_dof = 0; i_dof < ndof; i_dof++ )
831  {
832  // QUAD
833  for ( q = 0; q < NumQuadPoints ; q++ )
834  {
835  // DIM 1
836  for ( d1 = 0; d1 < 3 ; d1++ )
837  {
838  dphi_phys[i_dof][q][d1] = 0.0;
839 
840  // DIM 2
841  for ( d2 = 0; d2 < 3 ; d2++ )
842  {
843  dphi_phys[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi[i_dof][q][d2];
844  }
845  }
846  }
847  }
848 
849  // QUAD
850  for ( q = 0; q < NumQuadPoints ; q++ )
851  {
852  for ( d1 = 0; d1 < 3 ; d1++ )
853  {
854  uhq[d1][q] = 0.0;
855  for ( i_dof = 0; i_dof < ndof; i_dof++ )
856  {
857  e_idof = M_elements[i_elem][i_dof] + d1*M_numScalarDofs ;
858  uhq[d1][q] += u_h[e_idof] * M_phi[i_dof][q];
859  //printf("\n u_h[%d] = %f", e_idof, u_h[e_idof]);
860  }
861  }
862  }
863 
864  // DOF - test
865  for ( i_test = 0; i_test < ndof; i_test++ )
866  {
867  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
868 
869  // DOF - trial
870  for ( i_trial = 0; i_trial < ndof; i_trial++ )
871  {
872  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
873 
874  integral = 0.0;
875  // QUAD
876  for ( q = 0; q < NumQuadPoints ; q++ )
877  {
878  // DIM 1
879  for ( d1 = 0; d1 < 3 ; d1++ )
880  {
881  integral += uhq[d1][q] * dphi_phys[i_trial][q][d1] * M_phi[i_test][q] * w_quad[q];
882  }
883  }
884  M_vals[i_elem][i_test][i_trial] = integral * M_detJacobian[i_elem];
885  }
886  }
887  }
888  }
889 
890  for ( int k = 0; k < M_numElements; ++k )
891  {
892  matrix.matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
893  }
894 
895  for ( UInt d1 = 1; d1 < 3 ; d1++ )
896  {
897  for ( int k = 0; k < M_numElements; ++k )
898  {
899  for ( UInt i = 0; i < ndof; i++ )
900  {
901  M_rows[k][i] += M_numScalarDofs;
902  M_cols[k][i] += M_numScalarDofs;
903  }
904  matrix.matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
905  }
906  }
907 }
908 //=========================================================================
909 // NAVIER STOKES MATRICES
910 //=========================================================================
911 void
913 {
914  int ndof = M_referenceFE->nbDof();
915  int NumQuadPoints = M_qr->nbQuadPt();
916 
917  double w_quad[NumQuadPoints];
918  for ( int q = 0; q < NumQuadPoints ; q++ )
919  {
920  w_quad[q] = M_qr->weight(q);
921  }
922 
923  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
924  {
925  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial;
926  double integral;
927 
928  double dphi_phys[ndof][NumQuadPoints][3];
929 
930  // ELEMENTI
931  #pragma omp for
932  for ( i_el = 0; i_el < M_numElements ; i_el++ )
933  {
934  i_elem = i_el;
935 
936  // DOF
937  for ( i_dof = 0; i_dof < ndof; i_dof++ )
938  {
939  // QUAD
940  for ( q = 0; q < NumQuadPoints ; q++ )
941  {
942  // DIM 1
943  for ( d1 = 0; d1 < 3 ; d1++ )
944  {
945  dphi_phys[i_dof][q][d1] = 0.0;
946 
947  // DIM 2
948  for ( d2 = 0; d2 < 3 ; d2++ )
949  {
950  dphi_phys[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi[i_dof][q][d2];
951  }
952  }
953  }
954  }
955 
956  // DOF - test
957  for ( i_test = 0; i_test < ndof; i_test++ )
958  {
959  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
960 
961  // DOF - trial
962  for ( i_trial = 0; i_trial < ndof; i_trial++ )
963  {
964  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
965 
966  integral = 0.0;
967  // QUAD
968  for ( q = 0; q < NumQuadPoints ; q++ )
969  {
970  integral += M_phi[i_test][q] * M_phi[i_trial][q]*w_quad[q]; // MASS
971  // DIM 1
972  for ( d1 = 0; d1 < 3 ; d1++ )
973  {
974  integral += dphi_phys[i_test][q][d1] * dphi_phys[i_trial][q][d1]*w_quad[q]; // STIFFNESS
975  }
976  }
977  M_vals[i_elem][i_test][i_trial] = integral * M_detJacobian[i_elem];
978  }
979  }
980  }
981  }
982 
983  for ( int k = 0; k < M_numElements; ++k )
984  {
985  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
986  }
987 
988  for ( UInt d1 = 1; d1 < 3 ; d1++ )
989  {
990  for ( int k = 0; k < M_numElements; ++k )
991  {
992  for ( UInt i = 0; i < ndof; i++ )
993  {
994  M_rows[k][i] += M_numScalarDofs;
995  M_cols[k][i] += M_numScalarDofs;
996  }
997  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
998  }
999  }
1000 }
1001 //=========================================================================
1002 void
1004 {
1005  int ndof = M_referenceFE->nbDof();
1006  int NumQuadPoints = M_qr->nbQuadPt();
1007  int ndof_vec = M_referenceFE->nbDof()*3;
1008 
1009  double w_quad[NumQuadPoints];
1010  for ( int q = 0; q < NumQuadPoints ; q++ )
1011  {
1012  w_quad[q] = M_qr->weight(q);
1013  }
1014 
1015  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
1016  {
1017  int i_elem, i_dof, q, d1, d2, i_test, i_trial, e_idof;
1018  double integral, integral_test, integral_trial;
1019 
1020  double dphi_phys[ndof][NumQuadPoints][3];
1021 
1022  double uhq[3][NumQuadPoints];
1023 
1024  // ELEMENTI,
1025  #pragma omp for
1026  for ( i_elem = 0; i_elem < M_numElements; i_elem++ )
1027  {
1028  // DOF
1029  for ( i_dof = 0; i_dof < ndof; i_dof++ )
1030  {
1031  // QUAD
1032  for ( q = 0; q < NumQuadPoints ; q++ )
1033  {
1034  // DIM 1
1035  for ( d1 = 0; d1 < 3 ; d1++ )
1036  {
1037  dphi_phys[i_dof][q][d1] = 0.0;
1038 
1039  // DIM 2
1040  for ( d2 = 0; d2 < 3 ; d2++ )
1041  {
1042  dphi_phys[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi[i_dof][q][d2];
1043  }
1044  }
1045  }
1046  }
1047 
1048  // QUAD
1049  for ( q = 0; q < NumQuadPoints ; q++ )
1050  {
1051  for ( d1 = 0; d1 < 3 ; d1++ )
1052  {
1053  uhq[d1][q] = 0.0;
1054  for ( i_dof = 0; i_dof < ndof; i_dof++ )
1055  {
1056  e_idof = M_elements[i_elem][i_dof] + d1*M_numScalarDofs ;
1057  uhq[d1][q] += u_h[e_idof] * M_phi[i_dof][q];
1058  }
1059  }
1060  }
1061 
1062  // STABILIZZAZIONE - coefficienti Tau_M e Tau_C
1063  for ( q = 0; q < NumQuadPoints ; q++ )
1064  {
1065  M_Tau_M[i_elem][q] = 1.0/std::sqrt(
1067  +M_density*M_density*( uhq[0][q]*( M_G[i_elem][0][0]* uhq[0][q] + M_G[i_elem][0][1] * uhq[1][q] + M_G[i_elem][0][2] * uhq[2][q] ) +
1068  uhq[1][q]*( M_G[i_elem][1][0]* uhq[0][q] + M_G[i_elem][1][1] * uhq[1][q] + M_G[i_elem][1][2] * uhq[2][q] ) +
1069  uhq[2][q]*( M_G[i_elem][2][0]* uhq[0][q] + M_G[i_elem][2][1] * uhq[1][q] + M_G[i_elem][2][2] * uhq[2][q] )
1070  ) // TAU_M_DEN_VEL
1072  M_G[i_elem][0][0]*M_G[i_elem][0][0] + M_G[i_elem][0][1]*M_G[i_elem][0][1] + M_G[i_elem][0][2]*M_G[i_elem][0][2] +
1073  M_G[i_elem][1][0]*M_G[i_elem][1][0] + M_G[i_elem][1][1]*M_G[i_elem][1][1] + M_G[i_elem][1][2]*M_G[i_elem][1][2] +
1074  M_G[i_elem][2][0]*M_G[i_elem][2][0] + M_G[i_elem][2][1]*M_G[i_elem][2][1] + M_G[i_elem][2][2]*M_G[i_elem][2][2]
1075  ) // TAU_M_DEN_VISC*/
1076  );
1077 
1078  M_Tau_C[i_elem][q] = 1.0/( M_g[i_elem][0]*M_Tau_M[i_elem][q]*M_g[i_elem][0] +
1079  M_g[i_elem][1]*M_Tau_M[i_elem][q]*M_g[i_elem][1] +
1080  M_g[i_elem][2]*M_Tau_M[i_elem][q]*M_g[i_elem][2]
1081  );
1082 
1083  }
1084 
1085 
1086  // DOF - test
1087  for ( i_test = 0; i_test < ndof; i_test++ )
1088  {
1089  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
1090 
1091  // DOF - trial
1092  for ( i_trial = 0; i_trial < ndof; i_trial++ )
1093  {
1094  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
1095 
1096  integral = 0.0;
1097  // QUAD
1098  for ( q = 0; q < NumQuadPoints ; q++ )
1099  {
1100  integral_test = 0;
1101  integral_trial = 0;
1102 
1103  // DIM 1
1104  for ( d1 = 0; d1 < 3 ; d1++ )
1105  {
1106  integral_test += uhq[d1][q] * dphi_phys[i_test][q][d1]; // w grad(phi_i)
1107  integral_trial += uhq[d1][q] * dphi_phys[i_trial][q][d1]; // w grad(phi_j) terzo indice dphi_phys e' derivata in x,y,z
1108  }
1109  integral += M_Tau_M[i_elem][q] * (integral_test * integral_trial + integral_test * M_phi[i_trial][q] ) * w_quad[q];
1110  // above, the term "integral_test * M_phi[i_trial][q]" is the one which comes from (w grad(phi_i), phi_j)
1111  }
1112  M_vals_supg[i_elem][0][0][i_test][i_trial] = integral * M_detJacobian[i_elem]; // (w grad(phi_i), w grad(phi_j) )
1113  M_vals_supg[i_elem][1][1][i_test][i_trial] = integral * M_detJacobian[i_elem];
1114  M_vals_supg[i_elem][2][2][i_test][i_trial] = integral * M_detJacobian[i_elem];
1115 
1116  for ( d1 = 0; d1 < 3; d1++ )
1117  {
1118  for ( d2 = 0; d2 < 3; d2++ )
1119  {
1120  integral = 0.0;
1121  // QUAD
1122  for ( q = 0; q < NumQuadPoints ; q++ )
1123  {
1124  integral += M_Tau_C[i_elem][q] * dphi_phys[i_test][q][d1] * dphi_phys[i_trial][q][d2] * w_quad[q]; // div(phi_i) * div(phi_j)
1125  }
1126  M_vals_supg[i_elem][d1][d2][i_test][i_trial] += integral * M_detJacobian[i_elem];
1127  }
1128  }
1129 
1130  }
1131  }
1132  }
1133  }
1134 
1135  for ( UInt d1 = 0; d1 < 3 ; d1++ ) // row index
1136  {
1137  for ( UInt d2 = 0; d2 < 3 ; d2++ ) // column
1138  {
1139  for ( int k = 0; k < M_numElements; ++k )
1140  {
1141  for ( UInt i = 0; i < ndof; i++ )
1142  {
1143  M_rows_tmp[k][i] = M_rows[k][i] + d1 * M_numScalarDofs;
1144  M_cols_tmp[k][i] = M_cols[k][i] + d2 * M_numScalarDofs;
1145  }
1146  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows_tmp[k], ndof, M_cols_tmp[k], M_vals_supg[k][d1][d2], Epetra_FECrsMatrix::ROW_MAJOR);
1147  }
1148  }
1149  }
1150 }
1151 //=========================================================================
1152 void
1154 {
1155  int ndof = M_referenceFE->nbDof();
1156  int NumQuadPoints = M_qr->nbQuadPt();
1157 
1158  double w_quad[NumQuadPoints];
1159  for ( int q = 0; q < NumQuadPoints ; q++ )
1160  {
1161  w_quad[q] = M_qr->weight(q);
1162  }
1163 
1164  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
1165  {
1166  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial, e_idof;
1167  double integral;
1168 
1169  double dphi_phys[ndof][NumQuadPoints][3];
1170 
1171  double uhq[3][NumQuadPoints];
1172 
1173  // ELEMENTI
1174  #pragma omp for
1175  for ( i_el = 0; i_el < M_numElements ; i_el++ )
1176  {
1177  i_elem = i_el;
1178 
1179  // DOF
1180  for ( i_dof = 0; i_dof < ndof; i_dof++ )
1181  {
1182  // QUAD
1183  for ( q = 0; q < NumQuadPoints ; q++ )
1184  {
1185  // DIM 1
1186  for ( d1 = 0; d1 < 3 ; d1++ )
1187  {
1188  dphi_phys[i_dof][q][d1] = 0.0;
1189 
1190  // DIM 2
1191  for ( d2 = 0; d2 < 3 ; d2++ )
1192  {
1193  dphi_phys[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi[i_dof][q][d2];
1194  }
1195  }
1196  }
1197  }
1198 
1199  // QUAD
1200  for ( q = 0; q < NumQuadPoints ; q++ )
1201  {
1202  for ( d1 = 0; d1 < 3 ; d1++ )
1203  {
1204  uhq[d1][q] = 0.0;
1205  for ( i_dof = 0; i_dof < ndof; i_dof++ )
1206  {
1207  e_idof = M_elements[i_elem][i_dof] + d1*M_numScalarDofs ;
1208  uhq[d1][q] += u_h[e_idof] * M_phi[i_dof][q];
1209  }
1210  }
1211  }
1212 
1213  // STABILIZZAZIONE - coefficienti Tau_M e Tau_C
1214  for ( q = 0; q < NumQuadPoints ; q++ )
1215  {
1216  M_Tau_M[i_elem][q] = 1.0/std::sqrt(
1218  +M_density*M_density*( uhq[0][q]*( M_G[i_elem][0][0]* uhq[0][q] + M_G[i_elem][0][1] * uhq[1][q] + M_G[i_elem][0][2] * uhq[2][q] ) +
1219  uhq[1][q]*( M_G[i_elem][1][0]* uhq[0][q] + M_G[i_elem][1][1] * uhq[1][q] + M_G[i_elem][1][2] * uhq[2][q] ) +
1220  uhq[2][q]*( M_G[i_elem][2][0]* uhq[0][q] + M_G[i_elem][2][1] * uhq[1][q] + M_G[i_elem][2][2] * uhq[2][q] )
1221  ) // TAU_M_DEN_VEL
1223  M_G[i_elem][0][0]*M_G[i_elem][0][0] + M_G[i_elem][0][1]*M_G[i_elem][0][1] + M_G[i_elem][0][2]*M_G[i_elem][0][2] +
1224  M_G[i_elem][1][0]*M_G[i_elem][1][0] + M_G[i_elem][1][1]*M_G[i_elem][1][1] + M_G[i_elem][1][2]*M_G[i_elem][1][2] +
1225  M_G[i_elem][2][0]*M_G[i_elem][2][0] + M_G[i_elem][2][1]*M_G[i_elem][2][1] + M_G[i_elem][2][2]*M_G[i_elem][2][2]
1226  ) // TAU_M_DEN_VISC*/
1227  );
1228  }
1229 
1230  // DOF - test
1231  for ( i_test = 0; i_test < ndof; i_test++ )
1232  {
1233  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
1234 
1235  // DOF - trial
1236  for ( i_trial = 0; i_trial < ndof; i_trial++ )
1237  {
1238  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
1239 
1240  integral = 0.0;
1241  // QUAD
1242  for ( q = 0; q < NumQuadPoints ; q++ )
1243  {
1244  // DIM 1
1245  for ( d1 = 0; d1 < 3 ; d1++ )
1246  {
1247  integral += M_Tau_M[i_elem][q] * dphi_phys[i_test][q][d1] * dphi_phys[i_trial][q][d1]*w_quad[q];
1248  }
1249  }
1250  M_vals[i_elem][i_test][i_trial] = integral * M_detJacobian[i_elem];
1251  }
1252  }
1253  }
1254  }
1255 
1256  for ( int k = 0; k < M_numElements; ++k )
1257  {
1258  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
1259  }
1260 }
1261 //=========================================================================
1262 void
1263 FastAssembler::setConstants_NavierStokes( const Real& density, const Real& viscosity, const Real& timestep, const Real& orderBDF, const Real& C_I )
1264 {
1265  M_density = density;
1266  M_viscosity = viscosity;
1267  M_timestep = timestep;
1268  M_orderBDF = orderBDF;
1269  M_C_I = C_I;
1270 }
1271 //=========================================================================
1272 void
1274 {
1275  int ndof = M_referenceFE->nbDof();
1276  int NumQuadPoints = M_qr->nbQuadPt();
1277 
1278  double w_quad[NumQuadPoints];
1279  for ( int q = 0; q < NumQuadPoints ; q++ )
1280  {
1281  w_quad[q] = M_qr->weight(q);
1282  }
1283 
1284  #pragma omp parallel firstprivate( w_quad, ndof, NumQuadPoints)
1285  {
1286  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial, iCoor, jCoor, k1, k2;
1287  double integral, partialSum, integral_test, integral_trial;
1288 
1289  double d2phi_phys[ndof][NumQuadPoints][3][3];
1290 
1291  // ELEMENTI
1292  #pragma omp for
1293  for ( i_elem = 0; i_elem < M_numElements ; i_elem++ )
1294  {
1295  // QUAD
1296  for ( q = 0; q < NumQuadPoints ; q++ )
1297  {
1298  // DOF
1299  for ( i_dof = 0; i_dof < ndof; i_dof++ )
1300  {
1301  // DIM 1
1302  for ( iCoor = 0; iCoor < 3 ; iCoor++ )
1303  {
1304  // DIM 2
1305  for ( jCoor = 0; jCoor < 3 ; jCoor++ )
1306  {
1307  partialSum = 0.0;
1308  // DIM 1
1309  for ( k1 = 0; k1 < 3 ; k1++ )
1310  {
1311  // DIM 2
1312  for ( k2 = 0; k2 < 3 ; k2++ )
1313  {
1314  partialSum += M_invJacobian[i_elem][iCoor][k1]
1315  * M_d2phi[i_dof][q][k1][k2]
1316  * M_invJacobian[i_elem][jCoor][k2];
1317  }
1318  }
1319  d2phi_phys[i_dof][q][iCoor][jCoor] = partialSum;
1320  }
1321  }
1322  }
1323  }
1324 
1325  // DOF - test
1326  for ( i_test = 0; i_test < ndof; i_test++ )
1327  {
1328  M_rows[i_elem][i_test] = M_elements[i_elem][i_test];
1329 
1330  // DOF - trial
1331  for ( i_trial = 0; i_trial < ndof; i_trial++ )
1332  {
1333  M_cols[i_elem][i_trial] = M_elements[i_elem][i_trial];
1334 
1335  integral = 0.0;
1336  // QUAD
1337  for ( q = 0; q < NumQuadPoints ; q++ )
1338  {
1339  integral_test = 0.0;
1340  integral_trial = 0.0;
1341  // DIM 1
1342  for ( d1 = 0; d1 < 3 ; d1++ )
1343  {
1344  integral_test += d2phi_phys[i_test][q][d1][d1];
1345  integral_trial += d2phi_phys[i_trial][q][d1][d1];
1346  }
1347  integral += integral_test * integral_trial * w_quad[q];
1348  }
1349  M_vals[i_elem][i_test][i_trial] = integral * M_detJacobian[i_elem];
1350  }
1351  }
1352  }
1353  }
1354 
1355  for ( int k = 0; k < M_numElements; ++k )
1356  {
1357  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
1358  }
1359 
1360  for ( UInt d1 = 1; d1 < 3 ; d1++ )
1361  {
1362  for ( int k = 0; k < M_numElements; ++k )
1363  {
1364  for ( UInt i = 0; i < ndof; i++ )
1365  {
1366  M_rows[k][i] += M_numScalarDofs;
1367  M_cols[k][i] += M_numScalarDofs;
1368  }
1369  matrix->matrixPtr()->InsertGlobalValues ( ndof, M_rows[k], ndof, M_cols[k], M_vals[k], Epetra_FECrsMatrix::ROW_MAJOR);
1370  }
1371  }
1372 
1373 }
FastAssembler(const meshPtr_Type &mesh, const commPtr_Type &comm, const ReferenceFE *refFE, const qr_Type *qr)
Constructor.
void assemble_SUPG_block00(matrixPtr_Type &matrix, const vector_Type &u_h)
FE Assembly of SUPG terms - block (0,0)
void allocateSpace(const int &numElements, CurrentFE *fe, const fespacePtr_Type &fespace, const UInt *meshSub_elements)
Allocate space for members before the assembly.
boost::shared_ptr< matrix_Type > matrixPtr_Type
void assembleMass_vectorial(matrixPtr_Type &matrix)
FE Assembly of vectorial mass matrix.
void assembleGradGrad_vectorial(matrixPtr_Type &matrix)
FE Assembly of vectorial grad-grad.
const Real & weight(const UInt &ig) const
weight(ig) is the ig-th quadrature weight
boost::shared_ptr< fespace_Type > fespacePtr_Type
void NS_constant_terms_00(matrixPtr_Type &matrix)
FE Assembly of NS constant terms (no scaling by coefficients like density or bdf) ...
void assembleGradGrad_scalar(matrixPtr_Type &matrix)
FE Assembly of scalar grad-grad.
boost::shared_ptr< comm_Type > commPtr_Type
double ***** M_vals_supg
const data_type & operator[](const UInt row) const
Access operators.
void assembleConvective(matrix_Type &matrix, const vector_Type &u_h)
FE Assembly of NS constant terms (no scaling by coefficients like viscosity)
~FastAssembler()
Destructor.
boost::shared_ptr< mesh_Type > meshPtr_Type
MatrixEpetra< Real > matrix_Type
void updateInverseJacobian(const UInt &iQuadPt)
QuadratureRule qr_Type
VectorEpetra vector_Type
Real tInverseJacobian(UInt element1, UInt element2, UInt quadNode) const
Getter for the inverse of the jacobian.
Definition: CurrentFE.hpp:465
void assemble_SUPG_block11(matrixPtr_Type &matrix, const vector_Type &u_h)
FE Assembly of SUPG terms - block (1,1)
void allocateSpace_SUPG(CurrentFE *fe)
Allocate space for supg before the assembly.
void allocateSpace(const int &numElements, CurrentFE *fe, const fespacePtr_Type &fespace)
Allocate space for members before the assembly.
double Real
Generic real data.
Definition: LifeV.hpp:175
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
Definition: CurrentFE.hpp:243
The class for a reference Lagrangian finite element.
void setConstants_NavierStokes(const Real &density, const Real &viscosity, const Real &timestep, const Real &orderBDF, const Real &C_I)
Set physical parameters for NS.
Real detJacobian(UInt quadNode) const
Getter for the determinant of the jacobian in a given quadrature node.
Definition: CurrentFE.hpp:451
const ReferenceFE * M_referenceFE
void assembleConvective(matrixPtr_Type &matrix, const vector_Type &u_h)
FE Assembly of NS constant terms (no scaling by coefficients like viscosity)
const qr_Type * M_qr
const UInt & nbQuadPt() const
Getter for the number of quadrature points.
void assembleMass_scalar(matrixPtr_Type &matrix)
FE Assembly of scalar mass matrix.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
void assembleLaplacianPhiILaplacianPhiJ_vectorial(matrixPtr_Type &matrix)
FE Assembly of laplacian PhiI laplacian PhiJ.