FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
boundary_factory.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/conformal_mesh.hpp>
10#include <kernel/geometry/mesh_part.hpp>
11#include <kernel/geometry/intern/boundary_computer.hpp>
12#include <kernel/util/dist.hpp>
13
14namespace FEAT
15{
16 namespace Geometry
17 {
26 template<typename ParentMesh_>
28 public Factory<MeshPart<ParentMesh_>>
29 {
30 public:
34 typedef ParentMesh_ ParentMeshType;
42 static constexpr int shape_dim = ShapeType::dimension;
43
44 private:
48 Intern::BoundaryFaceComputer<ShapeType> _face_computer;
50 std::array<std::vector<int>, std::size_t(shape_dim)> _bnd_masks;
52 std::array<std::vector<Index>, std::size_t(shape_dim)> _face_idx;
53
54 public:
61 explicit BoundaryFactory(const ParentMeshType& mesh_in) :
62 _mesh_in(mesh_in)
63 {
64 _face_computer.compute_all(mesh_in.get_index_set_holder(), _bnd_masks, _face_idx);
65 }
66
68 virtual Index get_num_entities(int dim) override
69 {
70 if(dim < shape_dim)
71 return Index(_face_idx.at(std::size_t(dim)).size());
72 else
73 return Index(0);
74 }
75
77 virtual void fill_attribute_sets(typename BaseClass::AttributeSetContainer&) override
78 {
79 }
80
82 virtual void fill_index_sets(std::unique_ptr<typename BaseClass::IndexSetHolderType>&) override
83 {
84 }
85
87 virtual void fill_target_sets(TargetSetHolderType& target_set_holder) override
88 {
89 _face_computer.fill_target_sets(target_set_holder, _face_idx);
90 }
91
92 }; // class BoundaryFactory<...>
93
103 template<typename Mesh_>
105 {
106 BoundaryFactory<Mesh_> factory(mesh);
107 return factory.make();
108 }
109
119 template<typename Mesh_>
120 std::unique_ptr<MeshPart<Mesh_>> make_unique_boundary_meshpart(const Mesh_& mesh)
121 {
122 BoundaryFactory<Mesh_> factory(mesh);
123 return factory.make_unique();
124 }
125
126
145 template<typename ParentMesh_>
147 public Factory<MeshPart<ParentMesh_>>
148 {
149 public:
153 typedef ParentMesh_ ParentMeshType;
161 static constexpr int shape_dim = ShapeType::dimension;
163 static constexpr int facet_dim = shape_dim - 1;
164
165 private:
169 Intern::BoundaryFaceComputer<ShapeType> _face_computer;
171 std::vector<int> _facet_mask;
173 std::array<std::vector<int>, std::size_t(shape_dim)> _bnd_masks;
175 std::array<std::vector<Index>, std::size_t(shape_dim)> _face_idx;
176
177 public:
184 explicit MaskedBoundaryFactory(const ParentMeshType& mesh_in) :
185 _mesh_in(mesh_in),
187 {
188 }
189
190 // Adds a single facet to the boundary facet mask.
191 void add_mask_facet(Index facet_idx)
192 {
193 _facet_mask.at(facet_idx) = 1;
194 }
195
203 {
204 const TargetSet& trg_set = part.template get_target_set<facet_dim>();
205 for(Index i(0); i < trg_set.get_num_entities(); ++i)
206 _facet_mask.at(trg_set[i]) = 1;
207 }
208
210 void compile()
211 {
212 _face_computer.compute_masks(_mesh_in.get_index_set_holder(), _bnd_masks, _face_idx, _facet_mask);
213 _face_computer.compute_faces(_bnd_masks, _face_idx);
214 }
215
217 virtual Index get_num_entities(int dim) override
218 {
219 if(dim < shape_dim)
220 return Index(_face_idx.at(std::size_t(dim)).size());
221 else
222 return Index(0);
223 }
224
226 virtual void fill_attribute_sets(typename BaseClass::AttributeSetContainer&) override
227 {
228 }
229
231 virtual void fill_index_sets(std::unique_ptr<typename BaseClass::IndexSetHolderType>&) override
232 {
233 }
234
236 virtual void fill_target_sets(TargetSetHolderType& target_set_holder) override
237 {
238 _face_computer.fill_target_sets(target_set_holder, _face_idx);
239 }
240 }; // class MaskedBoundaryFactory<...>
241
270 template<typename ParentMesh_>
272 public Factory<MeshPart<ParentMesh_>>
273 {
274 public:
278 typedef ParentMesh_ ParentMeshType;
286 static constexpr int shape_dim = ShapeType::dimension;
288 static constexpr int facet_dim = shape_dim - 1;
289
290 private:
294 Intern::BoundaryFaceComputer<ShapeType> _face_computer;
296 std::vector<int> _facet_mask;
298 std::array<std::vector<int>, std::size_t(shape_dim)> _bnd_masks;
300 std::array<std::vector<Index>, std::size_t(shape_dim)> _face_idx;
302 std::vector<std::pair<int, const MeshType*>> _halos;
303
304 public:
312 _mesh_in(mesh_in),
314 {
315 }
316
317 // Adds a single facet to the mask.
318 void add_mask_facet(Index facet_idx)
319 {
320 _facet_mask.at(facet_idx) = 1;
321 }
322
330 {
331 const TargetSet& trg_set = part.template get_target_set<facet_dim>();
332 for(Index i(0); i < trg_set.get_num_entities(); ++i)
333 _facet_mask.at(trg_set[i]) = 1;
334 }
335
345 void add_halo(int rank, const MeshPart<ParentMeshType>& halo)
346 {
347 // add the halo as a mask meshpart
348 add_mask_meshpart(halo);
349 // and save the halo
350 //_halos.emplace(rank, &halo);
351 _halos.push_back(std::make_pair(rank, &halo));
352 }
353
363 void compile(const Dist::Comm& comm)
364 {
365 _face_computer.compute_masks(_mesh_in.get_index_set_holder(), _bnd_masks, _face_idx, _facet_mask);
366 _sync_bnd_masks(comm);
367 _face_computer.compute_faces(_bnd_masks, _face_idx);
368 }
369
371 virtual Index get_num_entities(int dim) override
372 {
373 if(dim < shape_dim)
374 return Index(_face_idx.at(std::size_t(dim)).size());
375 else
376 return Index(0);
377 }
378
380 virtual void fill_attribute_sets(typename BaseClass::AttributeSetContainer&) override
381 {
382 }
383
385 virtual void fill_index_sets(std::unique_ptr<typename BaseClass::IndexSetHolderType>&) override
386 {
387 }
388
390 virtual void fill_target_sets(TargetSetHolderType& target_set_holder) override
391 {
392 _face_computer.fill_target_sets(target_set_holder, _face_idx);
393 }
394
395 protected:
399 void _sync_bnd_masks(const Dist::Comm& comm)
400 {
401 if(_halos.empty())
402 return;
403
404 // allocate halo buffers
405 std::vector<std::vector<int>> halo_send_bufs(_halos.size()), halo_recv_bufs(_halos.size());
406
407 // create send buffers and allocate receive buffers
408 for(std::size_t i(0); i < _halos.size(); ++i)
409 {
410 // count total number of entries in halo
411 Index count = 0u;
412 for(int dim = 0; dim < shape_dim; ++dim) // we don't need to sync dim=shape_dim here
413 count += _halos[i].second->get_num_entities(dim);
414
415 halo_recv_bufs[i].resize(count);
416 halo_send_bufs[i].resize(count); // build_halo_buffer uses push_back
417 _face_computer.build_halo_buffer(halo_send_bufs[i], _bnd_masks, _halos[i].second->get_target_set_holder());
418 }
419
420 // post receive requests
421 Dist::RequestVector recv_reqs(_halos.size());
422 for(std::size_t i(0); i < _halos.size(); ++i)
423 recv_reqs.push_back(comm.irecv(halo_recv_bufs[i].data(), halo_recv_bufs[i].size(), _halos[i].first));
424
425 // post send requests
426 Dist::RequestVector send_reqs(_halos.size());
427 for(std::size_t i(0); i < _halos.size(); ++i)
428 send_reqs.push_back(comm.isend(halo_send_bufs[i].data(), halo_send_bufs[i].size(), _halos[i].first));
429
430 // wait for all receives to finish
431 recv_reqs.wait_all();
432
433 // process receives halo buffers
434 for(std::size_t i(0); i < _halos.size(); ++i)
435 {
436 _face_computer.mask_halo_buffer(_bnd_masks, halo_recv_bufs[i], _halos[i].second->get_target_set_holder());
437 }
438
439 // wait for all sends to finish
440 send_reqs.wait_all();
441 }
442 }; // class GlobalMaskedBoundaryFactory<...>
443
453 template<typename MeshNode_>
455 {
456 GlobalMaskedBoundaryFactory<typename MeshNode_::MeshType> boundary_factory(*node.get_mesh());
457
458 for(const auto& pair : node.get_halo_map())
459 {
460 boundary_factory.add_halo(pair.first, *pair.second);
461 }
462 boundary_factory.compile(comm);
463 return boundary_factory.make();
464 }
465
475 template<typename MeshNode_>
476 std::unique_ptr<MeshPart<typename MeshNode_::MeshType>> make_unique_boundary_meshpart(const MeshNode_& node, const Dist::Comm& comm)
477 {
478 GlobalMaskedBoundaryFactory<typename MeshNode_::MeshType> boundary_factory(*node.get_mesh());
479
480 for(const auto& pair : node.get_halo_map())
481 {
482 boundary_factory.add_halo(pair.first, *pair.second);
483 }
484 boundary_factory.compile(comm);
485 return boundary_factory.make_unique();
486 }
487 } // namespace Geometry
488} // namespace FEAT
Communicator class.
Definition: dist.hpp:1349
Request irecv(void *buffer, std::size_t count, const Datatype &datatype, int source, int tag=0) const
Nonblocking Receive.
Definition: dist.cpp:716
Request isend(const void *buffer, std::size_t count, const Datatype &datatype, int dest, int tag=0) const
Nonblocking Send.
Definition: dist.cpp:704
Communication Request vector class.
Definition: dist.hpp:640
void push_back(Request &&request)
Inserts a new request at the end of the request vector.
Definition: dist.hpp:886
void wait_all()
Blocks until all active requests are fulfilled.
Definition: dist.cpp:324
BoundaryFactory implementation.
Intern::BoundaryFaceComputer< ShapeType > _face_computer
a boundary face computer object for the dirty work
MeshType::ShapeType ShapeType
the shape type
static constexpr int shape_dim
the facet dimension
std::array< std::vector< int >, std::size_t(shape_dim)> _bnd_masks
the face masks for each face dimensions
std::array< std::vector< Index >, std::size_t(shape_dim)> _face_idx
the (cell_dim_-1)-dimensional boundary face indices for each face dimension
virtual Index get_num_entities(int dim) override
Returns the number of entities.
virtual void fill_index_sets(std::unique_ptr< typename BaseClass::IndexSetHolderType > &) override
Fills the MeshPart's index_set_holder, except that it doesn't as there is no topology.
BoundaryFactory(const ParentMeshType &mesh_in)
Constructor.
virtual void fill_target_sets(TargetSetHolderType &target_set_holder) override
Fills the MeshPart's target set.
MeshType::TargetSetHolderType TargetSetHolderType
target set holder type
const ParentMeshType & _mesh_in
a reference to the input mesh
MeshPart< ParentMeshType > MeshType
The MeshPart type.
virtual void fill_attribute_sets(typename BaseClass::AttributeSetContainer &) override
Fills the MeshPart's target set, except that it doesn't.
ParentMesh_ ParentMeshType
the parent mesh type
Factory< MeshPart< ParentMesh_ > > BaseClass
Our base class.
Mesh Factory class template.
Definition: factory.hpp:33
GlobalMaskedBoundaryFactory implementation.
virtual void fill_index_sets(std::unique_ptr< typename BaseClass::IndexSetHolderType > &) override
Fills the MeshPart's index_set_holder, except that it doesn't as there is no topology.
std::array< std::vector< int >, std::size_t(shape_dim)> _bnd_masks
the face masks for each face dimensions
ParentMesh_ ParentMeshType
the parent mesh type
MeshPart< ParentMeshType > MeshType
The MeshPart type.
GlobalMaskedBoundaryFactory(const ParentMeshType &mesh_in)
Constructor.
virtual void fill_attribute_sets(typename BaseClass::AttributeSetContainer &) override
Fills the MeshPart's target set, except that it doesn't.
void _sync_bnd_masks(const Dist::Comm &comm)
Synchronizes the boundary masks over the communicators.
Factory< MeshPart< ParentMesh_ > > BaseClass
Our base class.
virtual Index get_num_entities(int dim) override
Returns the number of entities.
static constexpr int shape_dim
the shape dimension
const ParentMeshType & _mesh_in
a reference to the input mesh
MeshType::ShapeType ShapeType
the shape type
void add_mask_meshpart(const MeshPart< ParentMeshType > &part)
Adds all facets in a mesh-part to the boundary facet mask.
std::vector< int > _facet_mask
a mask vector for the facets
MeshType::TargetSetHolderType TargetSetHolderType
target set holder type
virtual void fill_target_sets(TargetSetHolderType &target_set_holder) override
Fills the MeshPart's target set.
std::array< std::vector< Index >, std::size_t(shape_dim)> _face_idx
the (cell_dim_-1)-dimensional boundary face indices for each face dimension
std::vector< std::pair< int, const MeshType * > > _halos
a map of all halos
void compile(const Dist::Comm &comm)
Compiles the factory.
void add_halo(int rank, const MeshPart< ParentMeshType > &halo)
Adds a halo to the mask and saves it for synchronization.
Intern::BoundaryFaceComputer< ShapeType > _face_computer
a boundary face computer object for the dirty work
static constexpr int facet_dim
the facet dimension
MaskedBoundaryFactory implementation.
void add_mask_meshpart(const MeshPart< ParentMeshType > &part)
Adds all facets in a mesh-part to the boundary facet mask.
std::array< std::vector< int >, std::size_t(shape_dim)> _bnd_masks
the face masks for each face dimensions
virtual void fill_index_sets(std::unique_ptr< typename BaseClass::IndexSetHolderType > &) override
Fills the MeshPart's index_set_holder, except that it doesn't as there is no topology.
ParentMesh_ ParentMeshType
the parent mesh type
static constexpr int shape_dim
the shape dimension
static constexpr int facet_dim
the facet dimension
MaskedBoundaryFactory(const ParentMeshType &mesh_in)
Constructor.
MeshType::TargetSetHolderType TargetSetHolderType
target set holder type
std::vector< int > _facet_mask
a mask vector for the facets
virtual void fill_attribute_sets(typename BaseClass::AttributeSetContainer &) override
Fills the MeshPart's target set, except that it doesn't.
const ParentMeshType & _mesh_in
a reference to the input mesh
Factory< MeshPart< ParentMesh_ > > BaseClass
Our base class.
MeshPart< ParentMeshType > MeshType
The MeshPart type.
void compile()
Compiles the factory.
Intern::BoundaryFaceComputer< ShapeType > _face_computer
a boundary face computer object for the dirty work
std::array< std::vector< Index >, std::size_t(shape_dim)> _face_idx
the (cell_dim_-1)-dimensional boundary face indices for each face dimension
virtual void fill_target_sets(TargetSetHolderType &target_set_holder) override
Fills the MeshPart's target set.
MeshType::ShapeType ShapeType
the shape type
virtual Index get_num_entities(int dim) override
Returns the number of entities.
Class template for partial meshes.
Definition: mesh_part.hpp:90
MeshType::ShapeType ShapeType
Shape type.
Definition: mesh_part.hpp:95
TargetSetHolder< ShapeType > TargetSetHolderType
Target set holder type.
Definition: mesh_part.hpp:101
Target set class.
Definition: target_set.hpp:27
Index get_num_entities() const
Returns the number of entities.
Definition: target_set.hpp:92
std::unique_ptr< MeshPart< Mesh_ > > make_unique_boundary_meshpart(const Mesh_ &mesh)
Creates a new boundary mesh-part for a given mesh.
MeshPart< Mesh_ > make_boundary_meshpart(const Mesh_ &mesh)
Creates a new boundary mesh-part for a given mesh.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.