3 #ifndef DUNE_FOAMGRID_FACTORY_HH
4 #define DUNE_FOAMGRID_FACTORY_HH
13 #include <unordered_map>
15 #include <dune/common/version.hh>
16 #include <dune/common/function.hh>
17 #include <dune/common/fvector.hh>
18 #include <dune/common/hash.hh>
19 #include <dune/common/to_unique_ptr.hh>
21 #include <dune/grid/common/gridfactory.hh>
28 template <
int dimgr
id,
int dimworld,
class ct>
30 :
public GridFactoryInterface<FoamGrid<dimgrid, dimworld, ct> >
42 grid_->entityImps_.resize(1);
58 grid_->entityImps_.resize(1);
68 void insertVertex(
const FieldVector<ctype,dimworld>& pos)
override {
69 std::get<0>(
grid_->entityImps_[0]).emplace_back(
72 grid_->getNextFreeId()
82 return entity.impl().target_->leafIndex_;
90 return vertex.impl().target_->leafIndex_;
98 return intersection.boundarySegmentIndex();
111 std::vector<FoamGridEntityImp<0, dimgrid, dimworld, ctype>*>
vertexArray_;
117 template <
int dimgr
id,
int dimworld,
class ct>
118 class GridFactory<
FoamGrid<dimgrid, dimworld, ct> >
124 template <
int dimworld,
class ct>
151 boundarySegmentIndices_[ vertices[0] ] = this->boundarySegmentCounter_++;
158 const std::shared_ptr<BoundarySegment<dimgrid, dimworld> >& boundarySegment)
override
160 DUNE_THROW(Dune::NotImplemented,
"Parameterized boundary segments are not implemented");
167 if ( !intersection.boundary() || intersection.inside().level() != 0 )
170 const auto& vertex = intersection.inside().template subEntity<1>(intersection.indexInInside());
171 const auto& it = boundarySegmentIndices_.find( this->insertionIndex(vertex) );
172 return (it != boundarySegmentIndices_.end());
180 const std::vector<unsigned int>& vertices)
override
182 assert(type.isLine());
184 std::get<1>(this->grid_->entityImps_[0]).emplace_back(
185 this->vertexArray_[vertices[0]],
186 this->vertexArray_[vertices[1]],
188 this->grid_->getNextFreeId()
198 const std::vector<unsigned int>& vertices,
199 const std::shared_ptr<VirtualFunction<FieldVector<ctype,dimgrid>,FieldVector<ctype,dimworld> > >& elementParametrization)
override
201 assert(type.isLine());
202 EntityImp<1> newElement(this->vertexArray_[vertices[0]],
203 this->vertexArray_[vertices[1]],
205 this->grid_->getNextFreeId());
207 newElement.elementParametrization_ = elementParametrization;
209 std::get<dimgrid>(this->grid_->entityImps_[0]).push_back(newElement);
216 #if DUNE_VERSION_LT(DUNE_COMMON, 2, 7)
219 ToUniquePtr<FoamGrid<1, dimworld, ctype>>
createGrid()
override {
223 if (this->grid_==
nullptr)
227 for (
auto& element : std::get<dimgrid>(this->grid_->entityImps_[0]))
229 element.vertex_[0]->elements_.push_back(&element);
230 element.vertex_[1]->elements_.push_back(&element);
234 this->grid_->setIndices();
240 for (
auto& facet : std::get<0>(this->grid_->entityImps_[0]))
242 if (facet.elements_.size() == 1)
244 const auto it = boundarySegmentIndices_.find( facet.vertex_[0]->leafIndex_ );
245 if (it != boundarySegmentIndices_.end())
246 facet.boundarySegmentIndex_ = it->second;
248 facet.boundarySegmentIndex_ = this->boundarySegmentCounter_++;
257 tmp->numBoundarySegments_ = this->boundarySegmentCounter_;
258 this->grid_ =
nullptr;
263 std::unordered_map<unsigned int, unsigned int> boundarySegmentIndices_;
268 template <
int dimworld,
class ct>
295 std::array<unsigned int, 2> vertexIndices {{ vertices[0], vertices[1] }};
298 if ( vertexIndices[0] > vertexIndices[1] )
299 std::swap( vertexIndices[0], vertexIndices[1] );
301 boundarySegmentIndices_[ vertexIndices ] = this->boundarySegmentCounter_++;
308 const std::shared_ptr<BoundarySegment<dimgrid, dimworld> >& boundarySegment)
override
310 DUNE_THROW(Dune::NotImplemented,
"Parameterized boundary segments are not implemented");
317 if ( !intersection.boundary() || intersection.inside().level() != 0 )
321 const auto refElement = ReferenceElements<ctype, dimgrid>::general(intersection.inside().type());
323 const int subIdx0 = refElement.subEntity(intersection.indexInInside(), 1, 0, dimgrid);
324 const auto vertex0 = intersection.inside().template subEntity<2>( subIdx0 );
325 const int subIdx1 = refElement.subEntity(intersection.indexInInside(), 1, 1, dimgrid);
326 const auto vertex1 = intersection.inside().template subEntity<2>( subIdx1 );
328 std::array<unsigned int, 2> vertexIndices {{
329 this->insertionIndex( vertex0 ),
330 this->insertionIndex( vertex1 )
334 if ( vertexIndices[0] > vertexIndices[1] )
335 std::swap( vertexIndices[0], vertexIndices[1] );
337 const auto& it = boundarySegmentIndices_.find( vertexIndices );
338 return (it != boundarySegmentIndices_.end());
346 const std::vector<unsigned int>& vertices)
override {
348 assert(type.isTriangle());
351 newElement.vertex_[0] = this->vertexArray_[vertices[0]];
352 newElement.vertex_[1] = this->vertexArray_[vertices[1]];
353 newElement.vertex_[2] = this->vertexArray_[vertices[2]];
355 std::get<dimgrid>(this->grid_->entityImps_[0]).push_back(newElement);
364 const std::vector<unsigned int>& vertices,
365 const std::shared_ptr<VirtualFunction<FieldVector<ctype,dimgrid>,FieldVector<ctype,dimworld> > >& elementParametrization)
override
367 assert(type.isTriangle());
369 newElement.vertex_[0] = this->vertexArray_[vertices[0]];
370 newElement.vertex_[1] = this->vertexArray_[vertices[1]];
371 newElement.vertex_[2] = this->vertexArray_[vertices[2]];
373 newElement.elementParametrization_ = elementParametrization;
375 std::get<dimgrid>(this->grid_->entityImps_[0]).push_back(newElement);
381 #if DUNE_VERSION_LT(DUNE_COMMON, 2, 7)
384 ToUniquePtr<FoamGrid<dimgrid, dimworld, ctype>>
createGrid()
override {
388 if (this->grid_==
nullptr)
397 HashPair<const EntityImp<0>*>> edgeMap;
398 for (
auto& element : std::get<dimgrid>(this->grid_->entityImps_[0]))
400 const auto refElement = ReferenceElements<ctype, dimgrid>::general(element.type());
403 for (std::size_t i=0; i<element.facet_.size(); ++i)
408 auto v0 = element.vertex_[refElement.subEntity(i, 1, 0, 2)];
409 auto v1 = element.vertex_[refElement.subEntity(i, 1, 1, 2)];
416 auto e = edgeMap.find(std::make_pair(v0, v1));
417 if (e != edgeMap.end())
421 std::get<1>(this->grid_->entityImps_[0]).emplace_back(v0, v1, 0, this->grid_->getNextFreeId());
423 auto newEdge = &*std::get<1>(this->grid_->entityImps_[0]).rbegin();
424 edgeMap.insert(std::make_pair(std::make_pair(v0, v1), newEdge));
429 element.facet_[i] = edge;
432 edge->elements_.push_back(&element);
437 this->grid_->setIndices();
444 for (
auto& facet : std::get<1>(this->grid_->entityImps_[0]))
446 if (facet.elements_.size() == 1)
448 std::array<unsigned int, 2> vertexIndices {{ facet.vertex_[0]->leafIndex_, facet.vertex_[1]->leafIndex_ }};
450 if ( vertexIndices[0] > vertexIndices[1] )
451 std::swap( vertexIndices[0], vertexIndices[1] );
453 const auto it = boundarySegmentIndices_.find( vertexIndices );
454 if (it != boundarySegmentIndices_.end())
455 facet.boundarySegmentIndex_ = it->second;
457 facet.boundarySegmentIndex_ = this->boundarySegmentCounter_++;
466 tmp->numBoundarySegments_ = this->boundarySegmentCounter_;
467 this->grid_ =
nullptr;
472 template<
class T,
class U = T>
474 std::size_t operator() (
const std::pair<T, U>& a)
const {
475 std::size_t seed = 0;
476 hash_combine(seed, a.first);
477 hash_combine(seed, a.second);
482 struct HashUIntArray {
483 std::size_t operator() (
const std::array<unsigned int, 2>& a)
const {
484 return hash_range(a.begin(), a.end());
488 std::unordered_map<std::array<unsigned int, 2>,
unsigned int, HashUIntArray> boundarySegmentIndices_;
Specialization of the generic GridFactory for FoamGrid<dimgrid, dimworld>
Definition: foamgridfactory.hh:31
~GridFactoryBase() override
Destructor.
Definition: foamgridfactory.hh:62
void insertVertex(const FieldVector< ctype, dimworld > &pos) override
Insert a vertex into the coarse grid.
Definition: foamgridfactory.hh:68
unsigned int insertionIndex(const typename FoamGrid< dimgrid, dimworld, ctype >::LeafIntersection &intersection) const override
Obtain a boundary's insertion index.
Definition: foamgridfactory.hh:96
GridFactoryBase(FoamGrid< dimgrid, dimworld, ctype > *grid)
Constructor for a given grid object.
Definition: foamgridfactory.hh:54
std::vector< FoamGridEntityImp< 0, dimgrid, dimworld, ctype > * > vertexArray_
Array containing all vertices.
Definition: foamgridfactory.hh:111
unsigned int boundarySegmentCounter_
Counter that creates the boundary segment indices.
Definition: foamgridfactory.hh:114
bool factoryOwnsGrid_
Definition: foamgridfactory.hh:108
FoamGrid< dimgrid, dimworld, ctype > * grid_
Definition: foamgridfactory.hh:104
unsigned int insertionIndex(const typename FoamGrid< dimgrid, dimworld, ctype >::Traits::template Codim< dimgrid >::Entity &vertex) const override
Obtain a vertex' insertion index.
Definition: foamgridfactory.hh:88
GridFactoryBase()
Default constructor.
Definition: foamgridfactory.hh:38
unsigned int insertionIndex(const typename FoamGrid< dimgrid, dimworld, ctype >::Traits::template Codim< 0 >::Entity &entity) const override
Obtain an element's insertion index.
Definition: foamgridfactory.hh:80
ToUniquePtr< FoamGrid< 1, dimworld, ctype > > createGrid() override
Finalize grid creation and hand over the grid.
Definition: foamgridfactory.hh:219
void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices, const std::shared_ptr< VirtualFunction< FieldVector< ctype, dimgrid >, FieldVector< ctype, dimworld > > > &elementParametrization) override
Insert a parametrized element into the coarse grid.
Definition: foamgridfactory.hh:197
void insertBoundarySegment(const std::vector< unsigned int > &vertices, const std::shared_ptr< BoundarySegment< dimgrid, dimworld > > &boundarySegment) override
Insert a boundary segment and the boundary segment geometry This influences the ordering of the bound...
Definition: foamgridfactory.hh:157
bool wasInserted(const typename FoamGrid< dimgrid, dimworld, ctype >::LeafIntersection &intersection) const override
Return true if leaf intersection was inserted as boundary segment.
Definition: foamgridfactory.hh:165
void insertBoundarySegment(const std::vector< unsigned int > &vertices) override
Insert a boundary segment. This is only needed if you want to control the numbering of the boundary s...
Definition: foamgridfactory.hh:149
void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices) override
Insert an element into the coarse grid.
Definition: foamgridfactory.hh:179
GridFactory(FoamGrid< 1, dimworld, ctype > *grid)
Definition: foamgridfactory.hh:142
GridFactory()
Definition: foamgridfactory.hh:140
GridFactory()
Definition: foamgridfactory.hh:284
void insertBoundarySegment(const std::vector< unsigned int > &vertices) override
Insert a boundary segment. This is only needed if you want to control the numbering of the boundary s...
Definition: foamgridfactory.hh:293
void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices, const std::shared_ptr< VirtualFunction< FieldVector< ctype, dimgrid >, FieldVector< ctype, dimworld > > > &elementParametrization) override
Insert a parametrized element into the coarse grid.
Definition: foamgridfactory.hh:363
ToUniquePtr< FoamGrid< dimgrid, dimworld, ctype > > createGrid() override
Finalize grid creation and hand over the grid The receiver takes responsibility of the memory allocat...
Definition: foamgridfactory.hh:384
void insertBoundarySegment(const std::vector< unsigned int > &vertices, const std::shared_ptr< BoundarySegment< dimgrid, dimworld > > &boundarySegment) override
Insert a boundary segment (== a line) and the boundary segment geometry This influences the ordering ...
Definition: foamgridfactory.hh:307
bool wasInserted(const typename FoamGrid< dimgrid, dimworld, ctype >::LeafIntersection &intersection) const override
Return true if leaf intersection was inserted as boundary segment.
Definition: foamgridfactory.hh:315
void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices) override
Insert an element into the coarse grid.
Definition: foamgridfactory.hh:345
GridFactory(FoamGrid< 2, dimworld, ctype > *grid)
Definition: foamgridfactory.hh:286
The actual entity implementation.
Definition: foamgridvertex.hh:47