1 #include <lifev/core/fem/FastAssemblerMixed.hpp> 6 using namespace std::chrono;
10 using namespace LifeV;
16 const qr_Type* qr_integration ) :
36 for (
int j = 0; j < 3; j++ )
46 for (
int i = 0; i < M_referenceFE_test->nbDof(); i++ )
48 delete [] M_phi_test[i];
55 for (
int i = 0; i < M_referenceFE_trial->nbDof(); i++ )
57 delete [] M_phi_trial[i];
64 for(
int i = 0 ; i < M_referenceFE_test->nbDof() ; i++ )
66 for (
int j = 0; j < M_qr_integration->nbQuadPt(); j++ )
68 delete [] M_dphi_test[i][j];
70 delete [] M_dphi_test[i];
76 for(
int i = 0 ; i < M_referenceFE_trial->nbDof() ; i++ )
78 for (
int j = 0; j < M_qr_integration->nbQuadPt(); j++ )
80 delete [] M_dphi_trial[i][j];
82 delete [] M_dphi_trial[i];
106 for (
int k = 0; k < 3; k++ )
108 for (
int j = 0; j < M_referenceFE_test->nbDof(); j++ )
110 delete [] M_vals[i][k][j];
130 M_numScalarDofs_test = fespace_test->dof().numTotalDof();
132 M_numScalarDofs_trial = fespace_trial->dof().numTotalDof();
143 for (
int j = 0; j < 3 ; j++ )
151 fe_test->update( M_mesh->element (i), UPDATE_DPHI );
153 for (
int j = 0; j < 3; j++ )
155 for (
int k = 0; k < 3; k++ )
166 M_phi_test =
new double* [ M_referenceFE_test->nbDof() ];
167 for (
int i = 0; i < M_referenceFE_test->nbDof(); i++ )
169 M_phi_test[i] =
new double [ M_qr_integration->nbQuadPt() ];
175 for (UInt j (0); j < M_referenceFE_test->nbDof(); ++j)
177 M_phi_test[j][q] = M_referenceFE_test->phi (j, M_qr_integration->quadPointCoor (q) );
183 M_dphi_test =
new double** [ M_referenceFE_test->nbDof() ];
185 for (
int i = 0; i < M_referenceFE_test->nbDof(); i++ )
187 M_dphi_test[i] =
new double* [ M_qr_integration->nbQuadPt() ];
188 for (
int j = 0; j < M_qr_integration->nbQuadPt() ; j++ )
190 M_dphi_test[i][j] =
new double [ 3 ];
197 for (UInt i (0); i < M_referenceFE_test->nbDof(); ++i)
199 for (UInt j (0); j < 3; ++j)
201 M_dphi_test[i][q][j] = M_referenceFE_test->dPhi (i, j, M_qr_integration->quadPointCoor (q) );
210 M_phi_trial =
new double* [ M_referenceFE_trial->nbDof() ];
211 for (
int i = 0; i < M_referenceFE_trial->nbDof(); i++ )
213 M_phi_trial[i] =
new double [ M_qr_integration->nbQuadPt() ];
219 for (UInt j (0); j < M_referenceFE_trial->nbDof(); ++j)
221 M_phi_trial[j][q] = M_referenceFE_trial->phi (j, M_qr_integration->quadPointCoor (q) );
227 M_dphi_trial =
new double** [ M_referenceFE_trial->nbDof() ];
229 for (
int i = 0; i < M_referenceFE_trial->nbDof(); i++ )
231 M_dphi_trial[i] =
new double* [ M_qr_integration->nbQuadPt() ];
232 for (
int j = 0; j < M_qr_integration->nbQuadPt() ; j++ )
234 M_dphi_trial[i][j] =
new double [ 3 ];
241 for (UInt i (0); i < M_referenceFE_trial->nbDof(); ++i)
243 for (UInt j (0); j < 3; ++j)
245 M_dphi_trial[i][q][j] = M_referenceFE_trial->dPhi (i, j, M_qr_integration->quadPointCoor (q) );
263 for (
int j = 0; j < M_referenceFE_test->nbDof(); j++ )
265 M_elements_test[i][j] = fespace_test->dof().localToGlobalMap (i, j);
282 for (
int j = 0; j < M_referenceFE_trial->nbDof(); j++ )
284 M_elements_trial[i][j] = fespace_trial->dof().localToGlobalMap (i, j);
296 M_vals[i_elem] =
new double** [ 3 ];
297 for (
int k = 0; k < 3; k++ )
299 M_vals[i_elem][k] =
new double* [ M_referenceFE_test->nbDof() ];
300 for (
int i = 0; i < M_referenceFE_test->nbDof(); i++ )
302 M_vals[i_elem][k][i] =
new double [ M_referenceFE_trial->nbDof() ];
311 M_rows[i_elem] =
new int [ M_referenceFE_test->nbDof() ];
318 M_cols[i_elem] =
new int [ M_referenceFE_trial->nbDof() ];
328 int ndof_test = M_referenceFE_test->nbDof();
329 int ndof_trial = M_referenceFE_trial->nbDof();
332 double w_quad[NumQuadPoints];
333 for (
int q = 0; q < NumQuadPoints ; q++ )
338 #pragma omp parallel firstprivate ( w_quad, ndof_test, ndof_trial, NumQuadPoints ) 340 int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial, dim_mat;
343 double dphi_phys[ndof_test][NumQuadPoints][3];
352 for ( i_dof = 0; i_dof < ndof_test; i_dof++ )
355 for ( q = 0; q < NumQuadPoints ; q++ )
358 for ( d1 = 0; d1 < 3 ; d1++ )
360 dphi_phys[i_dof][q][d1] = 0.0;
363 for ( d2 = 0; d2 < 3 ; d2++ )
371 for ( dim_mat = 0; dim_mat < 3 ; dim_mat++ )
374 for ( i_test = 0; i_test < ndof_test; i_test++ )
379 for ( i_trial = 0; i_trial < ndof_trial; i_trial++ )
385 for ( q = 0; q < NumQuadPoints ; q++ )
387 integral += dphi_phys[i_test][q][dim_mat]*
M_phi_trial[i_trial][q]*w_quad[q];
399 matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][0], Epetra_FECrsMatrix::ROW_MAJOR);
402 for (
UInt d1 = 1; d1 < 3 ; d1++ )
406 for (
UInt i = 0; i < ndof_test; i++ )
410 matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][d1], Epetra_FECrsMatrix::ROW_MAJOR);
420 int ndof_test = M_referenceFE_test->nbDof();
421 int ndof_trial = M_referenceFE_trial->nbDof();
424 double w_quad[NumQuadPoints];
425 for (
int q = 0; q < NumQuadPoints ; q++ )
430 #pragma omp parallel firstprivate ( w_quad, ndof_test, ndof_trial, NumQuadPoints ) 432 int i_el, i_elem, i_dof, q, d1, d2, i_test, i_trial, dim_mat;
435 double dphi_phys[ndof_trial][NumQuadPoints][3];
444 for ( i_dof = 0; i_dof < ndof_trial; i_dof++ )
447 for ( q = 0; q < NumQuadPoints ; q++ )
450 for ( d1 = 0; d1 < 3 ; d1++ )
452 dphi_phys[i_dof][q][d1] = 0.0;
455 for ( d2 = 0; d2 < 3 ; d2++ )
463 for ( dim_mat = 0; dim_mat < 3 ; dim_mat++ )
466 for ( i_test = 0; i_test < ndof_test; i_test++ )
471 for ( i_trial = 0; i_trial < ndof_trial; i_trial++ )
477 for ( q = 0; q < NumQuadPoints ; q++ )
479 integral += dphi_phys[i_trial][q][dim_mat]*
M_phi_test[i_test][q]*w_quad[q];
491 matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][0], Epetra_FECrsMatrix::ROW_MAJOR);
494 for (
UInt d1 = 1; d1 < 3 ; d1++ )
498 for (
UInt i = 0; i < ndof_trial; i++ )
502 matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][d1], Epetra_FECrsMatrix::ROW_MAJOR);
510 int ndof_test = M_referenceFE_test->nbDof();
511 int ndof_trial = M_referenceFE_trial->nbDof();
514 double w_quad[NumQuadPoints];
515 for (
int q = 0; q < NumQuadPoints ; q++ )
520 #pragma omp parallel firstprivate ( w_quad, ndof_test, ndof_trial, NumQuadPoints ) 522 int i_elem, i_dof, q, d1, d2, i_test, i_trial, dim_mat, e_idof;
523 double integral, integral_partial;
525 double dphi_phys_test[ndof_test][NumQuadPoints][3];
526 double dphi_phys_trial[ndof_trial][NumQuadPoints][3];
528 double uhq[3][NumQuadPoints];
535 for ( i_dof = 0; i_dof < ndof_test; i_dof++ )
538 for ( q = 0; q < NumQuadPoints ; q++ )
541 for ( d1 = 0; d1 < 3 ; d1++ )
543 dphi_phys_test[i_dof][q][d1] = 0.0;
546 for ( d2 = 0; d2 < 3 ; d2++ )
555 for ( i_dof = 0; i_dof < ndof_trial; i_dof++ )
558 for ( q = 0; q < NumQuadPoints ; q++ )
561 for ( d1 = 0; d1 < 3 ; d1++ )
563 dphi_phys_trial[i_dof][q][d1] = 0.0;
566 for ( d2 = 0; d2 < 3 ; d2++ )
575 for ( q = 0; q < NumQuadPoints ; q++ )
577 for ( d1 = 0; d1 < 3 ; d1++ )
580 for ( i_dof = 0; i_dof < ndof_trial; i_dof++ )
588 for ( dim_mat = 0; dim_mat < 3 ; dim_mat++ )
591 for ( i_test = 0; i_test < ndof_test; i_test++ )
596 for ( i_trial = 0; i_trial < ndof_trial; i_trial++ )
603 for ( q = 0; q < NumQuadPoints ; q++ )
605 integral_partial = 0.0;
606 for ( d1 = 0; d1 < 3 ; d1++ )
608 integral_partial += dphi_phys_trial[i_trial][q][d1] * uhq[d1][q];
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];
623 matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][0], Epetra_FECrsMatrix::ROW_MAJOR);
626 for (
UInt d1 = 1; d1 < 3 ; d1++ )
630 for (
UInt i = 0; i < ndof_trial; i++ )
634 matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][d1], Epetra_FECrsMatrix::ROW_MAJOR);
642 int ndof_test = M_referenceFE_test->nbDof();
643 int ndof_trial = M_referenceFE_trial->nbDof();
646 double w_quad[NumQuadPoints];
647 for (
int q = 0; q < NumQuadPoints ; q++ )
652 #pragma omp parallel firstprivate ( w_quad, ndof_test, ndof_trial, NumQuadPoints ) 654 int i_elem, i_dof, q, d1, d2, i_test, i_trial, dim_mat, e_idof;
655 double integral, integral_partial;
657 double dphi_phys_test[ndof_test][NumQuadPoints][3];
658 double dphi_phys_trial[ndof_trial][NumQuadPoints][3];
660 double uhq[3][NumQuadPoints];
667 for ( i_dof = 0; i_dof < ndof_test; i_dof++ )
670 for ( q = 0; q < NumQuadPoints ; q++ )
673 for ( d1 = 0; d1 < 3 ; d1++ )
675 dphi_phys_test[i_dof][q][d1] = 0.0;
678 for ( d2 = 0; d2 < 3 ; d2++ )
687 for ( i_dof = 0; i_dof < ndof_trial; i_dof++ )
690 for ( q = 0; q < NumQuadPoints ; q++ )
693 for ( d1 = 0; d1 < 3 ; d1++ )
695 dphi_phys_trial[i_dof][q][d1] = 0.0;
698 for ( d2 = 0; d2 < 3 ; d2++ )
707 for ( q = 0; q < NumQuadPoints ; q++ )
709 for ( d1 = 0; d1 < 3 ; d1++ )
712 for ( i_dof = 0; i_dof < ndof_test; i_dof++ )
720 for ( dim_mat = 0; dim_mat < 3 ; dim_mat++ )
723 for ( i_test = 0; i_test < ndof_test; i_test++ )
728 for ( i_trial = 0; i_trial < ndof_trial; i_trial++ )
735 for ( q = 0; q < NumQuadPoints ; q++ )
737 integral_partial = 0.0;
738 for ( d1 = 0; d1 < 3 ; d1++ )
740 integral_partial += dphi_phys_test[i_test][q][d1] * uhq[d1][q];
742 integral += dphi_phys_trial[i_trial][q][dim_mat] * integral_partial * w_quad[q];
754 matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][0], Epetra_FECrsMatrix::ROW_MAJOR);
757 for (
UInt d1 = 1; d1 < 3 ; d1++ )
761 for (
UInt i = 0; i < ndof_test; i++ )
765 matrix->matrixPtr()->InsertGlobalValues ( ndof_test, M_rows[k], ndof_trial, M_cols[k], M_vals[k][d1], Epetra_FECrsMatrix::ROW_MAJOR);
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
double ** M_elements_trial
boost::shared_ptr< matrix_Type > matrixPtr_Type
double ** M_elements_test
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)
int M_numScalarDofs_trial
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.
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.
~FastAssemblerMixed()
Destructor.
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...
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.
const qr_Type * M_qr_integration
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)