LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
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
26namespace lf::uscalfe {
32using quad_rule_collection_t = std::map<lf::base::RefEl, lf::quad::QuadRule>;
33
85template <base::Scalar SCALAR, mesh::utils::MeshFunction DIFF_COEFF,
86 mesh::utils::MeshFunction REACTION_COEFF>
88 public:
92 using Scalar =
94 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>() +
96 Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>())::Scalar;
97 using ElemMat = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
98
104 ReactionDiffusionElementMatrixProvider &&) noexcept = default;
126 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
127 DIFF_COEFF alpha, REACTION_COEFF gamma);
128
145 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
146 DIFF_COEFF alpha, REACTION_COEFF gamma,
147 quad_rule_collection_t qr_collection);
148
155 virtual bool isActive(const lf::mesh::Entity & /*cell*/) { return true; }
173 ElemMat Eval(const lf::mesh::Entity &cell);
174
177
178 private:
182 DIFF_COEFF alpha_;
184 REACTION_COEFF gamma_;
187 // fe_precomp_[i] contains precomputed reference finite element for ref_el i.
188 std::array<PrecomputedScalarReferenceFiniteElement<SCALAR>, 5> fe_precomp_;
189};
190
194std::shared_ptr<spdlog::logger> &ReactionDiffusionElementMatrixProviderLogger();
195
196template <class PTR, class DIFF_COEFF, class REACTION_COEFF>
197ReactionDiffusionElementMatrixProvider(PTR fe_space, DIFF_COEFF alpha,
198 REACTION_COEFF gamma)
200 typename PTR::element_type::Scalar, DIFF_COEFF, REACTION_COEFF>;
201
202template <class PTR, class DIFF_COEFF, class REACTION_COEFF>
204 PTR fe_space, DIFF_COEFF alpha, REACTION_COEFF gamma,
205 std::map<lf::base::RefEl, lf::quad::QuadRule>)
207 typename PTR::element_type::Scalar, DIFF_COEFF, REACTION_COEFF>;
208
209// First constructor (internal construction of quadrature rules
210template <base::Scalar SCALAR, mesh::utils::MeshFunction DIFF_COEFF,
211 mesh::utils::MeshFunction REACTION_COEFF>
214 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
215 DIFF_COEFF alpha, REACTION_COEFF gamma)
216 : alpha_(std::move(alpha)), gamma_(std::move(gamma)), fe_precomp_() {
217 for (auto ref_el : {base::RefEl::kTria(), base::RefEl::kQuad()}) {
218 auto fe = fe_space->ShapeFunctionLayout(ref_el);
219 // Check whether shape functions for that entity type are available.
220 // Note that the corresponding PrecomputedScalarReferenceFiniteElement local
221 // object is not initialized if the associated description of local shape
222 // functions is missing.
223 if (fe != nullptr) {
224 // Precompute cell-independent quantities based on quadrature rules
225 // with twice the degree of exactness compared to the degree of the
226 // finite element space.
228 fe, quad::make_QuadRule(ref_el, 2 * fe->Degree()));
229 }
230 }
231}
232
233// Second constructor (quadrature rules passed as arguments)
234template <base::Scalar SCALAR, mesh::utils::MeshFunction DIFF_COEFF,
235 mesh::utils::MeshFunction REACTION_COEFF>
238 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
239 DIFF_COEFF alpha, REACTION_COEFF gamma,
240 quad_rule_collection_t qr_collection)
241 : alpha_(std::move(alpha)), gamma_(std::move(gamma)), fe_precomp_() {
242 for (auto ref_el : {base::RefEl::kTria(), base::RefEl::kQuad()}) {
243 // Obtain pointer to an object describing local shape functions
244 auto fe = fe_space->ShapeFunctionLayout(ref_el);
245 // Check whether shape functions for that entity type are available
246 // Note that the corresponding PrecomputedScalarReferenceFiniteElement local
247 // object is not initialized if the associated description of local shape
248 // functions is missing.
249 if (fe != nullptr) {
250 // Obtain quadrature rule from user-supplied collection.
251 auto qr_coll_ptr = qr_collection.find(ref_el);
252 if (qr_coll_ptr != qr_collection.end()) {
253 // A quadrature rule for the current entity type is available
254 lf::quad::QuadRule qr = qr_coll_ptr->second;
255 LF_ASSERT_MSG(qr.RefEl() == ref_el,
256 "qr.RefEl() = " << qr.RefEl() << " <-> " << ref_el);
257 // Precomputations of cell-independent quantities
258 fe_precomp_[ref_el.Id()] =
260 }
261 }
262 }
263}
264
265// Main method for the computation of the element matrix
266template <base::Scalar SCALAR, mesh::utils::MeshFunction DIFF_COEFF,
267 mesh::utils::MeshFunction 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(
328 JinvT.block(0, 2 * static_cast<Eigen::Index>(k), world_dim, 2) *
330 .block(0, 2 * k, mat.rows(), 2)
331 .transpose());
332 // Transformed gradients multiplied with coefficient
333 const auto alpha_trf_grad(alphaval[k] * trf_grad);
334 mat += w * (trf_grad.adjoint() * alpha_trf_grad +
335 (gammaval[k] * pfe.PrecompReferenceShapeFunctions().col(k)) *
336 (pfe.PrecompReferenceShapeFunctions().col(k).adjoint()));
337 }
338 return mat;
339}
340
367template <base::Scalar SCALAR, mesh::utils::MeshFunction COEFF,
368 typename EDGESELECTOR>
370 public:
372 using scalar_t =
373 decltype(static_cast<SCALAR>(0) *
375 using ElemMat = Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>;
376
381 MassEdgeMatrixProvider &operator=(const MassEdgeMatrixProvider &) = delete;
397 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space, COEFF gamma,
398 EDGESELECTOR edge_selector = base::PredicateTrue{})
399 : gamma_(std::move(gamma)),
400 edge_sel_(std::move(edge_selector)),
401 fe_precomp_() {
402 auto fe = fe_space->ShapeFunctionLayout(base::RefEl::kSegment());
403 LF_ASSERT_MSG(fe != nullptr, "No shape functions specified for edges");
404 // Precompute entity-independent quantities based on a LehrFEM++ built-in
405 // quadrature rule
407 fe, quad::make_QuadRule(base::RefEl::kSegment(), 2 * fe->Degree()));
408 }
421 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space, COEFF gamma,
422 lf::quad::QuadRule quadrule,
423 EDGESELECTOR edge_selector = base::PredicateTrue{})
424 : gamma_(std::move(gamma)),
425 edge_sel_(std::move(edge_selector)),
426 fe_precomp_() {
427 auto fe = fe_space->ShapeFunctionLayout(base::RefEl::kSegment());
428 LF_ASSERT_MSG(fe != nullptr, "No shape functions specified for edges");
429 LF_ASSERT_MSG(quadrule.RefEl() == base::RefEl::kSegment(),
430 "Quadrature rule not meant for EDGE entities!");
431 // Precompute entity-independent quantities
433 }
434
441 bool isActive(const lf::mesh::Entity &edge) {
442 LF_ASSERT_MSG(edge.RefEl() == lf::base::RefEl::kSegment(),
443 "Wrong type for an edge");
444 return edge_sel_(edge);
445 }
446
462 ElemMat Eval(const lf::mesh::Entity &edge);
463
464 virtual ~MassEdgeMatrixProvider() = default;
465
466 private:
467 COEFF gamma_; // functor for coefficient
468 EDGESELECTOR edge_sel_; // Defines the active edges
469 // Precomputed quantities at quadrature points
471};
472
476std::shared_ptr<spdlog::logger> &MassEdgeMatrixProviderLogger();
477
478// deduction guide:
479template <class PTR, mesh::utils::MeshFunction COEFF,
480 class EDGESELECTOR = base::PredicateTrue>
481MassEdgeMatrixProvider(PTR, COEFF coeff,
482 EDGESELECTOR edge_predicate = base::PredicateTrue{})
483 -> MassEdgeMatrixProvider<typename PTR::element_type::Scalar, COEFF,
484 EDGESELECTOR>;
485
486// Eval() method
487// TODO(craffael) remove const once
488// https://
489// developercommunity.visualstudio.com/content/problem/180948/vs2017-155-c-cv-qualifiers-lost-on-type-alias-used.html
490// is resolved
491template <base::Scalar SCALAR, mesh::utils::MeshFunction COEFF,
492 class EDGESELECTOR>
495 const lf::mesh::Entity &edge) {
496 // Topological type of the cell
497 const lf::base::RefEl ref_el{edge.RefEl()};
498 LF_ASSERT_MSG(ref_el == lf::base::RefEl::kSegment(),
499 "Edge must be of segment type");
500 // Query the shape of the edge
501 const lf::geometry::Geometry *geo_ptr = edge.Geometry();
502 LF_ASSERT_MSG(geo_ptr != nullptr, "Invalid geometry!");
503
504 // Obtain the metric factors for the quadrature points
505 const Eigen::VectorXd determinants(
506 geo_ptr->IntegrationElement(fe_precomp_.Qr().Points()));
507 LF_ASSERT_MSG(determinants.size() == fe_precomp_.Qr().NumPoints(),
508 "Mismatch " << determinants.size() << " <-> "
509 << fe_precomp_.Qr().NumPoints());
510
511 // Element matrix
512 ElemMat mat(fe_precomp_.NumRefShapeFunctions(),
513 fe_precomp_.NumRefShapeFunctions());
514 mat.setZero();
515
516 auto gammaval = gamma_(edge, fe_precomp_.Qr().Points());
517
518 // Loop over quadrature points
519 for (long k = 0; k < determinants.size(); ++k) {
520 // Build local matrix by summing rank-1 contributions
521 // from quadrature points.
522 const auto w =
523 (fe_precomp_.Qr().Weights()[k] * determinants[k]) * gammaval[k];
524 mat += ((fe_precomp_.PrecompReferenceShapeFunctions().col(k)) *
525 (fe_precomp_.PrecompReferenceShapeFunctions().col(k).adjoint())) *
526 w;
527 }
528 return mat;
529}
530
562template <base::Scalar SCALAR, mesh::utils::MeshFunction MESH_FUNCTION>
564 public:
566 using scalar_t =
567 decltype(static_cast<SCALAR>(0) *
569 0));
570 using ElemVec = Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>;
571
575 delete;
577 default;
579 const ScalarLoadElementVectorProvider &) = delete;
593 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
594 MESH_FUNCTION f);
604 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
605 MESH_FUNCTION f, quad_rule_collection_t qr_collection);
607 virtual bool isActive(const lf::mesh::Entity & /*cell*/) { return true; }
608 /*
609 * @brief Main method for computing the element vector
610 *
611 * @param cell current cell for which the element vector is desired
612 * @return local load vector as column vector
613 *
614 */
615 ElemVec Eval(const lf::mesh::Entity &cell);
616
618
619 private:
621 MESH_FUNCTION f_;
622
623 std::array<PrecomputedScalarReferenceFiniteElement<SCALAR>, 5> fe_precomp_;
624};
625
629std::shared_ptr<spdlog::logger> &ScalarLoadElementVectorProviderLogger();
630
631// Deduction guide
632template <class PTR, class MESH_FUNCTION>
633ScalarLoadElementVectorProvider(PTR fe_space, MESH_FUNCTION mf)
634 -> ScalarLoadElementVectorProvider<typename PTR::element_type::Scalar,
635 MESH_FUNCTION>;
636
637// Constructors
638template <base::Scalar SCALAR, mesh::utils::MeshFunction MESH_FUNCTION>
641 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
642 MESH_FUNCTION f)
643 : f_(std::move(f)) {
644 for (auto ref_el : {base::RefEl::kTria(), base::RefEl::kQuad()}) {
645 auto fe = fe_space->ShapeFunctionLayout(ref_el);
646 // Check whether shape functions for that entity type are available
647 if (fe != nullptr) {
648 // Precompute cell-independent quantities based on quadrature rules
649 // with twice the degree of exactness compared to the degree of the
650 // finite element space.
651 fe_precomp_[ref_el.Id()] =
653 fe, quad::make_QuadRule(ref_el, 2 * fe->Degree()));
654 }
655 }
656}
657
658template <base::Scalar SCALAR, mesh::utils::MeshFunction MESH_FUNCTION>
661 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space,
662 MESH_FUNCTION f, quad_rule_collection_t qr_collection)
663 : f_(std::move(f)) {
664 for (auto ref_el : {base::RefEl::kTria(), base::RefEl::kQuad()}) {
665 auto fe = fe_space->ShapeFunctionLayout(ref_el);
666 // Check whether shape functions for that entity type are available
667 if (fe != nullptr) {
668 // Obtain quadrature rule from user-supplied collection.
669 auto qr_coll_ptr = qr_collection.find(ref_el);
670 if (qr_coll_ptr != qr_collection.end()) {
671 // A quadrature rule for the current entity type is available
672 const lf::quad::QuadRule qr = qr_coll_ptr->second;
673 LF_ASSERT_MSG(qr.RefEl() == ref_el,
674 "qr.RefEl() = " << qr.RefEl() << " <-> " << ref_el);
675 // Precompute cell-independent quantities using the user-supplied
676 // quadrature rules
677 fe_precomp_[ref_el.Id()] =
679 } else {
680 // Quadrature rule is missing for an entity type for which
681 // local shape functions are available
682 LF_ASSERT_MSG(false, "Quadrature rule missing for " << ref_el);
683 }
684 }
685 }
686}
687
688// TODO(craffael) remove const once
689// http://developercommunity.visualstudio.com/content/problem/180948/vs2017-155-c-cv-qualifiers-lost-on-type-alias-used.html
690// is resolved
691template <base::Scalar SCALAR, mesh::utils::MeshFunction MESH_FUNCTION>
694 const lf::mesh::Entity &cell) {
695 // Type for source function
697 // Topological type of the cell
698 const lf::base::RefEl ref_el{cell.RefEl()};
699 // Obtain precomputed information about values of local shape functions
700 // and their gradients at quadrature points.
701 auto &pfe = fe_precomp_[ref_el.Id()];
702 // Accident: cell is of a type not coverence by finite element specifications
703 LF_ASSERT_MSG(
704 pfe.isInitialized(),
705 "No local shape function information for entity type " << ref_el);
706
707 // Query the shape of the cell
708 const lf::geometry::Geometry *geo_ptr = cell.Geometry();
709 LF_ASSERT_MSG(geo_ptr != nullptr, "Invalid geometry!");
710 LF_ASSERT_MSG((geo_ptr->DimLocal() == 2),
711 "Only 2D implementation available!");
712 SPDLOG_LOGGER_TRACE(ScalarLoadElementVectorProviderLogger(),
713 "{}, shape = \n{}", ref_el,
714 geo_ptr->Global(ref_el.NodeCoords()));
715
716 // Obtain the metric factors for the quadrature points
717 const Eigen::VectorXd determinants(
718 geo_ptr->IntegrationElement(pfe.Qr().Points()));
719 LF_ASSERT_MSG(
720 determinants.size() == pfe.Qr().NumPoints(),
721 "Mismatch " << determinants.size() << " <-> " << pfe.Qr().NumPoints());
722 SPDLOG_LOGGER_TRACE(ScalarLoadElementVectorProviderLogger(),
723 "LOCVEC({}): Metric factors :\n{}", ref_el,
724 determinants.transpose());
725
726 // Element vector
727 ElemVec vec(pfe.NumRefShapeFunctions());
728 vec.setZero();
729
730 auto fval = f_(cell, pfe.Qr().Points());
731
732 // Loop over quadrature points
733 for (long k = 0; k < determinants.size(); ++k) {
734 SPDLOG_LOGGER_TRACE(ScalarLoadElementVectorProviderLogger(),
735 "LOCVEC: [{}] -> [weight = {}]",
736 pfe.Qr().Points().transpose(), pfe.Qr().Weights()[k]);
737 // Contribution of current quadrature point
738 vec += (pfe.Qr().Weights()[k] * determinants[k] * fval[k]) *
739 pfe.PrecompReferenceShapeFunctions().col(k).conjugate();
740 }
741
742 SPDLOG_LOGGER_TRACE(ScalarLoadElementVectorProviderLogger(), "LOCVEC = \n{}",
743 vec.transpose());
744
745 return vec;
746}
747
784template <base::Scalar SCALAR, mesh::utils::MeshFunction FUNCTOR,
785 class EDGESELECTOR = base::PredicateTrue>
787 public:
788 using Scalar =
789 decltype(static_cast<SCALAR>(0) *
791 using ElemVec = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
792
797 default;
799 const ScalarLoadEdgeVectorProvider &) = delete;
801 delete;
815 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space, FUNCTOR g,
816 EDGESELECTOR edge_sel = base::PredicateTrue{})
817 : g_(std::move(g)), edge_sel_(std::move(edge_sel)), pfe_() {
818 auto fe = fe_space->ShapeFunctionLayout(base::RefEl::kSegment());
819 LF_ASSERT_MSG(fe != nullptr, "No shape functions specified for edges");
820 // Precompute entity-independent quantities based on a LehrFEM++ built-in
821 // quadrature rule
823 fe, quad::make_QuadRule(base::RefEl::kSegment(), 2 * fe->Degree()));
824 }
825
834 std::shared_ptr<const UniformScalarFESpace<SCALAR>> fe_space, FUNCTOR g,
835 lf::quad::QuadRule quadrule,
836 EDGESELECTOR edge_sel = base::PredicateTrue{})
837 : g_(std::move(g)), edge_sel_(std::move(edge_sel)), pfe_() {
838 auto fe = fe_space->ShapeFunctionLayout(base::RefEl::kSegment());
839 LF_ASSERT_MSG(fe != nullptr, "No shape functions specified for edges");
840 LF_ASSERT_MSG(quadrule.RefEl() == base::RefEl::kSegment(),
841 "Quadrature rule not meant for EDGE entities!");
842 // Precompute entity-independent quantities
844 }
845
847 virtual bool isActive(const lf::mesh::Entity &cell) {
848 return edge_sel_(cell);
849 }
850 /*
851 * @brief Main method for computing the element vector
852 *
853 * @param cell current cell for which the element vector is desired
854 * @return local load vector as column vector
855 *
856 */
857 ElemVec Eval(const lf::mesh::Entity &edge);
858
859 virtual ~ScalarLoadEdgeVectorProvider() = default;
860
861 private:
862 FUNCTOR g_; // source function
863 EDGESELECTOR edge_sel_; // selects edges
865};
866
870std::shared_ptr<spdlog::logger> &ScalarLoadEdgeVectorProviderLogger();
871
872// deduction guide
873template <class PTR, class FUNCTOR, class EDGESELECTOR = base::PredicateTrue>
875 -> ScalarLoadEdgeVectorProvider<typename PTR::element_type::Scalar, FUNCTOR,
876 EDGESELECTOR>;
877
878// Eval() method
879// TODO(craffael) remove const once
880// https://developercommunity.visualstudio.com/content/problem/180948/vs2017-155-c-cv-qualifiers-lost-on-type-alias-used.html
881// is resolved
882template <base::Scalar SCALAR, mesh::utils::MeshFunction FUNCTOR,
883 class EDGESELECTOR>
886 const lf::mesh::Entity &edge) {
887 // Topological type of the cell
888 const lf::base::RefEl ref_el{edge.RefEl()};
889 LF_ASSERT_MSG(ref_el == lf::base::RefEl::kSegment(),
890 "Edge must be of segment type");
891 // Query the shape of the edge
892 const lf::geometry::Geometry *geo_ptr = edge.Geometry();
893 LF_ASSERT_MSG(geo_ptr != nullptr, "Invalid geometry!");
894
895 // Quadrature points on physical edge
896 const Eigen::MatrixXd mapped_qpts(geo_ptr->Global(pfe_.Qr().Points()));
897 LF_ASSERT_MSG(
898 mapped_qpts.cols() == pfe_.Qr().NumPoints(),
899 "Mismatch " << mapped_qpts.cols() << " <-> " << pfe_.Qr().NumPoints());
900
901 // Obtain the metric factors for the quadrature points
902 const Eigen::VectorXd determinants(
903 geo_ptr->IntegrationElement(pfe_.Qr().Points()));
904 LF_ASSERT_MSG(
905 determinants.size() == pfe_.Qr().NumPoints(),
906 "Mismatch " << determinants.size() << " <-> " << pfe_.Qr().NumPoints());
907
908 // Element vector
909 ElemVec vec(pfe_.NumRefShapeFunctions());
910 vec.setZero();
911
912 auto g_vals = g_(edge, pfe_.Qr().Points());
913
914 // Loop over quadrature points
915 for (base::size_type k = 0; k < pfe_.Qr().NumPoints(); ++k) {
916 // Add contribution of quadrature point to local vector
917 const auto w = (pfe_.Qr().Weights()[k] * determinants[k]) * g_vals[k];
918 vec += pfe_.PrecompReferenceShapeFunctions().col(k).conjugate() * w;
919 }
920 return vec;
921}
922
923} // namespace lf::uscalfe
924
925#endif
A simple, general purpose exception class that is thrown by LehrFEM++ if something is wrong.
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:109
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
Definition ref_el.h:153
static constexpr RefEl kTria()
Returns the reference triangle.
Definition ref_el.h:161
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Definition ref_el.h:169
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:42
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
decltype(static_cast< SCALAR >(0) * static_cast< mesh::utils::MeshFunctionReturnType< COEFF > >(0)) scalar_t
Scalar type of the element matrix.
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_
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 ...
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
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
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(static_cast< SCALAR >(0) * static_cast< mesh::utils::MeshFunctionReturnType< FUNCTOR > >(0)) Scalar
Local computation of general element (load) vector for scalar finite elements; volume contributions o...
Eigen::Matrix< scalar_t, Eigen::Dynamic, 1 > ElemVec
decltype(static_cast< SCALAR >(0) * static_cast< mesh::utils::MeshFunctionReturnType< MESH_FUNCTION > >( 0)) scalar_t
Scalar type of the element matrix.
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
Concept which is fulfilled if a type T is a scalar type, i.e. if it is a "field" in the mathematical ...
A MeshFunction is a function object that can be evaluated at any point on the mesh.
unsigned int size_type
general type for variables related to size of arrays
Definition types.h:20
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::map< lf::base::RefEl, lf::quad::QuadRule > quad_rule_collection_t
Auxiliary data structure for passing collections of quadrature rules.
std::shared_ptr< spdlog::logger > & MassEdgeMatrixProviderLogger()
logger for MassEdgeMatrixProvider
std::shared_ptr< spdlog::logger > & ScalarLoadElementVectorProviderLogger()
logger used by ScalarLoadElementVectorProvider
lf::assemble::dim_t dim_t
Definition lagr_fe.h:32
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 >
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:31