LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
assembler.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
16#ifndef _LF_ASSEMBLE_H
17#define _LF_ASSEMBLE_H
18
19#include <fmt/ranges.h>
20#include <spdlog/fmt/ostr.h>
21#include <spdlog/sinks/stdout_color_sinks.h>
22#include <spdlog/spdlog.h>
23
24#include <iostream>
25
26#include "dofhandler.h"
27
28namespace lf::assemble {
29
59std::shared_ptr<spdlog::logger> &AssembleMatrixLogger();
60
112template <typename TMPMATRIX, class ENTITY_MATRIX_PROVIDER>
113void AssembleMatrixLocally(dim_t codim, const DofHandler &dof_handler_trial,
114 const DofHandler &dof_handler_test,
115 ENTITY_MATRIX_PROVIDER &entity_matrix_provider,
116 TMPMATRIX &matrix) {
117 // Fetch pointer to underlying mesh
118 auto mesh = dof_handler_trial.Mesh();
119 LF_ASSERT_MSG(mesh == dof_handler_test.Mesh(),
120 "Trial and test space must be defined on the same mesh");
121 // Central assembly loop over entities of co-dimension specified by
122 // the function argument codim
123 for (const lf::mesh::Entity *entity : mesh->Entities(codim)) {
124 // Some entities may be skipped
125 if (entity_matrix_provider.isActive(*entity)) {
126 // log the entity reference element + it's global index on level Debug
127 SPDLOG_LOGGER_DEBUG(AssembleMatrixLogger(), "Entity {} ({})", *entity,
128 mesh->Index(*entity));
129 // Size, aka number of rows and columns, of element matrix
130 const size_type nrows_loc = dof_handler_test.NumLocalDofs(*entity);
131 const size_type ncols_loc = dof_handler_trial.NumLocalDofs(*entity);
132 // row indices of for contributions of cells
134 dof_handler_test.GlobalDofIndices(*entity));
135 // Column indices of for contributions of cells
137 dof_handler_trial.GlobalDofIndices(*entity));
138 // Request local matrix from entity_matrix_provider object. In the
139 // case codim = 0, when `entity` is a cell, this is the element matrix
140 const auto elem_mat{entity_matrix_provider.Eval(*entity)};
141 LF_ASSERT_MSG(elem_mat.rows() >= nrows_loc,
142 "nrows mismatch " << elem_mat.rows() << " <-> " << nrows_loc
143 << ", entity " << mesh->Index(*entity));
144 LF_ASSERT_MSG(elem_mat.cols() >= ncols_loc,
145 "ncols mismatch " << elem_mat.cols() << " <-> " << nrows_loc
146 << ", entity " << mesh->Index(*entity));
147
148 // Log global row and column indices on level debug
149 SPDLOG_LOGGER_DEBUG(AssembleMatrixLogger(), "row_idx = {}, col_idx = {}",
150 row_idx, col_idx);
151
152 // Log shape of element matrix on level debug
153 SPDLOG_LOGGER_DEBUG(AssembleMatrixLogger(), "{} x {} element matrix",
154 nrows_loc, ncols_loc);
155
156 // Log element matrix itself on level trace
157 // TODO(craffael): Doesn't work yet because of fmt issue:
158 // https://github.com/fmtlib/fmt/issues/1885
159 // SPDLOG_LOGGER_TRACE(AssembleMatrixLogger, elem_mat);
160
161 // Assembly double loop
162 std::stringstream ss; // used to log all triplets on one line.
163
164 for (int i = 0; i < nrows_loc; i++) {
165 for (int j = 0; j < ncols_loc; j++) {
166 // Add the element at position (i,j) of the local matrix
167 // to the entry at (row_idx[i], col_idx[j]) of the global matrix
168 matrix.AddToEntry(row_idx[i], col_idx[j], elem_mat(i, j));
169
170 // log the added "triplet" on level trace:
171 if (AssembleMatrixLogger()->should_log(spdlog::level::trace)) {
172 // if we are on level trace, build string of all triplets:
173 ss << "(" << row_idx[i] << ',' << col_idx[j]
174 << ")+= " << elem_mat(i, j) << ", ";
175 }
176 }
177 } // end assembly local double loop
178
179 // log all the triplets on one line on level trace:
180 SPDLOG_LOGGER_TRACE(AssembleMatrixLogger(), ss.str());
181
182 } // end if(isActive() )
183 } // end main assembly loop
184} // end AssembleMatrixLocally
185
207template <typename TMPMATRIX, class ENTITY_MATRIX_PROVIDER>
209 dim_t codim, const DofHandler &dof_handler_trial,
210 const DofHandler &dof_handler_test,
211 ENTITY_MATRIX_PROVIDER &entity_matrix_provider) {
212 TMPMATRIX matrix{dof_handler_test.NumDofs(), dof_handler_trial.NumDofs()};
213 matrix.setZero();
214 AssembleMatrixLocally<TMPMATRIX, ENTITY_MATRIX_PROVIDER>(
215 codim, dof_handler_trial, dof_handler_test, entity_matrix_provider,
216 matrix);
217 return matrix;
218}
219
241template <typename TMPMATRIX, class ENTITY_MATRIX_PROVIDER>
243 dim_t codim, const DofHandler &dof_handler,
244 ENTITY_MATRIX_PROVIDER &entity_matrix_provider) {
245 return AssembleMatrixLocally<TMPMATRIX, ENTITY_MATRIX_PROVIDER>(
246 codim, dof_handler, dof_handler, entity_matrix_provider);
247} // end of group assemble_matrix_locally
249
296template <typename VECTOR, class ENTITY_VECTOR_PROVIDER>
297void AssembleVectorLocally(dim_t codim, const DofHandler &dof_handler,
298 ENTITY_VECTOR_PROVIDER &entity_vector_provider,
299 VECTOR &resultvector) {
300 // Pointer to underlying mesh
301 auto mesh = dof_handler.Mesh();
302
303 // Central assembly loop over entities of the co-dimension specified via
304 // the template argument CODIM
305 for (const lf::mesh::Entity *entity : mesh->Entities(codim)) {
306 // Some cells may be skipped
307 if (entity_vector_provider.isActive(*entity)) {
308 // Length of element vector
309 const size_type veclen = dof_handler.NumLocalDofs(*entity);
310 // global dof indices for contribution of the entity
312 dof_handler.GlobalDofIndices(*entity));
313 // Request local vector from entity_vector_provider object. In the case
314 // CODIM = 0, when `entity` is a cell, this is the element vector
315 const auto elem_vec{entity_vector_provider.Eval(*entity)};
316 LF_ASSERT_MSG(elem_vec.size() >= veclen,
317 "length mismatch " << elem_vec.size() << " <-> " << veclen
318 << ", entity " << mesh->Index(*entity));
319 // Assembly (single) loop
320 for (int i = 0; i < veclen; i++) {
321 resultvector[dof_idx[i]] += elem_vec[i];
322 } // end assembly localloop
323 } // end if(isActive() )
324 } // end main assembly loop
325} // end AssembleVectorLocally
326
346template <typename VECTOR, class ENTITY_VECTOR_PROVIDER>
347VECTOR AssembleVectorLocally(dim_t codim, const DofHandler &dof_handler,
348 ENTITY_VECTOR_PROVIDER &entity_vector_provider) {
349 // Allocated vector holding r.h.s. vector to be assembled
350 VECTOR resultvector{dof_handler.NumDofs()};
351 // Initialize to zero: assembly of new vector
352 resultvector.setZero();
353 // Perform actual assembly
354 AssembleVectorLocally<VECTOR, ENTITY_VECTOR_PROVIDER>(
355 codim, dof_handler, entity_vector_provider, resultvector);
356 return resultvector;
357} // end AssembleVectorLocally
358 // end group assemble_vector_locally
360
361} // namespace lf::assemble
362
363#endif
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
Definition: dofhandler.h:109
virtual std::shared_ptr< const lf::mesh::Mesh > Mesh() const =0
Acess to underlying mesh object.
virtual nonstd::span< const gdof_idx_t > GlobalDofIndices(const lf::mesh::Entity &entity) const =0
access to indices of global dof's belonging to an entity
virtual size_type NumLocalDofs(const lf::mesh::Entity &entity) const =0
tells the number of degrees of freedom subordinate/_belonging_ to to an entity
virtual size_type NumDofs() const =0
total number of dof's handled by the object
Interface class representing a topological entity in a cellular complex
Definition: entity.h:39
void AssembleMatrixLocally(dim_t codim, const DofHandler &dof_handler_trial, const DofHandler &dof_handler_test, ENTITY_MATRIX_PROVIDER &entity_matrix_provider, TMPMATRIX &matrix)
Assembly function for standard assembly of finite element matrices.
Definition: assembler.h:113
std::shared_ptr< spdlog::logger > & AssembleMatrixLogger()
The logger that is used by AssembleMatrixLocally() to log additional information. (for logging levels...
Definition: assembler.cc:19
void AssembleVectorLocally(dim_t codim, const DofHandler &dof_handler, ENTITY_VECTOR_PROVIDER &entity_vector_provider, VECTOR &resultvector)
entity-local assembly of (right-hand-side) vectors from element vectors
Definition: assembler.h:297
D.o.f. index mapping and assembly facilities.
Definition: assemble.h:30
lf::base::size_type size_type
lf::base::dim_t dim_t