FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
symbolic_assembler.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
10#include <kernel/adjacency/graph.hpp>
11#include <kernel/space/dof_mapping_renderer.hpp>
12#include <kernel/lafem/null_matrix.hpp>
13#include <kernel/geometry/intern/coarse_fine_cell_mapping.hpp>
14
15namespace FEAT
16{
17 namespace Assembly
18 {
47 {
48 public:
58 template<typename TestSpace_, typename TrialSpace_>
59 static Adjacency::Graph assemble_graph_std2(const TestSpace_& test_space, const TrialSpace_& trial_space)
60 {
61 // render dof-graphs
62 Adjacency::Graph test_dof_graph(Space::DofMappingRenderer::render(test_space));
63 Adjacency::Graph trial_dof_graph(Space::DofMappingRenderer::render(trial_space));
64
65 // check dimensions
66 XASSERTM(test_dof_graph.get_num_nodes_domain() == trial_dof_graph.get_num_nodes_domain(), "invalid test-/trial-space pair");
67
68 // render transposed test-dof-mapping
69 Adjacency::Graph test_dof_support(Adjacency::RenderType::transpose, test_dof_graph);
70
71 // render composite test-dof-mapping/trial-dof-support graph
72 Adjacency::Graph dof_adjactor(Adjacency::RenderType::injectify_sorted, test_dof_support, trial_dof_graph);
73
74 // return the graph
75 return dof_adjactor;
76 }
77
87 template<typename Space_>
88 static Adjacency::Graph assemble_graph_std1(const Space_& space)
89 {
90 // create dof-mapping
92
93 // render transposed dof-mapping
95
96 // render composite dof-mapping/dof-support graph
97 Adjacency::Graph dof_adjactor(Adjacency::RenderType::injectify_sorted, dof_support, dof_graph);
98
99 // return the graph
100 return dof_adjactor;
101 }
102
112 template<typename TestSpace_, typename TrialSpace_>
113 static Adjacency::Graph assemble_graph_ext_facet2(const TestSpace_& test_space, const TrialSpace_& trial_space)
114 {
115 // render dof-graphs
116 Adjacency::Graph test_dof_graph(Space::DofMappingRenderer::render(test_space));
117 Adjacency::Graph trial_dof_graph(Space::DofMappingRenderer::render(trial_space));
118
119 // check dimensions
120 XASSERTM(test_dof_graph.get_num_nodes_domain() == trial_dof_graph.get_num_nodes_domain(), "invalid test-/trial-space pair");
121
122 // get the shape dimension
123 typedef typename TestSpace_::ShapeType ShapeType;
124 static constexpr Index shape_dim = Index(ShapeType::dimension);
125
126 // get the facet index set
127 const auto& facet_at_shape = test_space.get_trafo().get_mesh().template get_index_set<shape_dim, shape_dim-1>();
128
129 // transpose to get the facet support
130 Adjacency::Graph shape_at_facet(Adjacency::RenderType::transpose, facet_at_shape);
131
132 // render transposed test-dof-mapping
133 Adjacency::Graph test_dof_support(Adjacency::RenderType::transpose, test_dof_graph);
134
135 // render extended test-dof-support
136 Adjacency::Graph test_dof_ext_sup(Adjacency::RenderType::injectify, test_dof_support, facet_at_shape);
137
138 // render extended trial-dof-mapping
139 Adjacency::Graph trial_dof_ext_graph(Adjacency::RenderType::injectify, shape_at_facet, trial_dof_graph);
140
141 // render composite test-dof-mapping/trial-dof-support graph
142 Adjacency::Graph dof_adjactor(Adjacency::RenderType::injectify_sorted, test_dof_ext_sup, trial_dof_ext_graph);
143
144 // return the graph
145 return dof_adjactor;
146 }
147
157 template<typename Space_>
158 static Adjacency::Graph assemble_graph_ext_facet1(const Space_& space)
159 {
160 // create dof-mapping
162
163 // get the shape dimension
164 typedef typename Space_::ShapeType ShapeType;
165 static constexpr Index shape_dim = Index(ShapeType::dimension);
166
167 // get the facet index set
168 const auto& facet_at_shape = space.get_trafo().get_mesh().template get_index_set<shape_dim, shape_dim-1>();
169
170 // transpose to get the facet support
171 Adjacency::Graph shape_at_facet(Adjacency::RenderType::transpose, facet_at_shape);
172
173 // render extended dof-mapping
174 Adjacency::Graph dof_ext_graph(Adjacency::RenderType::injectify, shape_at_facet, dof_graph);
175
176 // render transposed extended dof-mapping
177 Adjacency::Graph dof_ext_sup(Adjacency::RenderType::transpose, dof_ext_graph);
178
179 // render composite dof-mapping/dof-support graph
180 Adjacency::Graph dof_adjactor(Adjacency::RenderType::injectify_sorted, dof_ext_sup, dof_ext_graph);
181
182 // return the graph
183 return dof_adjactor;
184 }
185
195 template<typename TestSpace_, typename TrialSpace_>
196 static Adjacency::Graph assemble_graph_ext_node2(const TestSpace_& test_space, const TrialSpace_& trial_space)
197 {
198 // render dof-graphs
199 Adjacency::Graph test_dof_graph(Space::DofMappingRenderer::render(test_space));
200 Adjacency::Graph trial_dof_graph(Space::DofMappingRenderer::render(trial_space));
201
202 // check dimensions
203 XASSERTM(test_dof_graph.get_num_nodes_domain() == trial_dof_graph.get_num_nodes_domain(), "invalid test-/trial-space pair");
204
205 // get the shape dimension
206 typedef typename TestSpace_::ShapeType ShapeType;
207 static constexpr Index shape_dim = Index(ShapeType::dimension);
208
209 // get the facet index set
210 const auto& facet_at_shape = test_space.get_trafo().get_mesh().template get_index_set<shape_dim, 0>();
211
212 // transpose to get the facet support
213 Adjacency::Graph shape_at_facet(Adjacency::RenderType::transpose, facet_at_shape);
214
215 // render transposed test-dof-mapping
216 Adjacency::Graph test_dof_support(Adjacency::RenderType::transpose, test_dof_graph);
217
218 // render extended test-dof-support
219 Adjacency::Graph test_dof_ext_sup(Adjacency::RenderType::injectify, test_dof_support, facet_at_shape);
220
221 // render extended trial-dof-mapping
222 Adjacency::Graph trial_dof_ext_graph(Adjacency::RenderType::injectify, shape_at_facet, trial_dof_graph);
223
224 // render composite test-dof-mapping/trial-dof-support graph
225 Adjacency::Graph dof_adjactor(Adjacency::RenderType::injectify_sorted, test_dof_ext_sup, trial_dof_ext_graph);
226
227 // return the graph
228 return dof_adjactor;
229 }
230
240 template<typename Space_>
241 static Adjacency::Graph assemble_graph_ext_node1(const Space_& space)
242 {
243 // create dof-mapping
245
246 // get the shape dimension
247 typedef typename Space_::ShapeType ShapeType;
248 static constexpr Index shape_dim = Index(ShapeType::dimension);
249
250 // get the facet index set
251 const auto& facet_at_shape = space.get_trafo().get_mesh().template get_index_set<shape_dim, 0>();
252
253 // transpose to get the facet support
254 Adjacency::Graph shape_at_facet(Adjacency::RenderType::transpose, facet_at_shape);
255
256 // render extended dof-mapping
257 Adjacency::Graph dof_ext_graph(Adjacency::RenderType::injectify, shape_at_facet, dof_graph);
258
259 // render transposed extended dof-mapping
260 Adjacency::Graph dof_ext_sup(Adjacency::RenderType::transpose, dof_ext_graph);
261
262 // render composite dof-mapping/dof-support graph
263 Adjacency::Graph dof_adjactor(Adjacency::RenderType::injectify_sorted, dof_ext_sup, dof_ext_graph);
264
265 // return the graph
266 return dof_adjactor;
267 }
268
278 template<typename Space_>
279 static Adjacency::Graph assemble_graph_diag(const Space_& space)
280 {
281 // get number of DOFs
282 const Index n = space.get_num_dofs();
283
284 // create a graph
285 Adjacency::Graph graph(n, n, n);
286
287 // get and fill the arrays
288 Index* dom_ptr = graph.get_domain_ptr();
289 Index* img_idx = graph.get_image_idx();
290 for(Index i(0); i < n; ++i)
291 dom_ptr[i] = img_idx[i] = i;
292 dom_ptr[n] = n;
293
294 // return the graph
295 return graph;
296 }
297
315 template<typename TestSpace_, typename TrialSpace_, typename TrialToTestAdjator_>
317 const TestSpace_& test_space,
318 const TrialSpace_& trial_space,
319 const TrialToTestAdjator_& trial2test_adjactor)
320 {
321 // create test- and trial-dof-mappers
322 Adjacency::Graph test_dof_mapping(Space::DofMappingRenderer::render(test_space));
323 Adjacency::Graph trial_dof_mapping(Space::DofMappingRenderer::render(trial_space));
324
325 // get trial and test mesh permutations
326 const Adjacency::Permutation& trial_perm = trial_space.get_trafo().get_mesh().get_mesh_permutation().get_perm();
327 const Adjacency::Permutation& test_inv_perm = test_space.get_trafo().get_mesh().get_mesh_permutation().get_inv_perm();
328 if(!trial_perm.empty() || !test_inv_perm.empty())
329 {
330 // render trial2test adjactor
331 Adjacency::Graph trial2test_graph(Adjacency::RenderType::as_is, trial2test_adjactor);
332
333 // permute graph indices
334 Adjacency::Graph permuted_graph;
335 if(trial_perm.empty())
336 {
337 // no trial permutation, only test mesh permuted
338 permuted_graph = std::move(trial2test_graph);
339 permuted_graph.permute_indices(test_inv_perm);
340 }
341 else if(test_inv_perm.empty())
342 {
343 // no test permutation, only trial mesh permuted
344 // create a dummy identity permutation for the test mesh
345 Adjacency::Permutation id_perm(trial2test_graph.get_num_nodes_image(), Adjacency::Permutation::ConstrType::identity);
346 permuted_graph = Adjacency::Graph(trial2test_graph, trial_perm, id_perm);
347 }
348 else
349 {
350 // both trial and test permutations exist
351 permuted_graph = Adjacency::Graph(trial2test_graph, trial_perm, test_inv_perm);
352 }
353
354 // render transposed test-dof-mapping
355 Adjacency::Graph test_dof_support(Adjacency::RenderType::injectify_transpose, permuted_graph, test_dof_mapping);
356
357 // render composite test-dof-mapping/trial-dof-support graph
358 Adjacency::Graph dof_adjactor(Adjacency::RenderType::injectify_sorted, test_dof_support, trial_dof_mapping);
359
360 // return the graph
361 return dof_adjactor;
362 }
363 else // no permutation
364 {
365 // render transposed test-dof-mapping
366 Adjacency::Graph test_dof_support(Adjacency::RenderType::injectify_transpose, trial2test_adjactor, test_dof_mapping);
367
368 // render composite test-dof-mapping/trial-dof-support graph
369 Adjacency::Graph dof_adjactor(Adjacency::RenderType::injectify_sorted, test_dof_support, trial_dof_mapping);
370
371 // return the graph
372 return dof_adjactor;
373 }
374 }
375
393 template<typename FineTestSpace_, typename CoarseTrialSpace_>
395 const FineTestSpace_& fine_space,
396 const CoarseTrialSpace_& coarse_space)
397 {
398 // create an refinement adjactor
400 refine_adjactor(fine_space.get_trafo().get_mesh(), coarse_space.get_trafo().get_mesh());
401
402 // call inter-mesh assembler
403 return assemble_graph_intermesh(fine_space, coarse_space, refine_adjactor);
404 }
405
415 template<typename MatrixType_, typename TestSpace_, typename TrialSpace_>
416 static void assemble_matrix_std2(MatrixType_ & matrix,
417 const TestSpace_& test_space, const TrialSpace_& trial_space)
418 {
419 matrix = MatrixType_(assemble_graph_std2(test_space, trial_space));
420 }
421
423 template<typename DT_, typename IT_, int BH_, int BW_, typename TestSpace_, typename TrialSpace_>
426 const TestSpace_& test_space, const TrialSpace_& trial_space)
427 {
428 // only the dimensions are required here
429 matrix.resize(test_space.get_num_dofs(), trial_space.get_num_dofs());
430 }
431
441 template<typename MatrixType_, typename Space_>
442 static void assemble_matrix_std1(MatrixType_ & matrix, const Space_& space)
443 {
444 matrix = MatrixType_(assemble_graph_std1(space));
445 }
446
448 template<typename DT_, typename IT_, int BH_, int BW_, typename Space_>
450 LAFEM::NullMatrix<DT_, IT_, BH_, BW_>& matrix, const Space_& space)
451 {
452 // only the dimensions are required here
453 matrix.resize(space.get_num_dofs(), space.get_num_dofs());
454 }
455
465 template<typename MatrixType_, typename TestSpace_, typename TrialSpace_>
466 static void assemble_matrix_ext_facet2(MatrixType_ & matrix,
467 const TestSpace_& test_space, const TrialSpace_& trial_space)
468 {
469 matrix = MatrixType_(assemble_graph_ext_facet2(test_space, trial_space));
470 }
471
481 template<typename MatrixType_, typename Space_>
482 static void assemble_matrix_ext_facet1(MatrixType_ & matrix, const Space_& space)
483 {
484 matrix = MatrixType_(assemble_graph_ext_facet1(space));
485 }
486
496 template<typename MatrixType_, typename TestSpace_, typename TrialSpace_>
497 static void assemble_matrix_ext_node2(MatrixType_ & matrix,
498 const TestSpace_& test_space, const TrialSpace_& trial_space)
499 {
500 matrix = MatrixType_(assemble_graph_ext_node2(test_space, trial_space));
501 }
502
512 template<typename MatrixType_, typename Space_>
513 static void assemble_matrix_ext_node1(MatrixType_ & matrix, const Space_& space)
514 {
515 matrix = MatrixType_(assemble_graph_ext_node1(space));
516 }
517
527 template<typename MatrixType_, typename Space_>
528 static void assemble_matrix_diag(MatrixType_ & matrix, const Space_& space)
529 {
530 matrix = MatrixType_(assemble_graph_diag(space));
531 }
532
547 template<typename MatrixType_, typename TestSpace_, typename TrialSpace_, typename Trial2TestAdjactor_>
548 static void assemble_matrix_intermesh(MatrixType_ & matrix,
549 const TestSpace_& test_space, const TrialSpace_& trial_space,
550 const Trial2TestAdjactor_& trial2test_adjactor)
551 {
552 matrix = MatrixType_(assemble_graph_intermesh(test_space, trial_space, trial2test_adjactor));
553 }
554
569 template<typename MatrixType_, typename FineSpace_, typename CoarseSpace_>
570 static void assemble_matrix_2lvl(MatrixType_ & matrix,
571 const FineSpace_& fine_space, const CoarseSpace_& coarse_space)
572 {
573 matrix = MatrixType_(assemble_graph_2lvl(fine_space, coarse_space));
574 }
575 }; // class SymbolicAssembler
576 } // namespace Assembly
577} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Adjacency Graph implementation.
Definition: graph.hpp:34
Index * get_domain_ptr()
Returns the domain pointer array.
Definition: graph.hpp:359
Index * get_image_idx()
Returns the image node index array.
Definition: graph.hpp:374
void permute_indices(const Adjacency::Permutation &inv_perm)
Permutes the image indices.
Definition: graph.cpp:221
bool empty() const
Checks whether the permutation is empty.
@ identity
create identity permutation
Symbolic Matrix and Graph assembler class.
static void assemble_matrix_std1(LAFEM::NullMatrix< DT_, IT_, BH_, BW_ > &matrix, const Space_ &space)
specialization for NullMatrix
static void assemble_matrix_std1(MatrixType_ &matrix, const Space_ &space)
Assembles a standard matrix structure from a single space.
static void assemble_matrix_ext_node1(MatrixType_ &matrix, const Space_ &space)
Assembles an extended-node matrix structure from a single space.
static void assemble_matrix_ext_facet2(MatrixType_ &matrix, const TestSpace_ &test_space, const TrialSpace_ &trial_space)
Assembles an extended-facet matrix structure from a test-trial-space pair.
static Adjacency::Graph assemble_graph_ext_facet2(const TestSpace_ &test_space, const TrialSpace_ &trial_space)
Assembles the extended-facet Dof-Adjacency graph for different test- and trial-spaces.
static void assemble_matrix_diag(MatrixType_ &matrix, const Space_ &space)
Assembles a diagonal matrix structure from a single space.
static Adjacency::Graph assemble_graph_2lvl(const FineTestSpace_ &fine_space, const CoarseTrialSpace_ &coarse_space)
Assembles the 2-level refinement Dof-Adjacency graph.
static void assemble_matrix_std2(LAFEM::NullMatrix< DT_, IT_, BH_, BW_ > &matrix, const TestSpace_ &test_space, const TrialSpace_ &trial_space)
specialization for NullMatrix
static Adjacency::Graph assemble_graph_std1(const Space_ &space)
Assembles the standard Dof-Adjacency graph for identical test- and trial-spaces.
static void assemble_matrix_ext_node2(MatrixType_ &matrix, const TestSpace_ &test_space, const TrialSpace_ &trial_space)
Assembles an extended-node matrix structure from a test-trial-space pair.
static Adjacency::Graph assemble_graph_ext_node1(const Space_ &space)
Assembles the extended-node Dof-Adjacency graph for identical test- and trial-spaces.
static Adjacency::Graph assemble_graph_diag(const Space_ &space)
Assembles the diagonal Dof-Adjacency graph for identical test- and trial-spaces.
static Adjacency::Graph assemble_graph_ext_facet1(const Space_ &space)
Assembles the extended-facet Dof-Adjacency graph for identical test- and trial-spaces.
static void assemble_matrix_ext_facet1(MatrixType_ &matrix, const Space_ &space)
Assembles an extended-facet matrix structure from a single space.
static Adjacency::Graph assemble_graph_ext_node2(const TestSpace_ &test_space, const TrialSpace_ &trial_space)
Assembles the extended-node Dof-Adjacency graph for different test- and trial-spaces.
static void assemble_matrix_std2(MatrixType_ &matrix, const TestSpace_ &test_space, const TrialSpace_ &trial_space)
Assembles a standard matrix structure from a test-trial-space pair.
static void assemble_matrix_intermesh(MatrixType_ &matrix, const TestSpace_ &test_space, const TrialSpace_ &trial_space, const Trial2TestAdjactor_ &trial2test_adjactor)
Assembles a matrix structure from a test-trial-mesh pair defined on different meshes.
static Adjacency::Graph assemble_graph_std2(const TestSpace_ &test_space, const TrialSpace_ &trial_space)
Assembles the standard Dof-Adjacency graph for different test- and trial-spaces.
static void assemble_matrix_2lvl(MatrixType_ &matrix, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space)
Assembles a 2-level matrix structure from a fine-coarse-space pair.
static Adjacency::Graph assemble_graph_intermesh(const TestSpace_ &test_space, const TrialSpace_ &trial_space, const TrialToTestAdjator_ &trial2test_adjactor)
Assembles the Dof-Adjacency graph where test and trial spaces are defined on different meshes.
A coarse cell to fine cell mapping class.
Null Matrix implementation.
Definition: null_matrix.hpp:56
void resize(Index rows_in, Index columns_in)
Resizes the matrix to different dimensions.
static Adjacency::Graph render(const Space_ &space)
Renders the dof-mapping of a space into an adjacency graph.
@ injectify_sorted
Render-Injectified mode, sort image indices.
@ transpose
Render-Transpose mode.
@ injectify_transpose
Render-Injectified-Transpose mode.
@ injectify
Render-Injectified mode.
@ as_is
Render-As-Is mode.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.