53 enum { dimension = G::dimension };
54 enum { dimworld = G::dimensionworld };
56 using Grid = AdaptiveGrid_t<G>;
57 using HostGrid =
typename Grid::HostGrid;
59 using ctype =
typename Grid::ctype;
70 static std::shared_ptr<Grid>
create(std::string name)
89 auto filename = Parameters::get<std::string>(name_ +
"->macro file name");
90 auto structured = Parameters::get<std::string>(name_ +
"->structured");
91 std::unique_ptr<HostGrid> gridPtr;
94 gridPtr = create_unstructured_grid(filename.value());
95 }
else if (structured) {
97 if (structured.value() ==
"cube") {
99 }
else if (structured.value() ==
"simplex") {
102 error_exit(
"Unknown structured grid type. Must be either `cube` or `simplex` in parameter [meshName]->structured.");
106 gridPtr = create_by_gridtype<HostGrid>(Dune::PriorityTag<42>{});
110 auto globalRefinements = Parameters::get<int>(name_ +
"->global refinements");
111 if (globalRefinements)
112 gridPtr->globalRefine(globalRefinements.value());
113 auto loadBalance = Parameters::get<bool>(name_ +
"->load balance");
114 if (loadBalance && loadBalance.value())
115 gridPtr->loadBalance();
117 return construct(std::move(gridPtr));
123 return create_structured_grid([](
auto&& lower,
auto&& upper,
auto&& numCells)
125 return Dune::StructuredGridFactory<HostGrid>::createCubeGrid(lower, upper, numCells);
132 return create_structured_grid([](
auto&& lower,
auto&& upper,
auto&& numCells)
134 return Dune::StructuredGridFactory<HostGrid>::createSimplexGrid(lower, upper, numCells);
151 static std::unique_ptr<Grid> construct(std::unique_ptr<Grid> hostGrid)
153 return std::move(hostGrid);
157 static std::unique_ptr<Grid> construct(std::unique_ptr<HG> hostGrid)
159 return std::make_unique<Grid>(std::move(hostGrid));
163 template <
class Size =
unsigned int,
class Factory>
164 std::unique_ptr<HostGrid> create_structured_grid(Factory factory)
const
166 if constexpr (
int(Grid::dimension) ==
int(Grid::dimensionworld)) {
168 Dune::FieldVector<ctype,
int(dimworld)> lower(0);
170 Dune::FieldVector<ctype,
int(dimworld)> upper(1);
172 auto numCells = Dune::filledArray<std::size_t(dimension),Size>(1);
177 return factory(lower, upper, numCells);
179 error_exit(
"Structured grids can be created for dim == dow only.");
185 std::unique_ptr<HostGrid> create_unstructured_grid(std::string
const& filename)
const
187 filesystem::path fn(filename);
188 auto ext = fn.extension();
192 if (Dune::Gmsh4::fileVersion(filename)[0] >= 4)
193 return Dune::Gmsh4Reader<HostGrid, Dune::Gmsh4::LagrangeGridCreator<HostGrid>>::createGridFromFile(filename);
196 return read_gmsh_file<HostGrid>(filename, Dune::PriorityTag<42>{});
199 else if (ext ==
".vtu") {
200 return Dune::Vtk::VtkReader<HostGrid, Dune::Vtk::LagrangeGridCreator<HostGrid>>::createGridFromFile(filename);
203 else if (ext ==
".1d" || ext ==
".2d" || ext ==
".3d" || ext ==
".amc") {
204 return read_alberta_file<HostGrid>(filename, Dune::PriorityTag<42>{});
207 error_exit(
"Cannot read grid file. Unknown file extension.");
212 template <
class Gr
idType>
213 using SupportsGmshReader =
decltype(std::declval<Dune::GridFactory<GridType>>().insertBoundarySegment(
214 std::declval<std::vector<unsigned int>>(),
215 std::declval<std::shared_ptr<Dune::BoundarySegment<GridType::dimension, GridType::dimensionworld> >>()) );
217 template <
class Gr
idType,
class LC>
218 using SupportsInsertionIndex =
decltype(std::declval<Dune::GridFactory<GridType>>().insertionIndex(std::declval<LC>()));
221 template <
class GridType = HostGrid,
222 REQUIRES(Dune::Std::is_detected<SupportsGmshReader, GridType>::value)>
223 std::unique_ptr<GridType> read_gmsh_file(std::string
const& filename, Dune::PriorityTag<1>)
const
225 Dune::GridFactory<GridType> factory;
229 using HasInsertionIndexEntity
230 = Dune::Std::is_detected<SupportsInsertionIndex, GridType, typename GridType::template Codim<0>::Entity>;
231 using HasInsertionIndexIntersection
232 = Dune::Std::is_detected<SupportsInsertionIndex, GridType, typename GridType::LeafIntersection>;
234 auto gridPtr = factory.createGrid();
236 (!HasInsertionIndexEntity::value && !HasInsertionIndexIntersection::value))
237 return std::unique_ptr<GridType>(std::move(gridPtr));
240 if (!
boundaryIds.empty() && HasInsertionIndexIntersection::value)
241 boundaryIds_.resize(gridPtr->numBoundarySegments());
242 if (!
elementIds.empty() && HasInsertionIndexEntity::value)
243 elementIds_.resize(gridPtr->size(0));
245 auto const& indexSet = gridPtr->leafIndexSet();
246 for (
auto const& e : elements(gridPtr->leafGridView())) {
247 if constexpr(HasInsertionIndexEntity::value) {
249 elementIds_[indexSet.index(e)] =
elementIds[factory.insertionIndex(e)];
252 if (
boundaryIds.empty() || !e.hasBoundaryIntersections())
255 for (
auto const& it : intersections(gridPtr->leafGridView(), e)) {
256 if constexpr(HasInsertionIndexIntersection::value) {
258 boundaryIds_[it.boundarySegmentIndex()]
264 return std::unique_ptr<GridType>(std::move(gridPtr));
268 template <
class Gr
idType = HostGr
id>
269 std::unique_ptr<GridType> read_gmsh_file(std::string
const&, Dune::PriorityTag<0>)
const
271 error_exit(
"Gmsh reader not supported for this grid type!");
278 template <
class Gr
idType>
279 using IsAlbertaGrid =
decltype(std::declval<GridType>().alberta2dune(0,0));
282 template <
class GridType = HostGrid,
283 REQUIRES(GridType::dimensionworld == DIM_OF_WORLD),
284 REQUIRES(Dune::Std::is_detected<IsAlbertaGrid, GridType>::value)>
285 std::unique_ptr<GridType> read_alberta_file(std::string
const& filename, Dune::PriorityTag<3>)
const
287 return std::make_unique<GridType>(filename);
291 template <
class GridType = HostGrid,
292 REQUIRES(GridType::dimensionworld == DIM_OF_WORLD)>
293 std::unique_ptr<GridType> read_alberta_file(std::string
const& filename, Dune::PriorityTag<2>)
const
295 Dune::GridFactory<GridType> factory;
297 Dune::AlbertaReader<GridType> reader;
298 reader.readGrid(filename, factory);
300 return std::unique_ptr<GridType>{factory.createGrid()};
304 template <
class GridType = HostGrid,
305 REQUIRES(GridType::dimensionworld != DIM_OF_WORLD)>
306 std::unique_ptr<GridType> read_alberta_file(std::string
const& filename, Dune::PriorityTag<1>)
const
308 error_exit(
"AlbertaGrid (and AlbertaReader) require WORLDDIM == Grid::dimensionworld. Change the cmake parameters!");
313 template <
class Gr
idType>
314 std::unique_ptr<GridType> read_alberta_file(std::string
const&, Dune::PriorityTag<0>)
const
316 error_exit(
"AlbertaGrid (and AlbertaReader) not available. Set AlbertaFlags to your executable in cmake!");
322 template <
class GridType = HostGrid,
323 class =
typename GridType::YGrid>
324 std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<2>)
const
328 std::string periodic(dimension,
'0');
331 return create_yaspgrid(Types<GridType>{}, overlap, std::bitset<dimension>(periodic));
334 template <
int dim,
class ct>
335 std::unique_ptr<HostGrid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::EquidistantCoordinates<ct,dim>>>,
336 int overlap, std::bitset<dimension>
const& per)
const
338 return create_structured_grid<int>([&](
auto&& ,
auto&& upper, std::array<int,dimension>
const& numCells)
340 return std::make_unique<HostGrid>(upper, numCells, per, overlap);
344 template <
int dim,
class ct>
345 std::unique_ptr<HostGrid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::EquidistantOffsetCoordinates<ct,dim>>>,
346 int overlap, std::bitset<dimension>
const& per)
const
348 return create_structured_grid<int>([&](
auto&& lower,
auto&& upper, std::array<int,dimension>
const& numCells)
350 return std::make_unique<HostGrid>(lower, upper, numCells, per, overlap);
354 template <
int dim,
class ct>
355 std::unique_ptr<HostGrid> create_yaspgrid(Types<Dune::YaspGrid<dim,Dune::TensorProductCoordinates<ct,dim>>>,
356 int, std::bitset<dimension>
const&)
const
358 error_exit(
"MeshCreator cannot create YaspGrid with TensorProductCoordinates.");
365 template <
class GridType = HostGrid,
366 class =
typename GridType::ReferenceCube,
367 class =
typename GridType::MultiIndex>
368 std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<1>)
const
370 return create_structured_grid<int>([](
auto&& lower,
auto&& upper, std::array<int,dimension>
const& numCells)
372 typename GridType::MultiIndex multiIndex(numCells);
373 return std::make_unique<GridType>(lower, upper, multiIndex);
379 template <
class Gr
idType = HostGr
id>
380 std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<0>)
const
382 error_exit(
"Don't know how to create the grid.");
388 mutable std::vector<int> boundaryIds_;
389 mutable std::vector<int> elementIds_;