LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
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 INCG_LF_ASSEMBLE_H
17#define INCG_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 "assemble_concepts.h"
27#include "dofhandler.h"
28
29namespace lf::assemble {
30
61std::shared_ptr<spdlog::logger> &AssembleMatrixLogger();
62
114template <typename TMPMATRIX, EntityMatrixProvider ENTITY_MATRIX_PROVIDER>
118 TMPMATRIX &matrix) {
119 // Fetch pointer to underlying mesh
120 auto mesh = dof_handler_trial.Mesh();
121 LF_ASSERT_MSG(mesh == dof_handler_test.Mesh(),
122 "Trial and test space must be defined on the same mesh");
123 // Central assembly loop over entities of co-dimension specified by
124 // the function argument codim
125 for (const lf::mesh::Entity *entity : mesh->Entities(codim)) {
126 // Some entities may be skipped
127 if (entity_matrix_provider.isActive(*entity)) {
128 // log the entity reference element + it's global index on level Debug
129 SPDLOG_LOGGER_DEBUG(AssembleMatrixLogger(), "Entity {} ({})", *entity,
130 mesh->Index(*entity));
131 // Size, aka number of rows and columns, of element matrix
132 const size_type nrows_loc = dof_handler_test.NumLocalDofs(*entity);
133 const size_type ncols_loc = dof_handler_trial.NumLocalDofs(*entity);
134 // row indices of for contributions of cells
135 std::span<const gdof_idx_t> row_idx(
136 dof_handler_test.GlobalDofIndices(*entity));
137 // Column indices of for contributions of cells
138 std::span<const gdof_idx_t> col_idx(
139 dof_handler_trial.GlobalDofIndices(*entity));
140 // Request local matrix from entity_matrix_provider object. In the
141 // case codim = 0, when `entity` is a cell, this is the element matrix
142 const auto elem_mat{entity_matrix_provider.Eval(*entity)};
143 LF_ASSERT_MSG(elem_mat.rows() >= nrows_loc,
144 "nrows mismatch " << elem_mat.rows() << " <-> " << nrows_loc
145 << ", entity " << mesh->Index(*entity));
146 LF_ASSERT_MSG(elem_mat.cols() >= ncols_loc,
147 "ncols mismatch " << elem_mat.cols() << " <-> " << nrows_loc
148 << ", entity " << mesh->Index(*entity));
149
150 // Log global row and column indices on level debug
151 SPDLOG_LOGGER_DEBUG(AssembleMatrixLogger(), "row_idx = {}, col_idx = {}",
153
154 // Log shape of element matrix on level debug
155 SPDLOG_LOGGER_DEBUG(AssembleMatrixLogger(), "{} x {} element matrix",
157
158 // Log element matrix itself on level trace
159 // TODO(craffael): Doesn't work yet because of fmt issue:
160 // https://github.com/fmtlib/fmt/issues/1885
161 // SPDLOG_LOGGER_TRACE(AssembleMatrixLogger, elem_mat);
162
163 // Assembly double loop
164 std::stringstream ss; // used to log all triplets on one line.
165
166 for (int i = 0; i < nrows_loc; i++) {
167 for (int j = 0; j < ncols_loc; j++) {
168 // Add the element at position (i,j) of the local matrix
169 // to the entry at (row_idx[i], col_idx[j]) of the global matrix
170 matrix.AddToEntry(row_idx[i], col_idx[j], elem_mat(i, j));
171
172 // log the added "triplet" on level trace:
173 if (AssembleMatrixLogger()->should_log(spdlog::level::trace)) {
174 // if we are on level trace, build string of all triplets:
175 ss << "(" << row_idx[i] << ',' << col_idx[j]
176 << ")+= " << elem_mat(i, j) << ", ";
177 }
178 }
179 } // end assembly local double loop
180
181 // log all the triplets on one line on level trace:
183
184 } // end if(isActive() )
185 } // end main assembly loop
186} // end AssembleMatrixLocally
187
209template <typename TMPMATRIX, EntityMatrixProvider ENTITY_MATRIX_PROVIDER>
221
243template <typename TMPMATRIX, EntityMatrixProvider ENTITY_MATRIX_PROVIDER>
250 // end of group assemble_matrix_locally
251
298template <typename VECTOR, EntityVectorProvider ENTITY_VECTOR_PROVIDER>
300 ENTITY_VECTOR_PROVIDER &entity_vector_provider,
302 // Pointer to underlying mesh
303 auto mesh = dof_handler.Mesh();
304
305 // Central assembly loop over entities of the co-dimension specified via
306 // the template argument CODIM
307 for (const lf::mesh::Entity *entity : mesh->Entities(codim)) {
308 // Some cells may be skipped
309 if (entity_vector_provider.isActive(*entity)) {
310 // Length of element vector
311 const size_type veclen = dof_handler.NumLocalDofs(*entity);
312 // global dof indices for contribution of the entity
313 const std::span<const gdof_idx_t> dof_idx(
314 dof_handler.GlobalDofIndices(*entity));
315 // Request local vector from entity_vector_provider object. In the case
316 // CODIM = 0, when `entity` is a cell, this is the element vector
317 const auto elem_vec{entity_vector_provider.Eval(*entity)};
318 LF_ASSERT_MSG(elem_vec.size() >= veclen,
319 "length mismatch " << elem_vec.size() << " <-> " << veclen
320 << ", entity " << mesh->Index(*entity));
321 // Assembly (single) loop
322 for (int i = 0; i < veclen; i++) {
324 } // end assembly localloop
325 } // end if(isActive() )
326 } // end main assembly loop
327} // end AssembleVectorLocally
328
354template <typename VECTOR, class ENTITY_VECTOR_PROVIDER>
356 ENTITY_VECTOR_PROVIDER &entity_vector_provider) {
357 // Allocated vector holding r.h.s. vector to be assembled
359 // Initialize to zero: assembly of new vector
360 resultvector.setZero();
361 // Perform actual assembly
363 codim, dof_handler, entity_vector_provider, resultvector);
364 return resultvector;
365} // end AssembleVectorLocally
366
367 // end group assemble_vector_locally
368
369} // namespace lf::assemble
370
371#endif
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
Definition dofhandler.h:112
virtual std::shared_ptr< const lf::mesh::Mesh > Mesh() const =0
Acess to underlying mesh object.
virtual std::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:42
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:115
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:299
D.o.f. index mapping and assembly facilities.
Definition assemble.h:31
lf::base::size_type size_type
lf::base::dim_t dim_t