AMDiS 2.11-git
The Adaptive Multi-Dimensional Simulation Toolbox
 
Loading...
Searching...
No Matches
AdaptiveGrid.hpp
1#pragma once
2
3#include <algorithm>
4#include <list>
5#include <memory>
6#include <mutex>
7#include <shared_mutex>
8#include <type_traits>
9#include <utility>
10
11#include <dune/common/hybridutilities.hh>
12#include <dune/common/timer.hh>
13#include <dune/common/version.hh>
14#include <dune/common/parallel/mpihelper.hh>
15
16#include <dune/geometry/type.hh>
17#include <dune/grid/common/backuprestore.hh>
18#include <dune/grid/common/capabilities.hh>
19#include <dune/grid/common/grid.hh>
20#include <dune/grid/utility/structuredgridfactory.hh>
21
22#include <amdis/common/Concepts.hpp>
23#include <amdis/common/DefaultGridView.hpp>
24#include <amdis/common/SharedPtr.hpp>
25#include <amdis/Observer.hpp>
26#include <amdis/Output.hpp>
27
28namespace AMDiS
29{
30 // forward declaration
31 template <class HostGrid>
32 class AdaptiveGridFamily;
33
34
37
43 template <class HG>
45 : public Dune::GridDefaultImplementation<
46 HG::dimension, HG::dimensionworld, typename HG::ctype, AdaptiveGridFamily<HG> >
47 , public Notifier<event::preAdapt, event::adapt, event::postAdapt>
48 {
49 using Self = AdaptiveGrid<HG>;
50
51 public:
52
53 using HostGrid = HG;
55 using Traits = typename GridFamily::Traits;
56 using Element = typename Traits::template Codim<0>::Entity;
57
58
59 public:
60
61 template <class HostGrid_,
62 Dune::disableCopyMove<Self, HostGrid_> = 0>
63 explicit AdaptiveGrid(HostGrid_&& hostGrid)
64 : hostGrid_(wrap_or_share(FWD(hostGrid)))
65 {}
66
68 std::shared_ptr<HostGrid> const& hostGrid() const { return hostGrid_; }
69
70
71 public:
72
75
77 template <int codim, Dune::PartitionIteratorType pt = Dune::All_Partition>
78 auto lbegin(int level) const { return hostGrid_->levelGridView(level).template begin<codim,pt>(); }
79
81 template <int codim, Dune::PartitionIteratorType pt = Dune::All_Partition>
82 auto lend(int level) const { return hostGrid_->levelGridView(level).template end<codim,pt>(); }
83
84
86 template <int codim, Dune::PartitionIteratorType pt = Dune::All_Partition>
87 auto leafbegin() const { return hostGrid_->leafGridView().template begin<codim,pt>(); }
88
90 template <int codim, Dune::PartitionIteratorType pt = Dune::All_Partition>
91 auto leafend() const { return hostGrid_->leafGridView().template end<codim,pt>(); }
92
93
95 auto ilevelbegin(Element const& e) const { return hostGrid_->levelGridView(e.level()).ibegin(e); }
96
98 auto ilevelend(Element const& e) const { return hostGrid_->levelGridView(e.level()).iend(e); }
99
101 auto ileafbegin(Element const& e) const { return hostGrid_->leafGridView().ibegin(e); }
102
104 auto ileafend(Element const& e) const { return hostGrid_->leafGridView().iend(e); }
105
107
108
111
113 int maxLevel() const { return hostGrid_->maxLevel(); }
114
116 int size(int level, int codim) const { return hostGrid_->size(level, codim); }
117
119 int size(int codim) const { return hostGrid_->size(codim); }
120
122 int size(int level, Dune::GeometryType type) const { return hostGrid_->size(level, type); }
123
125 int size(Dune::GeometryType type) const { return hostGrid_->size(type); }
126
128 std::size_t numBoundarySegments() const { return hostGrid_->numBoundarySegments(); }
129
131
132
135
137 auto const& globalIdSet() const { return hostGrid_->globalIdSet(); }
138
140 auto const& localIdSet() const { return hostGrid_->localIdSet(); }
141
143 auto const& levelIndexSet(int level) const { return hostGrid_->levelIndexSet(level); }
144
146 auto const& leafIndexSet() const { return hostGrid_->leafIndexSet(); }
147
149
150
153
155 void globalRefine(int refCount)
156 {
157 for (int i = 0; i < refCount; ++i) {
158 // mark all entities for grid refinement
159 for (const auto& element : elements(hostGrid_->leafGridView()))
160 hostGrid_->mark(1, element);
161 preAdapt();
162 adapt();
163 postAdapt();
164 }
165 }
166
168 bool mark(int refCount, Element const& e) { return hostGrid_->mark(refCount, e); }
169
171 int getMark(Element const& e) const { return hostGrid_->getMark(e); }
172
174 bool preAdapt()
175 {
176 Dune::Timer t;
177 mightCoarsen_ = hostGrid_->preAdapt();
178 hostGrid_->comm().max(&mightCoarsen_, 1);
179 this->notify(event::preAdapt{mightCoarsen_});
180 info(2,"AdaptiveGrid::preAdapt needed {} seconds", t.elapsed());
181 return mightCoarsen_;
182 }
183
185 bool adapt()
186 {
187 Dune::Timer t;
188 refined_ = hostGrid_->adapt();
189 hostGrid_->comm().max(&refined_, 1);
190 this->notify(event::adapt{mightCoarsen_ || refined_});
191 info(2,"AdaptiveGrid::adapt needed {} seconds", t.elapsed());
192 return refined_;
193 }
194
197 {
198 Dune::Timer t;
199 hostGrid_->postAdapt();
200 this->notify(event::postAdapt{});
201 changeIndex_++;
202 info(2,"AdaptiveGrid::postAdapt needed {} seconds", t.elapsed());
203 }
204
206 void update()
207 {
208 this->notify(event::adapt{true});
209 }
210
212 unsigned long changeIndex() const
213 {
214 return changeIndex_;
215 }
216
217 // @}
218
219
222
224 auto const& comm() const { return hostGrid_->comm(); }
225
227 template <class DataHandle>
228 void communicate(DataHandle& handle, Dune::InterfaceType iftype,
229 Dune::CommunicationDirection dir, int level) const
230 {
231 hostGrid_->levelGridView(level).communicate(handle,iftype,dir);
232 }
233
235 template <class DataHandle>
236 void communicate(DataHandle& handle, Dune::InterfaceType iftype,
237 Dune::CommunicationDirection dir) const
238 {
239 hostGrid_->leafGridView().communicate(handle,iftype,dir);
240 }
241
243
249 {
250 if constexpr (std::is_convertible_v<decltype(std::declval<HG>().loadBalance()), bool>)
251 return hostGrid_->loadBalance();
252 else {
253 hostGrid_->loadBalance();
254 return true;
255 }
256 }
257
259
266 template <class DataHandle>
267 bool loadBalance(DataHandle& handle)
268 {
269 if constexpr (std::is_convertible_v<decltype(std::declval<HG>().loadBalance(handle)), bool>)
270 return hostGrid_->loadBalance(handle);
271 else {
272 hostGrid_->loadBalance(handle);
273 return true;
274 }
275 }
276
277
279 int overlapSize(int level, int codim) const { return hostGrid_->levelGridView(level).overlapSize(codim); }
280
282 int overlapSize(int codim) const { return hostGrid_->leafGridView().overlapSize(codim); }
283
285 int ghostSize(int level, int codim) const { return hostGrid_->levelGridView(level).ghostSize(codim); }
286
288 int ghostSize(int codim) const { return hostGrid_->leafGridView().ghostSize(codim); }
289
291
293 bool isLevelwiseConforming(int level) const
294 {
295 return hostGrid_->levelGridView(level).isConforming();
296 }
297
300 {
301 return hostGrid_->leafGridView().isConforming();
302 }
303
304
306 template <class EntitySeed>
307 auto entity(EntitySeed const& seed) const { return hostGrid_->entity(seed); }
308
309
310 private:
311
313 std::shared_ptr<HostGrid> hostGrid_;
314
317 bool mightCoarsen_ = false;
318
320 bool refined_ = false;
321
324 unsigned long changeIndex_ = 0;
325 };
326
327 // deduction guide
328 template <class HostGrid>
329 AdaptiveGrid(HostGrid const&)
330 -> AdaptiveGrid<HostGrid>;
331
332
333 template <class HostGrid>
335 {
336 public:
337 struct Traits : HostGrid::Traits
338 {
340 using Communication = typename HostGrid::Traits::Communication;
341 using LeafGridView = Dune::GridView< AMDiS::DefaultLeafGridViewTraits<const Grid> >;
342 using LevelGridView = Dune::GridView< AMDiS::DefaultLevelGridViewTraits<const Grid> >;
343 };
344 };
345
346
348 template <class HostGrid>
349 unsigned long changeIndex(HostGrid const& /*hostGrid*/)
350 {
351 return 0;
352 }
353
355 template <class HostGrid>
356 unsigned long changeIndex(AdaptiveGrid<HostGrid> const& grid)
357 {
358 return grid.changeIndex();
359 }
360
361
362 namespace Impl
363 {
364 template <class HostGrid>
365 struct AdaptiveGridImpl
366 {
367 using type = AdaptiveGrid<HostGrid>;
368 };
369
370 template <class HostGrid>
371 struct AdaptiveGridImpl<AdaptiveGrid<HostGrid>>
372 {
373 using type = AdaptiveGrid<HostGrid>;
374 };
375 }
376
379 template <class HostGrid>
380 using AdaptiveGrid_t = typename Impl::AdaptiveGridImpl<HostGrid>::type;
381
382
383} // end namespace AMDiS
384
385
386namespace Dune
387{
390 template <class HostGrid>
391 class GridFactory<AMDiS::AdaptiveGrid<HostGrid> >
392 : public GridFactoryInterface<AMDiS::AdaptiveGrid<HostGrid> >
393 {
394 using Self = GridFactory;
396 using GridType = AMDiS::AdaptiveGrid<HostGrid>;
397 using HostGridFactory = GridFactory<HostGrid>;
398
399 public:
400
401 using ctype = typename GridType::ctype;
402
403 enum { dim = GridType::dimension };
404 enum { dimworld = GridType::dimensionworld };
405
406 template <class... Args,
407 Dune::disableCopyMove<Self, Args...> = 0>
408 GridFactory(Args&&... args)
409 : hostFactory_(FWD(args)...)
410 {}
411
413 void insertVertex(FieldVector<ctype,dimworld> const& pos) override
414 {
415 hostFactory_.insertVertex(pos);
416 }
417
418 template <class F, class... Args>
419 using HasInsertElement = decltype(std::declval<F>().insertElement(std::declval<Args>()...));
420
422 void insertElement(GeometryType const& type,
423 std::vector<unsigned int> const& vertices) override
424 {
425 hostFactory_.insertElement(type, vertices);
426 }
427
428 using ElementParametrizationType
429 = std::function<FieldVector<ctype,dimworld>(FieldVector<ctype,dim>)>;
430
432 void insertElement(GeometryType const& type,
433 std::vector<unsigned int> const& vertices,
434 ElementParametrizationType elementParametrization) override
435 {
436 using A0 = GeometryType;
437 using A1 = std::vector<unsigned int>;
438 using A2 = ElementParametrizationType;
439 if constexpr (Std::is_detected<HasInsertElement, HostGridFactory, A0,A1,A2>::value)
440 hostFactory_.insertElement(type, vertices, elementParametrization);
441 else
442 AMDiS::error_exit("insertElement() not implemented for HostGrid type.");
443 }
444 using Super::insertElement;
445
446 template <class F, class... Args>
447 using HasInsertBoundarySegment = decltype(std::declval<F>().insertBoundarySegment(std::declval<Args>()...));
448
450 void insertBoundarySegment(std::vector<unsigned int> const& vertices) override
451 {
452 hostFactory_.insertBoundarySegment(vertices);
453 }
454
455 using BoundarySegmentType = std::shared_ptr<BoundarySegment<dim,dimworld> >;
456
458 void insertBoundarySegment(std::vector<unsigned int> const& vertices,
459 BoundarySegmentType const& boundarySegment) override
460 {
461 using A0 = std::vector<unsigned int>;
462 using A1 = BoundarySegmentType;
463 if constexpr (Std::is_detected<HasInsertBoundarySegment, HostGridFactory, A0,A1>::value)
464 hostFactory_.insertBoundarySegment(vertices, boundarySegment);
465 else
466 AMDiS::error_exit("insertBoundarySegment() not implemented for HostGrid type.");
467 }
468
470 std::unique_ptr<GridType> createGrid() override
471 {
472 std::unique_ptr<HostGrid> hostGrid(hostFactory_.createGrid());
473 return std::make_unique<GridType>(std::move(hostGrid));
474 }
475
476 private:
477 HostGridFactory hostFactory_;
478 };
479
480
481 namespace Impl
482 {
483 template <class HostGrid, bool = Dune::Capabilities::hasBackupRestoreFacilities<HostGrid>::v>
484 class BackupRestoreFacilityImpl {};
485
486 template <class HostGrid>
487 class BackupRestoreFacilityImpl<HostGrid,true>
488 {
490 using HostBackupRestoreFacility = BackupRestoreFacility<HostGrid>;
491
492 public:
493
495 template <class Output>
496 static void backup(Grid const& grid, Output const& filename_or_stream)
497 {
498 HostBackupRestoreFacility::backup(*grid.hostGrid(), filename_or_stream);
499 }
500
502 template <class Input>
503 static Grid* restore(Input const& filename_or_stream)
504 {
505 std::unique_ptr<HostGrid> hostGrid(HostBackupRestoreFacility::restore(filename_or_stream));
506 return new Grid(std::move(hostGrid));
507 }
508 };
509
510 } // end namespace Impl
511
512
515 template <class HostGrid>
516 class BackupRestoreFacility<AMDiS::AdaptiveGrid<HostGrid>>
517 : public Impl::BackupRestoreFacilityImpl<HostGrid>
518 {
519 public:
520 using Impl::BackupRestoreFacilityImpl<HostGrid>::BackupRestoreFacilityImpl;
521 };
522
523
524 namespace Capabilities
525 {
526 template <class HostGrid, int codim>
527 struct hasEntity<AMDiS::AdaptiveGrid<HostGrid>, codim>
528 : hasEntity<HostGrid,codim>{};
529
530 template <class HostGrid, int codim>
531 struct hasEntityIterator<AMDiS::AdaptiveGrid<HostGrid>, codim>
532 : hasEntityIterator<HostGrid, codim> {};
533
534 template <class HostGrid>
535 struct isLevelwiseConforming<AMDiS::AdaptiveGrid<HostGrid> >
536 : isLevelwiseConforming<HostGrid> {};
537
538 template <class HostGrid>
539 struct isLeafwiseConforming<AMDiS::AdaptiveGrid<HostGrid> >
540 : isLeafwiseConforming<HostGrid> {};
541
542 template <class HostGrid>
543 struct hasSingleGeometryType<AMDiS::AdaptiveGrid<HostGrid> >
544 : hasSingleGeometryType<HostGrid> {};
545
546 template <class HostGrid, int codim >
547 struct canCommunicate<AMDiS::AdaptiveGrid<HostGrid>, codim>
548 : canCommunicate<HostGrid, codim> {};
549
550 template <class HostGrid>
551 struct hasBackupRestoreFacilities<AMDiS::AdaptiveGrid<HostGrid> >
552 : hasBackupRestoreFacilities<HostGrid> {};
553
554 template <class HostGrid>
555 struct threadSafe<AMDiS::AdaptiveGrid<HostGrid> >
556 : threadSafe<HostGrid> {};
557
558 template <class HostGrid>
559 struct viewThreadSafe<AMDiS::AdaptiveGrid<HostGrid> >
560 : viewThreadSafe<HostGrid> {};
561
562 } // end namespace Capabilities
563} // end namespace Dune
Definition AdaptiveGrid.hpp:335
Wrapper class for Dune-grids that allows automatic signalling of events during grid adaptation.
Definition AdaptiveGrid.hpp:48
auto const & comm() const
Return const reference to a collective communication object.
Definition AdaptiveGrid.hpp:224
void globalRefine(int refCount)
Refines all grid elements refCount times.
Definition AdaptiveGrid.hpp:155
auto const & localIdSet() const
Return const reference to the host grids local id set.
Definition AdaptiveGrid.hpp:140
auto ileafbegin(Element const &e) const
Obtain begin intersection iterator with respect to the leaf GridView.
Definition AdaptiveGrid.hpp:101
void postAdapt()
Perform cleanup after grid adaptation and notify observers of the postAdapt event.
Definition AdaptiveGrid.hpp:196
int ghostSize(int level, int codim) const
Return size of the ghost region for a given codim on the level grid view.
Definition AdaptiveGrid.hpp:285
std::size_t numBoundarySegments() const
Returns the number of boundary segments within the macro grid.
Definition AdaptiveGrid.hpp:128
auto leafend() const
One past the end of the sequence of leaf entities.
Definition AdaptiveGrid.hpp:91
unsigned long changeIndex() const
Returns the grid change index, see changeIndex.
Definition AdaptiveGrid.hpp:212
auto const & globalIdSet() const
Return const reference to the grids global id set.
Definition AdaptiveGrid.hpp:137
auto lbegin(int level) const
Iterator to first entity of given codim on level.
Definition AdaptiveGrid.hpp:78
void communicate(DataHandle &handle, Dune::InterfaceType iftype, Dune::CommunicationDirection dir) const
Communicate data of leaf gridView.
Definition AdaptiveGrid.hpp:236
void communicate(DataHandle &handle, Dune::InterfaceType iftype, Dune::CommunicationDirection dir, int level) const
Communicate data of level gridView.
Definition AdaptiveGrid.hpp:228
auto ilevelbegin(Element const &e) const
Obtain begin intersection iterator with respect to the level GridView.
Definition AdaptiveGrid.hpp:95
bool mark(int refCount, Element const &e)
Marks an entity to be refined/coarsened in a subsequent adapt.
Definition AdaptiveGrid.hpp:168
int ghostSize(int codim) const
Return size of the ghost region for a given codim on the leaf grid view.
Definition AdaptiveGrid.hpp:288
int overlapSize(int codim) const
Return size of the overlap region for a given codim on the leaf grid view.
Definition AdaptiveGrid.hpp:282
int size(int level, Dune::GeometryType type) const
Return number of entities per level and geometry type in this process.
Definition AdaptiveGrid.hpp:122
int size(int level, int codim) const
Number of grid entities per level and codim.
Definition AdaptiveGrid.hpp:116
auto entity(EntitySeed const &seed) const
Obtain Entity from EntitySeed of the HostGrid.
Definition AdaptiveGrid.hpp:307
auto const & levelIndexSet(int level) const
Return const reference to the host grids level index set for level level.
Definition AdaptiveGrid.hpp:143
bool preAdapt()
Prepare the grid for adaptation and notify observers of the preAdapt event.
Definition AdaptiveGrid.hpp:174
auto leafbegin() const
Iterator to first leaf entity of given codim.
Definition AdaptiveGrid.hpp:87
bool isLeafwiseConforming() const
Return true if the leaf-grid view represents a conforming grid.
Definition AdaptiveGrid.hpp:299
int maxLevel() const
Return maximum level defined in this grid.
Definition AdaptiveGrid.hpp:113
bool loadBalance()
Calls loadBalance on the underlying grid.
Definition AdaptiveGrid.hpp:248
int overlapSize(int level, int codim) const
Return size of the overlap region for a given codim on the level grid view.
Definition AdaptiveGrid.hpp:279
auto ileafend(Element const &e) const
Obtain end intersection iterator with respect to the leaf GridView.
Definition AdaptiveGrid.hpp:104
void update()
Update all registered dependent objects if grid is changed manually.
Definition AdaptiveGrid.hpp:206
auto const & leafIndexSet() const
Return const reference to the host grids leaf index set.
Definition AdaptiveGrid.hpp:146
std::shared_ptr< HostGrid > const & hostGrid() const
Return the underlying grid.
Definition AdaptiveGrid.hpp:68
bool adapt()
Adapt the grid and notify observers of the adapt event.
Definition AdaptiveGrid.hpp:185
bool loadBalance(DataHandle &handle)
Calls loadBalance(handle) on the underlying grid.
Definition AdaptiveGrid.hpp:267
bool isLevelwiseConforming(int level) const
Return true if the level-rid view represents a conforming grid.
Definition AdaptiveGrid.hpp:293
int size(Dune::GeometryType type) const
Return number of leaf entities per geometry type in this process.
Definition AdaptiveGrid.hpp:125
int size(int codim) const
Return number of leaf entities of a given codim in this process.
Definition AdaptiveGrid.hpp:119
auto ilevelend(Element const &e) const
Obtain end intersection iterator with respect to the level GridView.
Definition AdaptiveGrid.hpp:98
auto lend(int level) const
one past the end on this level
Definition AdaptiveGrid.hpp:82
int getMark(Element const &e) const
Return refinement mark for entity.
Definition AdaptiveGrid.hpp:171
Mixin for signaling of certain events.
Definition Observer.hpp:57
Definition AdaptiveGrid.hpp:338
Definition Observer.hpp:25
Definition Observer.hpp:30
Definition Observer.hpp:19