FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
patch_meshpart_splitter.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/geometry/mesh_part.hpp>
10
11// includes, system
12#include <map>
13
14namespace FEAT
15{
16 namespace Geometry
17 {
19 // Forward declarations
20 class PatchPartMap;
21
22 template<typename, int>
23 class PatchPartMapHolder;
25
34 template<typename Mesh_>
36
55 template<typename Shape_, int num_coords_, typename Coord_>
56 class PatchMeshPartSplitter<Geometry::ConformalMesh<Shape_, num_coords_, Coord_>> :
57 public Factory<MeshPart<Geometry::ConformalMesh<Shape_, num_coords_, Coord_>>>
58 {
59 public:
61 typedef Shape_ ShapeType;
63 static constexpr int shape_dim = ShapeType::dimension;
76
77 protected:
82
86 const IndexSetHolder<ShapeType>* _cur_part_topology;
89
90 public:
100 explicit PatchMeshPartSplitter(const MeshType& base_mesh, const MeshPartType& patch_mesh_part) :
101 _base_mesh(base_mesh),
102 _patch_mesh_part(patch_mesh_part),
103 _cur_part_attribute_container(nullptr),
104 _cur_part_topology(nullptr),
105 _part_holder(patch_mesh_part.get_target_set_holder())
106 {
107 }
108
113 {
114 }
115
126 bool build(const MeshPartType& mesh_part)
127 {
128 _cur_part_topology = mesh_part.get_topology();
129 _cur_part_attribute_container = &(mesh_part.get_mesh_attributes());
130 return _part_holder.build(mesh_part.get_target_set_holder(), mesh_part.get_topology());
131 }
132
133 /* *************************************************************************************** */
134 /* F A C T O R Y I N T E R F A C E I M P L E M E N T A T I O N */
135 /* *************************************************************************************** */
136
146 virtual Index get_num_entities(int dim) override
147 {
148 return _part_holder.get_num_entities(dim);
149 }
150
157 virtual void fill_attribute_sets(AttributeSetContainer& attribute_container) override
158 {
159 _part_holder.fill_attribute_sets(attribute_container, *_cur_part_attribute_container);
160 }
161
168 virtual void fill_index_sets(std::unique_ptr<IndexSetHolderType>& index_set_holder) override
169 {
170 XASSERT(index_set_holder == nullptr);
171
172 // If the base MeshPart has a topology, create one for the patch MeshPart, too
173 if(_part_holder.has_topology())
174 {
175 // Get num_entities for all shape dimensions
176 Index num_entities[shape_dim+1];
177 for(int i(0); i < shape_dim+1; ++i)
178 num_entities[i] = get_num_entities(i);
179
180 // Create this MeshPart's topology
181 index_set_holder.reset(new IndexSetHolderType(num_entities));
182 // This creates vertex-at-shape information for all shapes
183 _part_holder.fill_index_sets(*index_set_holder, *_cur_part_topology);
184 // Build the redundant index sets
186 }
187 }
188
195 virtual void fill_target_sets(TargetSetHolderType& target_set_holder) override
196 {
197 _part_holder.fill_target_sets(target_set_holder);
198 }
199 }; // class PatchMeshPartSplitter<ConformalMesh<...>>
200
221 {
222 private:
224 std::map<Index,Index> _idx_map;
226 std::map<Index,Index> _io_map;
228 std::vector<Index> _indices;
229
230 public:
237 explicit PatchPartMap(const TargetSet& target_set) :
238 _idx_map(),
239 _io_map(),
240 _indices()
241 {
242 // loop over all indices
243 for(Index i(0); i < target_set.get_num_entities(); ++i)
244 {
245 // This maps the BaseMesh entity j = target_set[i] to the patch MeshPart entity i
246 XASSERTM(_idx_map.emplace(target_set[i], i).second, "internal error");
247 }
248 }
249
259 bool build(const TargetSet& target_in)
260 {
261 // Very important: Clear old information
262 _indices.clear();
263 _io_map.clear();
264
265 // We need information for every entity in the BaseMesh MeshPart
266 for(Index i(0); i < target_in.get_num_entities(); ++i)
267 {
268 // Check if the BaseMesh entity referenced by the BaseMesh MeshPart is in the PatchMeshPart
269 auto it = _idx_map.find(target_in[i]);
270 if(it != _idx_map.end())
271 {
272 // We create new entries in the PatchMeshPart MeshPart here, so the entity i in the BaseMesh MeshPart
273 // refers to the newly created entity in the PatchMeshPart MeshPart
274 _io_map.emplace(i, Index(_indices.size()));
275 // Add the new entity
276 _indices.push_back(it->second);
277 }
278 }
279 return !_indices.empty();
280 }
281
287 Index size() const
288 {
289 return Index(_indices.size());
290 }
291
304 template<typename Attribute_>
306 std::map<String, std::unique_ptr<Attribute_>>& attribute_container_out,
307 const std::map<String, std::unique_ptr<Attribute_>>& attribute_container_in) const
308 {
309 for(auto it(attribute_container_in.begin()); it != attribute_container_in.end(); ++it)
310 {
311 // Create new attribute for the PatchMeshPart MeshPart
312 std::unique_ptr<Attribute_> new_attribute(new Attribute_(
313 Index(_indices.size()), it->second->get_dimension()));
314
315 const int dim = it->second->get_dimension();
316
317 // Emplace all elements referred to by the _io_map into new_attribute
318 for(auto jt: _io_map)
319 {
320 for(int k(0); k < dim; ++k)
321 new_attribute->operator()(jt.second, k) = it->second->operator()(jt.first, k);
322 }
323
324 // Push the new attribute to set_out
325 XASSERTM(attribute_container_out.insert(std::make_pair(it->first, std::move(new_attribute))).second, "Error inserting new AttributeSet");
326 }
327 }
328
335 void fill_target_set(TargetSet& target_out) const
336 {
337 XASSERT(target_out.get_num_entities() == size());
338 for(Index i(0); i < target_out.get_num_entities(); ++i)
339 {
340 target_out[i] = _indices[i];
341 }
342 }
343
371 template<typename IndexSetType_>
372 void fill_index_set(IndexSetType_& index_set_out, const IndexSetType_& index_set_in,
373 const std::map<Index, Index>& vertex_map) const
374 {
375 // We need to check all shape entities in the MeshPart referring to the BaseMesh
376 for(Index k(0); k < index_set_in.get_num_entities(); ++k)
377 {
378 // Check if the BaseMesh entity referred to by the BaseMesh MeshPart is also present in the PatchMeshPart
379 auto kt = _io_map.find(k);
380 if(kt != _io_map.end())
381 {
382 // For all vertices at that entity, we need to find them in the PatchMeshPart's MeshPart
383 for(int j(0); j < index_set_in.get_num_indices(); ++j)
384 {
385 // Fetch the BaseMesh MeshPart's vertex number
386 Index i_in(index_set_in(k,j));
387 // That vertex is definitely in the PatchMeshPart's MeshPart, but we need to catch any errors here
388 auto jt = vertex_map.find(i_in);
389 if(jt != vertex_map.end())
390 // This is the correct number
391 index_set_out(kt->second, j) = jt->second;
392 else
393 XABORTM("Vertex "+stringify(i_in)+" missing in MeshPart topology!");
394 }
395 }
396 }
397 }
398
405 const std::map<Index, Index>& get_io_map() const
406 {
407 return _io_map;
408 }
409 }; // class PatchPartMap
410
422 template<typename Shape_, int dim_ = Shape_::dimension>
424 public PatchPartMapHolder<Shape_, dim_ - 1>
425 {
426 public:
428 typedef PatchPartMapHolder<Shape_, dim_ - 1> BaseClass;
429
430 private:
435
436 public:
443 explicit PatchPartMapHolder(const TargetSetHolder<Shape_>& tsh) :
444 BaseClass(tsh),
445 _patch_map(tsh.template get_target_set<dim_>()),
446 _has_topology(false)
447 {
448 }
449
462 bool build(const TargetSetHolder<Shape_>& tsh, const IndexSetHolder<Shape_>* ish)
463 {
464 ish == nullptr ? _has_topology = false : _has_topology = true;
465
466 // Call the BaseClass version (meaning of lower shape dimension) first
467 bool b1 = BaseClass::build(tsh, ish);
468 bool b2 = _patch_map.build(tsh.template get_target_set<dim_>());
469
470 return b1 || b2;
471 }
472
481 Index get_num_entities(int dim) const
482 {
483 XASSERT(dim <= dim_);
484 if(dim == dim_)
485 return _patch_map.size();
486 else
487 return BaseClass::get_num_entities(dim);
488 }
489
496 bool has_topology() const
497 {
498 return _has_topology;
499 }
500
513 template<typename AttributeSetContainer_>
515 AttributeSetContainer_& attribute_container_out,
516 const AttributeSetContainer_& attribute_container_in) const
517 {
518 // Fill attribute sets of one shape dimension lower first
519 BaseClass::fill_attribute_sets(attribute_container_out, attribute_container_in);
520 }
521
528 void fill_target_sets(TargetSetHolder<Shape_>& tsh) const
529 {
531 _patch_map.fill_target_set(tsh.template get_target_set<dim_>());
532 }
533
548 template<typename IndexSetHolder_>
549 void fill_index_sets(IndexSetHolder_& ish, const IndexSetHolder_& ish_in) const
550 {
551 BaseClass::fill_index_sets(ish, ish_in);
552 _patch_map.fill_index_set(ish.template get_index_set<dim_,0>(), ish_in.template get_index_set<dim_,0>(),
554 }
555
563 const std::map<Index, Index>& get_vertex_map() const
564 {
566 }
567 }; // class PatchPartMapHolder<...>
568
570
573 template<typename Shape_>
574 class PatchPartMapHolder<Shape_, 0>
575 {
576 private:
577 PatchPartMap _patch_map;
578
579 public:
580 explicit PatchPartMapHolder(const TargetSetHolder<Shape_>& tsh) :
581 _patch_map(tsh.template get_target_set<0>())
582 {
583 }
584
585 bool build(const TargetSetHolder<Shape_>& tsh, const IndexSetHolder<Shape_>* DOXY(ish))
586 {
587 return _patch_map.build(tsh.template get_target_set<0>());
588 }
589
590 Index get_num_entities(int dim) const
591 {
592 XASSERT(dim == 0);
593 return _patch_map.size();
594 }
595
596 template<typename AttributeSetContainer_>
598 AttributeSetContainer_& attribute_container_out,
599 const AttributeSetContainer_& attribute_container_in) const
600 {
601 // Fill attribute set to shape dimension 0
602 _patch_map.fill_attribute_set( attribute_container_out, attribute_container_in);
603 }
604
605 template<typename IndexSetHolder_>
606 void fill_index_sets(IndexSetHolder_& DOXY(ish), const IndexSetHolder_& DOXY(ish_in)) const
607 {
608 }
609
610 void fill_target_sets(TargetSetHolder<Shape_>& tsh) const
611 {
612 _patch_map.fill_target_set(tsh.template get_target_set<0>());
613 }
614
615
616 const std::map<Index, Index>& get_vertex_map() const
617 {
618 return _patch_map.get_io_map();
619 }
620 }; // class PatchPartMapHolder<Shape_, 0>
622
623 } // namespace Geometry
624} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Conformal mesh class template.
Coord_ CoordType
Coordinate type.
Mesh Factory class template.
Definition: factory.hpp:33
Class template for partial meshes.
Definition: mesh_part.hpp:90
const AttributeSetContainer & get_mesh_attributes() const
Returns a const reference to the mesh attributes container.
Definition: mesh_part.hpp:346
TargetSetHolder< ShapeType > TargetSetHolderType
Target set holder type.
Definition: mesh_part.hpp:101
IndexSetHolder< ShapeType > IndexSetHolderType
Index set holder type.
Definition: mesh_part.hpp:99
std::map< String, std::unique_ptr< AttributeSetType > > AttributeSetContainer
submesh node bin container type
Definition: mesh_part.hpp:138
const IndexSetHolder< ShapeType > * _cur_part_topology
The topology of the current BaseMesh MeshPart.
bool build(const MeshPartType &mesh_part)
Assembles information from a MeshPart referring to the BaseMesh.
PatchPartMapHolder< ShapeType, ShapeType::dimension > _part_holder
The BaseMesh MeshPart to PatchMeshPart MeshPart mapping information.
virtual void fill_attribute_sets(AttributeSetContainer &attribute_container) override
Fills the attribute sets.
const AttributeSetContainer * _cur_part_attribute_container
The mesh attributes of the current BaseMesh MeshPart.
PatchMeshPartSplitter(const MeshType &base_mesh, const MeshPartType &patch_mesh_part)
Constructor.
virtual void fill_target_sets(TargetSetHolderType &target_set_holder) override
Fills the target sets.
virtual void fill_index_sets(std::unique_ptr< IndexSetHolderType > &index_set_holder) override
Fills the index sets.
Class for creating MeshParts referring to a patch BaseMesh.
This is a container class for holding PatchPartMaps for all dimensions.
bool has_topology() const
Does the current BaseMesh MeshPart have a topology?
void fill_target_sets(TargetSetHolder< Shape_ > &tsh) const
Factory interface: Fills the TargetSetHolder.
const std::map< Index, Index > & get_vertex_map() const
Gets the vertex map.
bool _has_topology
We need to know if the last BaseMesh MeshPart from build() had a topology.
void fill_index_sets(IndexSetHolder_ &ish, const IndexSetHolder_ &ish_in) const
Factory interface: Fills the IndexSetHolder.
Index get_num_entities(int dim) const
Gets the number of entities.
PatchPartMapHolder< Shape_, dim_ - 1 > BaseClass
Our base class.
PatchPartMap _patch_map
The PatchPartMap for our dimension.
void fill_attribute_sets(AttributeSetContainer_ &attribute_container_out, const AttributeSetContainer_ &attribute_container_in) const
MeshPart Factory interface: Fills the AttributeSetContainer.
bool build(const TargetSetHolder< Shape_ > &tsh, const IndexSetHolder< Shape_ > *ish)
Assembles information from a BaseMesh MeshPart.
PatchPartMapHolder(const TargetSetHolder< Shape_ > &tsh)
Standard constructor.
Mapping class for BaseMesh/PatchBaseMesh and MeshPart index conversions.
std::map< Index, Index > _io_map
Index map from base mesh MeshPart entities to patch boundary MeshPart entities.
bool build(const TargetSet &target_in)
Creates mapping information from a BaseMesh MeshPart to a Patch MeshPart boundary MeshPart.
PatchPartMap(const TargetSet &target_set)
Standard constructor.
void fill_index_set(IndexSetType_ &index_set_out, const IndexSetType_ &index_set_in, const std::map< Index, Index > &vertex_map) const
Fills the vertex-at-shape IndexSet of the PatchMeshPart MeshPart.
void fill_attribute_set(std::map< String, std::unique_ptr< Attribute_ > > &attribute_container_out, const std::map< String, std::unique_ptr< Attribute_ > > &attribute_container_in) const
Fills an attribute set.
void fill_target_set(TargetSet &target_out) const
Fills the PatchMeshPart MeshPart's TargetSet.
std::map< Index, Index > _idx_map
Index map from BaseMesh entity to PatchMeshPart entity.
const std::map< Index, Index > & get_io_map() const
Gets the mapping BaseMesh MeshPart entities to PatchMeshPart MeshPart entities.
Index size() const
The size of the PatchMeshPart MeshPart.
std::vector< Index > _indices
This is basically the TargetSet mapping PatchMeshPart MeshPart entities to the PatchMeshPart.
static void compute(IndexSetHolder< Shape_ > &index_set_holder)
Routine that does the actual work.
Target set class.
Definition: target_set.hpp:27
Index get_num_entities() const
Returns the number of entities.
Definition: target_set.hpp:92
String class implementation.
Definition: string.hpp:46
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
std::uint64_t Index
Index data type.