39 #ifndef ADRASSEMBLER_H 40 #define ADRASSEMBLER_H 1
43 #include <boost/scoped_ptr.hpp> 46 #include <lifev/core/LifeV.hpp> 48 #include <lifev/core/util/LifeChrono.hpp> 50 #include <lifev/core/fem/Assembly.hpp> 51 #include <lifev/core/fem/FESpace.hpp> 52 #include <lifev/core/fem/AssemblyElemental.hpp> 165 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
175 typedef FESpace<mesh_type, map_Type> fespace_type;
176 typedef std::shared_ptr<fespace_type> fespace_ptrType;
178 typedef std::shared_ptr<matrix_type> matrix_ptrType;
183 typedef std::function<Real (
const Real&,
const Real&,
const Real&,
const Real&,
const ID&) > function_type;
195 virtual ~ADRAssembler() {}
214 void setup (
const fespace_ptrType& fespace,
const fespace_ptrType& betaFESpace);
223 inline void addMass (matrix_ptrType matrix,
const Real& coefficient = 1.0)
225 addMass (matrix, coefficient, 0, 0);
234 void addMass (matrix_ptrType matrix,
const Real& coefficient,
const UInt& offsetLeft,
const UInt& offsetUp);
245 inline void addAdvection (matrix_ptrType matrix,
const vector_type& beta)
247 addAdvection (matrix, beta, 0, 0);
256 void addAdvection (matrix_ptrType matrix,
const vector_type& beta,
const UInt& offsetLeft,
const UInt& offsetUp);
265 inline void addDiffusion (matrix_ptrType matrix,
const Real& coefficient = 1.0)
267 addDiffusion (matrix, coefficient, 0, 0);
276 void addDiffusion (matrix_ptrType matrix,
const Real& coefficient,
const UInt& offsetLeft,
const UInt& offsetUp);
279 void addStiffStrain (matrix_ptrType& matrix,
const Real& coefficient = 1.0)
281 addStiffStrain (matrix, coefficient, 0, 0);
285 void addStiffStrain (matrix_ptrType& matrix,
const Real& coefficient,
const UInt& offsetLeft,
const UInt& offsetUp);
292 void addMassRhs (vector_type& rhs,
const vector_type& f);
299 void addMassRhs (vector_type& rhs,
const function_type& f,
const Real& t);
309 void setFespace (
const fespace_ptrType& fespace);
315 void setBetaFespace (
const fespace_ptrType& betaFESpace);
324 ASSERT (M_massCFE != 0,
"No mass currentFE for setting the quadrature rule!");
325 M_massCFE->setQuadRule (qr);
335 ASSERT (M_diffCFE != 0,
"No diffusion currentFE for setting the quadrature rule!");
336 M_diffCFE->setQuadRule (qr);
346 ASSERT (M_advCFE != 0,
"No advection (u) currentFE for setting the quadrature rule!");
347 ASSERT (M_advBetaCFE != 0,
"No advection (beta) currentFE for setting the quadrature rule!");
348 M_advCFE->setQuadRule (qr);
349 M_advBetaCFE->setQuadRule (qr);
359 ASSERT (M_massRhsCFE != 0,
"No Rhs currentFE for setting the quadrature rule!");
360 M_massRhsCFE->setQuadRule (qr);
370 chrono_type& massAssemblyChrono()
372 return M_massAssemblyChrono;
376 chrono_type& advectionAssemblyChrono()
378 return M_advectionAssemblyChrono;
382 chrono_type& diffusionAssemblyChrono()
384 return M_diffusionAssemblyChrono;
388 chrono_type& setupChrono()
390 return M_setupChrono;
394 chrono_type& massRhsAssemblyChrono()
396 return M_massRhsAssemblyChrono;
405 typedef std::unique_ptr<currentFE_type> currentFE_ptrType;
408 typedef std::unique_ptr<localMatrix_type> localMatrix_ptrType;
411 typedef std::unique_ptr<localVector_type> localVector_ptrType;
417 ADRAssembler (
const ADRAssembler&);
422 fespace_ptrType M_fespace;
425 fespace_ptrType M_betaFESpace;
428 currentFE_ptrType M_massCFE;
431 currentFE_ptrType M_diffCFE;
434 currentFE_ptrType M_advCFE;
437 currentFE_ptrType M_advBetaCFE;
440 currentFE_ptrType M_massRhsCFE;
444 localMatrix_ptrType M_localMass;
447 localMatrix_ptrType M_localAdv;
450 localMatrix_ptrType M_localDiff;
453 localVector_ptrType M_localMassRhs;
456 chrono_type M_diffusionAssemblyChrono;
457 chrono_type M_advectionAssemblyChrono;
458 chrono_type M_massAssemblyChrono;
459 chrono_type M_setupChrono;
460 chrono_type M_massRhsAssemblyChrono;
466 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
467 ADRAssembler< mesh_type, matrix_type, vector_type>::
484 M_diffusionAssemblyChrono
(),
485 M_advectionAssemblyChrono
(),
486 M_massAssemblyChrono
(),
488 M_massRhsAssemblyChrono
() 495 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
497 ADRAssembler< mesh_type, matrix_type, vector_type>::
498 setup (
const fespace_ptrType& fespace,
const fespace_ptrType& betaFESpace )
500 ASSERT (fespace != 0,
" Empty FE Space cannot setup the ADR assembler ");
501 ASSERT (betaFESpace != 0,
"Empty beta FE Space cannot setup the ADR assembler ");
505 setFespace (fespace);
506 setBetaFespace (betaFESpace);
515 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
517 ADRAssembler< mesh_type, matrix_type, vector_type>::
518 addMass (matrix_ptrType matrix,
const Real& coefficient,
const UInt& offsetLeft,
const UInt& offsetUp)
521 ASSERT (M_fespace != 0,
"No FE space for assembling the mass!");
526 const UInt nbElements (M_fespace->mesh()->numElements() );
527 const UInt fieldDim (M_fespace->fieldDim() );
528 const UInt nbTotalDof (M_fespace->dof().numTotalDof() );
531 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
534 M_massCFE->update ( M_fespace->mesh()->element (iterElement), UPDATE_WDET );
540 AssemblyElemental::mass (*M_localMass, *M_massCFE, coefficient, fieldDim);
543 for (
UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
545 assembleMatrix ( *matrix,
551 iFieldDim, iFieldDim,
552 iFieldDim * nbTotalDof + offsetLeft, iFieldDim * nbTotalDof + offsetUp);
560 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
562 ADRAssembler< mesh_type, matrix_type, vector_type>::
563 addAdvection (matrix_ptrType matrix,
const vector_type& beta,
const UInt& offsetLeft,
const UInt& offsetUp)
566 if (beta.mapType() ==
Unique)
568 addAdvection (matrix, vector_type (beta,
Repeated), offsetLeft, offsetUp);
573 ASSERT (M_fespace != 0,
"No FE space for assembling the advection!");
574 ASSERT (M_betaFESpace != 0,
"No FE space (beta) for assembling the advection!");
580 const UInt nbElements (M_fespace->mesh()->numElements() );
581 const UInt fieldDim (M_fespace->fieldDim() );
582 const UInt betaFieldDim (M_betaFESpace->fieldDim() );
583 const UInt nbTotalDof (M_fespace->dof().numTotalDof() );
584 const UInt nbQuadPt (M_advCFE->nbQuadPt() );
588 std::vector< std::vector< Real > > localBetaValue (nbQuadPt, std::vector<Real> ( betaFieldDim, 0.0 ) );
591 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
594 M_advCFE->update ( M_fespace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
600 AssemblyElemental::interpolate (localBetaValue, *M_advBetaCFE, betaFieldDim, M_betaFESpace->dof(), iterElement, beta);
603 AssemblyElemental::advection (*M_localAdv, *M_advCFE, 1.0, localBetaValue, fieldDim);
607 for (
UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
609 assembleMatrix ( *matrix,
615 iFieldDim, iFieldDim,
616 iFieldDim * nbTotalDof + offsetLeft, iFieldDim * nbTotalDof + offsetUp );
620 M_advectionAssemblyChrono
.stop();
623 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
625 ADRAssembler< mesh_type, matrix_type, vector_type>::
626 addDiffusion (matrix_ptrType matrix,
const Real& coefficient,
const UInt& offsetLeft,
const UInt& offsetUp)
629 ASSERT (M_fespace != 0,
"No FE space for assembling the diffusion!");
634 const UInt nbElements (M_fespace->mesh()->numElements() );
635 const UInt fieldDim (M_fespace->fieldDim() );
636 const UInt nbTotalDof (M_fespace->dof().numTotalDof() );
639 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
642 M_diffCFE->update ( M_fespace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
648 AssemblyElemental::stiffness (*M_localDiff, *M_diffCFE, coefficient, fieldDim);
651 for (
UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
653 assembleMatrix ( *matrix,
659 iFieldDim, iFieldDim,
660 iFieldDim * nbTotalDof + offsetLeft, iFieldDim * nbTotalDof + offsetUp );
664 M_diffusionAssemblyChrono
.stop();
667 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
669 ADRAssembler<mesh_type, matrix_type, vector_type>::
670 addStiffStrain (matrix_ptrType& matrix,
const Real& coefficient,
const UInt& offsetLeft,
const UInt& offsetUp)
672 ASSERT (M_fespace != 0,
"No FE space for assembling the stiff strain.");
673 ASSERT (offsetLeft + M_fespace->dof().numTotalDof() * (M_fespace->fieldDim() ) <=
674 UInt (matrix->matrixPtr()->NumGlobalCols() ),
675 " The matrix is too small (columns) for the assembly of the stiff strain");
676 ASSERT (offsetUp + M_fespace->dof().numTotalDof() * (M_fespace->fieldDim() ) <=
677 UInt (matrix->matrixPtr()->NumGlobalRows() ),
678 " The matrix is too small (rows) for the assembly of the stiff strain");
681 const UInt nbElements (M_fespace->mesh()->numElements() );
682 const UInt fieldDim (M_fespace->fieldDim() );
683 const UInt nbTotalDof (M_fespace->dof().numTotalDof() );
686 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
689 M_diffCFE->update ( M_fespace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
695 AssemblyElemental::stiffStrain (*M_localDiff, *M_diffCFE, 2.0 * coefficient, fieldDim);
698 for (
UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
700 for (
UInt jFieldDim (0); jFieldDim < fieldDim; ++jFieldDim)
702 assembleMatrix ( *matrix,
708 iFieldDim, jFieldDim,
709 iFieldDim * nbTotalDof + offsetUp, jFieldDim * nbTotalDof + offsetLeft);
715 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
717 ADRAssembler< mesh_type, matrix_type, vector_type>::
718 addMassRhs (vector_type& rhs,
const vector_type& f)
721 if (f.mapType() ==
Unique)
723 addMassRhs (rhs, vector_type (f,
Repeated) );
728 ASSERT (M_fespace != 0,
"No FE space for assembling the right hand side (mass)!");
733 const UInt nbElements (M_fespace->mesh()->numElements() );
734 const UInt fieldDim (M_fespace->fieldDim() );
735 const UInt nbFEDof (M_massRhsCFE->nbFEDof() );
736 const UInt nbQuadPt (M_massRhsCFE->nbQuadPt() );
737 const UInt nbTotalDof (M_fespace->dof().numTotalDof() );
740 Real localValue (0.0);
741 std::vector<Real> fValues (nbQuadPt, 0.0);
744 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
747 M_massRhsCFE->update ( M_fespace->mesh()->element (iterElement), UPDATE_WDET );
750 M_localMassRhs->zero();
753 for (
UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim)
755 localVector_type::
vector_view localView = M_localMassRhs->block (iterFDim);
758 for (
UInt iQuadPt (0); iQuadPt < nbQuadPt; ++iQuadPt)
760 fValues[iQuadPt] = 0.0;
761 for (
UInt iDof (0); iDof < nbFEDof ; ++iDof)
764 f[ M_fespace->dof().localToGlobalMap (iterElement, iDof) + iterFDim * nbTotalDof]
765 * M_massRhsCFE->phi (iDof, iQuadPt);
770 for (
UInt iDof (0); iDof < nbFEDof ; ++iDof)
775 for (
UInt iQuadPt (0); iQuadPt < nbQuadPt; ++iQuadPt)
777 localValue += fValues[iQuadPt]
778 * M_massRhsCFE->phi (iDof, iQuadPt)
779 * M_massRhsCFE->wDetJacobian (iQuadPt);
783 localView (iDof) = localValue;
788 for (
UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim)
790 assembleVector ( rhs,
796 iterFDim * M_fespace->dof().numTotalDof() );
800 M_massRhsAssemblyChrono
.stop();
803 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
805 ADRAssembler< mesh_type, matrix_type, vector_type>::
806 addMassRhs (vector_type& rhs,
const function_type& f,
const Real& t)
809 ASSERT (M_fespace != 0,
"No FE space for assembling the right hand side (mass)!");
814 const UInt nbElements (M_fespace->mesh()->numElements() );
815 const UInt fieldDim (M_fespace->fieldDim() );
816 const UInt nbFEDof (M_massRhsCFE->nbFEDof() );
817 const UInt nbQuadPt (M_massRhsCFE->nbQuadPt() );
820 Real localValue (0.0);
821 std::vector<Real> fValues (nbQuadPt, 0.0);
824 for (
UInt iterElement (0); iterElement < nbElements; ++iterElement)
827 M_massRhsCFE->update ( M_fespace->mesh()->element (iterElement), UPDATE_QUAD_NODES | UPDATE_WDET );
830 M_localMassRhs->zero();
833 for (
UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim)
835 localVector_type::
vector_view localView = M_localMassRhs->block (iterFDim);
838 for (
UInt iQuadPt (0); iQuadPt < nbQuadPt; ++iQuadPt)
840 fValues[iQuadPt] = f (t,
841 M_massRhsCFE->quadNode (iQuadPt, 0),
842 M_massRhsCFE->quadNode (iQuadPt, 1),
843 M_massRhsCFE->quadNode (iQuadPt, 2),
848 for (
UInt iDof (0); iDof < nbFEDof ; ++iDof)
853 for (
UInt iQuadPt (0); iQuadPt < nbQuadPt; ++iQuadPt)
855 localValue += fValues[iQuadPt]
856 * M_massRhsCFE->phi (iDof, iQuadPt)
857 * M_massRhsCFE->wDetJacobian (iQuadPt);
861 localView (iDof) = localValue;
866 for (
UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim)
868 assembleVector ( rhs,
874 iterFDim * M_fespace->dof().numTotalDof() );
878 M_massRhsAssemblyChrono
.stop();
886 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
888 ADRAssembler< mesh_type, matrix_type, vector_type>::
889 setFespace (
const fespace_ptrType& fespace)
891 ASSERT (fespace != 0,
" Setting the FE space for the unknown to 0 is not permitted ");
895 M_massCFE.reset (
new currentFE_type (M_fespace->refFE(), M_fespace->fe().geoMap(), M_fespace->qr() ) );
896 M_localMass.reset (
new localMatrix_type (M_fespace->fe().nbFEDof(),
897 M_fespace->fieldDim(),
898 M_fespace->fieldDim() ) );
900 M_advCFE.reset (
new currentFE_type (M_fespace->refFE(), M_fespace->fe().geoMap(), M_fespace->qr() ) );
901 M_localAdv.reset (
new localMatrix_type (M_fespace->fe().nbFEDof(),
902 M_fespace->fieldDim(),
903 M_fespace->fieldDim() ) );
905 M_diffCFE.reset (
new currentFE_type (M_fespace->refFE(), M_fespace->fe().geoMap(), M_fespace->qr() ) );
906 M_localDiff.reset (
new localMatrix_type (M_fespace->fe().nbFEDof(),
907 M_fespace->fieldDim(),
908 M_fespace->fieldDim() ) );
910 M_massRhsCFE.reset (
new currentFE_type (M_fespace->refFE(), M_fespace->fe().geoMap(), M_fespace->qr() ) );
911 M_localMassRhs.reset (
new localVector_type (M_fespace->fe().nbFEDof(), M_fespace->fieldDim() ) );
914 template<
typename mesh_type,
typename matrix_type,
typename vector_type>
916 ADRAssembler< mesh_type, matrix_type, vector_type>::
917 setBetaFespace (
const fespace_ptrType& betaFESpace)
919 ASSERT (M_fespace != 0,
" No FE space for the unknown! Use setFespace before setBetaFespace!");
920 ASSERT (M_advCFE != 0,
" No current FE set for the advection of the unknown! Internal error.");
921 M_betaFESpace = betaFESpace;
923 M_advBetaCFE.reset (
new currentFE_type (M_betaFESpace->refFE(), M_fespace->fe().geoMap(), M_advCFE->quadRule() ) );
void start()
Start the timer.
void updateInverseJacobian(const UInt &iQuadPt)
Epetra_Import const & importer()
Getter for the Epetra_Import.
double Real
Generic real data.
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
void stop()
Stop the timer.
QuadratureRule - The basis class for storing and accessing quadrature rules.
uint32_type UInt
generic unsigned integer (used mainly for addressing)