LifeV
FastAssemblerMixed.cpp
Go to the documentation of this file.
1 #include <lifev/core/fem/FastAssemblerMixed.hpp>
2 #include <chrono>
3 #ifdef EPETRA_HAVE_OMP
4 #include <omp.h>
5 #endif
6 using namespace std::chrono;
7 
8 using namespace std;
9 
10 using namespace LifeV;
11 
12 //=========================================================================
13 // Constructor //
15  const ReferenceFE* refFE_test, const ReferenceFE* refFE_trial,
16  const qr_Type* qr_integration ) :
17  M_mesh ( mesh ),
18  M_comm ( comm ),
19  M_referenceFE_test ( refFE_test ),
20  M_referenceFE_trial ( refFE_trial ),
21  M_qr_integration ( qr_integration )
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_test->nbDof(); i++ )
47  {
48  delete [] M_phi_test[i];
49  }
50 
51  delete [] M_phi_test;
52 
53  //---------------------
54 
55  for ( int i = 0; i < M_referenceFE_trial->nbDof(); i++ )
56  {
57  delete [] M_phi_trial[i];
58  }
59 
60  delete [] M_phi_trial;
61 
62  //---------------------
63 
64  for( int i = 0 ; i < M_referenceFE_test->nbDof() ; i++ )
65  {
66  for ( int j = 0; j < M_qr_integration->nbQuadPt(); j++ )
67  {
68  delete [] M_dphi_test[i][j];
69  }
70  delete [] M_dphi_test[i];
71  }
72  delete [] M_dphi_test;
73 
74  //---------------------
75 
76  for( int i = 0 ; i < M_referenceFE_trial->nbDof() ; i++ )
77  {
78  for ( int j = 0; j < M_qr_integration->nbQuadPt(); j++ )
79  {
80  delete [] M_dphi_trial[i][j];
81  }
82  delete [] M_dphi_trial[i];
83  }
84  delete [] M_dphi_trial;
85 
86  //---------------------
87 
88  for( int i = 0 ; i < M_numElements ; i++ )
89  {
90  delete [] M_elements_test[i];
91  }
92  delete [] M_elements_test;
93 
94  //---------------------
95 
96  for( int i = 0 ; i < M_numElements ; i++ )
97  {
98  delete [] M_elements_trial[i];
99  }
100  delete [] M_elements_trial;
101 
102  //---------------------
103 
104  for( int i = 0 ; i < M_numElements ; i++ )
105  {
106  for ( int k = 0; k < 3; k++ )
107  {
108  for ( int j = 0; j < M_referenceFE_test->nbDof(); j++ )
109  {
110  delete [] M_vals[i][k][j];
111  }
112  delete [] M_vals[i][k];
113  }
114  delete [] M_rows[i];
115  delete [] M_cols[i];
116  delete [] M_vals[i];
117  }
118  delete [] M_rows;
119  delete [] M_cols;
120  delete [] M_vals;
121 }
122 //=========================================================================
123 void
124 FastAssemblerMixed::allocateSpace ( const int& numElements,
125  CurrentFE* fe_test, const fespacePtr_Type& fespace_test,
126  CurrentFE* fe_trial, const fespacePtr_Type& fespace_trial )
127 {
128  M_numElements = numElements;
129 
130  M_numScalarDofs_test = fespace_test->dof().numTotalDof();
131 
132  M_numScalarDofs_trial = fespace_trial->dof().numTotalDof();
133 
134  //-------------------------------------------------------------------------------------------------
135 
136  M_detJacobian = new double[ M_numElements ];
137 
138  M_invJacobian = new double** [ M_numElements];
139 
140  for ( int i = 0; i < M_numElements; i++ )
141  {
142  M_invJacobian[i] = new double* [ 3 ];
143  for ( int j = 0; j < 3 ; j++ )
144  {
145  M_invJacobian[i][j] = new double [ 3 ];
146  }
147  }
148 
149  for ( int i = 0; i < M_numElements; i++ )
150  {
151  fe_test->update( M_mesh->element (i), UPDATE_DPHI );
152  M_detJacobian[i] = fe_test->detJacobian(0);
153  for ( int j = 0; j < 3; j++ )
154  {
155  for ( int k = 0; k < 3; k++ )
156  {
157  M_invJacobian[i][j][k] = fe_test->tInverseJacobian(j,k,2);
158  }
159  }
160  }
161 
162  //-------------------------------------------------------------------------------------------------
163  // TEST FUNCTIONS - phi_i and d_phi_i
164  //-------------------------------------------------------------------------------------------------
165 
166  M_phi_test = new double* [ M_referenceFE_test->nbDof() ];
167  for ( int i = 0; i < M_referenceFE_test->nbDof(); i++ )
168  {
169  M_phi_test[i] = new double [ M_qr_integration->nbQuadPt() ];
170  }
171 
172  // PHI REF
173  for (UInt q (0); q < M_qr_integration->nbQuadPt(); ++q)
174  {
175  for (UInt j (0); j < M_referenceFE_test->nbDof(); ++j)
176  {
177  M_phi_test[j][q] = M_referenceFE_test->phi (j, M_qr_integration->quadPointCoor (q) );
178  }
179  }
180 
181  //-------------------------------------------------------------------------------------------------
182 
183  M_dphi_test = new double** [ M_referenceFE_test->nbDof() ];
184 
185  for ( int i = 0; i < M_referenceFE_test->nbDof(); i++ )
186  {
187  M_dphi_test[i] = new double* [ M_qr_integration->nbQuadPt() ];
188  for ( int j = 0; j < M_qr_integration->nbQuadPt() ; j++ )
189  {
190  M_dphi_test[i][j] = new double [ 3 ];
191  }
192  }
193 
194  //DPHI REF
195  for (UInt q (0); q < M_qr_integration->nbQuadPt(); ++q)
196  {
197  for (UInt i (0); i < M_referenceFE_test->nbDof(); ++i)
198  {
199  for (UInt j (0); j < 3; ++j)
200  {
201  M_dphi_test[i][q][j] = M_referenceFE_test->dPhi (i, j, M_qr_integration->quadPointCoor (q) );
202  }
203  }
204  }
205 
206  //-------------------------------------------------------------------------------------------------
207  // TRIAL FUNCTIONS - phi_j and d_phi_j
208  //-------------------------------------------------------------------------------------------------
209 
210  M_phi_trial = new double* [ M_referenceFE_trial->nbDof() ];
211  for ( int i = 0; i < M_referenceFE_trial->nbDof(); i++ )
212  {
213  M_phi_trial[i] = new double [ M_qr_integration->nbQuadPt() ];
214  }
215 
216  // PHI REF
217  for (UInt q (0); q < M_qr_integration->nbQuadPt(); ++q)
218  {
219  for (UInt j (0); j < M_referenceFE_trial->nbDof(); ++j)
220  {
221  M_phi_trial[j][q] = M_referenceFE_trial->phi (j, M_qr_integration->quadPointCoor (q) );
222  }
223  }
224 
225  //-------------------------------------------------------------------------------------------------
226 
227  M_dphi_trial = new double** [ M_referenceFE_trial->nbDof() ];
228 
229  for ( int i = 0; i < M_referenceFE_trial->nbDof(); i++ )
230  {
231  M_dphi_trial[i] = new double* [ M_qr_integration->nbQuadPt() ];
232  for ( int j = 0; j < M_qr_integration->nbQuadPt() ; j++ )
233  {
234  M_dphi_trial[i][j] = new double [ 3 ];
235  }
236  }
237 
238  //DPHI REF
239  for (UInt q (0); q < M_qr_integration->nbQuadPt(); ++q)
240  {
241  for (UInt i (0); i < M_referenceFE_trial->nbDof(); ++i)
242  {
243  for (UInt j (0); j < 3; ++j)
244  {
245  M_dphi_trial[i][q][j] = M_referenceFE_trial->dPhi (i, j, M_qr_integration->quadPointCoor (q) );
246  }
247  }
248  }
249 
250  //-------------------------------------------------------------------------------------------------
251  // CONNECTIVITY TEST
252  //-------------------------------------------------------------------------------------------------
253 
254  M_elements_test = new double* [ M_numElements ];
255 
256  for ( int i = 0; i < M_numElements; i++ )
257  {
258  M_elements_test[i] = new double [ M_referenceFE_test->nbDof() ];
259  }
260 
261  for ( int i = 0; i < M_numElements; i++ )
262  {
263  for ( int j = 0; j < M_referenceFE_test->nbDof(); j++ )
264  {
265  M_elements_test[i][j] = fespace_test->dof().localToGlobalMap (i, j);
266  }
267  }
268 
269  //-------------------------------------------------------------------------------------------------
270  // CONNECTIVITY TRIAL
271  //-------------------------------------------------------------------------------------------------
272 
273  M_elements_trial = new double* [ M_numElements ];
274 
275  for ( int i = 0; i < M_numElements; i++ )
276  {
277  M_elements_trial[i] = new double [ M_referenceFE_trial->nbDof() ];
278  }
279 
280  for ( int i = 0; i < M_numElements; i++ )
281  {
282  for ( int j = 0; j < M_referenceFE_trial->nbDof(); j++ )
283  {
284  M_elements_trial[i][j] = fespace_trial->dof().localToGlobalMap (i, j);
285  }
286  }
287 
288  //-------------------------------------------------------------------------------------------------
289  // Allocate space for M_rows, M_cols and M_vals
290  //-------------------------------------------------------------------------------------------------
291 
292  M_vals = new double*** [M_numElements];
293 
294  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
295  {
296  M_vals[i_elem] = new double** [ 3 ];
297  for ( int k = 0; k < 3; k++ )
298  {
299  M_vals[i_elem][k] = new double* [ M_referenceFE_test->nbDof() ];
300  for ( int i = 0; i < M_referenceFE_test->nbDof(); i++ )
301  {
302  M_vals[i_elem][k][i] = new double [ M_referenceFE_trial->nbDof() ];
303  }
304  }
305  }
306 
307  M_rows = new int* [M_numElements];
308 
309  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
310  {
311  M_rows[i_elem] = new int [ M_referenceFE_test->nbDof() ];
312  }
313 
314  M_cols = new int* [M_numElements];
315 
316  for ( int i_elem = 0; i_elem < M_numElements; i_elem++ )
317  {
318  M_cols[i_elem] = new int [ M_referenceFE_trial->nbDof() ];
319  }
320 }
321 //=====================================================================================================
322 void
324 {
325 
326  // In this case we need to assemble: -1.0 * div(phi_i)*phi_j
327 
328  int ndof_test = M_referenceFE_test->nbDof();
329  int ndof_trial = M_referenceFE_trial->nbDof();
330  int NumQuadPoints = M_qr_integration->nbQuadPt(); // WARNING!!
331 
332  double w_quad[NumQuadPoints]; // Note: suppose that test has more precise qr than trial
333  for ( int q = 0; q < NumQuadPoints ; q++ )
334  {
335  w_quad[q] = M_qr_integration->weight(q);
336  }
337 
338  #pragma omp parallel firstprivate ( w_quad, ndof_test, ndof_trial, NumQuadPoints )
339  {
340  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial, dim_mat;
341  double integral;
342 
343  double dphi_phys[ndof_test][NumQuadPoints][3]; // Gradient in the physical domain
344 
345  // ELEMENTI
346  #pragma omp for
347  for ( i_el = 0; i_el < M_numElements ; i_el++ )
348  {
349  i_elem = i_el;
350 
351  // DOF
352  for ( i_dof = 0; i_dof < ndof_test; i_dof++ )
353  {
354  // QUAD
355  for ( q = 0; q < NumQuadPoints ; q++ )
356  {
357  // DIM 1
358  for ( d1 = 0; d1 < 3 ; d1++ )
359  {
360  dphi_phys[i_dof][q][d1] = 0.0;
361 
362  // DIM 2
363  for ( d2 = 0; d2 < 3 ; d2++ )
364  {
365  dphi_phys[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi_test[i_dof][q][d2];
366  }
367  }
368  }
369  }
370 
371  for ( dim_mat = 0; dim_mat < 3 ; dim_mat++ )
372  {
373  // DOF - test
374  for ( i_test = 0; i_test < ndof_test; i_test++ )
375  {
376  M_rows[i_elem][i_test] = M_elements_test[i_elem][i_test];
377 
378  // DOF - trial
379  for ( i_trial = 0; i_trial < ndof_trial; i_trial++ )
380  {
381  M_cols[i_elem][i_trial] = M_elements_trial[i_elem][i_trial];
382 
383  integral = 0.0;
384  // QUAD
385  for ( q = 0; q < NumQuadPoints ; q++ )
386  {
387  integral += dphi_phys[i_test][q][dim_mat]*M_phi_trial[i_trial][q]*w_quad[q];
388  }
389 
390  M_vals[i_elem][dim_mat][i_test][i_trial] = -1.0 * integral * M_detJacobian[i_elem];
391  }
392  }
393  }
394  }
395  }
396 
397  for ( int k = 0; k < M_numElements; ++k )
398  {
399  matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][0], Epetra_FECrsMatrix::ROW_MAJOR);
400  }
401 
402  for ( UInt d1 = 1; d1 < 3 ; d1++ )
403  {
404  for ( int k = 0; k < M_numElements; ++k )
405  {
406  for ( UInt i = 0; i < ndof_test; i++ )
407  {
408  M_rows[k][i] += M_numScalarDofs_test;
409  }
410  matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][d1], Epetra_FECrsMatrix::ROW_MAJOR);
411  }
412  }
413 }
414 //=====================================================================================================
415 void
417 {
418  // In this case we need to assemble: phi_i * div(phi_j)
419 
420  int ndof_test = M_referenceFE_test->nbDof();
421  int ndof_trial = M_referenceFE_trial->nbDof();
422  int NumQuadPoints = M_qr_integration->nbQuadPt();
423 
424  double w_quad[NumQuadPoints];
425  for ( int q = 0; q < NumQuadPoints ; q++ )
426  {
427  w_quad[q] = M_qr_integration->weight(q);
428  }
429 
430  #pragma omp parallel firstprivate ( w_quad, ndof_test, ndof_trial, NumQuadPoints )
431  {
432  int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial, dim_mat;
433  double integral;
434 
435  double dphi_phys[ndof_trial][NumQuadPoints][3]; // Gradient in the physical domain
436 
437  // ELEMENTI
438  #pragma omp for
439  for ( i_el = 0; i_el < M_numElements ; i_el++ )
440  {
441  i_elem = i_el;
442 
443  // DOF
444  for ( i_dof = 0; i_dof < ndof_trial; i_dof++ )
445  {
446  // QUAD
447  for ( q = 0; q < NumQuadPoints ; q++ )
448  {
449  // DIM 1
450  for ( d1 = 0; d1 < 3 ; d1++ )
451  {
452  dphi_phys[i_dof][q][d1] = 0.0;
453 
454  // DIM 2
455  for ( d2 = 0; d2 < 3 ; d2++ )
456  {
457  dphi_phys[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi_trial[i_dof][q][d2];
458  }
459  }
460  }
461  }
462 
463  for ( dim_mat = 0; dim_mat < 3 ; dim_mat++ )
464  {
465  // DOF - test
466  for ( i_test = 0; i_test < ndof_test; i_test++ )
467  {
468  M_rows[i_elem][i_test] = M_elements_test[i_elem][i_test];
469 
470  // DOF - trial
471  for ( i_trial = 0; i_trial < ndof_trial; i_trial++ )
472  {
473  M_cols[i_elem][i_trial] = M_elements_trial[i_elem][i_trial];
474 
475  integral = 0.0;
476  // QUAD
477  for ( q = 0; q < NumQuadPoints ; q++ )
478  {
479  integral += dphi_phys[i_trial][q][dim_mat]*M_phi_test[i_test][q]*w_quad[q];
480  }
481 
482  M_vals[i_elem][dim_mat][i_test][i_trial] = integral * M_detJacobian[i_elem];
483  }
484  }
485  }
486  }
487  }
488 
489  for ( int k = 0; k < M_numElements; ++k )
490  {
491  matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][0], Epetra_FECrsMatrix::ROW_MAJOR);
492  }
493 
494  for ( UInt d1 = 1; d1 < 3 ; d1++ )
495  {
496  for ( int k = 0; k < M_numElements; ++k )
497  {
498  for ( UInt i = 0; i < ndof_trial; i++ )
499  {
500  M_cols[k][i] += M_numScalarDofs_trial;
501  }
502  matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][d1], Epetra_FECrsMatrix::ROW_MAJOR);
503  }
504  }
505 }
506 //=====================================================================================================
507 void
509 {
510  int ndof_test = M_referenceFE_test->nbDof();
511  int ndof_trial = M_referenceFE_trial->nbDof();
512  int NumQuadPoints = M_qr_integration->nbQuadPt();
513 
514  double w_quad[NumQuadPoints];
515  for ( int q = 0; q < NumQuadPoints ; q++ )
516  {
517  w_quad[q] = M_qr_integration->weight(q);
518  }
519 
520  #pragma omp parallel firstprivate ( w_quad, ndof_test, ndof_trial, NumQuadPoints )
521  {
522  int i_elem, i_dof, q, d1, d2, i_test, i_trial, dim_mat, e_idof;
523  double integral, integral_partial;
524 
525  double dphi_phys_test[ndof_test][NumQuadPoints][3]; // Gradient in the physical domain
526  double dphi_phys_trial[ndof_trial][NumQuadPoints][3];
527 
528  double uhq[3][NumQuadPoints];
529 
530  // ELEMENTI
531  #pragma omp for
532  for ( i_elem = 0; i_elem < M_numElements ; i_elem++ )
533  {
534  // DOF
535  for ( i_dof = 0; i_dof < ndof_test; i_dof++ )
536  {
537  // QUAD
538  for ( q = 0; q < NumQuadPoints ; q++ )
539  {
540  // DIM 1
541  for ( d1 = 0; d1 < 3 ; d1++ )
542  {
543  dphi_phys_test[i_dof][q][d1] = 0.0;
544 
545  // DIM 2
546  for ( d2 = 0; d2 < 3 ; d2++ )
547  {
548  dphi_phys_test[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi_test[i_dof][q][d2];
549  }
550  }
551  }
552  }
553 
554  // DOF -- nota che può essere ottimizzato rishapando il gradiente fisico. Prima q poi d1 poi d2 e poi i_dof
555  for ( i_dof = 0; i_dof < ndof_trial; i_dof++ )
556  {
557  // QUAD
558  for ( q = 0; q < NumQuadPoints ; q++ )
559  {
560  // DIM 1
561  for ( d1 = 0; d1 < 3 ; d1++ )
562  {
563  dphi_phys_trial[i_dof][q][d1] = 0.0;
564 
565  // DIM 2
566  for ( d2 = 0; d2 < 3 ; d2++ )
567  {
568  dphi_phys_trial[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi_trial[i_dof][q][d2];
569  }
570  }
571  }
572  }
573 
574  // QUAD
575  for ( q = 0; q < NumQuadPoints ; q++ )
576  {
577  for ( d1 = 0; d1 < 3 ; d1++ )
578  {
579  uhq[d1][q] = 0.0;
580  for ( i_dof = 0; i_dof < ndof_trial; i_dof++ )
581  {
582  e_idof = M_elements_trial[i_elem][i_dof] + d1*M_numScalarDofs_trial ;
583  uhq[d1][q] += u_h[e_idof] * M_phi_trial[i_dof][q];
584  }
585  }
586  }
587 
588  for ( dim_mat = 0; dim_mat < 3 ; dim_mat++ )
589  {
590  // DOF - test
591  for ( i_test = 0; i_test < ndof_test; i_test++ )
592  {
593  M_rows[i_elem][i_test] = M_elements_test[i_elem][i_test];
594 
595  // DOF - trial
596  for ( i_trial = 0; i_trial < ndof_trial; i_trial++ )
597  {
598  M_cols[i_elem][i_trial] = M_elements_trial[i_elem][i_trial];
599 
600  integral = 0.0;
601 
602  // QUAD
603  for ( q = 0; q < NumQuadPoints ; q++ )
604  {
605  integral_partial = 0.0;
606  for ( d1 = 0; d1 < 3 ; d1++ )
607  {
608  integral_partial += dphi_phys_trial[i_trial][q][d1] * uhq[d1][q];
609  }
610  integral += ( dphi_phys_test[i_test][q][dim_mat] * M_phi_trial[i_trial][q] +
611  dphi_phys_test[i_test][q][dim_mat] * integral_partial ) * w_quad[q];
612  }
613 
614  M_vals[i_elem][dim_mat][i_test][i_trial] = integral * M_detJacobian[i_elem];
615  }
616  }
617  }
618  }
619  }
620 
621  for ( int k = 0; k < M_numElements; ++k )
622  {
623  matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][0], Epetra_FECrsMatrix::ROW_MAJOR);
624  }
625 
626  for ( UInt d1 = 1; d1 < 3 ; d1++ )
627  {
628  for ( int k = 0; k < M_numElements; ++k )
629  {
630  for ( UInt i = 0; i < ndof_trial; i++ )
631  {
632  M_cols[k][i] += M_numScalarDofs_trial;
633  }
634  matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][d1], Epetra_FECrsMatrix::ROW_MAJOR);
635  }
636  }
637 }
638 //=====================================================================================================
639 void
641 {
642  int ndof_test = M_referenceFE_test->nbDof();
643  int ndof_trial = M_referenceFE_trial->nbDof();
644  int NumQuadPoints = M_qr_integration->nbQuadPt();
645 
646  double w_quad[NumQuadPoints];
647  for ( int q = 0; q < NumQuadPoints ; q++ )
648  {
649  w_quad[q] = M_qr_integration->weight(q);
650  }
651 
652  #pragma omp parallel firstprivate ( w_quad, ndof_test, ndof_trial, NumQuadPoints )
653  {
654  int i_elem, i_dof, q, d1, d2, i_test, i_trial, dim_mat, e_idof;
655  double integral, integral_partial;
656 
657  double dphi_phys_test[ndof_test][NumQuadPoints][3]; // Gradient in the physical domain
658  double dphi_phys_trial[ndof_trial][NumQuadPoints][3];
659 
660  double uhq[3][NumQuadPoints];
661 
662  // ELEMENTI
663  #pragma omp for
664  for ( i_elem = 0; i_elem < M_numElements ; i_elem++ )
665  {
666  // DOF
667  for ( i_dof = 0; i_dof < ndof_test; i_dof++ )
668  {
669  // QUAD
670  for ( q = 0; q < NumQuadPoints ; q++ )
671  {
672  // DIM 1
673  for ( d1 = 0; d1 < 3 ; d1++ )
674  {
675  dphi_phys_test[i_dof][q][d1] = 0.0;
676 
677  // DIM 2
678  for ( d2 = 0; d2 < 3 ; d2++ )
679  {
680  dphi_phys_test[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi_test[i_dof][q][d2];
681  }
682  }
683  }
684  }
685 
686  // DOF -- nota che può essere ottimizzato rishapando il gradiente fisico. Prima q poi d1 poi d2 e poi i_dof
687  for ( i_dof = 0; i_dof < ndof_trial; i_dof++ )
688  {
689  // QUAD
690  for ( q = 0; q < NumQuadPoints ; q++ )
691  {
692  // DIM 1
693  for ( d1 = 0; d1 < 3 ; d1++ )
694  {
695  dphi_phys_trial[i_dof][q][d1] = 0.0;
696 
697  // DIM 2
698  for ( d2 = 0; d2 < 3 ; d2++ )
699  {
700  dphi_phys_trial[i_dof][q][d1] += M_invJacobian[i_elem][d1][d2] * M_dphi_trial[i_dof][q][d2];
701  }
702  }
703  }
704  }
705 
706  // QUAD
707  for ( q = 0; q < NumQuadPoints ; q++ )
708  {
709  for ( d1 = 0; d1 < 3 ; d1++ )
710  {
711  uhq[d1][q] = 0.0;
712  for ( i_dof = 0; i_dof < ndof_test; i_dof++ )
713  {
714  e_idof = M_elements_test[i_elem][i_dof] + d1*M_numScalarDofs_test ;
715  uhq[d1][q] += u_h[e_idof] * M_phi_test[i_dof][q];
716  }
717  }
718  }
719 
720  for ( dim_mat = 0; dim_mat < 3 ; dim_mat++ )
721  {
722  // DOF - test
723  for ( i_test = 0; i_test < ndof_test; i_test++ )
724  {
725  M_rows[i_elem][i_test] = M_elements_test[i_elem][i_test];
726 
727  // DOF - trial
728  for ( i_trial = 0; i_trial < ndof_trial; i_trial++ )
729  {
730  M_cols[i_elem][i_trial] = M_elements_trial[i_elem][i_trial];
731 
732  integral = 0.0;
733 
734  // QUAD
735  for ( q = 0; q < NumQuadPoints ; q++ )
736  {
737  integral_partial = 0.0;
738  for ( d1 = 0; d1 < 3 ; d1++ )
739  {
740  integral_partial += dphi_phys_test[i_test][q][d1] * uhq[d1][q];
741  }
742  integral += dphi_phys_trial[i_trial][q][dim_mat] * integral_partial * w_quad[q];
743  }
744 
745  M_vals[i_elem][dim_mat][i_test][i_trial] = integral * M_detJacobian[i_elem];
746  }
747  }
748  }
749  }
750  }
751 
752  for ( int k = 0; k < M_numElements; ++k )
753  {
754  matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][0], Epetra_FECrsMatrix::ROW_MAJOR);
755  }
756 
757  for ( UInt d1 = 1; d1 < 3 ; d1++ )
758  {
759  for ( int k = 0; k < M_numElements; ++k )
760  {
761  for ( UInt i = 0; i < ndof_test; i++ )
762  {
763  M_rows[k][i] += M_numScalarDofs_test;
764  }
765  matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][d1], Epetra_FECrsMatrix::ROW_MAJOR);
766  }
767  }
768 }
const Real & weight(const UInt &ig) const
weight(ig) is the ig-th quadrature weight
boost::shared_ptr< mesh_Type > meshPtr_Type
const ReferenceFE * M_referenceFE_trial
boost::shared_ptr< matrix_Type > matrixPtr_Type
const data_type & operator[](const UInt row) const
Access operators.
void assemble_SUPG_block01(matrixPtr_Type &matrix, const vector_Type &u_h)
FE Assembly block (0,1) of SUPG stabilization for Navier-Stokes.
void updateInverseJacobian(const UInt &iQuadPt)
void assemble_NS_block10(matrixPtr_Type &matrix)
FE Assembly block (1,0) of Navier-Stokes.
Real tInverseJacobian(UInt element1, UInt element2, UInt quadNode) const
Getter for the inverse of the jacobian.
Definition: CurrentFE.hpp:465
void allocateSpace(const int &numElements, CurrentFE *fe_test, const fespacePtr_Type &fespace_test, CurrentFE *fe_trial, const fespacePtr_Type &fespace_trial)
Allocate space for members before the assembly.
void assemble_SUPG_block10(matrixPtr_Type &matrix, const vector_Type &u_h)
FE Assembly block (1,0) of SUPG stabilization for Navier-Stokes.
void assemble_NS_block01(matrixPtr_Type &matrix)
FE Assembly block (0,1) of Navier-Stokes.
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
Definition: CurrentFE.hpp:243
boost::shared_ptr< comm_Type > commPtr_Type
The class for a reference Lagrangian finite element.
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_test
FastAssemblerMixed(const meshPtr_Type &mesh, const commPtr_Type &comm, const ReferenceFE *refFE_test, const ReferenceFE *refFE_trial, const qr_Type *qr_integration)
Constructor.
const UInt & nbQuadPt() const
Getter for the number of quadrature points.
boost::shared_ptr< fespace_Type > fespacePtr_Type
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191