FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
unit_filter_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
9#include <kernel/assembly/base.hpp>
10#include <kernel/analytic/function.hpp>
11#include <kernel/lafem/unit_filter.hpp>
12#include <kernel/lafem/unit_filter_blocked.hpp>
13#include <kernel/lafem/dense_vector.hpp>
14#include <kernel/geometry/mesh_part.hpp>
15
16// includes, system
17#include <set>
18#include <map>
19#include <vector>
20
21namespace FEAT
22{
23 namespace Assembly
24 {
26 namespace Intern
27 {
28 // forward declarations
29 template<int shape_dim_>
30 struct UnitAsmWrapper;
31 } // namespace Intern
33
42 template<typename Mesh_>
44 {
45 public:
47 typedef Mesh_ MeshType;
48
49 private:
51 static constexpr int shape_dim = MeshType::shape_dim;
52
54 typedef std::set<Index> IdxSet;
55
58
59 public:
60 UnitFilterAssembler() = default;
62 UnitFilterAssembler& operator=(UnitFilterAssembler&&) = default;
64 UnitFilterAssembler& operator=(const UnitFilterAssembler&) = delete;
65 virtual ~UnitFilterAssembler() = default;
66
74 {
75 Intern::UnitAsmWrapper<shape_dim>::merge(_cells, mesh_part);
76 }
77
90 template<typename DataType_, typename IndexType_, typename Space_>
91 void assemble(LAFEM::UnitFilter<DataType_, IndexType_>& filter, const Space_& space) const
92 {
93 // build index set
94 std::set<Index> idx_set;
95 Intern::UnitAsmWrapper<shape_dim>::assemble(idx_set, space, _cells);
96
97 // allocate filter if necessary
98 if(filter.size() == Index(0))
99 {
100 filter = LAFEM::UnitFilter<DataType_, IndexType_>(space.get_num_dofs());
101 }
102
103 // loop over all dof-indices
104 typename std::set<Index>::const_iterator it(idx_set.begin());
105 typename std::set<Index>::const_iterator jt(idx_set.end());
106 for(Index i(0); it != jt; ++it, ++i)
107 {
108 // store the dof-index
109 filter.add(IndexType_(*it), DataType_(0));
110 }
111 }
112
128 template<typename DataType_, typename IndexType_, typename Space_>
131 const Space_& space,
133 {
134 // build index set
135 std::set<Index> idx_set;
136 Intern::UnitAsmWrapper<shape_dim>::assemble(idx_set, space, _cells);
137
138 // allocate filter if necessary
139 if(filter.size() == Index(0))
140 {
141 filter = LAFEM::UnitFilter<DataType_, IndexType_>(space.get_num_dofs());
142 }
143
144 // loop over all dof-indices
145 typename std::set<Index>::const_iterator it(idx_set.begin());
146 typename std::set<Index>::const_iterator jt(idx_set.end());
147 for(Index i(0); it != jt; ++it, ++i)
148 {
149 // store the dof-index
150 filter.add(IndexType_(*it), vector_(IndexType_(*it)));
151 }
152 }
153
170 template<
171 typename DataType_,
172 typename IndexType_,
173 typename Space_,
174 typename Function_>
177 const Space_& space,
178 const Function_& function) const
179 {
180 // ensure that the function is scalar
181 typedef typename Function_::ImageType FuncImageType;
182 static_assert(FuncImageType::is_scalar, "only scalar functions are supported");
183
184 // build index-value map
185 std::map<Index, DataType_> idx_map;
186 Intern::UnitAsmWrapper<shape_dim>::assemble(idx_map, space, _cells, function);
187
188 // allocate filter if necessary
189 if(filter.size() == Index(0))
190 {
191 filter = LAFEM::UnitFilter<DataType_, IndexType_>(space.get_num_dofs());
192 }
193
194 // loop over all dof-indices
195 typename std::map<Index, DataType_>::const_iterator it(idx_map.begin());
196 typename std::map<Index, DataType_>::const_iterator jt(idx_map.end());
197 for(Index i(0); it != jt; ++it, ++i)
198 {
199 // store the dof-index
200 filter.add(IndexType_(it->first), it->second);
201 }
202 }
203
215 template<typename DataType_, typename IndexType_, int BlockSize_, typename Space_>
218 const Space_& space) const
219 {
220 // build index set
221 std::set<Index> idx_set;
222 Intern::UnitAsmWrapper<shape_dim>::assemble(idx_set, space, _cells);
223
224 // allocate filter if necessary
225 if (filter.size() == Index(0))
226 {
228 }
229
230 // loop over all dof-indices
231 typename std::set<Index>::const_iterator it(idx_set.begin());
232 typename std::set<Index>::const_iterator jt(idx_set.end());
234 for(Index i(0); it != jt; ++it, ++i)
235 {
236 // store the dof-index
237 filter.add(IndexType_(*it), tmp);
238 }
239 }
240
256 template<typename DataType_, typename IndexType_, int BlockSize_, typename Space_, typename Function_>
259 const Space_& space,
260 const Function_& function) const
261 {
262 // ensure that the function is a vector field of correct dimension
263 typedef typename Function_::ImageType FuncImageType;
264 static_assert(FuncImageType::is_vector, "only vector fields are supported");
265 static_assert(FuncImageType::image_dim == BlockSize_, "invalid filter block size");
266
267 // get the value type of the function
269
270 // build index-value map
271 std::map<Index, ValueType> idx_map;
272 Intern::UnitAsmWrapper<shape_dim>::assemble(idx_map, space, _cells, function);
273
274 // allocate filter if necessary
275 if (filter.size() == Index(0))
276 {
278 }
279
280 // loop over all dof-indices
281 auto it(idx_map.begin());
282 auto jt(idx_map.end());
283 for(Index i(0); it != jt; ++it, ++i)
284 {
285 // store the dof-index
286 filter.add(IndexType_(it->first), it->second);
287 }
288 }
289
305 template<typename DTF_, typename ITF_, typename DTV_, typename ITV_,int BlockSize_, typename Space_>
308 const Space_& space,
310 {
311 // build index set
312 std::set<Index> idx_set;
313 Intern::UnitAsmWrapper<shape_dim>::assemble(idx_set, space, _cells);
314
315 // allocate filter if necessary
316 if (filter.size() == Index(0))
317 {
318 filter = LAFEM::UnitFilterBlocked<DTF_, ITF_, BlockSize_>(space.get_num_dofs());
319 }
320
321 // loop over all dof-indices
322 typename std::set<Index>::const_iterator it(idx_set.begin());
323 typename std::set<Index>::const_iterator jt(idx_set.end());
324 for(Index i(0); it != jt; ++it, ++i)
325 {
326 // store the dof-index
327 filter.add(ITF_(*it), vector_(ITV_(*it)));
328 }
329 }
330 }; // class UnitFilterAssembler
331
333 namespace Intern
334 {
336 template<int shape_dim_>
337 struct UnitAsmHelper
338 {
339 template<typename MeshPart_>
340 static void merge(std::set<Index>& idx, const MeshPart_& mesh_part)
341 {
342 // fetch the target set for this dimension
343 const typename MeshPart_::template TargetSet<shape_dim_>::Type&
344 target_set(mesh_part.template get_target_set<shape_dim_>());
345
346 // merge
347 const Index num_entities = target_set.get_num_entities();
348 for(Index i(0); i < num_entities; ++i)
349 {
350 idx.insert(target_set[i]);
351 }
352 }
353
355 template<typename Space_>
356 static void assemble(std::set<Index>& idx, const Space_& space, const std::set<Index>& cells)
357 {
358 // create a dof-assignment object
359 typename Space_::template DofAssignment<shape_dim_>::Type dof_assign(space);
360
361 // loop over all target indices
362 std::set<Index>::const_iterator it(cells.begin());
363 std::set<Index>::const_iterator jt(cells.end());
364 for(; it != jt; ++it)
365 {
366 dof_assign.prepare(*it);
367 const int num_assign(dof_assign.get_num_assigned_dofs());
368 for(int j(0); j < num_assign; ++j)
369 {
370 idx.insert(dof_assign.get_index(j));
371 }
372 dof_assign.finish();
373 }
374 }
375
377 template<
378 typename DataType_,
379 typename Space_,
380 typename Function_>
381 static void assemble(
382 std::map<Index, DataType_>& idx,
383 const Space_& space,
384 const std::set<Index>& cells,
385 const Function_& function)
386 {
387 // create a node-functional object
388 typedef typename Space_::template NodeFunctional<shape_dim_, DataType_>::Type NodeFunc;
389
390 // check for empty node functional set
391 static constexpr Index max_dofs = NodeFunc::max_assigned_dofs;
392 if(max_dofs <= 0)
393 return;
394
395 // create node functional
396 NodeFunc node_func(space);
397
398 // create a dof-assignment object
399 typename Space_::template DofAssignment<shape_dim_, DataType_>::Type dof_assign(space);
400
401 // create node data; avoid zero-length vectors
402 Tiny::Vector<DataType_, max_dofs+1> node_data;
403
404 // loop over all target indices
405 std::set<Index>::const_iterator it(cells.begin());
406 std::set<Index>::const_iterator jt(cells.end());
407 for(; it != jt; ++it)
408 {
409 node_func.prepare(*it);
410 node_func(node_data, function);
411 node_func.finish();
412
413 dof_assign.prepare(*it);
414
415 const int num_assign(dof_assign.get_num_assigned_dofs());
416 for(int j(0); j < num_assign; ++j)
417 {
418 idx.insert(std::make_pair(dof_assign.get_index(j), node_data[j]));
419 }
420 dof_assign.finish();
421 }
422 }
423
425 template<
426 typename DataType_,
427 int dim_,
428 int s_,
429 typename Space_,
430 typename Function_>
431 static void assemble(
432 std::map<Index, Tiny::Vector<DataType_, dim_, s_>>& idx,
433 const Space_& space,
434 const std::set<Index>& cells,
435 const Function_& function)
436 {
437 // create a node-functional object
438 typedef typename Space_::template NodeFunctional<shape_dim_, DataType_>::Type NodeFunc;
439
440 // check for empty node functional set
441 static constexpr Index max_dofs = NodeFunc::max_assigned_dofs;
442 if(max_dofs <= 0)
443 return;
444
445 // create node functional
446 NodeFunc node_func(space);
447
448 // create a dof-assignment object
449 typename Space_::template DofAssignment<shape_dim_, DataType_>::Type dof_assign(space);
450
451 typedef Tiny::Vector<DataType_, dim_, s_> ValueType;
452
453 // create node data; avoid zero-length vectors
454 Tiny::Vector<ValueType, max_dofs+1> node_data;
455
456 // loop over all target indices
457 std::set<Index>::const_iterator it(cells.begin());
458 std::set<Index>::const_iterator jt(cells.end());
459 for(; it != jt; ++it)
460 {
461 node_func.prepare(*it);
462 node_func(node_data, function);
463 node_func.finish();
464
465 dof_assign.prepare(*it);
466
467 const int num_assign(dof_assign.get_num_assigned_dofs());
468 for(int j(0); j < num_assign; ++j)
469 {
470 idx.insert(std::make_pair(dof_assign.get_index(j), node_data[j]));
471 }
472 dof_assign.finish();
473 }
474 }
475 };
476
478 template<int shape_dim_>
479 struct UnitAsmWrapper
480 {
481 template<typename MeshPart_>
482 static void merge(std::set<Index>* idx, const MeshPart_& mesh_part)
483 {
484 UnitAsmWrapper<shape_dim_ - 1>::merge(idx, mesh_part);
485 UnitAsmHelper<shape_dim_>::merge(idx[shape_dim_], mesh_part);
486 }
487
488 template<typename Space_>
489 static void assemble(std::set<Index>& idx, const Space_& space, const std::set<Index>* cells)
490 {
491 UnitAsmWrapper<shape_dim_ - 1>::assemble(idx, space, cells);
492 UnitAsmHelper<shape_dim_>::assemble(idx, space, cells[shape_dim_]);
493 }
494
495 template<
496 typename DataType_,
497 typename Space_,
498 typename Function_>
499 static void assemble(
500 std::map<Index, DataType_>& idx,
501 const Space_& space,
502 const std::set<Index>* cells,
503 const Function_& function)
504 {
505 UnitAsmWrapper<shape_dim_ - 1>::assemble(idx, space, cells, function);
506 UnitAsmHelper<shape_dim_>::assemble(idx, space, cells[shape_dim_], function);
507 }
508 };
509
510 template<>
511 struct UnitAsmWrapper<0>
512 {
513 template<typename MeshPart_>
514 static void merge(std::set<Index>* idx, const MeshPart_& mesh_part)
515 {
516 UnitAsmHelper<0>::merge(idx[0], mesh_part);
517 }
518
519 template<typename Space_>
520 static void assemble(std::set<Index>& idx, const Space_& space, const std::set<Index>* cells)
521 {
522 UnitAsmHelper<0>::assemble(idx, space, cells[0]);
523 }
524
525 template<
526 typename DataType_,
527 typename Space_,
528 typename Function_>
529 static void assemble(
530 std::map<Index, DataType_>& idx,
531 const Space_& space,
532 const std::set<Index>* cells,
533 const Function_& function)
534 {
535 UnitAsmHelper<0>::assemble(idx, space, cells[0], function);
536 }
537 };
538 } // namespace Intern
540 } // namespace Assembly
541} // namespace FEAT
Unit-Filter assembly class template.
void add_mesh_part(const Geometry::MeshPart< MeshType > &mesh_part)
Adds the dofs on a mesh-part to the dof-set.
void assemble(LAFEM::UnitFilter< DataType_, IndexType_ > &filter, const Space_ &space) const
Builds a homogeneous unit-filter.
IdxSet _cells[shape_dim+1]
dof-index set
std::set< Index > IdxSet
dof-index set typedef
void assemble(LAFEM::UnitFilterBlocked< DTF_, ITF_, BlockSize_ > &filter, const Space_ &space, const LAFEM::DenseVectorBlocked< DTV_, ITV_, BlockSize_ > &vector_) const
Builds an inhomogeneous blocked unit filter.
void assemble(LAFEM::UnitFilter< DataType_, IndexType_ > &filter, const Space_ &space, const Function_ &function) const
Builds an (inhomogeneous) unit-filter.
void assemble(LAFEM::UnitFilterBlocked< DataType_, IndexType_, BlockSize_ > &filter, const Space_ &space, const Function_ &function) const
Builds an inhomogeneous blocked unit filter.
void assemble(LAFEM::UnitFilter< DataType_, IndexType_ > &filter, const Space_ &space, const LAFEM::DenseVector< DataType_, IndexType_ > &vector_) const
Builds an inhomogeneous unit-filter.
static constexpr int shape_dim
shape dimension
void assemble(LAFEM::UnitFilterBlocked< DataType_, IndexType_, BlockSize_ > &filter, const Space_ &space) const
Builds a homogeneous blocked unit filter.
Class template for partial meshes.
Definition: mesh_part.hpp:90
Blocked Dense data vector class template.
Dense data vector class template.
Unit Filter Blocked class template.
Unit Filter class template.
Definition: unit_filter.hpp:29
Tiny Vector class template.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.