LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
lin_fe.h
1/* **************************************************************************
2 * LehrFEM++ - A simple C++ finite element libray for teaching
3 * Developed from 2018 at the Seminar of Applied Mathematics of ETH Zurich,
4 * lead developers Dr. R. Casagrande and Prof. R. Hiptmair
5 ***************************************************************************/
6
7#ifndef LF_LINFE_H
8#define LF_LINFE_H
9/***************************************************************************
10 * LehrFEM++ - A simple C++ finite element libray for teaching
11 * Developed from 2018 at the Seminar of Applied Mathematics of ETH Zurich,
12 * lead developers Dr. R. Casagrande and Prof. R. Hiptmair
13 ***************************************************************************/
14
24#include <iostream>
25
26#include "uscalfe.h"
27
28namespace lf::uscalfe {
48 public:
49 using ElemMat = Eigen::Matrix<double, 4, 4>;
50
58 [[nodiscard]] virtual bool isActive(const lf::mesh::Entity & /*cell*/) const {
59 return true;
60 }
69 [[nodiscard]] ElemMat Eval(const lf::mesh::Entity &cell) const;
70
71 private:
73 const double kSqrt3 = 1.0 / std::sqrt(3.0);
74 const double kZeta_0 = 0.5 - 0.5 * kSqrt3;
75 const double kZeta_1 = 0.5 + 0.5 * kSqrt3;
76 const std::array<Eigen::Vector2d, 4> kQuadPoints{
77 Eigen::Vector2d{kZeta_0, kZeta_0}, Eigen::Vector2d{kZeta_0, kZeta_1},
78 Eigen::Vector2d{kZeta_1, kZeta_0}, Eigen::Vector2d{kZeta_1, kZeta_1}};
79 // Gradients of refrence shape functions in rows of a matrix
80 static Eigen::Matrix<double, 4, 2> DervRefShapFncts(
81 const Eigen::Vector2d &xh);
82 // Barycenter of triangle
83 const Eigen::Matrix<double, 2, 1> kTriabc{
84 (Eigen::Matrix<double, 2, 1>() << (1.0 / 3), (1.0 / 3)).finished()};
85 // Point in reference square
86 const Eigen::Matrix<double, 2, 1> kQuadpt{
87 (Eigen::Matrix<double, 2, 1>() << 0.7, 0.3).finished()};
88
89 public:
93 static std::shared_ptr<spdlog::logger> &Logger();
94};
95
125template <typename SCALAR, typename FUNCTOR>
127 public:
128 using ElemVec = Eigen::Matrix<SCALAR, 4, 1>;
129
131 explicit LinearFELocalLoadVector(FUNCTOR f) : f_(f) {}
133 [[nodiscard]] virtual bool isActive(const lf::mesh::Entity & /*cell*/) const {
134 return true;
135 }
145 [[nodiscard]] ElemVec Eval(const lf::mesh::Entity &cell) const;
146
147 private:
150 FUNCTOR f_;
151};
152
157std::shared_ptr<spdlog::logger> &LinearFeLocalLoadVectorLogger();
158
159// TODO(craffael) remove const once
160// https://developercommunity.visualstudio.com/content/problem/180948/vs2017-155-c-cv-qualifiers-lost-on-type-alias-used.html
161// is resolved
162template <typename SCALAR, typename FUNCTOR>
165 const lf::mesh::Entity &cell) const {
166 // Topological type of the cell
167 const lf::base::RefEl ref_el{cell.RefEl()};
168 const lf::base::size_type num_nodes{ref_el.NumNodes()};
169
170 // Obtain the vertex coordinates of the cell, which completely
171 // describe its shape.
172 const lf::geometry::Geometry *geo_ptr = cell.Geometry();
173 LF_ASSERT_MSG(geo_ptr != nullptr, "Invalid geometry!");
174 LF_ASSERT_MSG((geo_ptr->DimGlobal() == 2) && (geo_ptr->DimLocal() == 2),
175 "Only 2D implementation available!");
176 const Eigen::MatrixXd &ref_el_corners(ref_el.NodeCoords());
177 // World coordinates of vertices
178 // const Eigen::MatrixXd vertices{geo_ptr->Global(ref_el_corners)};
179 // Debugging output
180 SPDLOG_LOGGER_TRACE(LinearFeLocalLoadVectorLogger(), "{}, shape = \n{}",
181 ref_el, geo_ptr->Global(ref_el_corners));
182
183 // Midpoints of edges in the reference cell
184 Eigen::MatrixXd ref_mp(2, 4);
185 switch (ref_el) {
186 case lf::base::RefEl::kTria(): {
187 // clang-format off
188 ref_mp << 0.5,0.5,0.0,-1.0,
189 0.0,0.5,0.5,-1.0;
190 // clang-format on
191 break;
192 }
193 case lf::base::RefEl::kQuad(): {
194 // clang-format off
195 ref_mp << 0.5,1,0.5,0.0,
196 0.0,0.5,1.0,0.5;
197 // clang-format on
198 break;
199 }
200 default: {
201 LF_ASSERT_MSG(false, "Illegal entity type!");
202 break;
203 }
204 } // end switch
205
206 const double area = lf::geometry::Volume(*geo_ptr);
207
208 // Vector for returning element vector
209 ElemVec elem_vec = ElemVec::Zero();
210 // Run over the midpoints of edges and fetch values of the source function
211 // there
212 auto fvals = f_(cell, ref_mp);
213
214 for (int k = 0; k < num_nodes; k++) {
215 elem_vec[k] += 0.5 * fvals[k];
216 elem_vec[(k + 1) % num_nodes] += 0.5 * fvals[k];
217 }
218 SPDLOG_LOGGER_TRACE(LinearFeLocalLoadVectorLogger(), "element vector = {}",
219 elem_vec.head(num_nodes).transpose());
220
221 return (area / num_nodes) * elem_vec;
222}
223
224} // namespace lf::uscalfe
225
226#endif
Represents a reference element with all its properties.
Definition ref_el.h:109
static constexpr RefEl kTria()
Returns the reference triangle.
Definition ref_el.h:161
constexpr size_type NumNodes() const
The number of nodes of this reference element.
Definition ref_el.h:213
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.
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.
Computing the element matrix for the (negative) Laplacian and linear finite elements.
Definition lin_fe.h:47
LinearFELaplaceElementMatrix()=default
Idle constructor.
const double kSqrt3
quadrature points on reference quadrilateral
Definition lin_fe.h:73
virtual bool isActive(const lf::mesh::Entity &) const
All cells are considered active in the default implementation.
Definition lin_fe.h:58
Eigen::Matrix< double, 4, 4 > ElemMat
Definition lin_fe.h:49
const Eigen::Matrix< double, 2, 1 > kTriabc
Definition lin_fe.h:83
const Eigen::Matrix< double, 2, 1 > kQuadpt
Definition lin_fe.h:86
ElemMat Eval(const lf::mesh::Entity &cell) const
main routine for the computation of element matrices
Definition lin_fe.cc:39
static std::shared_ptr< spdlog::logger > & Logger()
Used by LinearFELaplaceElementMatrix to log additional (debug) info.
Definition lin_fe.cc:21
static Eigen::Matrix< double, 4, 2 > DervRefShapFncts(const Eigen::Vector2d &xh)
Definition lin_fe.cc:27
const std::array< Eigen::Vector2d, 4 > kQuadPoints
Definition lin_fe.h:76
Class for computation of local load vector for linear finite elements.
Definition lin_fe.h:126
LinearFELocalLoadVector(FUNCTOR f)
Constructor storing the right hand side function.
Definition lin_fe.h:131
ElemVec Eval(const lf::mesh::Entity &cell) const
Main method for computing the element vector.
Definition lin_fe.h:164
virtual bool isActive(const lf::mesh::Entity &) const
Default implement: all cells are active.
Definition lin_fe.h:133
Eigen::Matrix< SCALAR, 4, 1 > ElemVec
Definition lin_fe.h:128
unsigned int size_type
general type for variables related to size of arrays
Definition types.h:20
double Volume(const Geometry &geo)
Compute the (approximate) volume (area) of a shape.
Collects data structures and algorithms designed for scalar finite element methods primarily meant fo...
std::shared_ptr< spdlog::logger > & LinearFeLocalLoadVectorLogger()
Used by LinearFELocalLoadVector to log additional (debug) information during vector assembly.
Definition lin_fe.cc:167