38 #ifndef OSEENASSEMBLER_H 39 #define OSEENASSEMBLER_H 1
41 #include <lifev/core/util/LifeChrono.hpp> 42 #include <lifev/core/LifeV.hpp> 44 #include <lifev/core/fem/Assembly.hpp> 45 #include <lifev/core/fem/FESpace.hpp> 46 #include <lifev/core/fem/AssemblyElemental.hpp> 47 #include <lifev/core/fem/BCHandler.hpp> 48 #include <lifev/core/fem/QuadratureRuleProvider.hpp> 50 #include <boost/shared_ptr.hpp> 51 #include <boost/scoped_ptr.hpp> 65 template<
typename meshType,
typename matrixType,
typename vectorType>
78 typedef AssemblyElemental::function_Type function_Type;
110 setup (uFESpace, pFESpace, uFESpace);
125 addViscousStress (matrix, viscosity, 0, 0);
134 addStiffStrain (matrix, viscosity, 0, 0);
143 addGradPressure (matrix, M_uFESpace->dof().numTotalDof() *nDimensions, 0);
156 addGradientTranspose (matrix, 0, M_uFESpace->dof().numTotalDof() *nDimensions, coefficient);
169 addDivergence (matrix, 0, M_uFESpace->dof().numTotalDof() *nDimensions, coefficient);
178 addMass (matrix, coefficient, 0, 0);
182 void addMass (matrixType& matrix,
const Real& coefficient,
const UInt& offsetLeft,
const UInt offsetUp);
187 addPressureMass (matrix, coefficient, M_uFESpace->dof().numTotalDof() *nDimensions,
188 M_uFESpace->dof().numTotalDof() *nDimensions);
195 void addMassDivW (matrixType& matrix,
const Real& coefficient,
const vectorType& beta)
197 addMassDivW (matrix, coefficient, beta, 0, 0);
201 void addMassDivW (matrixType& matrix,
const Real& coefficient,
const vectorType& beta,
const UInt& offsetLeft,
const UInt offsetUp);
206 addConvection (matrix, coefficient, beta, 0, 0);
210 void addConvection (matrixType& matrix,
const Real& coefficient,
const vectorType& beta,
const UInt& offsetLeft,
const UInt offsetUp);
218 addNewtonConvection ( matrix, beta, 0, 0 );
224 addSymmetricConvection (matrix, coefficient, beta, 0, 0);
233 void addMassRhs (vectorType& rhs,
const function_Type& fun,
const Real& t);
249 ASSERT (M_massRhsCFE != 0,
"No Rhs currentFE for setting the quadrature rule!");
250 M_massRhsCFE->setQuadRule (qr);
332 template<
typename meshType,
typename matrixType,
typename vectorType>
365 template<
typename meshType,
typename matrixType,
typename vectorType>
370 ASSERT (uFESpace != 0,
"Impossible to set empty FE space for the velocity. ");
371 ASSERT (pFESpace != 0,
"Impossible to set empty FE space for the pressure. ");
372 ASSERT (betaFESpace != 0,
"Impossible to set empty FE space for the convective field (beta). ");
374 ASSERT (uFESpace->fieldDim() == nDimensions,
"FE space for the velocity has to be vectorial");
375 ASSERT (pFESpace->fieldDim() == 1,
"FE space for the pressure has to be scalar");
376 ASSERT (betaFESpace->fieldDim() == nDimensions,
"FE space for the convective field (beta) has to be vectorial");
382 UInt uDegree (M_uFESpace->polynomialDegree() );
383 UInt pDegree (M_pFESpace->polynomialDegree() );
384 UInt betaDegree (M_betaFESpace->polynomialDegree() );
386 M_viscousCFE.reset (
new currentFE_Type (M_uFESpace->refFE(),
387 M_uFESpace->fe().geoMap(),
388 QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree - 2) ) );
390 M_gradPressureUCFE.reset (
new currentFE_Type (M_uFESpace->refFE(),
391 M_uFESpace->fe().geoMap(),
392 QuadratureRuleProvider::provideExactness (TETRA, uDegree + pDegree - 1) ) );
394 M_gradPressurePCFE.reset (
new currentFE_Type (M_pFESpace->refFE(),
395 M_uFESpace->fe().geoMap(),
396 QuadratureRuleProvider::provideExactness (TETRA, uDegree + pDegree - 1) ) );
398 M_divergenceUCFE.reset (
new currentFE_Type (M_uFESpace->refFE(),
399 M_uFESpace->fe().geoMap(),
400 QuadratureRuleProvider::provideExactness (TETRA, uDegree + pDegree - 1) ) );
403 M_divergencePCFE.reset (
new currentFE_Type (M_pFESpace->refFE(),
404 M_uFESpace->fe().geoMap(),
405 QuadratureRuleProvider::provideExactness (TETRA, uDegree + pDegree - 1) ) );
407 M_massCFE.reset (
new currentFE_Type (M_uFESpace->refFE(),
408 M_uFESpace->fe().geoMap(),
409 QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree) ) );
411 M_massBetaCFE.reset (
new currentFE_Type (M_betaFESpace->refFE(),
412 M_uFESpace->fe().geoMap(),
413 QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree) ) );
415 M_massPressureCFE.reset (
new currentFE_Type (M_pFESpace->refFE(),
416 M_pFESpace->fe().geoMap(),
417 QuadratureRuleProvider::provideExactness (TETRA, 2 * pDegree) ) );
419 M_convectionUCFE.reset (
new currentFE_Type (M_uFESpace->refFE(),
420 M_uFESpace->fe().geoMap(),
421 QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree + betaDegree - 1) ) );
423 M_convectionBetaCFE.reset (
new currentFE_Type (M_betaFESpace->refFE(),
424 M_uFESpace->fe().geoMap(),
425 QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree + betaDegree - 1) ) );
427 M_convectionRhsUCFE.reset (
new currentFE_Type (M_betaFESpace->refFE(),
428 M_uFESpace->fe().geoMap(),
429 QuadratureRuleProvider::provideExactness (TETRA, 2 * betaDegree + betaDegree - 1) ) );
431 M_localViscous.reset (
new localMatrix_Type (M_uFESpace->fe().nbFEDof(),
432 M_uFESpace->fieldDim(),
433 M_uFESpace->fieldDim() ) );
435 M_localGradPressure.reset (
new localMatrix_Type (M_uFESpace->fe().nbFEDof(), nDimensions, 0,
436 M_pFESpace->fe().nbFEDof(), 0, 1) );
438 M_localDivergence.reset (
new localMatrix_Type (M_uFESpace->fe().nbFEDof(), 0, nDimensions,
439 M_pFESpace->fe().nbFEDof(), 1, 0) );
441 M_localMass.reset (
new localMatrix_Type (M_uFESpace->fe().nbFEDof(),
442 M_uFESpace->fieldDim(),
443 M_uFESpace->fieldDim() ) );
445 M_localMassPressure.reset (
new localMatrix_Type (M_pFESpace->fe().nbFEDof(),
446 M_pFESpace->fieldDim(),
447 M_pFESpace->fieldDim() ) );
448 M_localConvection.reset (
new localMatrix_Type (M_uFESpace->fe().nbFEDof(),
449 M_uFESpace->fieldDim(),
450 M_uFESpace->fieldDim() ) );
452 M_localConvectionRhs.reset (
new localVector_Type (M_uFESpace->fe().nbFEDof(), M_uFESpace->fieldDim() ) );
454 M_massRhsCFE.reset (
new currentFE_Type (M_uFESpace->refFE(), M_uFESpace->fe().geoMap(), M_uFESpace->qr() ) );
456 M_localMassRhs.reset (
new localVector_Type (M_uFESpace->fe().nbFEDof(), M_uFESpace->fieldDim() ) );
463 template<
typename meshType,
typename matrixType,
typename vectorType>
468 ASSERT (M_uFESpace != 0,
"No FE space for assembling the viscous stress.");
469 ASSERT (offsetLeft + M_uFESpace->dof().numTotalDof() * (M_uFESpace->fieldDim() ) <=
470 UInt (matrix.matrixPtr()->NumGlobalCols() ),
471 " The matrix is too small (columns) for the assembly of the viscous stress");
472 ASSERT (offsetUp + M_uFESpace->dof().numTotalDof() * (M_uFESpace->fieldDim() ) <=
473 UInt (matrix.matrixPtr()->NumGlobalRows() ),
474 " The matrix is too small (rows) for the assembly of the viscous stress");
477 const UInt nbElements (M_uFESpace->mesh()->numElements() );
478 const UInt fieldDim (M_uFESpace->fieldDim() );
479 const UInt nbTotalDof (M_uFESpace->dof().numTotalDof() );
482 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
485 M_viscousCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
488 M_localViscous->zero();
491 AssemblyElemental::stiffness (*M_localViscous, *M_viscousCFE, viscosity, fieldDim);
494 for (
UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
496 assembleMatrix ( matrix,
502 iFieldDim, iFieldDim,
503 iFieldDim * nbTotalDof + offsetUp, iFieldDim * nbTotalDof + offsetLeft);
508 template<
typename meshType,
typename matrixType,
typename vectorType>
513 ASSERT (M_uFESpace != 0,
"No FE space for assembling the stiff strain.");
514 ASSERT (offsetLeft + M_uFESpace->dof().numTotalDof() * (M_uFESpace->fieldDim() ) <=
515 UInt (matrix.matrixPtr()->NumGlobalCols() ),
516 " The matrix is too small (columns) for the assembly of the stiff strain");
517 ASSERT (offsetUp + M_uFESpace->dof().numTotalDof() * (M_uFESpace->fieldDim() ) <=
518 UInt (matrix.matrixPtr()->NumGlobalRows() ),
519 " The matrix is too small (rows) for the assembly of the stiff strain");
522 const UInt nbElements (M_uFESpace->mesh()->numElements() );
523 const UInt fieldDim (M_uFESpace->fieldDim() );
524 const UInt nbTotalDof (M_uFESpace->dof().numTotalDof() );
527 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
530 M_viscousCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
533 M_localViscous->zero();
536 AssemblyElemental::stiffStrain (*M_localViscous, *M_viscousCFE, 2.0 * viscosity, fieldDim);
539 for (
UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
541 for (
UInt jFieldDim (0); jFieldDim < fieldDim; ++jFieldDim)
543 assembleMatrix ( matrix,
549 iFieldDim, jFieldDim,
550 iFieldDim * nbTotalDof + offsetUp, jFieldDim * nbTotalDof + offsetLeft);
556 template<
typename meshType,
typename matrixType,
typename vectorType>
561 ASSERT (M_uFESpace != 0,
"No velocity FE space for assembling the pressure gradient.");
562 ASSERT (M_pFESpace != 0,
"No pressure FE space for assembling the pressure gradient.");
563 ASSERT (offsetLeft + M_pFESpace->dof().numTotalDof() <=
564 UInt (matrix.matrixPtr()->NumGlobalCols() ),
565 "The matrix is too small (columns) for the assembly of the pressure gradient");
566 ASSERT (offsetUp + M_uFESpace->dof().numTotalDof() *nDimensions <=
567 UInt (matrix.matrixPtr()->NumGlobalRows() ),
568 " The matrix is too small (rows) for the assembly of the pressure gradient");
571 const UInt nbElements (M_uFESpace->mesh()->numElements() );
572 const UInt fieldDim (M_uFESpace->fieldDim() );
573 const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
576 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
579 M_gradPressureUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
580 M_gradPressurePCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
583 M_localGradPressure->zero();
586 AssemblyElemental::grad (*M_localGradPressure, *M_gradPressureUCFE, *M_gradPressurePCFE, fieldDim);
591 assembleMatrix ( matrix,
592 *M_localGradPressure,
598 iFieldDim * nbUTotalDof + offsetUp, offsetLeft);
603 template<
typename meshType,
typename matrixType,
typename vectorType>
608 ASSERT (M_uFESpace != 0,
"No velocity FE space for assembling the pressure gradient.");
609 ASSERT (M_pFESpace != 0,
"No pressure FE space for assembling the pressure gradient.");
610 ASSERT (offsetUp + M_pFESpace->dof().numTotalDof() <=
611 UInt (matrix.matrixPtr()->NumGlobalCols() ),
612 "The matrix is too small (columns) for the assembly of the pressure gradient");
613 ASSERT (offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions <=
614 UInt (matrix.matrixPtr()->NumGlobalRows() ),
615 " The matrix is too small (rows) for the assembly of the pressure gradient");
618 const UInt nbElements (M_uFESpace->mesh()->numElements() );
619 const UInt fieldDim (M_uFESpace->fieldDim() );
620 const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
623 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
626 M_gradPressureUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
627 M_gradPressurePCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
630 M_localGradPressure->zero();
633 AssemblyElemental::grad (*M_localGradPressure, *M_gradPressureUCFE, *M_gradPressurePCFE, fieldDim);
638 assembleTransposeMatrix ( matrix,
640 *M_localGradPressure,
646 offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
650 template<
typename meshType,
typename matrixType,
typename vectorType>
655 ASSERT (M_uFESpace != 0,
"No velocity FE space for assembling the divergence.");
656 ASSERT (M_pFESpace != 0,
"No pressure FE space for assembling the divergence.");
657 ASSERT (offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions <=
658 UInt (matrix.matrixPtr()->NumGlobalCols() ),
659 "The matrix is too small (columns) for the assembly of the divergence");
660 ASSERT (offsetUp + M_pFESpace->dof().numTotalDof() <=
661 UInt ( matrix.matrixPtr()->NumGlobalRows() ),
662 " The matrix is too small (rows) for the assembly of the divergence");
665 const UInt nbElements (M_uFESpace->mesh()->numElements() );
666 const UInt fieldDim (M_uFESpace->fieldDim() );
667 const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
670 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
673 M_divergenceUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
674 M_divergencePCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
677 M_localDivergence->zero();
680 AssemblyElemental::divergence (*M_localDivergence, *M_divergenceUCFE, *M_divergencePCFE, fieldDim, coefficient);
685 assembleMatrix ( matrix,
692 offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
698 template<
typename meshType,
typename matrixType,
typename vectorType>
704 if (beta.mapType() ==
Unique)
706 addConvection (matrix, coefficient, vectorType (beta,
Repeated), offsetLeft, offsetUp);
710 ASSERT (M_uFESpace != 0,
"No velocity FE space for assembling the convection.");
711 ASSERT (M_betaFESpace != 0,
"No convective FE space for assembling the convection.");
712 ASSERT (
static_cast<Int> (offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions) <= matrix.matrixPtr()->NumGlobalCols(),
713 "The matrix is too small (columns) for the assembly of the convection");
714 ASSERT (
static_cast<Int> (offsetUp + M_uFESpace->dof().numTotalDof() *nDimensions) <= matrix.matrixPtr()->NumGlobalRows(),
715 " The matrix is too small (rows) for the assembly of the convection");
718 const UInt nbElements (M_uFESpace->mesh()->numElements() );
719 const UInt fieldDim (M_uFESpace->fieldDim() );
720 const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
721 const UInt nbQuadPt (M_convectionUCFE->nbQuadPt() );
723 std::vector< std::vector< Real > > localBetaValue (nbQuadPt, std::vector<Real> (nDimensions, 0.0) );
726 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
729 M_convectionUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
732 M_localConvection->zero();
735 AssemblyElemental::interpolate (localBetaValue, *M_convectionBetaCFE, nDimensions, M_betaFESpace->dof(), iterElement, beta);
738 AssemblyElemental::advection (*M_localConvection, *M_convectionUCFE, coefficient, localBetaValue, fieldDim);
743 assembleMatrix ( matrix,
749 iFieldDim, iFieldDim,
750 iFieldDim * nbUTotalDof + offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
755 template<
typename meshType,
typename matrixType,
typename vectorType>
761 if ( beta.mapType() ==
Unique )
763 addNewtonConvection ( matrix, vectorType ( beta,
Repeated ), offsetLeft, offsetUp );
767 ASSERT ( M_uFESpace != 0,
"No velocity FE space for assembling the convection." );
768 ASSERT ( M_betaFESpace != 0,
"No convective FE space for assembling the convection." );
769 ASSERT ( offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalCols(),
770 "The matrix is too small (columns) for the assembly of the convection" );
771 ASSERT ( offsetUp + M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalRows(),
772 " The matrix is too small (rows) for the assembly of the convection" );
775 const UInt nbElements ( M_uFESpace->mesh()->numElements() );
776 const UInt fieldDim ( M_uFESpace->fieldDim() );
777 const UInt nbUTotalDof ( M_uFESpace->dof().numTotalDof() );
780 for (
UInt iterElement ( 0 ); iterElement < nbElements; ++iterElement )
783 M_convectionUCFE->update ( M_uFESpace->mesh()->element ( iterElement ), UPDATE_DPHI | UPDATE_WDET );
786 M_localConvection->zero();
788 localVector_Type betaLocal ( M_uFESpace->fe().nbFEDof(), M_uFESpace->fieldDim() );
791 for ( UInt iNode = 0 ; iNode < M_uFESpace->fe().nbFEDof() ; iNode++ )
793 UInt iLocal = M_uFESpace->fe().patternFirst ( iNode );
795 for ( Int iComponent = 0; iComponent < fieldDim; ++iComponent )
797 UInt iGlobal = M_uFESpace->dof().localToGlobalMap ( iterElement, iLocal ) + iComponent * nbUTotalDof;
800 betaLocal.vec() [ iLocal + iComponent * M_uFESpace->fe().nbFEDof() ] = beta ( iGlobal );
809 AssemblyElemental::advectionNewton ( 1.0, betaLocal, *M_localConvection,
810 *M_convectionUCFE, iFieldDim, jFieldDim );
811 assembleMatrix ( matrix,
817 iFieldDim, jFieldDim,
818 iFieldDim * nbUTotalDof + offsetUp, jFieldDim * nbUTotalDof + offsetLeft );
824 template<
typename meshType,
typename matrixType,
typename vectorType>
831 if (beta.mapType() ==
Unique)
833 addSymmetricConvection (matrix, coefficient, vectorType (beta,
Repeated), offsetLeft, offsetUp);
837 ASSERT (M_uFESpace != 0,
"No velocity FE space for assembling the convection.");
838 ASSERT (M_betaFESpace != 0,
"No convective FE space for assembling the convection.");
839 ASSERT ( (
int) offsetLeft + (
int) M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalCols(),
840 "The matrix is too small (columns) for the assembly of the convection");
841 ASSERT ( (
int) offsetUp + (
int) M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalRows(),
842 " The matrix is too small (rows) for the assembly of the convection");
845 const UInt nbElements (M_uFESpace->mesh()->numElements() );
846 const UInt fieldDim (M_uFESpace->fieldDim() );
847 const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
848 const UInt nbQuadPt (M_convectionUCFE->nbQuadPt() );
850 std::vector< std::vector< Real > > localBetaValue (nbQuadPt, std::vector<Real> (nDimensions, 0.0) );
851 std::vector< std::vector< std::vector< Real > > >
852 localBetaGradient (nbQuadPt, std::vector<std::vector<Real> > (nDimensions, std::vector<Real> (nDimensions, 0.0) ) );
855 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
858 M_convectionUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
859 M_convectionBetaCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI );
862 M_localConvection->zero();
865 AssemblyElemental::interpolate (localBetaValue, *M_convectionBetaCFE, nDimensions, M_betaFESpace->dof(), iterElement, beta);
867 AssemblyElemental::interpolateGradient (localBetaGradient, *M_convectionBetaCFE, nDimensions, M_betaFESpace->dof(), iterElement, beta);
873 AssemblyElemental::symmetrizedAdvection (*M_localConvection, *M_convectionUCFE, coefficient, localBetaGradient, fieldDim);
881 assembleMatrix ( matrix,
887 iFieldDim, jFieldDim,
888 iFieldDim * nbUTotalDof + offsetUp, jFieldDim * nbUTotalDof + offsetLeft);
894 template<
typename meshType,
typename matrixType,
typename vectorType>
900 if (velocity.mapType() ==
Unique)
907 ASSERT (M_betaFESpace != 0,
"No convective FE space for assembling the convection.");
910 const UInt nbElements (M_betaFESpace->mesh()->numElements() );
911 const UInt fieldDim (M_betaFESpace->fieldDim() );
912 const UInt dim (M_betaFESpace->dim() );
913 const UInt nbFEDof (M_convectionRhsUCFE->nbFEDof() );
916 VectorElemental localVelocity (M_betaFESpace->fe().nbFEDof(), fieldDim);
919 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
922 M_convectionRhsUCFE->update ( M_betaFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
925 M_localConvectionRhs->zero();
926 localVelocity.zero();
928 for (
UInt iNode = 0 ; iNode < nbFEDof ; iNode++ )
930 UInt iLocal = M_betaFESpace->fe().patternFirst ( iNode );
932 for (
UInt iComponent = 0; iComponent < fieldDim; ++iComponent )
934 UInt iGlobal = M_betaFESpace->dof().localToGlobalMap ( iterElement, iLocal ) + iComponent * dim;
936 localVelocity.vec( ) [ iLocal + iComponent * nbFEDof ] = velocity ( iGlobal );
940 AssemblyElemental::source_advection (coefficient, localVelocity, localVelocity, *M_localConvectionRhs, *M_convectionRhsUCFE);
943 for (
UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim)
945 assembleVector ( rhs,
947 *M_localConvectionRhs,
949 M_betaFESpace->dof(),
951 iterFDim * M_betaFESpace->dof().numTotalDof() );
956 template<
typename meshType,
typename matrixType,
typename vectorType>
962 ASSERT (M_uFESpace != 0,
"No velocity FE space for assembling the mass.");
963 ASSERT (
static_cast<Int> (offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions) <= matrix.matrixPtr()->NumGlobalCols(),
964 "The matrix is too small (columns) for the assembly of the mass");
965 ASSERT (
static_cast<Int> (offsetUp + M_uFESpace->dof().numTotalDof() *nDimensions) <= matrix.matrixPtr()->NumGlobalRows(),
966 " The matrix is too small (rows) for the assembly of the mass");
969 const UInt nbElements (M_uFESpace->mesh()->numElements() );
970 const UInt fieldDim (M_uFESpace->fieldDim() );
971 const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
974 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
977 M_massCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
983 AssemblyElemental::mass (*M_localMass, *M_massCFE, coefficient, fieldDim);
988 assembleMatrix ( matrix,
994 iFieldDim, iFieldDim,
995 iFieldDim * nbUTotalDof + offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
1000 template<
typename meshType,
typename matrixType,
typename vectorType>
1006 ASSERT (M_pFESpace != 0,
"No pressure FE space for assembling the mass.");
1007 ASSERT ( (
int) offsetLeft + (
int) M_pFESpace->dof().numTotalDof() <= matrix.matrixPtr()->NumGlobalCols(),
1008 "The matrix is too small (columns) for the assembly of the mass");
1009 ASSERT ( (
int) offsetUp + (
int) M_pFESpace->dof().numTotalDof() <= matrix.matrixPtr()->NumGlobalRows(),
1010 " The matrix is too small (rows) for the assembly of the mass");
1013 const UInt nbElements (M_pFESpace->mesh()->numElements() );
1014 const UInt fieldDim (M_pFESpace->fieldDim() );
1018 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
1021 M_massPressureCFE->update ( M_pFESpace->mesh()->element (iterElement), UPDATE_WDET );
1024 M_localMassPressure->zero();
1027 AssemblyElemental::mass (*M_localMassPressure, *M_massPressureCFE, coefficient, fieldDim);
1030 for (
UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
1032 assembleMatrix ( matrix,
1033 *M_localMassPressure,
1038 iFieldDim, iFieldDim,
1039 offsetUp, offsetLeft);
1044 template<
typename meshType,
typename matrixType,
typename vectorType>
1050 if (beta.mapType() ==
Unique)
1052 addMassDivW (matrix, coefficient, vectorType (beta,
Repeated), offsetLeft, offsetUp);
1056 ASSERT (M_uFESpace != 0,
"No velocity FE space for assembling the mass.");
1057 ASSERT (M_betaFESpace != 0,
"No convective FE space for assembling the divergence.");
1058 ASSERT ( (
int) offsetLeft + (
int) M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalCols(),
1059 "The matrix is too small (columns) for the assembly of the mass");
1060 ASSERT ( (
int) offsetUp + (
int) M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalRows(),
1061 " The matrix is too small (rows) for the assembly of the mass");
1064 const UInt nbElements (M_uFESpace->mesh()->numElements() );
1065 const UInt fieldDim (M_uFESpace->fieldDim() );
1066 const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
1067 const UInt nbQuadPt (M_convectionUCFE->nbQuadPt() );
1069 std::vector< Real > localBetaDivergence (nbQuadPt);
1072 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
1075 M_convectionUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
1076 M_convectionBetaCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
1079 M_localMass->zero();
1082 AssemblyElemental::interpolateDivergence (localBetaDivergence, *M_convectionBetaCFE, M_betaFESpace->dof(), iterElement, beta);
1085 AssemblyElemental::massDivW (*M_localMass, *M_convectionUCFE, coefficient, localBetaDivergence, fieldDim);
1090 assembleMatrix ( matrix,
1096 iFieldDim, iFieldDim,
1097 iFieldDim * nbUTotalDof + offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
1102 template<
typename meshType,
typename matrixType,
typename vectorType>
1108 ASSERT (M_uFESpace != 0,
"No FE space for assembling the right hand side (mass)!");
1111 const UInt nbElements (M_uFESpace->mesh()->numElements() );
1112 const UInt fieldDim (M_uFESpace->fieldDim() );
1113 const UInt nbFEDof (M_massRhsCFE->nbFEDof() );
1116 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
1119 M_massRhsCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_QUAD_NODES | UPDATE_WDET );
1122 M_localMassRhs->zero();
1124 AssemblyElemental::bodyForces ( *M_localMassRhs,
1130 for (
UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim)
1132 assembleVector ( rhs,
1138 iterFDim * M_uFESpace->dof().numTotalDof() );
1144 template<
typename meshType,
typename matrixType,
typename vectorType>
1151 for (
ID hCounter = 0; hCounter < bcHandler
.size(); ++hCounter )
1153 ASSERT ( bcHandler[ hCounter ].type() == Flux,
"Works only with Flux BC type!");
1154 ASSERT ( bcHandler.bcUpdateDone () ,
" Please call bcHandler::Update() before calling this method!");
1159 UInt nDofF = M_uFESpace->feBd().nbFEDof();
1162 UInt totalDof = M_uFESpace->dof().numTotalDof();
1181 M_uFESpace->feBd().update ( M_uFESpace->mesh()->boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS | UPDATE_QUAD_NODES );
1183 for (
ID idofF = 0; idofF < nDofF; ++idofF )
1185 for (
int ic = 0; ic < (
int) nComp; ++ic)
1190 for (
int iq = 0; iq < (
int) M_uFESpace->feBd().nbQuadPt(); ++iq )
1192 sum += M_uFESpace->feBd().phi (
int ( idofF ), iq ) *
1193 M_uFESpace->feBd().normal (ic , iq) *
1194 M_uFESpace->feBd().wRootDetMetric (iq);
1197 vector.sumIntoGlobalValues (idDof, sum);
1204 vector.globalAssemble();
VectorElemental localVector_Type
const BCBase & operator[](const ID &) const
Extract a BC in the list, const.
std::unique_ptr< currentFE_Type > currentFEPtr_Type
void addConvectionRhs(vectorType &rhs, const Real &coefficient, const vectorType &velocity)
Add an explicit convection term to the right hand side.
fespacePtr_Type M_uFESpace
void setup(const fespacePtr_Type &uFESpace, const fespacePtr_Type &pFESpace)
Setup method for the FESpaces.
localMatrixPtr_Type M_localMass
void addConvection(matrixType &matrix, const Real &coefficient, const vectorType &beta, const UInt &offsetLeft, const UInt offsetUp)
Add the convective term with the given offsets.
std::unique_ptr< localVector_Type > localVectorPtr_Type
void addSymmetricConvection(matrixType &matrix, const Real &coefficient, const vectorType &beta, const UInt &offsetLeft, const UInt offsetUp)
Add the symmetric convective term with the given offset.
OseenAssembler(const OseenAssembler &)
void addPressureMass(matrixType &matrix, const Real &coefficient, const UInt &offsetLeft, const UInt offsetUp)
Add the mass using offsets.
void setQuadRuleForMassRhs(const QuadratureRule &qr)
Setter for the quadrature used for the right hand side.
std::shared_ptr< fespace_Type > fespacePtr_Type
BCHandler - class for handling boundary conditions.
currentFEPtr_Type M_massPressureCFE
void addGradientTranspose(matrixType &matrix, const Real &coefficient=1.0)
Add the term corresponding to the divergence free constraint.
void addGradientTranspose(matrixType &matrix, const UInt &offsetLeft, const UInt &offsetUp, const Real &coefficient=1.0)
Add the divergence free constraint in a given position of the matrix using the grad calls...
currentFEPtr_Type M_convectionUCFE
currentFEPtr_Type M_viscousCFE
currentFEPtr_Type M_massRhsCFE
currentFEPtr_Type M_massCFE
bool isDataAVector() const
Returns True if a FE BCVector has been provided to the class, False otherwise.
localMatrixPtr_Type M_localGradPressure
void addViscousStress(matrixType &matrix, const Real &viscosity)
Add the viscous stress in the standard block.
OseenAssembler()
Empty Constructor.
localMatrixPtr_Type M_localDivergence
MatrixElemental localMatrix_Type
UInt numberOfComponents() const
Returns the number of components involved in this boundary condition.
Epetra_Import const & importer()
Getter for the Epetra_Import.
void addDivergence(matrixType &matrix, const UInt &offsetLeft, const UInt &offsetUp, const Real &coefficient=1.0)
Add the divergence free constraint in a given position of the matrix.
void addMassDivW(matrixType &matrix, const Real &coefficient, const vectorType &beta, const UInt &offsetLeft, const UInt offsetUp)
Add a consistent stabilizing term with the given offsets.
fespacePtr_Type M_betaFESpace
void addDivergence(matrixType &matrix, const Real &coefficient=1.0)
Add the term corresponding to the divergence free constraint.
localMatrixPtr_Type M_localConvection
localMatrixPtr_Type M_localMassPressure
void addFluxTerms(vectorType &vector, BCHandler const &bcHandler)
currentFEPtr_Type M_convectionBetaCFE
void addStiffStrain(matrixType &matrix, const Real &viscosity)
Add the stiff strain in the standard block.
ID boundaryLocalToGlobalMap(const ID &i) const
Return the global DOF corresponding tho the i-th local DOF in the face.
void addNewtonConvection(matrixType &matrix, const vectorType &beta, const UInt &offsetLeft, const UInt offsetUp)
Add the convective term necessary to build the Newton method.
currentFEPtr_Type M_gradPressureUCFE
currentFEPtr_Type M_gradPressurePCFE
void addMassDivW(matrixType &matrix, const Real &coefficient, const vectorType &beta)
Add a consistent stabilizing term.
std::shared_ptr< matrixType > matrixPtr_Type
double Real
Generic real data.
void addGradPressure(matrixType &matrix)
Add the term involved in the gradient of the pressure term.
OseenAssembler - Assembly class for the Oseen problem.
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
localMatrixPtr_Type M_localViscous
localVectorPtr_Type M_localMassRhs
currentFEPtr_Type M_divergenceUCFE
FESpace< meshType, map_Type > fespace_Type
void setup(const fespacePtr_Type &uFESpace, const fespacePtr_Type &pFESpace, const fespacePtr_Type &betaFESpace)
Setup method for the FESpace with a different space for the convective field.
const BCIdentifierBase * operator[](const ID &i) const
Returns a pointer to the (i)-th element of the list of identifiers.
void addNewtonConvection(matrixType &matrix, const vectorType &beta)
Add the convective term necessary to build the Newton method.
const UInt nDimensions(NDIM)
void addViscousStress(matrixType &matrix, const Real &viscosity, const UInt &offsetLeft, const UInt &offsetUp)
Add the viscous stress using the given offsets.
currentFEPtr_Type M_massBetaCFE
localVectorPtr_Type M_localConvectionRhs
void addMass(matrixType &matrix, const Real &coefficient)
Add the mass.
void addPressureMass(matrixType &matrix, const Real &coefficient)
Add the Pressure mass.
void addGradPressure(matrixType &matrix, const UInt &offsetLeft, const UInt &offsetUp)
Add the term involved in the gradient of the pressure term using the given offsets.
fespacePtr_Type M_pFESpace
BCIdentifierNatural - Idenifier for Natural and Robin Boundary Condiions.
void addSymmetricConvection(matrixType &matrix, const Real &coefficient, const vectorType &beta)
Add the convective term.
UInt size() const
Number of the stored boundary conditions.
QuadratureRule - The basis class for storing and accessing quadrature rules.
UInt list_size() const
Returns the size of the identifiers list.
void addMass(matrixType &matrix, const Real &coefficient, const UInt &offsetLeft, const UInt offsetUp)
Add the mass using offsets.
currentFEPtr_Type M_convectionRhsUCFE
void addStiffStrain(matrixType &matrix, const Real &viscosity, const UInt &offsetLeft, const UInt &offsetUp)
Add the stiff strain using the given offsets.
std::vector< std::shared_ptr< BCIdentifierBase > > M_idVector
container for id's when the list is finalized
std::unique_ptr< localMatrix_Type > localMatrixPtr_Type
currentFEPtr_Type M_divergencePCFE
virtual ~OseenAssembler()
Destructor.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
void addConvection(matrixType &matrix, const Real &coefficient, const vectorType &beta)
Add the convective term.
void addMassRhs(vectorType &rhs, const function_Type &fun, const Real &t)