LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
loc_comp_ellbvp.h
1
9#include <map>
10
11#ifndef LF_LOCCOMPELLBVP
12#define LF_LOCCOMPELLBVP
13/***************************************************************************
14 * LehrFEM++ - A simple C++ finite element libray for teaching
15 * Developed from 2018 at the Seminar of Applied Mathematics of ETH Zurich,
16 * lead developers Dr. R. Casagrande and Prof. R. Hiptmair
17 ***************************************************************************/
18
19#include <lf/mesh/utils/utils.h>
20#include <lf/quad/quad.h>
21
22#include <iostream>
23
24#include "precomputed_scalar_reference_finite_element.h"
25#include "uscalfe.h"
26
27namespace lf::uscalfe {
33using quad_rule_collection_t = std::map<lf::base::RefEl, lf::quad::QuadRule>;
34
86template <typename SCALAR, typename DIFF_COEFF, typename REACTION_COEFF>
88 static_assert(mesh::utils::isMeshFunction<DIFF_COEFF>);
89 static_assert(mesh::utils::isMeshFunction<REACTION_COEFF>);
90
91 public:
95 using Scalar =
97 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>() +
99 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>())::Scalar;
100 using ElemMat = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
101
107 ReactionDiffusionElementMatrixProvider &&) noexcept = default;
129 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
130 DIFF_COEFF alpha, REACTION_COEFF gamma);
131
148 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
149 DIFF_COEFF alpha, REACTION_COEFF gamma,
150 quad_rule_collection_t qr_collection);
151
158 virtual bool isActive(const lf::mesh::Entity & /*cell*/) { return true; }
176 ElemMat Eval(const lf::mesh::Entity &cell);
177
180
181 private:
185 DIFF_COEFF alpha_;
187 REACTION_COEFF gamma_;
190 // fe_precomp_[i] contains precomputed reference finite element for ref_el i.
191 std::array<PrecomputedScalarReferenceFiniteElement<SCALAR>, 5> fe_precomp_;
192};
193
197std::shared_ptr<spdlog::logger> &ReactionDiffusionElementMatrixProviderLogger();
198
199template <class PTR, class DIFF_COEFF, class REACTION_COEFF>
200ReactionDiffusionElementMatrixProvider(PTR fe_space, DIFF_COEFF alpha,
201 REACTION_COEFF gamma)
203 typename PTR::element_type::Scalar, DIFF_COEFF, REACTION_COEFF>;
204
205template <class PTR, class DIFF_COEFF, class REACTION_COEFF>
207 PTR fe_space, DIFF_COEFF alpha, REACTION_COEFF gamma,
208 std::map<lf::base::RefEl, lf::quad::QuadRule>)
210 typename PTR::element_type::Scalar, DIFF_COEFF, REACTION_COEFF>;
211
212// First constructor (internal construction of quadrature rules
213template <typename SCALAR, typename DIFF_COEFF, typename REACTION_COEFF>
216 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
217 DIFF_COEFF alpha, REACTION_COEFF gamma)
218 : alpha_(std::move(alpha)), gamma_(std::move(gamma)), fe_precomp_() {
219 for (auto ref_el : {base::RefEl::kTria(), base::RefEl::kQuad()}) {
220 auto fe = fe_space->ShapeFunctionLayout(ref_el);
221 // Check whether shape functions for that entity type are available.
222 // Note that the corresponding PrecomputedScalarReferenceFiniteElement local
223 // object is not initialized if the associated description of local shape
224 // functions is missing.
225 if (fe != nullptr) {
226 // Precompute cell-independent quantities based on quadrature rules
227 // with twice the degree of exactness compared to the degree of the
228 // finite element space.
230 fe, quad::make_QuadRule(ref_el, 2 * fe->Degree()));
231 }
232 }
233}
234
235// Second constructor (quadrature rules passed as arguments)
236template <typename SCALAR, typename DIFF_COEFF, typename REACTION_COEFF>
239 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
240 DIFF_COEFF alpha, REACTION_COEFF gamma,
241 quad_rule_collection_t qr_collection)
242 : alpha_(std::move(alpha)), gamma_(std::move(gamma)), fe_precomp_() {
243 for (auto ref_el : {base::RefEl::kTria(), base::RefEl::kQuad()}) {
244 // Obtain pointer to an object describing local shape functions
245 auto fe = fe_space->ShapeFunctionLayout(ref_el);
246 // Check whether shape functions for that entity type are available
247 // Note that the corresponding PrecomputedScalarReferenceFiniteElement local
248 // object is not initialized if the associated description of local shape
249 // functions is missing.
250 if (fe != nullptr) {
251 // Obtain quadrature rule from user-supplied collection.
252 auto qr_coll_ptr = qr_collection.find(ref_el);
253 if (qr_coll_ptr != qr_collection.end()) {
254 // A quadrature rule for the current entity type is available
255 lf::quad::QuadRule qr = qr_coll_ptr->second;
256 LF_ASSERT_MSG(qr.RefEl() == ref_el,
257 "qr.RefEl() = " << qr.RefEl() << " <-> " << ref_el);
258 // Precomputations of cell-independent quantities
259 fe_precomp_[ref_el.Id()] =
261 }
262 }
263 }
264}
265
266// Main method for the computation of the element matrix
267template <typename SCALAR, typename DIFF_COEFF, typename REACTION_COEFF>
269 SCALAR, DIFF_COEFF, REACTION_COEFF>::ElemMat
271 SCALAR, DIFF_COEFF, REACTION_COEFF>::Eval(const lf::mesh::Entity &cell) {
272 // Topological type of the cell
273 const lf::base::RefEl ref_el{cell.RefEl()};
274 // Obtain precomputed information about values of local shape functions
275 // and their gradients at quadrature points.
277 fe_precomp_[ref_el.Id()];
278 if (!pfe.isInitialized()) {
279 // Accident: cell is of a type not covered by finite element
280 // specifications or there is no quadrature rule available for this
281 // reference element type
282 std::stringstream temp;
283 temp << "No local shape function information or no quadrature rule for "
284 "reference element type "
285 << ref_el;
286 throw base::LfException(temp.str());
287 }
288
289 // Query the shape of the cell
290 const lf::geometry::Geometry *geo_ptr = cell.Geometry();
291 LF_ASSERT_MSG(geo_ptr != nullptr, "Invalid geometry!");
292 LF_ASSERT_MSG((geo_ptr->DimLocal() == 2),
293 "Only 2D implementation available!");
295 "{}, shape = \n{}", ref_el,
296 geo_ptr->Global(ref_el.NodeCoords()));
297
298 // Physical dimension of the cell
299 const dim_t world_dim = geo_ptr->DimGlobal();
300 // Gram determinant at quadrature points
301 const Eigen::VectorXd determinants(
302 geo_ptr->IntegrationElement(pfe.Qr().Points()));
303 LF_ASSERT_MSG(
304 determinants.size() == pfe.Qr().NumPoints(),
305 "Mismatch " << determinants.size() << " <-> " << pfe.Qr().NumPoints());
306 // Fetch the transformation matrices for the gradients
307 const Eigen::MatrixXd JinvT(
308 geo_ptr->JacobianInverseGramian(pfe.Qr().Points()));
309 LF_ASSERT_MSG(
310 JinvT.cols() == 2 * pfe.Qr().NumPoints(),
311 "Mismatch " << JinvT.cols() << " <-> " << 2 * pfe.Qr().NumPoints());
312 LF_ASSERT_MSG(JinvT.rows() == world_dim,
313 "Mismatch " << JinvT.rows() << " <-> " << world_dim);
314
315 // compute values of coefficients alpha, gamma at quadrature points:
316 auto alphaval = alpha_(cell, pfe.Qr().Points());
317 auto gammaval = gamma_(cell, pfe.Qr().Points());
318
319 // Element matrix
321 mat.setZero();
322
323 // Loop over quadrature points
324 for (base::size_type k = 0; k < pfe.Qr().NumPoints(); ++k) {
325 const double w = pfe.Qr().Weights()[k] * determinants[k];
326 // Transformed gradients
327 const auto trf_grad(JinvT.block(0, 2 * k, world_dim, 2) *
329 .block(0, 2 * k, mat.rows(), 2)
330 .transpose());
331 // Transformed gradients multiplied with coefficient
332 const auto alpha_trf_grad(alphaval[k] * trf_grad);
333 mat += w * (trf_grad.adjoint() * alpha_trf_grad +
334 (gammaval[k] * pfe.PrecompReferenceShapeFunctions().col(k)) *
335 (pfe.PrecompReferenceShapeFunctions().col(k).adjoint()));
336 }
337 return mat;
338}
339
365template <typename SCALAR, typename COEFF, typename EDGESELECTOR>
367 public:
369 using scalar_t =
370 decltype(SCALAR(0) * mesh::utils::MeshFunctionReturnType<COEFF>(0));
371 using ElemMat = Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>;
372
377 MassEdgeMatrixProvider &operator=(const MassEdgeMatrixProvider &) = delete;
393 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space, COEFF gamma,
394 EDGESELECTOR edge_selector = base::PredicateTrue{})
395 : gamma_(std::move(gamma)),
396 edge_sel_(std::move(edge_selector)),
397 fe_precomp_() {
398 auto fe = fe_space->ShapeFunctionLayout(base::RefEl::kSegment());
399 LF_ASSERT_MSG(fe != nullptr, "No shape functions specified for edges");
400 // Precompute entity-independent quantities based on a LehrFEM++ built-in
401 // quadrature rule
403 fe, quad::make_QuadRule(base::RefEl::kSegment(), 2 * fe->Degree()));
404 }
417 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space, COEFF gamma,
418 lf::quad::QuadRule quadrule,
419 EDGESELECTOR edge_selector = base::PredicateTrue{})
420 : gamma_(std::move(gamma)),
421 edge_sel_(std::move(edge_selector)),
422 fe_precomp_() {
423 auto fe = fe_space->ShapeFunctionLayout(base::RefEl::kSegment());
424 LF_ASSERT_MSG(fe != nullptr, "No shape functions specified for edges");
425 LF_ASSERT_MSG(quadrule.RefEl() == base::RefEl::kSegment(),
426 "Quadrature rule not meant for EDGE entities!");
427 // Precompute entity-independent quantities
429 }
430
437 bool isActive(const lf::mesh::Entity &edge) {
438 LF_ASSERT_MSG(edge.RefEl() == lf::base::RefEl::kSegment(),
439 "Wrong type for an edge");
440 return edge_sel_(edge);
441 }
442
458 ElemMat Eval(const lf::mesh::Entity &edge);
459
460 virtual ~MassEdgeMatrixProvider() = default;
461
462 private:
463 COEFF gamma_; // functor for coefficient
464 EDGESELECTOR edge_sel_; // Defines the active edges
465 // Precomputed quantities at quadrature points
467};
468
472std::shared_ptr<spdlog::logger> &MassEdgeMatrixProviderLogger();
473
474// deduction guide:
475template <class PTR, class COEFF, class EDGESELECTOR = base::PredicateTrue>
476MassEdgeMatrixProvider(PTR, COEFF coeff,
477 EDGESELECTOR edge_predicate = base::PredicateTrue{})
478 -> MassEdgeMatrixProvider<typename PTR::element_type::Scalar, COEFF,
479 EDGESELECTOR>;
480
481// Eval() method
482// TODO(craffael) remove const once
483// https://
484// developercommunity.visualstudio.com/content/problem/180948/vs2017-155-c-cv-qualifiers-lost-on-type-alias-used.html
485// is resolved
486template <class SCALAR, class COEFF, class EDGESELECTOR>
489 const lf::mesh::Entity &edge) {
490 // Topological type of the cell
491 const lf::base::RefEl ref_el{edge.RefEl()};
492 LF_ASSERT_MSG(ref_el == lf::base::RefEl::kSegment(),
493 "Edge must be of segment type");
494 // Query the shape of the edge
495 const lf::geometry::Geometry *geo_ptr = edge.Geometry();
496 LF_ASSERT_MSG(geo_ptr != nullptr, "Invalid geometry!");
497
498 // Obtain the metric factors for the quadrature points
499 const Eigen::VectorXd determinants(
500 geo_ptr->IntegrationElement(fe_precomp_.Qr().Points()));
501 LF_ASSERT_MSG(determinants.size() == fe_precomp_.Qr().NumPoints(),
502 "Mismatch " << determinants.size() << " <-> "
503 << fe_precomp_.Qr().NumPoints());
504
505 // Element matrix
506 ElemMat mat(fe_precomp_.NumRefShapeFunctions(),
507 fe_precomp_.NumRefShapeFunctions());
508 mat.setZero();
509
510 auto gammaval = gamma_(edge, fe_precomp_.Qr().Points());
511
512 // Loop over quadrature points
513 for (long k = 0; k < determinants.size(); ++k) {
514 // Build local matrix by summing rank-1 contributions
515 // from quadrature points.
516 const auto w =
517 (fe_precomp_.Qr().Weights()[k] * determinants[k]) * gammaval[k];
518 mat += ((fe_precomp_.PrecompReferenceShapeFunctions().col(k)) *
519 (fe_precomp_.PrecompReferenceShapeFunctions().col(k).adjoint())) *
520 w;
521 }
522 return mat;
523}
524
556template <typename SCALAR, typename MESH_FUNCTION>
558 static_assert(mesh::utils::isMeshFunction<MESH_FUNCTION>);
559
560 public:
562 using scalar_t = decltype(
564 using ElemVec = Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>;
565
569 delete;
571 default;
573 const ScalarLoadElementVectorProvider &) = delete;
587 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
588 MESH_FUNCTION f);
598 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
599 MESH_FUNCTION f, quad_rule_collection_t qr_collection);
601 virtual bool isActive(const lf::mesh::Entity & /*cell*/) { return true; }
602 /*
603 * @brief Main method for computing the element vector
604 *
605 * @param cell current cell for which the element vector is desired
606 * @return local load vector as column vector
607 *
608 */
609 ElemVec Eval(const lf::mesh::Entity &cell);
610
612
613 private:
615 MESH_FUNCTION f_;
616
617 std::array<PrecomputedScalarReferenceFiniteElement<SCALAR>, 5> fe_precomp_;
618};
619
623std::shared_ptr<spdlog::logger> &ScalarLoadElementVectorProviderLogger();
624
625// Deduction guide
626template <class PTR, class MESH_FUNCTION>
627ScalarLoadElementVectorProvider(PTR fe_space, MESH_FUNCTION mf)
628 -> ScalarLoadElementVectorProvider<typename PTR::element_type::Scalar,
629 MESH_FUNCTION>;
630
631// Constructors
632template <typename SCALAR, typename MESH_FUNCTION>
635 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
636 MESH_FUNCTION f)
637 : f_(std::move(f)) {
638 for (auto ref_el : {base::RefEl::kTria(), base::RefEl::kQuad()}) {
639 auto fe = fe_space->ShapeFunctionLayout(ref_el);
640 // Check whether shape functions for that entity type are available
641 if (fe != nullptr) {
642 // Precompute cell-independent quantities based on quadrature rules
643 // with twice the degree of exactness compared to the degree of the
644 // finite element space.
645 fe_precomp_[ref_el.Id()] =
647 fe, quad::make_QuadRule(ref_el, 2 * fe->Degree()));
648 }
649 }
650}
651
652template <typename SCALAR, typename MESH_FUNCTION>
655 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
656 MESH_FUNCTION f, quad_rule_collection_t qr_collection)
657 : f_(std::move(f)) {
658 for (auto ref_el : {base::RefEl::kTria(), base::RefEl::kQuad()}) {
659 auto fe = fe_space->ShapeFunctionLayout(ref_el);
660 // Check whether shape functions for that entity type are available
661 if (fe != nullptr) {
662 // Obtain quadrature rule from user-supplied collection.
663 auto qr_coll_ptr = qr_collection.find(ref_el);
664 if (qr_coll_ptr != qr_collection.end()) {
665 // A quadrature rule for the current entity type is available
666 lf::quad::QuadRule qr = qr_coll_ptr->second;
667 LF_ASSERT_MSG(qr.RefEl() == ref_el,
668 "qr.RefEl() = " << qr.RefEl() << " <-> " << ref_el);
669 // Precompute cell-independent quantities using the user-supplied
670 // quadrature rules
671 fe_precomp_[ref_el.Id()] =
673 } else {
674 // Quadrature rule is missing for an entity type for which
675 // local shape functions are available
676 LF_ASSERT_MSG(false, "Quadrature rule missing for " << ref_el);
677 }
678 }
679 }
680}
681
682// TODO(craffael) remove const once
683// http://developercommunity.visualstudio.com/content/problem/180948/vs2017-155-c-cv-qualifiers-lost-on-type-alias-used.html
684// is resolved
685template <typename SCALAR, typename MESH_FUNCTION>
688 const lf::mesh::Entity &cell) {
689 // Type for source function
691 // Topological type of the cell
692 const lf::base::RefEl ref_el{cell.RefEl()};
693 // Obtain precomputed information about values of local shape functions
694 // and their gradients at quadrature points.
695 auto &pfe = fe_precomp_[ref_el.Id()];
696 // Accident: cell is of a type not coverence by finite element specifications
697 LF_ASSERT_MSG(
698 pfe.isInitialized(),
699 "No local shape function information for entity type " << ref_el);
700
701 // Query the shape of the cell
702 const lf::geometry::Geometry *geo_ptr = cell.Geometry();
703 LF_ASSERT_MSG(geo_ptr != nullptr, "Invalid geometry!");
704 LF_ASSERT_MSG((geo_ptr->DimLocal() == 2),
705 "Only 2D implementation available!");
706 SPDLOG_LOGGER_TRACE(ScalarLoadElementVectorProviderLogger(),
707 "{}, shape = \n{}", ref_el,
708 geo_ptr->Global(ref_el.NodeCoords()));
709
710 // Obtain the metric factors for the quadrature points
711 const Eigen::VectorXd determinants(
712 geo_ptr->IntegrationElement(pfe.Qr().Points()));
713 LF_ASSERT_MSG(
714 determinants.size() == pfe.Qr().NumPoints(),
715 "Mismatch " << determinants.size() << " <-> " << pfe.Qr().NumPoints());
716 SPDLOG_LOGGER_TRACE(ScalarLoadElementVectorProviderLogger(),
717 "LOCVEC({}): Metric factors :\n{}", ref_el,
718 determinants.transpose());
719
720 // Element vector
721 ElemVec vec(pfe.NumRefShapeFunctions());
722 vec.setZero();
723
724 auto fval = f_(cell, pfe.Qr().Points());
725
726 // Loop over quadrature points
727 for (long k = 0; k < determinants.size(); ++k) {
728 SPDLOG_LOGGER_TRACE(ScalarLoadElementVectorProviderLogger(),
729 "LOCVEC: [{}] -> [weight = {}]",
730 pfe.Qr().Points().transpose(), pfe.Qr().Weights()[k]);
731 // Contribution of current quadrature point
732 vec += (pfe.Qr().Weights()[k] * determinants[k] * fval[k]) *
733 pfe.PrecompReferenceShapeFunctions().col(k).conjugate();
734 }
735
736 SPDLOG_LOGGER_TRACE(ScalarLoadElementVectorProviderLogger(), "LOCVEC = \n{}",
737 vec.transpose());
738
739 return vec;
740}
741
778template <class SCALAR, class FUNCTOR, class EDGESELECTOR = base::PredicateTrue>
780 public:
781 static_assert(mesh::utils::isMeshFunction<FUNCTOR>,
782 "FUNCTOR does not fulfill the concept of a mesh function.");
783 using Scalar =
784 decltype(SCALAR(0) * mesh::utils::MeshFunctionReturnType<FUNCTOR>(0));
785 using ElemVec = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
786
791 default;
793 const ScalarLoadEdgeVectorProvider &) = delete;
795 delete;
809 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space, FUNCTOR g,
810 EDGESELECTOR edge_sel = base::PredicateTrue{})
811 : g_(std::move(g)), edge_sel_(std::move(edge_sel)), pfe_() {
812 auto fe = fe_space->ShapeFunctionLayout(base::RefEl::kSegment());
813 LF_ASSERT_MSG(fe != nullptr, "No shape functions specified for edges");
814 // Precompute entity-independent quantities based on a LehrFEM++ built-in
815 // quadrature rule
817 fe, quad::make_QuadRule(base::RefEl::kSegment(), 2 * fe->Degree()));
818 }
819
828 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space, FUNCTOR g,
829 lf::quad::QuadRule quadrule,
830 EDGESELECTOR edge_sel = base::PredicateTrue{})
831 : g_(std::move(g)), edge_sel_(std::move(edge_sel)), pfe_() {
832 auto fe = fe_space->ShapeFunctionLayout(base::RefEl::kSegment());
833 LF_ASSERT_MSG(fe != nullptr, "No shape functions specified for edges");
834 LF_ASSERT_MSG(quadrule.RefEl() == base::RefEl::kSegment(),
835 "Quadrature rule not meant for EDGE entities!");
836 // Precompute entity-independent quantities
838 }
839
841 virtual bool isActive(const lf::mesh::Entity &cell) {
842 return edge_sel_(cell);
843 }
844 /*
845 * @brief Main method for computing the element vector
846 *
847 * @param cell current cell for which the element vector is desired
848 * @return local load vector as column vector
849 *
850 */
851 ElemVec Eval(const lf::mesh::Entity &edge);
852
853 virtual ~ScalarLoadEdgeVectorProvider() = default;
854
855 private:
856 FUNCTOR g_; // source function
857 EDGESELECTOR edge_sel_; // selects edges
859};
860
864std::shared_ptr<spdlog::logger> &ScalarLoadEdgeVectorProviderLogger();
865
866// deduction guide
867template <class PTR, class FUNCTOR, class EDGESELECTOR = base::PredicateTrue>
869 -> ScalarLoadEdgeVectorProvider<typename PTR::element_type::Scalar, FUNCTOR,
870 EDGESELECTOR>;
871
872// Eval() method
873// TODO(craffael) remove const once
874// https://developercommunity.visualstudio.com/content/problem/180948/vs2017-155-c-cv-qualifiers-lost-on-type-alias-used.html
875// is resolved
876template <class SCALAR, class FUNCTOR, class EDGESELECTOR>
879 const lf::mesh::Entity &edge) {
880 // Topological type of the cell
881 const lf::base::RefEl ref_el{edge.RefEl()};
882 LF_ASSERT_MSG(ref_el == lf::base::RefEl::kSegment(),
883 "Edge must be of segment type");
884 // Query the shape of the edge
885 const lf::geometry::Geometry *geo_ptr = edge.Geometry();
886 LF_ASSERT_MSG(geo_ptr != nullptr, "Invalid geometry!");
887
888 // Quadrature points on physical edge
889 const Eigen::MatrixXd mapped_qpts(geo_ptr->Global(pfe_.Qr().Points()));
890 LF_ASSERT_MSG(
891 mapped_qpts.cols() == pfe_.Qr().NumPoints(),
892 "Mismatch " << mapped_qpts.cols() << " <-> " << pfe_.Qr().NumPoints());
893
894 // Obtain the metric factors for the quadrature points
895 const Eigen::VectorXd determinants(
896 geo_ptr->IntegrationElement(pfe_.Qr().Points()));
897 LF_ASSERT_MSG(
898 determinants.size() == pfe_.Qr().NumPoints(),
899 "Mismatch " << determinants.size() << " <-> " << pfe_.Qr().NumPoints());
900
901 // Element vector
902 ElemVec vec(pfe_.NumRefShapeFunctions());
903 vec.setZero();
904
905 auto g_vals = g_(edge, pfe_.Qr().Points());
906
907 // Loop over quadrature points
908 for (base::size_type k = 0; k < pfe_.Qr().NumPoints(); ++k) {
909 // Add contribution of quadrature point to local vector
910 const auto w = (pfe_.Qr().Weights()[k] * determinants[k]) * g_vals[k];
911 vec += pfe_.PrecompReferenceShapeFunctions().col(k).conjugate() * w;
912 }
913 return vec;
914}
915
916} // namespace lf::uscalfe
917
918#endif
A simple, general purpose exception class that is thrown by LehrFEM++ if something is wrong.
Definition: lf_exception.h:21
A Function Object that can be invoked with any arguments and that always returns the value true.
Represents a reference element with all its properties.
Definition: ref_el.h:106
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
Definition: ref_el.h:150
static constexpr RefEl kTria()
Returns the reference triangle.
Definition: ref_el.h:158
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Definition: ref_el.h:166
Interface class for shape information on a mesh cell in the spirit of parametric finite element metho...
virtual Eigen::MatrixXd Global(const Eigen::MatrixXd &local) const =0
Map a number of points in local coordinates into the global coordinate system.
virtual dim_t DimLocal() const =0
Dimension of the domain of this mapping.
virtual dim_t DimGlobal() const =0
Dimension of the image of this mapping.
virtual Eigen::MatrixXd JacobianInverseGramian(const Eigen::MatrixXd &local) const =0
Evaluate the Jacobian * Inverse Gramian ( ) simultaneously at numPoints.
virtual Eigen::VectorXd IntegrationElement(const Eigen::MatrixXd &local) const =0
The integration element (factor appearing in integral transformation formula, see below) at number of...
Interface class representing a topological entity in a cellular complex
Definition: entity.h:39
virtual const geometry::Geometry * Geometry() const =0
Describes the geometry of this entity.
virtual base::RefEl RefEl() const =0
Describes the reference element type of this entity.
Represents a Quadrature Rule over one of the Reference Elements.
Definition: quad_rule.h:58
const Eigen::VectorXd & Weights() const
All quadrature weights as a vector.
Definition: quad_rule.h:152
base::RefEl RefEl() const
The reference element over which this QuadRule integrates.
Definition: quad_rule.h:104
const Eigen::MatrixXd & Points() const
All quadrature points as column vectors.
Definition: quad_rule.h:145
base::size_type NumPoints() const
Return the total number of quadrature points (num of columns of points/weights)
Definition: quad_rule.h:158
Quadrature-based computation of local mass matrix for an edge.
MassEdgeMatrixProvider(std::shared_ptr< const UniformScalarFESpace< SCALAR > > fe_space, COEFF gamma, lf::quad::QuadRule quadrule, EDGESELECTOR edge_selector=base::PredicateTrue{})
Constructor performing cell-independent initializations.
bool isActive(const lf::mesh::Entity &edge)
If true, then an edge is taken into account during assembly.
MassEdgeMatrixProvider(MassEdgeMatrixProvider &&) noexcept=default
MassEdgeMatrixProvider(const MassEdgeMatrixProvider &)=delete
ElemMat Eval(const lf::mesh::Entity &edge)
actual computation of edge mass matrix
Eigen::Matrix< scalar_t, Eigen::Dynamic, Eigen::Dynamic > ElemMat
PrecomputedScalarReferenceFiniteElement< SCALAR > fe_precomp_
decltype(SCALAR(0) *mesh::utils::MeshFunctionReturnType< COEFF >(0)) scalar_t
Scalar type of the element matrix.
virtual ~MassEdgeMatrixProvider()=default
Helper class which stores a ScalarReferenceFiniteElement with precomputed values at the nodes of a qu...
size_type NumRefShapeFunctions() const override
Total number of reference shape functions associated with the reference cell.
const Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > & PrecompReferenceShapeFunctions() const
Value of EvalReferenceShapeFunctions(Qr().Points())
const quad::QuadRule & Qr() const
Return the Quadrature rule at which the shape functions (and their gradients) have been precomputed.
const Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > & PrecompGradientsReferenceShapeFunctions() const
Value of EvalGradientsReferenceShapeFunctions(Qr().Points())
Class for local quadrature based computations for Lagrangian finite elements and second-order scalar ...
typename decltype(mesh::utils::MeshFunctionReturnType< DIFF_COEFF >() *Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 >()+mesh::utils::MeshFunctionReturnType< REACTION_COEFF >() *Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 >())::Scalar Scalar
type of returned element matrix
virtual bool isActive(const lf::mesh::Entity &)
All cells are considered active in the default implementation.
std::array< PrecomputedScalarReferenceFiniteElement< SCALAR >, 5 > fe_precomp_
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > ElemMat
ReactionDiffusionElementMatrixProvider(const ReactionDiffusionElementMatrixProvider &)=delete
standard constructors
ElemMat Eval(const lf::mesh::Entity &cell)
main routine for the computation of element matrices
ReactionDiffusionElementMatrixProvider(ReactionDiffusionElementMatrixProvider &&) noexcept=default
Local edge contributions to element vector.
ScalarLoadEdgeVectorProvider(const ScalarLoadEdgeVectorProvider &)=delete
virtual bool isActive(const lf::mesh::Entity &cell)
Default implement: all edges are active.
ScalarLoadEdgeVectorProvider(std::shared_ptr< const UniformScalarFESpace< SCALAR > > fe_space, FUNCTOR g, lf::quad::QuadRule quadrule, EDGESELECTOR edge_sel=base::PredicateTrue{})
Constructor, performs precomputations.
PrecomputedScalarReferenceFiniteElement< SCALAR > pfe_
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > ElemVec
ElemVec Eval(const lf::mesh::Entity &edge)
ScalarLoadEdgeVectorProvider(ScalarLoadEdgeVectorProvider &&) noexcept=default
decltype(SCALAR(0) *mesh::utils::MeshFunctionReturnType< FUNCTOR >(0)) Scalar
Local computation of general element (load) vector for scalar finite elements; volume contributions o...
decltype(SCALAR(0) *mesh::utils::MeshFunctionReturnType< MESH_FUNCTION >(0)) scalar_t
Scalar type of the element matrix.
Eigen::Matrix< scalar_t, Eigen::Dynamic, 1 > ElemVec
ScalarLoadElementVectorProvider(const ScalarLoadElementVectorProvider &)=delete
ScalarLoadElementVectorProvider(ScalarLoadElementVectorProvider &&) noexcept=default
std::array< PrecomputedScalarReferenceFiniteElement< SCALAR >, 5 > fe_precomp_
ElemVec Eval(const lf::mesh::Entity &cell)
MESH_FUNCTION f_
An object providing the source function.
virtual bool isActive(const lf::mesh::Entity &)
Default implement: all cells are active.
Space of scalar valued finite element functions on a hybrid 2D mesh
unsigned int size_type
general type for variables related to size of arrays
Definition: base.h:24
internal::VectorElement_t< internal::MeshFunctionReturnType_t< R > > MeshFunctionReturnType
Determine the type of objects returned by a MeshFunction.
QuadRule make_QuadRule(base::RefEl ref_el, unsigned degree)
Returns a QuadRule object for the given Reference Element and Degree.
Collects data structures and algorithms designed for scalar finite element methods primarily meant fo...
ScalarLoadElementVectorProvider(PTR fe_space, MESH_FUNCTION mf) -> ScalarLoadElementVectorProvider< typename PTR::element_type::Scalar, MESH_FUNCTION >
std::shared_ptr< spdlog::logger > & MassEdgeMatrixProviderLogger()
logger for MassEdgeMatrixProvider
lf::assemble::dim_t dim_t
Definition: lagr_fe.h:32
std::shared_ptr< spdlog::logger > & ScalarLoadElementVectorProviderLogger()
logger used by ScalarLoadElementVectorProvider
std::shared_ptr< spdlog::logger > & ScalarLoadEdgeVectorProviderLogger()
logger for ScalarLoadEdgeVectorProvider class template.
ReactionDiffusionElementMatrixProvider(PTR fe_space, DIFF_COEFF alpha, REACTION_COEFF gamma) -> ReactionDiffusionElementMatrixProvider< typename PTR::element_type::Scalar, DIFF_COEFF, REACTION_COEFF >
ScalarLoadEdgeVectorProvider(PTR, FUNCTOR, EDGESELECTOR=base::PredicateTrue{}) -> ScalarLoadEdgeVectorProvider< typename PTR::element_type::Scalar, FUNCTOR, EDGESELECTOR >
std::map< lf::base::RefEl, lf::quad::QuadRule > quad_rule_collection_t
Auxiliary data structure for passing collections of quadrature rules.
MassEdgeMatrixProvider(PTR, COEFF coeff, EDGESELECTOR edge_predicate=base::PredicateTrue{}) -> MassEdgeMatrixProvider< typename PTR::element_type::Scalar, COEFF, EDGESELECTOR >
std::shared_ptr< spdlog::logger > & ReactionDiffusionElementMatrixProviderLogger()
logger for ReactionDiffusionElementMatrixProvider
Definition: assemble.h:30