diff --git a/amdis/MeshCreator.hpp b/amdis/MeshCreator.hpp index 080b2838551ef5f6993cdb3404b82851feb7153b..64756f126b0479fd2ffc6897cebb6bded78881a8 100644 --- a/amdis/MeshCreator.hpp +++ b/amdis/MeshCreator.hpp @@ -66,6 +66,12 @@ namespace AMDiS : name_(name) {} + /// Static create mthod. See \ref create() + static std::shared_ptr create(std::string name) + { + return MeshCreator{name}.create(); + } + /// Create a new grid by inspecting the intifile parameter group `[meshName]` /** * Reads first the parameter `[meshName]->macro file name` and if set @@ -78,7 +84,7 @@ namespace AMDiS * * Otherwise tries to create a grid depending on the grid type. **/ - std::shared_ptr create() const + std::unique_ptr create() const { auto filename = Parameters::get(name_ + "->macro file name"); auto structured = Parameters::get(name_ + "->structured"); @@ -142,15 +148,15 @@ namespace AMDiS } private: - static std::shared_ptr construct(std::unique_ptr hostGrid) + static std::unique_ptr construct(std::unique_ptr hostGrid) { return std::move(hostGrid); } template - static std::shared_ptr construct(std::unique_ptr hostGrid) + static std::unique_ptr construct(std::unique_ptr hostGrid) { - return std::make_shared(std::move(hostGrid)); + return std::make_unique(std::move(hostGrid)); } // use the structured grid factory to create the grid @@ -204,13 +210,55 @@ namespace AMDiS std::declval>(), std::declval >>()) ); + template + using SupportsInsertionIndex = decltype(std::declval>().insertionIndex(std::declval())); + // use GmshReader if GridFactory supports insertBoundarySegments template ::value)> std::unique_ptr read_gmsh_file(std::string const& filename, Dune::PriorityTag<1>) const { Dune::GmshReader reader; - return std::unique_ptr{reader.read(filename)}; // , boundaryIds_, elementIds_)}; + Dune::GridFactory factory; + std::vector boundaryIds, elementIds; + reader.read(factory, filename, boundaryIds, elementIds); + + using HasInsertionIndexEntity + = Dune::Std::is_detected::Entity>; + using HasInsertionIndexIntersection + = Dune::Std::is_detected; + + auto gridPtr = factory.createGrid(); + if ((boundaryIds.empty() && elementIds.empty()) || + (!HasInsertionIndexEntity::value && !HasInsertionIndexIntersection::value)) + return std::unique_ptr(std::move(gridPtr)); + + // map boundaryIds and elementIds read from file to grid indexing. + if (!boundaryIds.empty() && HasInsertionIndexIntersection::value) + boundaryIds_.resize(gridPtr->numBoundarySegments()); + if (!elementIds.empty() && HasInsertionIndexEntity::value) + elementIds_.resize(gridPtr->size(0)); + + auto const& indexSet = gridPtr->leafIndexSet(); + for (auto const& e : elements(gridPtr->leafGridView())) { + if constexpr(HasInsertionIndexEntity::value) { + if (!elementIds.empty()) + elementIds_[indexSet.index(e)] = elementIds[factory.insertionIndex(e)]; + } + + if (boundaryIds.empty() || !e.hasBoundaryIntersections()) + continue; + + for (auto const& it : intersections(gridPtr->leafGridView(), e)) { + if constexpr(HasInsertionIndexIntersection::value) { + if (it.boundary()) + boundaryIds_[it.boundarySegmentIndex()] + = boundaryIds[factory.insertionIndex(it)]; + } + } + } + + return std::unique_ptr(std::move(gridPtr)); } // fallback if GmshReader cannot be used