Loading [MathJax]/extensions/tex2jax.js

dune-mmesh (unstable)

mmesh.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_MMESH_GRID_MMESH_HH
4#define DUNE_MMESH_GRID_MMESH_HH
5
10#include <memory>
11#include <string>
12#include <unordered_map>
13#include <unordered_set>
14
15// dune-common includes
16#include <dune/common/deprecated.hh>
17#include <dune/common/parallel/communication.hh>
18#include <dune/common/parallel/mpihelper.hh>
19#include <dune/common/version.hh>
20#include <dune/grid/common/adaptcallback.hh>
21#include <dune/grid/common/capabilities.hh>
22#include <dune/grid/common/grid.hh>
23#include <dune/grid/io/file/vtk/vtkwriter.hh>
24
25// The components of the MMesh interface
26#include "../interface/traits.hh"
27#include "../misc/boundaryidprovider.hh"
28#include "../misc/twistutility.hh"
29#include "../remeshing/distance.hh"
30#include "../remeshing/longestedgerefinement.hh"
31#include "../remeshing/ratioindicator.hh"
32#include "common.hh"
33#include "connectedcomponent.hh"
35#include "entity.hh"
36#include "entityseed.hh"
37#include "geometry.hh"
38#include "hierarchiciterator.hh"
39#include "incidentiterator.hh"
40#include "indexsets.hh"
41#include "interfaceiterator.hh"
43#include "leafiterator.hh"
44#include "pointfieldvector.hh"
45#include "rangegenerators.hh"
46// Further includes below!
47
48#if HAVE_MPI
49#include <dune/common/parallel/mpicommunication.hh>
50
51#include "../misc/communication.hh"
52#include "../misc/partitionhelper.hh"
53using Comm = MPI_Comm;
54#else
55using Comm = Dune::No_Comm;
56#endif
57
58namespace Dune {
59
60// MMesh family
61template <int dim, class HostGrid>
62struct MMeshFamily {
63 public:
64 using Traits = GridTraits<
65 dim, dim, MMesh<HostGrid, dim>, MMeshGeometry, MMeshEntity,
66 MMeshLeafIterator, // LevelIterator
67 MMeshLeafIntersection,
68 MMeshLeafIntersection, // LevelIntersection
69 MMeshLeafIntersectionIterator,
70 MMeshLeafIntersectionIterator, // LevelIntersectionIterator
71 MMeshHierarchicIterator, MMeshLeafIterator,
72 MMeshLeafIndexSet<const MMesh<HostGrid, dim>>, // LevelIndexSet
73 MMeshLeafIndexSet<const MMesh<HostGrid, dim>>,
74 MMeshGlobalIdSet<const MMesh<HostGrid, dim>>, MMeshImpl::MultiId,
75 MMeshGlobalIdSet<const MMesh<HostGrid, dim>>, // LocalIdSet
76 MMeshImpl::MultiId, Communication<Comm>, DefaultLevelGridViewTraits,
77 DefaultLeafGridViewTraits, MMeshEntitySeed>;
78};
79
81
85template <class HostGrid, int dim, int codim>
86class HostGridEntityChooser_ {
87 struct type {};
88};
89
90template <class HG>
91class HostGridEntityChooser_<HG, 2, 0> {
92 public:
93 using type = typename HG::Face_handle;
94};
95template <class HG>
96class HostGridEntityChooser_<HG, 2, 1> {
97 public:
98 using type = std::pair<typename HG::Face_handle, int>;
99};
100template <class HG>
101class HostGridEntityChooser_<HG, 2, 2> {
102 public:
103 using type = typename HG::Vertex_handle;
104};
105
106template <class HG>
107class HostGridEntityChooser_<HG, 3, 0> {
108 public:
109 using type = typename HG::Cell_handle;
110};
111template <class HG>
112class HostGridEntityChooser_<HG, 3, 1> {
113 public:
114 using type = std::pair<typename HG::Cell_handle, int>;
115};
116template <class HG>
117class HostGridEntityChooser_<HG, 3, 2> {
118 public:
119 using type = CGAL::Triple<typename HG::Cell_handle, int, int>;
120};
121template <class HG>
122class HostGridEntityChooser_<HG, 3, 3> {
123 public:
124 using type = typename HG::Vertex_handle;
125};
126
128template <class Point, class Edge, class IdType, class VertexHandle,
129 class InterfaceGridConnectedComponent>
130struct RefinementInsertionPointStruct {
131 Point point;
132 std::size_t insertionLevel = 0;
133 Edge edge;
134 IdType edgeId;
135 VertexHandle v0, v1;
136 bool isInterface = false;
137 InterfaceGridConnectedComponent connectedcomponent;
138};
140
141//**********************************************************************
142//
143// --MMesh class
144//
145//************************************************************************
150template <class HostGrid, int dim>
151class MMesh
152#ifndef DOXYGEN_SHOULD_SKIP_THIS
153 : public GridDefaultImplementation<dim, dim,
154 double,
156 MMeshFamily<dim, HostGrid>>
157#endif /* DOXYGEN_SHOULD_SKIP_THIS */
158{
159 public:
161 static constexpr int dimension = dim;
162
164 using HostGridType = HostGrid;
165
167 using GridFamily = MMeshFamily<dim, HostGrid>;
168
170 using Point = typename HostGrid::Point;
171
173 using FieldType = typename Point::R::RT;
174
176 using IdType = MMeshImpl::MultiId;
177
179 using BoundarySegments = std::unordered_map<IdType, std::size_t>;
180
182 using BoundaryIds = std::unordered_map<std::size_t, std::size_t>;
183
185 using InterfaceSegments = std::unordered_map<IdType, std::size_t>;
186
187 //**********************************************************
188 // The Interface Methods
189 //**********************************************************
190
192 using Traits = typename GridFamily::Traits;
193
195 using GridImp = typename GridFamily::Traits::Grid;
196
198 using GridPtrType = std::unique_ptr<GridImp>;
199
201 using LeafIterator = typename Traits::template Codim<0>::LeafIterator;
202
204 using GlobalCoordinate = Dune::FieldVector<FieldType, dimension>;
205
207 template <int cd>
209 typename HostGridEntityChooser_<HostGridType, dimension, cd>::type;
210
213
216
219
222
224 using ElementOutput = std::list<HostGridEntity<0>>;
225
227 using BoundaryEdgesOutput = std::list<FacetHandle>;
228
230 using Entity = typename Traits::template Codim<0>::Entity;
231
233 using Facet = typename Traits::template Codim<1>::Entity;
234
236 using Edge = typename Traits::template Codim<dimension - 1>::Entity;
237
239 using Vertex = typename Traits::template Codim<dimension>::Entity;
240
242 using CachingEntity = MMeshCachingEntity<0, dimension, const GridImp>;
243
246
248 using InterfaceElement = typename Traits::template Codim<1>::Entity;
249
251 using Intersection = typename Traits::LeafIntersection;
252
255
258 typename InterfaceGrid::Traits::template Codim<0>::Entity;
259
263
266 RefinementInsertionPointStruct<Point, Edge, IdType, VertexHandle,
268
271
274
277
279 explicit MMesh(HostGrid hostgrid) : MMesh(hostgrid, {}, {}, {}, {}) {}
280
282 explicit MMesh(HostGrid hostgrid, BoundarySegments boundarySegments,
283 BoundarySegments interfaceBoundarySegments,
285 : hostgrid_(hostgrid),
286 boundarySegments_(boundarySegments),
287 boundaryIds_(boundaryIds),
288 interfaceSegments_(interfaceSegments),
289#ifdef HAVE_MPI
290 comm_(MPIHelper::getCommunicator()),
291#endif
292 partitionHelper_(*this) {
293 leafIndexSet_ = std::make_unique<MMeshLeafIndexSet<const GridImp>>(This());
294 globalIdSet_ = std::make_unique<MMeshGlobalIdSet<const GridImp>>(This());
295 globalIdSet_->update(This());
296
297 interfaceGrid_ =
298 std::make_shared<InterfaceGrid>(This(), interfaceBoundarySegments);
299 loadBalance();
300 indicator_.init(*this);
301 }
302
304 const GridImp* This() const { return static_cast<const GridImp*>(this); }
305 GridImp* This() { return static_cast<GridImp*>(this); }
306
307 public:
309 void update() {
310 setIds();
311 setIndices();
312 interfaceGrid_->setIds();
313 interfaceGrid_->setIndices();
314 }
315
316 private:
318 void setIds() { globalIdSet_->update(This()); }
319
321 void setIndices() {
322 leafIndexSet_->update(This());
323
324 if (comm().size() == 1)
325 localBoundarySegments_ = boundarySegments_;
326 else {
327 localBoundarySegments_.clear();
328 std::size_t count = 0;
329 for (const auto& e : elements(this->leafGridView()))
330 for (const auto& is : intersections(this->leafGridView(), e))
331 if (is.boundary()) {
332 IdType iid = globalIdSet_->template id<1>(
333 entity(is.impl().getHostIntersection()));
334 localBoundarySegments_.insert(std::make_pair(iid, count++));
335 }
336 }
337 }
338
339 public:
344 int maxLevel() const { return 0; }
345
348 int size(int level, int codim) const {
349 // we only have one level
350 assert(level == 0);
351 return size(codim);
352 }
353
355 size_t numBoundarySegments() const { return localBoundarySegments_.size(); }
356
359 return localBoundarySegments_;
360 }
361
363 const BoundaryIds& boundaryIds() const { return boundaryIds_; }
364
367 return interfaceSegments_;
368 }
369
371 InterfaceSegments& interfaceSegments() { return interfaceSegments_; }
372
374 void addInterface(const Intersection& intersection,
375 const std::size_t marker = 1) {
376 if (isInterface(intersection)) return;
377
378 const auto& facet = entity(intersection.impl().getHostIntersection());
379 std::vector<std::size_t> ids;
380 for (std::size_t i = 0; i < facet.subEntities(dim); ++i) {
381 const auto& vertex = facet.impl().template subEntity<dim>(i);
382 vertex.impl().hostEntity()->info().isInterface = true;
383 ids.push_back(globalIdSet().id(vertex).vt()[0]);
384 }
385 std::sort(ids.begin(), ids.end());
386 interfaceSegments_.insert(std::make_pair(ids, marker));
387
388 // Add interface element to connected component in order to mark element as
389 // new
390 const auto& ientity = asInterfaceEntity(intersection);
391 InterfaceGridConnectedComponent connectedComponent(ientity);
392 interfaceGrid_->markAsRefined({ids}, connectedComponent);
393
394 interfaceGrid_->setIds();
395 interfaceGrid_->setIndices();
396
397 if (comm().size() > 0) partitionHelper_.computeInterfacePartitions();
398 }
399
401 template <class I>
402 void addInterface(const I& intersection, const std::size_t marker = 1) {
403 addInterface(intersection.impl().hostIntersection(), marker);
404 }
405
407 int size(int codim) const { return leafIndexSet().size(codim); }
408
410 int size(int level, GeometryType type) const {
411 // we only have one level
412 assert(level == 0);
413 return size(type);
414 }
415
417 int size(GeometryType type) const { return leafIndexSet().size(type); }
418
420 const typename Traits::GlobalIdSet& globalIdSet() const {
421 return *globalIdSet_;
422 }
423
425 const typename Traits::LocalIdSet& localIdSet() const {
426 return *globalIdSet_;
427 }
428
430 const MMeshLeafIndexSet<const GridImp>& levelIndexSet(int level) const {
431 if (level != 0)
432 DUNE_THROW(GridError, "levelIndexSet of nonexisting level "
433 << level << " requested!");
434 return *leafIndexSet_;
435 }
436
438 const MMeshLeafIndexSet<const GridImp>& leafIndexSet() const {
439 return *leafIndexSet_;
440 }
441
443 template <class EntitySeed>
444 typename Traits::template Codim<EntitySeed::codimension>::Entity entity(
445 const EntitySeed& seed) const {
446 using EntityImp = MMeshEntity<EntitySeed::codimension, dimension,
447 const typename Traits::Grid>;
448
449 auto hostEntity = seed.impl().hostEntity();
450 assert(hostEntity != decltype(hostEntity)());
451 return EntityImp(This(), hostEntity);
452 }
453
455 Vertex entity(const HostGridEntity<dimension>& vertexHandle) const {
456 return entity(
457 typename Traits::template Codim<dimension>::EntitySeed(vertexHandle));
458 }
459
461 Entity entity(const HostGridEntity<0>& elementHandle) const {
462 return entity(
463 typename Traits::template Codim<0>::EntitySeed(elementHandle));
464 }
465
466 InterfaceElement entity(const FacetHandle& facetHandle) const {
467 return entity(typename Traits::template Codim<1>::EntitySeed(facetHandle));
468 }
469
470 template <int d = dim>
471 std::enable_if_t<d == 3, Edge> entity(
472 const HostGridEntity<2>& edgeHandle) const {
473 return entity(typename Traits::template Codim<2>::EntitySeed(edgeHandle));
474 }
475
477 template <int codim>
478 typename Traits::template Codim<codim>::LevelIterator lbegin(
479 int level) const {
481 }
482
484 template <int codim>
485 typename Traits::template Codim<codim>::LevelIterator lend(int level) const {
487 }
488
490 template <int codim, PartitionIteratorType PiType>
491 typename Traits::template Codim<codim>::template Partition<
492 PiType>::LevelIterator
493 lbegin(int level) const {
495 }
496
498 template <int codim, PartitionIteratorType PiType>
499 typename Traits::template Codim<codim>::template Partition<
500 PiType>::LevelIterator
501 lend(int level) const {
503 }
504
506 template <int codim>
507 typename Traits::template Codim<codim>::LeafIterator leafbegin() const {
509 }
510
512 template <int codim>
513 typename Traits::template Codim<codim>::LeafIterator leafend() const {
515 }
516
518 template <int codim, PartitionIteratorType PiType>
519 typename Traits::template Codim<codim>::template Partition<
520 PiType>::LeafIterator
521 leafbegin() const {
523 }
524
526 template <int codim, PartitionIteratorType PiType>
527 typename Traits::template Codim<codim>::template Partition<
528 PiType>::LeafIterator
529 leafend() const {
531 }
532
533 typename Traits::LevelIntersectionIterator ilevelbegin(
534 const typename Traits::template Codim<0>::Entity& entity) const {
535 return entity.impl().ilevelbegin();
536 }
537
538 typename Traits::LevelIntersectionIterator ilevelend(
539 const typename Traits::template Codim<0>::Entity& entity) const {
540 return entity.impl().ilevelend();
541 }
542
543 typename Traits::LeafIntersectionIterator ileafbegin(
544 const typename Traits::template Codim<0>::Entity& entity) const {
545 return entity.impl().ileafbegin();
546 }
547
548 typename Traits::LeafIntersectionIterator ileafend(
549 const typename Traits::template Codim<0>::Entity& entity) const {
550 return entity.impl().ileafend();
551 }
552
554 template <int codim>
556 bool includeBoundary = false) const {
557 using Impl =
559 return MMeshInterfaceIterator<codim, const GridImp>(Impl(this, false));
560 }
561
563 template <int codim>
565 bool includeBoundary = false) const {
566 using Impl =
569 Impl(this, true, includeBoundary));
570 }
571
574 bool includeBoundary = false) const {
575 using Impl =
578 Impl(this, includeBoundary));
579 }
580
583 bool includeBoundary = false) const {
584 using Impl =
587 Impl(this, true, includeBoundary));
588 }
589
591 bool isInterface(const Vertex& vertex) const {
592 return vertex.impl().hostEntity()->info().isInterface;
593 }
594
596 bool isInterface(const Intersection& intersection) const {
597 return isInterface(entity(intersection.impl().getHostIntersection()));
598 }
599
601 template <class OtherIntersection>
602 bool isInterface(const OtherIntersection& intersection) const {
603 return isInterface(intersection.impl().hostIntersection());
604 }
605
607 bool isInterface(const InterfaceElement& segment) const {
608 static std::vector<std::size_t> ids(segment.subEntities(dimension));
609 for (std::size_t i = 0; i < segment.subEntities(dimension); ++i) {
610 const auto& vertex = segment.impl().template subEntity<dimension>(i);
611 if (!vertex.impl().isInterface()) return false;
612
613 ids[i] = this->globalIdSet().id(vertex).vt()[0];
614 }
615
616 std::sort(ids.begin(), ids.end());
617
618 int count = interfaceSegments_.count(ids);
619 assert(count <= 1);
620 return (count > 0);
621 }
622
624 template <int d = dim>
625 std::enable_if_t<d == 3, bool> isInterface(const Edge& edge) const {
626 std::vector<std::size_t> ids;
627 for (std::size_t i = 0; i < edge.subEntities(dimension); ++i) {
628 const auto& vertex = edge.impl().template subEntity<dimension>(i);
629
630 if (!isInterface(vertex)) return false;
631
632 ids.push_back(this->globalIdSet().id(vertex).vt()[0]);
633 }
634
635 std::sort(ids.begin(), ids.end());
636
637 for (const auto& iseg : interfaceSegments_) {
638 const auto& seg = iseg.first.vt();
639 if ((seg[0] == ids[0] && seg[1] == ids[1]) ||
640 (seg[1] == ids[0] && seg[2] == ids[1]) ||
641 (seg[0] == ids[0] && seg[2] == ids[1]))
642 return true;
643 }
644
645 return false;
646 }
647
649 bool isOnInterface(const Entity& entity) const {
650 for (std::size_t i = 0; i < entity.subEntities(1); ++i)
651 if (isInterface(entity.template subEntity<1>(i))) return true;
652
653 return false;
654 }
655
658 return InterfaceEntity{{interfaceGrid_.get(), segment.impl().hostEntity()}};
659 }
660
662 InterfaceEntity asInterfaceEntity(const Intersection& intersection) const {
663 return InterfaceEntity{
664 {interfaceGrid_.get(), intersection.impl().getHostIntersection()}};
665 }
666
668 template <class OtherIntersection>
670 const OtherIntersection& intersection) const {
671 return asInterfaceEntity(intersection.impl().hostIntersection());
672 }
673
675 Intersection asIntersection(const InterfaceEntity& interfaceEntity) const {
676 const auto& host = interfaceEntity.impl().hostEntity();
677 return asIntersection(host);
678 }
679
681 Intersection asIntersection(const Facet& facet) const {
682 const auto& host = facet.impl().hostEntity();
683 return asIntersection(host);
684 }
685
688 FacetHandle hostFacet = host;
689
690 // make sure to get the intersection seen from inside at domain boundary
691 if (hostgrid_.is_infinite(hostFacet.first))
692 hostFacet = interfaceGrid().mirrorHostEntity(hostFacet);
693
694 return MMeshLeafIntersection<const GridImp>(This(), hostFacet.first,
695 hostFacet.second);
696 }
697
700 const Entity& element = {}) const {
701 return entity(
702 hostgrid_.inexact_locate(makePoint(p), element.impl().hostEntity()));
703 }
704
709 void globalRefine(int steps = 1) {
710 for (int i = 0; i < steps; ++i) {
711 // mark all elements
712 for (const auto& element : elements(this->leafGridView()))
713 mark(1, element);
714
715 preAdapt();
716 adapt();
717 postAdapt();
718 }
719 }
720
725 bool mark(int refCount,
726 const typename Traits::template Codim<0>::Entity& e) const {
727 e.impl().mark(refCount);
728 if (refCount > 0) ++refineMarked_;
729 if (refCount < 0) ++coarsenMarked_;
730 return true;
731 }
732
737 bool change = false;
738 indicator_.update();
739
740 for (const auto& element : elements(this->leafGridView())) {
741 mark(indicator_(element), element);
742 change |= indicator_(element) != 0;
743 }
744
745 for (const auto& ielement : elements(interfaceGrid_->leafGridView())) {
746 interfaceGrid_->mark(indicator_(ielement), ielement);
747 change |= indicator_(ielement) != 0;
748 }
749
750 return change;
751 }
752
757 int getMark(const typename Traits::template Codim<0>::Entity& e) const {
758 return e.impl().getMark();
759 }
760
762 bool preAdapt() {
763 return (interfaceGrid_->preAdapt()) || (coarsenMarked_ > 0) ||
764 (remove_.size() > 0);
765 }
766
768 void refineEdge(const Entity& entity, const std::size_t edgeIndex,
769 const double where = 0.5) {
771 ip.edge = entity.template subEntity<dim - 1>(edgeIndex);
772 ip.edgeId = globalIdSet().id(ip.edge);
773 ip.point = makePoint(where * ip.edge.geometry().corner(0) +
774 (1 - where) * ip.edge.geometry().corner(1));
775 ip.v0 = ip.edge.impl().template subEntity<dim>(0).impl().hostEntity();
776 ip.v1 = ip.edge.impl().template subEntity<dim>(1).impl().hostEntity();
777 ip.insertionLevel = ip.edge.impl().insertionLevel() + 1;
778
779 if (isInterface(ip.edge)) {
780 ip.isInterface = true;
781 if constexpr (dim != 3) {
782 InterfaceEntity component{
783 {interfaceGrid_.get(), ip.edge.impl().hostEntity()}};
784 ip.connectedcomponent = InterfaceGridConnectedComponent(component);
785 }
786 }
787
788 if (inserted_.insert(ip.edgeId).second) {
789 insert_.push_back(ip);
790 if (verbose_)
791 std::cout << "Insert vertex manually: " << ip.point << std::endl;
792 }
793 }
794
796 void insertVertexInCell(const GlobalCoordinate& position) {
798 ip.point = makePoint(position);
799
800 insert_.push_back(ip);
801 if (verbose_)
802 std::cout << "Insert vertex in cell manually: " << ip.point << std::endl;
803 }
804
807 const typename InterfaceGrid::Traits::template Codim<dim - 1>::Entity&
808 interfaceVertex) {
809 const Vertex& vertex = entity(interfaceVertex.impl().hostEntity());
810 removeVertex(vertex);
811 }
812
814 void removeVertex(const Vertex& vertex) {
815 if (removed_.insert(globalIdSet().id(vertex)).second) {
816 remove_.push_back(vertex.impl().hostEntity());
817 if (verbose_)
818 std::cout << "Remove vertex manually: " << vertex.geometry().center()
819 << std::endl;
820 }
821 }
822
826 bool adapt() {
827 // Obtain the adaption points
828 for (const auto& element : elements(this->leafGridView())) {
829 int mark = element.impl().getMark();
830
831 // refine
832 if (mark == 1) {
833 std::pair<Edge, GlobalCoordinate> pair =
835
837 ip.edge = pair.first;
838 ip.edgeId = globalIdSet().id(ip.edge);
839 ip.point = makePoint(pair.second);
840 ip.v0 = ip.edge.impl().template subEntity<dim>(0).impl().hostEntity();
841 ip.v1 = ip.edge.impl().template subEntity<dim>(1).impl().hostEntity();
842 ip.insertionLevel = ip.edge.impl().insertionLevel() + 1;
843
844 if (!isInterface(ip.edge))
845 if (inserted_.insert(ip.edgeId).second) {
846 insert_.push_back(ip);
847 if (verbose_)
848 std::cout << "Insert vertex because of marked cell: " << ip.point
849 << std::endl;
850 }
851 }
852
853 // coarsen
854 else if (mark == -1) {
855 auto vertex = RefinementStrategy::coarsening(element);
856
857 if (vertex != decltype(vertex)())
858 if (removed_.insert(globalIdSet().id(vertex)).second) {
859 remove_.push_back(vertex.impl().hostEntity());
860 if (verbose_)
861 std::cout << "Remove vertex because of marked cell: "
862 << vertex.geometry().center() << std::endl;
863 }
864 }
865 }
866
867 // Obtain the adaption points for the interface
868 for (const auto& element : elements(this->interfaceGrid().leafGridView())) {
869 int mark = this->interfaceGrid().getMark(element);
870
871 // refine
872 if (mark == 1) {
873 auto pair = InterfaceRefinementStrategy::refinement(element);
874
876 ip.edge = entity(pair.first.impl().hostEntity());
877 ip.edgeId = globalIdSet().id(ip.edge);
878 ip.point = makePoint(pair.second);
879 ip.v0 = ip.edge.impl().template subEntity<dim>(0).impl().hostEntity();
880 ip.v1 = ip.edge.impl().template subEntity<dim>(1).impl().hostEntity();
881 ip.insertionLevel = ip.edge.impl().insertionLevel() + 1;
882 ip.isInterface = true;
883 ip.connectedcomponent = InterfaceGridConnectedComponent(element);
884
885 if (inserted_.insert(ip.edgeId).second) {
886 insert_.push_back(ip);
887 if (verbose_)
888 std::cout << "Insert interface vertex because of marked cell: "
889 << ip.point << std::endl;
890 }
891 }
892
893 // coarsen
894 else if (mark == -1) {
895 auto ivertex = InterfaceRefinementStrategy::coarsening(element);
896 if (ivertex != decltype(ivertex)()) {
897 const Vertex& vertex = entity(ivertex.impl().hostEntity());
898
899 if (removed_.insert(globalIdSet().id(vertex)).second) {
900 remove_.push_back(vertex.impl().hostEntity());
901 if (verbose_)
902 std::cout << "Remove interface vertex because of marked cell: "
903 << vertex.geometry().center() << std::endl;
904 }
905 }
906 }
907 }
908
909 if (verbose_)
910 std::cout << "- insert " << insert_.size() << "\t remove "
911 << remove_.size() << std::endl;
912
913 return adapt_(true);
914 }
915
920 bool ensureInterfaceMovement(std::vector<GlobalCoordinate> shifts) {
921 assert(shifts.size() ==
922 this->interfaceGrid().leafIndexSet().size(dimension - 1));
923 bool change = false;
924
925 // check if grid is still valid
926 for (const auto& element : elements(this->leafGridView()))
927 if (signedVolume_(element) <= 0.0)
928 DUNE_THROW(GridError,
929 "A cell has a negative volume! Maybe the interface has been "
930 "moved too far?");
931
932 // temporarily move vertices
933 moveInterface(shifts);
934
935 for (const auto& element : elements(this->leafGridView()))
936 if (signedVolume_(element) <= 0.0) {
937 // disable removing of vertices in 3d
938 if constexpr (dim == 3) {
939 DUNE_THROW(GridError,
940 "Interface could not be moved, because the removal of "
941 "vertices is not supported in 3D!");
942 } else {
943 bool allInterface = true;
944 for (std::size_t j = 0; j < element.subEntities(dimension); ++j) {
945 const auto& v = element.template subEntity<dimension>(j);
946
947 // if vertex is part of interface, we have to do more
948 if (!v.impl().isInterface()) {
949 if (RefinementStrategy::boundaryFlag(v) == 1) continue;
950
951 bool inserted = removed_.insert(globalIdSet().id(v)).second;
952 if (inserted) {
953 remove_.push_back(v.impl().hostEntity());
954 change = true;
955 if (verbose_)
956 std::cout << "Remove vertex because of negative volume: "
957 << v.geometry().center() << std::endl;
958 }
959 allInterface = false;
960 }
961 }
962
963 // if all vertices are part of the interface, we can try to compute an
964 // intersection
965 if (allInterface) {
966 Edge interfaceEdge;
967 for (std::size_t j = 0; j < element.subEntities(1); ++j) {
968 const auto& edge = element.template subEntity<1>(j);
969 if (isInterface(edge)) {
970 if (interfaceEdge != Edge()) // with more than one interface
971 // edge we don't know what to do
972 DUNE_THROW(GridError,
973 "Interface could not be moved because a "
974 "constrained cell with more than one interface "
975 "edge would have negative volume!");
976
977 interfaceEdge = edge;
978 }
979 }
980
981 // with no interface edge we can try to coarsen the interface
982 if (interfaceEdge == Edge()) {
983 bool allNonRemovable = true;
984 for (std::size_t j = 0; j < element.subEntities(dimension); ++j) {
985 const auto v = element.template subEntity<dimension>(j);
986 const auto iv = interfaceGrid().entity(v.impl().hostEntity());
988 allNonRemovable = false;
989 bool inserted = removed_.insert(globalIdSet().id(v)).second;
990 if (inserted) {
991 remove_.push_back(v.impl().hostEntity());
992 change = true;
993 if (verbose_)
994 std::cout << "Remove interface vertex because of "
995 "negative volume: "
996 << v.geometry().center() << std::endl;
997 }
998 }
999 }
1000 if (allNonRemovable)
1001 DUNE_THROW(
1002 GridError,
1003 "Interface could not be moved because a constrained cell "
1004 "without any interface edge would have negative volume!");
1005 } else {
1006 // compute intersection
1007 Vertex thirdVertex;
1008 for (std::size_t j = 0; j < element.subEntities(dimension); ++j) {
1009 const auto& v = element.template subEntity<dimension>(j);
1010 if (v !=
1011 interfaceEdge.impl().template subEntity<dimension>(0) &&
1012 v != interfaceEdge.impl().template subEntity<dimension>(1))
1013 thirdVertex = v;
1014 }
1015
1016 Vertex adjVertex;
1017 InterfaceEntity crossingEdge;
1018
1019 const auto& iThirdVertex =
1020 interfaceGrid().entity(thirdVertex.impl().hostEntity());
1021 for (const auto& e : incidentInterfaceElements(iThirdVertex)) {
1022 if (crossingEdge != InterfaceEntity())
1023 DUNE_THROW(GridError,
1024 "Interface could not be moved because two "
1025 "interfaces cross!");
1026
1027 crossingEdge = e;
1028
1029 if (e.impl().template subEntity<1>(0) == iThirdVertex)
1030 adjVertex = entity(
1031 e.impl().template subEntity<1>(1).impl().hostEntity());
1032 else
1033 adjVertex = entity(
1034 e.impl().template subEntity<1>(0).impl().hostEntity());
1035 }
1036
1037 // compute intersection
1038 const auto iegeo = interfaceEdge.geometry();
1039 const auto& c0 = iegeo.corner(0);
1040 const auto& c1 = iegeo.corner(1);
1041 const auto cegeo = crossingEdge.geometry();
1043 Dune::PolygonCutting<double, GlobalCoordinate>::
1044 lineIntersectionPoint(c0, c1, cegeo.corner(0),
1045 cegeo.corner(1));
1046
1047 // check if intersection point is in interfaceEdge
1048 if ((c0 - x) * (c1 - x) > 0.) continue;
1049
1051 ip.edge = interfaceEdge;
1052 ip.edgeId = globalIdSet().id(interfaceEdge);
1053 ip.point = makePoint(x);
1054 ip.v0 = thirdVertex.impl().hostEntity();
1055 ip.insertionLevel = thirdVertex.impl().insertionLevel() + 1;
1056 ip.isInterface = true;
1057 ip.connectedcomponent = InterfaceGridConnectedComponent(
1058 (interfaceEdge.geometry().volume() >
1059 crossingEdge.geometry()
1060 .volume()) // take the edge with the larger volume
1062 interfaceEdge.impl().hostEntity())
1063 : crossingEdge);
1064
1065 if (verbose_)
1066 std::cout << "Insert interface intersection point: " << ip.point
1067 << std::endl;
1068
1069 insert_.push_back(ip);
1070 change = true;
1071
1072 // move third vertex back to old position
1073 const auto& idx =
1074 interfaceGrid().leafIndexSet().index(iThirdVertex);
1075 thirdVertex.impl().hostEntity()->point() =
1076 makePoint(thirdVertex.geometry().center() - shifts[idx]);
1077 shifts[idx] = GlobalCoordinate(0.0);
1078 }
1079 }
1080 }
1081 }
1082
1083 // move vertices back
1084 for (GlobalCoordinate& s : shifts) s *= -1.0;
1085 moveInterface(shifts);
1086
1087 return change;
1088 }
1089
1094 bool ensureVertexMovement(std::vector<GlobalCoordinate> shifts) {
1095 assert(shifts.size() == this->leafIndexSet().size(dimension));
1096 bool change = false;
1097
1098 // temporarily move vertices
1099 moveVertices(shifts);
1100
1101 for (const auto& element : elements(this->leafGridView()))
1102 if (signedVolume_(element) <= 0.0) {
1103 // disable removing of vertices in 3d
1104 if constexpr (dim == 3) {
1105 DUNE_THROW(GridError,
1106 "Vertices could not be moved, because the removal of "
1107 "vertices is not supported in 3D!");
1108 } else {
1109 for (std::size_t j = 0; j < element.subEntities(dimension); ++j) {
1110 const auto& v = element.template subEntity<dimension>(j);
1111
1112 // if vertex is part of interface, we have to do more
1113 if (!v.impl().isInterface()) {
1114 if (RefinementStrategy::boundaryFlag(v) == 1) continue;
1115
1116 bool inserted = removed_.insert(globalIdSet().id(v)).second;
1117 if (inserted) {
1118 remove_.push_back(v.impl().hostEntity());
1119 change = true;
1120 if (verbose_)
1121 std::cout << "Remove vertex because of negative volume: "
1122 << v.geometry().center() << std::endl;
1123 }
1124 }
1125 }
1126 }
1127 }
1128
1129 // move vertices back
1130 for (GlobalCoordinate& s : shifts) s *= -1.0;
1131 moveVertices(shifts);
1132
1133 return change;
1134 }
1135
1137 template <class GridImp, class DataHandle>
1138 bool adapt(AdaptDataHandleInterface<GridImp, DataHandle>& handle) {
1139 preAdapt();
1140 adapt();
1141 sequence_ += 1;
1142
1143 for (const auto& element : elements(this->leafGridView()))
1144 if (element.isNew()) {
1145 bool initialize = true;
1146
1147 for (const auto& old : element.impl().connectedComponent().children()) {
1148 const Entity& father = old;
1149
1150 MMeshImpl::CutSetTriangulation<Entity> cutSetTriangulation(old,
1151 element);
1152 for (auto& middle : cutSetTriangulation.triangles()) {
1153 middle.impl().bindFather(father);
1154 handle.prolongLocal(father, middle, true);
1155 middle.impl().bindFather(element);
1156 handle.restrictLocal(element, middle, initialize);
1157
1158 initialize = false;
1159 }
1160 }
1161 }
1162
1163 postAdapt();
1164 return true;
1165 }
1166
1167 private:
1168 template <int d = dim>
1169 std::enable_if_t<d == 2, FieldType> signedVolume_(
1170 const Entity& element) const {
1171 return hostgrid_.triangle(element.impl().hostEntity()).area();
1172 }
1173
1174 template <int d = dim>
1175 std::enable_if_t<d == 3, FieldType> signedVolume_(
1176 const Entity& element) const {
1177 return hostgrid_.tetrahedron(element.impl().hostEntity()).volume();
1178 }
1179
1180 bool adapt_(bool buildComponents = true) {
1181 if (insert_.size() == 0 && remove_.size() == 0) return false;
1182
1183 std::vector<std::size_t> insertComponentIds;
1184 std::vector<std::size_t> removeComponentIds;
1185 static constexpr bool writeComponents = verbose_; // for debugging
1186
1187 if (buildComponents) {
1188 // build the connected components
1189 componentCount_ =
1190 connectedComponents_.size() + 1; // 0 is the default component
1191
1192 // we have to mark the cells repeatedly for the case that conflict zones
1193 // overlap
1194 bool markAgain = true;
1195 std::size_t componentNumber;
1196 while (markAgain) {
1197 markAgain = false;
1198 insertComponentIds.clear();
1199 removeComponentIds.clear();
1200 insertComponentIds.reserve(insert_.size());
1201 removeComponentIds.reserve(remove_.size());
1202
1203 // mark elements as mightVanish
1204 for (const auto& ip : insert_) {
1205 if (ip.edgeId != IdType())
1206 markAgain |= markElementsForInsertion_(ip.edge, componentNumber);
1207 else
1208 markAgain |= markElementForInsertion_(ip.point, componentNumber);
1209
1210 insertComponentIds.push_back(componentNumber - 1);
1211 }
1212
1213 // mark elements as mightVanish
1214 for (const auto& vh : remove_) {
1215 markAgain |= markElementsForRemoval_(vh, componentNumber);
1216 removeComponentIds.push_back(componentNumber - 1);
1217 }
1218 }
1219
1220 buildConnectedComponents_();
1221
1222 // plot connected components
1223 if (writeComponents) writeComponents_();
1224 }
1225
1226 // actually insert the points
1227 std::vector<VertexHandle> newVertices;
1228 for (const auto& ip : insert_) {
1229 VertexHandle vh;
1230 bool connect = false;
1231 if (ip.edgeId != IdType()) {
1232 auto eh = ip.edge.impl().hostEntity();
1233
1234 // if edge id has changed, we have to update the edge handle
1235 if (this->globalIdSet().id(ip.edge) != ip.edgeId) {
1236 // add empty entry to newVertices to match indices with
1237 // insertComponentIds
1238 newVertices.emplace_back();
1239
1240 continue;
1241 // getEdge_( ip, eh ); // TODO this does not work correct yet
1242 }
1243
1244 if (ip.v0 !=
1245 ip.edge.impl().template subEntity<dim>(0).impl().hostEntity() &&
1246 ip.v0 !=
1247 ip.edge.impl().template subEntity<dim>(1).impl().hostEntity())
1248 connect = true;
1249
1250 if (ip.isInterface == true)
1251 vh = insertInInterface_(ip);
1252 else
1253 vh = insertInEdge_(ip.point, eh);
1254
1255 vh->info().insertionLevel = ip.insertionLevel;
1256 } else {
1257 vh = insertInCell_(ip.point);
1258
1259 // check if edge is really part of the triangulation
1260 if (ip.v0 != VertexHandle() &&
1261 !getHostGrid().tds().is_edge(ip.v0, vh)) // TODO 3D
1262 {
1263 // try again with half distance
1264 if constexpr (dimension == 2) hostgrid_.remove(vh);
1265
1267 x = makeFieldVector(ip.point);
1268 x -= makeFieldVector(ip.v0->point());
1269 x *= 0.5;
1270 x += makeFieldVector(ip.v0->point());
1271 vh = insertInCell_(makePoint(x));
1272
1273 if (!getHostGrid().tds().is_edge(ip.v0, vh)) // TODO 3D
1274 {
1275 // DUNE_THROW( GridError, "Edge added to interface is not part of
1276 // the new triangulation: " << ip.v0->point() << " to " <<
1277 // vh->point() );
1278 std::cerr << "Error: Edge added to interface is not part of the "
1279 "new triangulation: "
1280 << ip.v0->point() << " to " << vh->point() << std::endl;
1281 continue;
1282 }
1283 }
1284
1285 globalIdSet_->setNextId(vh);
1286 vh->info().insertionLevel = ip.insertionLevel;
1287
1288 if (ip.isInterface) connect = true;
1289 }
1290
1291 // connect vertex and ip.v0 with interface
1292 if (connect) {
1293 std::size_t id = vh->info().id;
1294 vh->info().isInterface = true;
1295 std::vector<std::size_t> ids;
1296 ids.push_back(id);
1297 ids.push_back(globalIdSet().id(entity(ip.v0)).vt()[0]);
1298 std::sort(ids.begin(), ids.end());
1299 interfaceSegments_.insert(std::make_pair(
1300 ids, 1)); // TODO: compute interface marker corresponding to ip.v0
1301
1302 // pass this refinement information to the interface grid
1303 interfaceGrid_->markAsRefined(/*children*/ {ids},
1304 ip.connectedcomponent);
1305
1306 // set boundary segment to the same as ip.v0 if possible, default to 0
1307 auto v0id = interfaceGrid_->globalIdSet()
1308 .id(interfaceGrid_->entity(ip.v0))
1309 .vt()[0];
1310 auto it = interfaceGrid_->boundarySegments().find({v0id});
1311 if (it != interfaceGrid_->boundarySegments().end())
1312 interfaceGrid_->addBoundarySegment({id}, it->second);
1313 else
1314 interfaceGrid_->addBoundarySegment({id}, 0);
1315 }
1316
1317 // store vertex handles for later use
1318 newVertices.push_back(vh);
1319 }
1320
1321 // actually remove the points
1322 int ci = 0;
1323 for (const auto& vh : remove_) {
1324 ElementOutput elements;
1325 if (vh->info().isInterface)
1326 elements = removeFromInterface_(vh);
1327 else
1328 hostgrid_.removeAndGiveNewElements(vh, elements);
1329
1330 // flag all elements inside conflict area as new and map connected
1331 // component
1332 if (buildComponents)
1333 markElementsAfterRemoval_(elements, removeComponentIds[ci]);
1334 ci++;
1335 }
1336
1337 // first update ids
1338 setIds();
1339 interfaceGrid_->setIds();
1340
1341 // then, update partitions
1342 if (comm().size() > 1) partitionHelper_.updatePartitions();
1343
1344 // afterwards, update index sets
1345 setIndices();
1346
1347 if (buildComponents) {
1348 // flag incident elements as new and map connected component
1349 for (std::size_t i = 0; i < newVertices.size(); ++i)
1350 if (newVertices[i] != VertexHandle())
1351 markElementsAfterInsertion_(newVertices[i], insertComponentIds[i]);
1352 }
1353
1354 // update interface grid
1355 interfaceGrid_->setIndices();
1356
1357 if (buildComponents) {
1358 if (writeComponents) writeComponents_();
1359 }
1360
1361 loadBalance();
1362 return newVertices.size() > 0;
1363 }
1364
1365 template <int d = dim>
1366 std::enable_if_t<d == 2, void> getEdge_(const RefinementInsertionPoint& ip,
1367 EdgeHandle& eh) const {
1368 assert(hostgrid_.is_edge(ip.v0, ip.v1));
1369 hostgrid_.is_edge(ip.v0, ip.v1, eh.first, eh.second);
1370 }
1371
1372 template <int d = dim>
1373 std::enable_if_t<d == 3, void> getEdge_(const RefinementInsertionPoint& ip,
1374 EdgeHandle& eh) const {
1375 assert(hostgrid_.is_edge(ip.v0, ip.v1, eh.first, eh.second, eh.third));
1376 hostgrid_.is_edge(ip.v0, ip.v1, eh.first, eh.second, eh.third);
1377 }
1378
1379 template <int d = dim>
1380 std::enable_if_t<d == 2, VertexHandle> insertInEdge_(const Point& point,
1381 const EdgeHandle& eh) {
1382 return hostgrid_.insert_in_edge(point, eh.first, eh.second);
1383 }
1384
1385 template <int d = dim>
1386 std::enable_if_t<d == 3, VertexHandle> insertInEdge_(const Point& point,
1387 const EdgeHandle& eh) {
1388 return hostgrid_.insert_in_edge(point, eh.first, eh.second, eh.third);
1389 }
1390
1391 template <int d = dim>
1392 std::enable_if_t<d == 2, VertexHandle> insertInCell_(const Point& point) {
1393 auto face = hostgrid_.locate(point);
1394 return hostgrid_.insert_in_face(point, face);
1395 }
1396
1397 template <int d = dim>
1398 std::enable_if_t<d == 3, VertexHandle> insertInCell_(const Point& point) {
1399 auto cell = hostgrid_.locate(point);
1400 return hostgrid_.insert_in_cell(point, cell);
1401 }
1402
1403 public:
1407 void moveInterface(const std::vector<GlobalCoordinate>& shifts) {
1408 const auto& iindexSet = this->interfaceGrid().leafIndexSet();
1409 assert(shifts.size() == iindexSet.size(dimension - 1));
1410
1411 for (const auto& vertex : vertices(this->interfaceGrid().leafGridView())) {
1412 const VertexHandle& vh = vertex.impl().hostEntity();
1413 vh->point() = makePoint(vertex.geometry().center() +
1414 shifts[iindexSet.index(vertex)]);
1415 }
1416 }
1417
1421 void moveVertices(const std::vector<GlobalCoordinate>& shifts) {
1422 const auto& indexSet = this->leafIndexSet();
1423 assert(shifts.size() == indexSet.size(dimension));
1424
1425 for (const auto& vertex : vertices(this->leafGridView())) {
1426 const VertexHandle& vh = vertex.impl().hostEntity();
1427 vh->point() = makePoint(vertex.geometry().center() +
1428 shifts[indexSet.index(vertex)]);
1429 }
1430 }
1431
1434 template <typename Vertex>
1435 void addToInterface(const Vertex& vertex, const GlobalCoordinate& p) {
1437 ip.edgeId = IdType();
1438 ip.point = makePoint(p);
1439 ip.v0 = vertex.impl().hostEntity();
1440 ip.insertionLevel = vertex.impl().insertionLevel() + 1;
1441 ip.isInterface = true;
1442
1443 // take some incident element as father
1444 for (const auto& elem : incidentInterfaceElements(vertex))
1445 if (!elem.isNew()) {
1446 ip.connectedcomponent = InterfaceGridConnectedComponent(elem);
1447 break;
1448 }
1449
1450 insert_.push_back(ip);
1451 if (verbose_)
1452 std::cout << "Add vertex to interface: " << ip.point << std::endl;
1453 }
1454
1456 void postAdapt() {
1457 for (const Entity& entity : elements(this->leafGridView())) {
1458 mark(0, entity);
1459 entity.impl().setIsNew(false);
1460 entity.impl().setWillVanish(false);
1461 entity.impl().hostEntity()->info().componentNumber = 0;
1462 }
1463
1464 refineMarked_ = 0;
1465 coarsenMarked_ = 0;
1466 createdEntityConnectedComponentMap_.clear();
1467 vanishingEntityConnectedComponentMap_.clear();
1468 connectedComponents_.clear();
1469
1470 insert_.clear();
1471 remove_.clear();
1472 inserted_.clear();
1473 removed_.clear();
1474 }
1475
1476 private:
1477 void writeComponents_() const {
1478 static int performCount = 0;
1479 const auto& gridView = this->leafGridView();
1480 const auto& indexSet = this->leafIndexSet();
1481
1482 std::vector<std::size_t> component(indexSet.size(0), 0);
1483 std::vector<std::size_t> findcomponent(indexSet.size(0), 0);
1484 std::vector<bool> isnew(indexSet.size(0), 0);
1485 std::vector<bool> mightvanish(indexSet.size(0), 0);
1486
1487 for (const auto& e : elements(gridView)) {
1488 component[indexSet.index(e)] =
1489 e.impl().hostEntity()->info().componentNumber;
1490 isnew[indexSet.index(e)] = e.isNew();
1491 mightvanish[indexSet.index(e)] = e.mightVanish();
1492 }
1493
1494 VTKWriter<typename Traits::LeafGridView> vtkWriter(gridView);
1495 vtkWriter.addCellData(component, "component");
1496 vtkWriter.addCellData(isnew, "isnew");
1497 vtkWriter.addCellData(mightvanish, "mightvanish");
1498 vtkWriter.write("mmesh-components-" + std::to_string(performCount));
1499
1500 VTKWriter<typename InterfaceGrid::LeafGridView> ivtkWriter(
1501 interfaceGrid_->leafGridView());
1502 ivtkWriter.write("mmesh-components-interface-" +
1503 std::to_string(performCount++));
1504 }
1505
1506 void buildConnectedComponents_() {
1507 for (const Entity& entity : elements(this->leafGridView())) {
1508 if (entity.mightVanish()) {
1509 const auto& hostEntity = entity.impl().hostEntity();
1510 const IdType id = this->globalIdSet().id(entity);
1511
1512 bool found = false;
1513 const std::size_t componentId = hostEntity->info().componentNumber - 1;
1514
1515 // check if component for entity exists already and add entity if
1516 // necessary
1517 if (componentId < connectedComponents_.size()) {
1518 // sth. changed, we have to update the component to include this
1519 // entity
1520 if (!entity.isNew()) {
1521 ConnectedComponent& component = connectedComponents_[componentId];
1522 if (!component.hasEntity(entity)) component.update(entity);
1523 }
1524
1525 vanishingEntityConnectedComponentMap_.insert(
1526 std::make_pair(id, componentId));
1527 }
1528 // else create new component
1529 else {
1530 connectedComponents_[componentId] =
1532 vanishingEntityConnectedComponentMap_.insert(
1533 std::make_pair(id, componentId));
1534 }
1535 }
1536 }
1537 }
1538
1541 VertexHandle insertInInterface_(const RefinementInsertionPoint& ip) {
1542 assert(isInterface(ip.edge));
1543
1544 // get the vertex ids of the interface segment
1545 std::vector<std::size_t> ids;
1546 for (std::size_t i = 0; i < ip.edge.subEntities(dim); ++i)
1547 ids.push_back(
1548 globalIdSet().id(ip.edge.impl().template subEntity<dim>(i)).vt()[0]);
1549 std::sort(ids.begin(), ids.end());
1550
1551 // erase old interface segment
1552 std::size_t marker = interfaceSegments_[ids];
1553 interfaceSegments_.erase(ids);
1554
1555 // insert the point
1556 auto eh = ip.edge.impl().hostEntity();
1557 const auto& vh = insertInEdge_(ip.point, eh);
1558 vh->info().isInterface = true;
1559
1560 // get the (next) id for vh
1561 std::size_t id = globalIdSet_->setNextId(vh);
1562
1563 // insert the new interface segments
1564 std::vector<std::vector<std::size_t>> allNewIds;
1565 for (int i = 0; i < dimension; ++i) {
1566 std::vector<std::size_t> newIds;
1567 newIds.push_back(id);
1568 for (int j = 0; j < dimension - 1; ++j)
1569 newIds.push_back(ids[(i + j) % dimension]);
1570
1571 std::sort(newIds.begin(), newIds.end());
1572 interfaceSegments_.insert(std::make_pair(newIds, marker));
1573 allNewIds.push_back(newIds);
1574 }
1575
1576 // pass this refinement information to the interface grid
1577 interfaceGrid_->markAsRefined(/*children*/ allNewIds,
1578 ip.connectedcomponent);
1579
1580 return vh;
1581 }
1582
1585 template <int d = dimension>
1586 std::enable_if_t<d == 2, ElementOutput> removeFromInterface_(
1587 const VertexHandle& vh) {
1588 std::size_t id = vh->info().id;
1589 InterfaceGridConnectedComponent connectedComponent;
1590
1591 // find and remove interface segments
1592 std::size_t marker = 1;
1593 std::vector<VertexHandle> otherVhs;
1594 for (const auto& e :
1595 incidentInterfaceElements(interfaceGrid_->entity(vh))) {
1596 // TODO: handle the case of overlapping components
1597 assert(!interfaceGrid_->hasConnectedComponent(e));
1598 connectedComponent.add(e);
1599
1600 const auto v0 = e.template subEntity<1>(0).impl().hostEntity();
1601 const auto v1 = e.template subEntity<1>(1).impl().hostEntity();
1602
1603 VertexHandle other = (v0 != vh) ? v0 : v1;
1604
1605 std::vector<std::size_t> ids(2);
1606 ids[0] = id;
1607 ids[1] = other->info().id;
1608 std::sort(ids.begin(), ids.end());
1609
1610 auto it = interfaceSegments_.find(ids);
1611 if (it != interfaceSegments_.end()) {
1612 marker = interfaceSegments_[ids];
1613 interfaceSegments_.erase(it);
1614 otherVhs.push_back(other);
1615 }
1616 }
1617
1618 if (otherVhs.size() != 2)
1619 return {}; // otherwise, we remove a tip or a junction
1620
1621 std::list<EdgeHandle> hole;
1622 hostgrid_.make_hole(vh, hole);
1623
1624 ElementOutput elements;
1625 hostgrid_.remeshHoleConstrained(vh, hole, elements, otherVhs);
1626
1627 // add the new interface segment
1628 std::vector<std::size_t> ids{
1629 {otherVhs[0]->info().id, otherVhs[1]->info().id}};
1630 std::sort(ids.begin(), ids.end());
1631 interfaceSegments_.insert(std::make_pair(ids, marker));
1632
1633 // pass this refinement information to the interface grid
1634 interfaceGrid_->markAsRefined(/*children*/ {ids}, connectedComponent);
1635
1636 return elements;
1637 }
1638
1639 template <int d = dimension>
1640 std::enable_if_t<d == 3, ElementOutput> removeFromInterface_(
1641 const VertexHandle& vh) {
1642 DUNE_THROW(NotImplemented, "removeFromInterface() in 3d");
1643 }
1644
1645 public:
1649 unsigned int overlapSize(int codim) const { return 0; }
1650
1652 unsigned int ghostSize(int codim) const {
1653 std::size_t size = 0;
1654
1655 if (codim == 0)
1656 for (const auto& e : elements(this->leafGridView(), Partitions::ghost))
1657 size++;
1658
1659 if (codim == 1)
1660 for (const auto& f : facets(this->leafGridView()))
1661 if (f.partitionType() == GhostEntity) size++;
1662
1663 if (codim == dimension)
1664 for (const auto& v : vertices(this->leafGridView()))
1665 if (v.partitionType() == GhostEntity) size++;
1666
1667 return size;
1668 }
1669
1671 unsigned int overlapSize(int level, int codim) const {
1672 return overlapSize(codim);
1673 }
1674
1676 unsigned int ghostSize(int level, int codim) const {
1677 return ghostSize(codim);
1678 }
1679
1684 partitionHelper_.distribute();
1685 update();
1686 };
1687
1694 template <class T>
1695 bool loadBalance(const T& t) {
1696 DUNE_THROW(NotImplemented, "MMesh::loadBalance(t)");
1697 };
1698
1699 void loadBalance(int strategy, int minlevel, int depth, int maxlevel,
1700 int minelement) {
1701 DUNE_THROW(NotImplemented, "MMesh::loadBalance()");
1702 }
1703
1705 const Communication<Comm>& comm() const { return comm_; }
1706
1707 template <class Data, class InterfaceType, class CommunicationDirection>
1708 void communicate(Data& dataHandle, InterfaceType interface,
1709 CommunicationDirection direction, int level = 0) const {
1710 if (comm().size() <= 1) return;
1711
1712#if HAVE_MPI
1713 if ((interface == InteriorBorder_All_Interface) ||
1714 (interface == All_All_Interface)) {
1715 MMeshCommunication<GridImp, GridImp> communication(partitionHelper_);
1716 const auto& gv = this->leafGridView();
1717
1718 switch (direction) {
1719 case ForwardCommunication:
1720 communication(gv.template begin<0, Interior_Partition>(),
1721 gv.template end<0, Interior_Partition>(),
1722 gv.template begin<0, Ghost_Partition>(),
1723 gv.template end<0, Ghost_Partition>(), dataHandle,
1724 InteriorEntity, GhostEntity,
1725 (interface == All_All_Interface));
1726 break;
1727
1728 case BackwardCommunication:
1729 communication(gv.template begin<0, Ghost_Partition>(),
1730 gv.template end<0, Ghost_Partition>(),
1731 gv.template begin<0, Interior_Partition>(),
1732 gv.template end<0, Interior_Partition>(), dataHandle,
1733 GhostEntity, InteriorEntity,
1734 (interface == All_All_Interface));
1735 break;
1736 }
1737 } else
1738 DUNE_THROW(NotImplemented, "Communication on interface type "
1739 << interface << " not implemented.");
1740#else
1741 DUNE_THROW(NotImplemented, "MPI not found!");
1742#endif // HAVE_MPI
1743 }
1744
1745 // **********************************************************
1746 // End of Interface Methods
1747 // **********************************************************
1748
1750 const HostGrid& getHostGrid() const { return hostgrid_; }
1751
1753 HostGrid& getHostGrid() { return hostgrid_; }
1754
1756 const InterfaceGrid& interfaceGrid() const { return *interfaceGrid_; }
1757
1759 InterfaceGrid& interfaceGrid() { return *interfaceGrid_; }
1760
1762 const auto& interfaceGridPtr() { return interfaceGrid_; }
1763
1764 const ConnectedComponent& getConnectedComponent(const Entity& entity) const {
1765 const auto& it = createdEntityConnectedComponentMap_.find(
1766 this->globalIdSet().id(entity));
1767 assert(it->second < connectedComponents_.size());
1768 assert(it != createdEntityConnectedComponentMap_.end());
1769 assert(connectedComponents_.at(it->second).size() > 0);
1770 return connectedComponents_.at(it->second);
1771 }
1772
1773 const RemeshingIndicator& indicator() const { return indicator_; }
1774
1775 RemeshingIndicator& indicator() { return indicator_; }
1776
1777 const auto& distance() const { return indicator_.distance(); }
1778
1779 int sequence() const { return sequence_; }
1780
1781 const PartitionHelper<GridImp>& partitionHelper() const {
1782 return partitionHelper_;
1783 }
1784
1785 private:
1786 // count how much elements where marked
1787 mutable int coarsenMarked_;
1788 mutable int refineMarked_;
1789 mutable std::size_t componentCount_;
1790
1792 std::unordered_map<IdType, ConnectedComponent> connectedComponents_;
1793
1795 std::unordered_map<IdType, std::size_t> vanishingEntityConnectedComponentMap_;
1796 std::unordered_map<IdType, std::size_t> createdEntityConnectedComponentMap_;
1797
1798 Communication<Comm> comm_;
1799 PartitionHelper<GridImp> partitionHelper_;
1800
1801 std::unique_ptr<MMeshLeafIndexSet<const GridImp>> leafIndexSet_;
1802 std::unique_ptr<MMeshGlobalIdSet<const GridImp>> globalIdSet_;
1803 std::shared_ptr<InterfaceGrid> interfaceGrid_;
1804
1805 std::vector<RefinementInsertionPoint> insert_;
1806 std::unordered_set<IdType> inserted_;
1807 std::vector<VertexHandle> remove_;
1808 std::unordered_set<IdType> removed_;
1809
1811 HostGrid hostgrid_;
1812 BoundarySegments boundarySegments_, localBoundarySegments_;
1813 BoundaryIds boundaryIds_;
1814 InterfaceSegments interfaceSegments_;
1815 RemeshingIndicator indicator_;
1816
1817 static const bool verbose_ = false;
1818 int sequence_ = 0;
1819
1820 private:
1822 bool markElementsForInsertion_(const Edge& edge,
1823 std::size_t& componentNumber) {
1824 ElementOutput elements;
1825 getIncidentToEdge_(edge, elements);
1826
1827 bool markAgain = getComponentNumber_(elements, componentNumber);
1828
1829 // set componentNumber and mightVanish
1830 for (const auto& element : elements) {
1831 element->info().componentNumber = componentNumber;
1832 element->info().mightVanish = true;
1833 }
1834
1835 return markAgain;
1836 }
1837
1839 template <int d = dimension>
1840 std::enable_if_t<d == 2, void> getIncidentToEdge_(
1841 const Edge& edge, ElementOutput& elements) const {
1842 const auto& eh = edge.impl().hostEntity();
1843 elements.push_back(eh.first);
1844 elements.push_back(eh.first->neighbor(eh.second));
1845 }
1846
1847 template <int d = dimension>
1848 std::enable_if_t<d == 3, void> getIncidentToEdge_(
1849 const Edge& edge, ElementOutput& elements) const {
1850 const auto& eh = edge.impl().hostEntity();
1851 auto cit = this->getHostGrid().incident_cells(eh);
1852 for (std::size_t i = 0; i < CGAL::circulator_size(cit); ++i, ++cit)
1853 elements.push_back(cit);
1854 }
1856
1858 bool markElementForInsertion_(const Point& point,
1859 std::size_t& componentNumber) {
1860 ElementOutput elements;
1861 elements.push_back(this->getHostGrid().locate(point));
1862
1863 bool markAgain = getComponentNumber_(elements, componentNumber);
1864
1865 // set componentNumber and mightVanish
1866 for (const auto& element : elements) {
1867 element->info().componentNumber = componentNumber;
1868 element->info().mightVanish = true;
1869 }
1870
1871 return markAgain;
1872 }
1873
1875 void markElementsAfterInsertion_(const HostGridEntity<dimension>& vh,
1876 const std::size_t componentId) {
1877 for (const auto& element : incidentElements(entity(vh))) {
1878 element.impl().hostEntity()->info().isNew = true;
1879 element.impl().hostEntity()->info().componentNumber = componentId + 1;
1880 const IdType id = this->globalIdSet().id(element);
1881 this->createdEntityConnectedComponentMap_.insert(
1882 std::make_pair(id, componentId));
1883 }
1884 }
1885
1887 bool markElementsForRemoval_(const HostGridEntity<dimension>& vh,
1888 std::size_t& componentNumber) {
1889 ElementOutput elements;
1890 for (const auto& element : incidentElements(entity(vh)))
1891 elements.push_back(element.impl().hostEntity());
1892
1893 bool markAgain = getComponentNumber_(elements, componentNumber);
1894
1895 // set componentNumber and mightVanish
1896 for (const auto& element : elements) {
1897 element->info().componentNumber = componentNumber;
1898 element->info().mightVanish = true;
1899 }
1900
1901 return markAgain;
1902 }
1903
1905 void markElementsAfterRemoval_(ElementOutput& elements,
1906 const std::size_t componentId) {
1907 // flag all elements in conflict as mightVanish
1908 for (const auto& element : elements) {
1909 element->info().isNew = true;
1910 element->info().componentNumber = componentId + 1;
1911
1912 const auto id = this->globalIdSet().id(this->entity(element));
1913 this->createdEntityConnectedComponentMap_.insert(
1914 std::make_pair(id, componentId));
1915 }
1916 }
1917
1919 bool getComponentNumber_(const ElementOutput& elements,
1920 std::size_t& componentNumber) const {
1921 bool markAgain = false;
1922 componentNumber = 0;
1923
1924 // search for a componentNumber
1925 for (const auto& element : elements)
1926 if (element->info().componentNumber > 0) {
1927 // check if we find different component numbers
1928 if (componentNumber != 0 &&
1929 element->info().componentNumber != componentNumber) {
1930 markAgain = true;
1931 componentNumber =
1932 std::min(element->info().componentNumber, componentNumber);
1933 } else
1934 componentNumber = element->info().componentNumber;
1935 }
1936
1937 // if no componentNumber was found, create a new one
1938 if (componentNumber == 0) componentNumber = componentCount_++;
1939
1940 return markAgain;
1941 }
1942
1943}; // end Class MMesh
1944
1945// Capabilites of MMesh
1946// --------------------
1947
1949namespace Capabilities {
1953template <class HostGrid, int dim>
1954struct hasSingleGeometryType<MMesh<HostGrid, dim>> {
1955 static const bool v = true;
1956 static const unsigned int topologyId = Dune::GeometryType::simplex;
1957};
1958
1962template <class HostGrid, int dim, int codim>
1963struct canCommunicate<MMesh<HostGrid, dim>, codim> {
1964 static const bool v = false;
1965};
1966
1967template <class HostGrid, int dim>
1968struct canCommunicate<MMesh<HostGrid, dim>, 0> {
1969 static const bool v = true;
1970};
1971
1975template <class HostGrid, int dim, int codim>
1976struct hasEntity<MMesh<HostGrid, dim>, codim> {
1977 static const bool v = (codim >= 0 && codim <= dim);
1978};
1979
1980template <class HostGrid, int dim, int codim>
1981struct hasEntityIterator<MMesh<HostGrid, dim>, codim> {
1982 static const bool v = (codim >= 0 && codim <= dim);
1983};
1984
1988template <class HostGrid, int dim>
1989struct isLevelwiseConforming<MMesh<HostGrid, dim>> {
1990 static const bool v = true;
1991};
1992
1996template <class HostGrid, int dim>
1997struct isLeafwiseConforming<MMesh<HostGrid, dim>> {
1998 static const bool v = true;
1999};
2000
2004template <class HostGrid, int dim>
2005struct hasBackupRestoreFacilities<MMesh<HostGrid, dim>> {
2006 static const bool v = false;
2007};
2008
2009} // end namespace Capabilities
2011
2012} // namespace Dune
2013
2014template <int codim, int dim, class HostGrid>
2015std::ostream& operator<<(
2016 std::ostream& stream,
2017 const Dune::Entity<codim, dim, const Dune::MMesh<HostGrid, dim>,
2018 Dune::MMeshEntity>& entity) {
2019 return stream << "MMeshEntity<codim=" << codim << ", dim=" << dim
2020 << ", center=(" << entity.geometry().center() << ")>";
2021}
2022
2023#include "../interface/grid.hh"
2024#include "../misc/capabilities.hh"
2025#include "../misc/persistentcontainer.hh"
2026#include "dgfparser.hh"
2027#include "gmshgridfactory.hh"
2028#include "gmshreader.hh"
2029#include "gridfactory.hh"
2030#include "structuredgridfactory.hh"
2031
2032#endif // DUNE_MMESH_GRID_MMESH_HH
Class defining a longest edge refinement strategy.
Definition: longestedgerefinement.hh:23
static auto refinement(const Element &element)
Returns the refinement/coarsening point for each grid cell.
Definition: longestedgerefinement.hh:42
static int boundaryFlag(const Vertex &v)
return if vertex is removable at the boundary
Definition: longestedgerefinement.hh:124
static Vertex coarsening(const Element &element)
return coarsening vertex (vertex of shortest edge)
Definition: longestedgerefinement.hh:65
static bool isRemoveable(const Vertex &vertex)
return if interface vertex is neither a tip nor a junction
Definition: longestedgerefinement.hh:155
The implementation of a connected component of entities in MMeshThe connected component stores a list...
Definition: connectedcomponent.hh:33
The implementation of entities in a MMesh.
Definition: entity.hh:50
The implementation of connected components in a MMeshInterfaceGridThe connected component copies the ...
Definition: connectedcomponent.hh:31
Provides a DUNE grid interface class for the interface of a MMesh interface grid .
Definition: grid.hh:90
const MMeshInterfaceGridLeafIndexSet< const GridImp > & leafIndexSet() const
Access to the LeafIndexSet.
Definition: grid.hh:236
int getMark(const typename Traits::template Codim< 0 >::Entity &e) const
Return refinement mark for entity.
Definition: grid.hh:369
Traits::template Codim< EntitySeed::codimension >::Entity entity(const EntitySeed &seed) const
Create Entity from EntitySeed.
Definition: grid.hh:242
std::enable_if_t< d==2, const MMeshInterfaceEntity< 0 > > mirrorHostEntity(const MMeshInterfaceEntity< 0 > &other) const
Mirror a host entity (2d)
Definition: grid.hh:602
An intersection with a leaf neighbor elementMesh entities of codimension 0 ("elements") allow to visi...
Definition: intersections.hh:35
Iterator over all entities of a given codimension and level of a grid (2D).
Definition: leafiterator.hh:21
The MMesh class templatized by the CGAL host grid type and the dimension. .
Definition: mmesh.hh:158
Dune::FieldVector< FieldType, dimension > GlobalCoordinate
The type used for coordinates.
Definition: mmesh.hh:204
const MMeshLeafIndexSet< const GridImp > & leafIndexSet() const
Access to the LeafIndexSet.
Definition: mmesh.hh:438
typename HostGrid::Point Point
The point type.
Definition: mmesh.hh:170
std::enable_if_t< d==3, bool > isInterface(const Edge &edge) const
Return if edge in 3d is part of an interface segment.
Definition: mmesh.hh:625
void globalRefine(int steps=1)
Global refine.
Definition: mmesh.hh:709
MMeshCachingEntity< 0, dimension, const GridImp > CachingEntity
The type of a caching entity.
Definition: mmesh.hh:242
std::list< HostGridEntity< 0 > > ElementOutput
The type of the element output.
Definition: mmesh.hh:224
Intersection asIntersection(const Facet &facet) const
Return a facet as intersection.
Definition: mmesh.hh:681
bool isInterface(const OtherIntersection &intersection) const
Return if intersection is part of the interface.
Definition: mmesh.hh:602
MMeshInterfaceVertexIterator< const GridImp > interfaceVerticesBegin(bool includeBoundary=false) const
iterator to first interface entity
Definition: mmesh.hh:573
bool preAdapt()
returns false, if at least one entity is marked for adaption
Definition: mmesh.hh:762
InterfaceEntity asInterfaceEntity(const Intersection &intersection) const
Return an intersection as a interface grid codim 0 entity.
Definition: mmesh.hh:662
std::unordered_map< IdType, std::size_t > InterfaceSegments
The interface segment set.
Definition: mmesh.hh:185
void update()
update the grid indices and ids
Definition: mmesh.hh:309
HostGridEntity< 0 > ElementHandle
The type of the underlying element handle.
Definition: mmesh.hh:212
Traits::template Codim< codim >::LeafIterator leafend() const
one past the end of the sequence of leaf entities
Definition: mmesh.hh:513
const InterfaceGrid & interfaceGrid() const
Get reference to the interface grid.
Definition: mmesh.hh:1756
typename HostGridEntityChooser_< HostGridType, dimension, cd >::type HostGridEntity
The type of the underlying entities.
Definition: mmesh.hh:209
MMesh(HostGrid hostgrid)
Constructor that takes a CGAL triangulation.
Definition: mmesh.hh:279
void removeVertex(const Vertex &vertex)
Remove vertex manually.
Definition: mmesh.hh:814
int size(int level, int codim) const
Number of grid entities per level and codim.
Definition: mmesh.hh:348
bool mark(int refCount, const typename Traits::template Codim< 0 >::Entity &e) const
Mark entity for refinement.
Definition: mmesh.hh:725
const HostGrid & getHostGrid() const
Get reference to the underlying CGAL triangulation.
Definition: mmesh.hh:1750
bool loadBalance(const T &t)
Distributes this grid over the available nodes in a distributed machine.
Definition: mmesh.hh:1695
Traits::template Codim< codim >::LeafIterator leafbegin() const
Iterator to first leaf entity of given codim.
Definition: mmesh.hh:507
bool isOnInterface(const Entity &entity) const
Return if entity shares a facet with the interface.
Definition: mmesh.hh:649
HostGridEntity< dimension > VertexHandle
The type of the underlying vertex handle.
Definition: mmesh.hh:221
const auto & interfaceGridPtr()
Get a pointer to the interface grid.
Definition: mmesh.hh:1762
unsigned int overlapSize(int codim) const
Size of the overlap on the leaf level.
Definition: mmesh.hh:1649
typename Traits::template Codim< 0 >::Entity Entity
The type of a codim 0 entity.
Definition: mmesh.hh:230
const MMeshLeafIndexSet< const GridImp > & levelIndexSet(int level) const
Access to the LevelIndexSets.
Definition: mmesh.hh:430
unsigned int ghostSize(int codim) const
Size of the ghost cell layer on the leaf level.
Definition: mmesh.hh:1652
const InterfaceSegments & interfaceSegments() const
returns the interface segment set
Definition: mmesh.hh:366
MMeshConnectedComponent< const GridImp > ConnectedComponent
The type used to store connected components of entities.
Definition: mmesh.hh:245
typename InterfaceGrid::Traits::template Codim< 0 >::Entity InterfaceEntity
The type of an interface grid entity.
Definition: mmesh.hh:258
int size(GeometryType type) const
number of leaf entities per codim and geometry type in this process
Definition: mmesh.hh:417
const BoundarySegments & boundarySegments() const
returns the boundary segment to index map
Definition: mmesh.hh:358
MMeshInterfaceIterator< codim, const GridImp > interfaceEnd(bool includeBoundary=false) const
one past the end of the sequence of interface entities
Definition: mmesh.hh:564
typename GridFamily::Traits::Grid GridImp
The grid implementation.
Definition: mmesh.hh:195
int getMark(const typename Traits::template Codim< 0 >::Entity &e) const
Return refinement mark for entity.
Definition: mmesh.hh:757
typename Traits::template Codim< 1 >::Entity Facet
The type of a codim 1 entity ('facet')
Definition: mmesh.hh:233
bool adapt()
Triggers the grid adaptation process.
Definition: mmesh.hh:826
Traits::template Codim< codim >::template Partition< PiType >::LeafIterator leafend() const
one past the end of the sequence of leaf entities
Definition: mmesh.hh:529
Traits::template Codim< codim >::LevelIterator lbegin(int level) const
Iterator to first entity of given codim on level.
Definition: mmesh.hh:478
Traits::template Codim< EntitySeed::codimension >::Entity entity(const EntitySeed &seed) const
Create Entity from EntitySeed.
Definition: mmesh.hh:444
std::list< FacetHandle > BoundaryEdgesOutput
The type of the boundary edges output.
Definition: mmesh.hh:227
InterfaceSegments & interfaceSegments()
returns the interface segment set
Definition: mmesh.hh:371
InterfaceGrid & interfaceGrid()
Get a non-const reference to the interface grid.
Definition: mmesh.hh:1759
int size(int level, GeometryType type) const
number of entities per level, codim and geometry type in this process
Definition: mmesh.hh:410
typename GridFamily::Traits Traits
The Traits.
Definition: mmesh.hh:192
static constexpr int dimension
The world dimension.
Definition: mmesh.hh:161
bool isInterface(const Intersection &intersection) const
Return if intersection is part of the interface.
Definition: mmesh.hh:596
typename Traits::template Codim< 1 >::Entity InterfaceElement
The type of an interface element.
Definition: mmesh.hh:248
HostGrid & getHostGrid()
Get non-const reference to the underlying CGAL triangulation.
Definition: mmesh.hh:1753
typename Traits::template Codim< 0 >::LeafIterator LeafIterator
The leaf iterator.
Definition: mmesh.hh:201
void addToInterface(const Vertex &vertex, const GlobalCoordinate &p)
Definition: mmesh.hh:1435
const Communication< Comm > & comm() const
Communication.
Definition: mmesh.hh:1705
void addInterface(const Intersection &intersection, const std::size_t marker=1)
Add an intersection to the interface.
Definition: mmesh.hh:374
bool adapt(AdaptDataHandleInterface< GridImp, DataHandle > &handle)
Callback for the grid adaptation process with restrict/prolong.
Definition: mmesh.hh:1138
MMeshInterfaceConnectedComponent< const InterfaceGrid > InterfaceGridConnectedComponent
The type of a connected component of interface grid entities.
Definition: mmesh.hh:262
bool isInterface(const Vertex &vertex) const
Return if vertex is part of the interface.
Definition: mmesh.hh:591
RatioIndicator< GridImp > RemeshingIndicator
The type of the employed remeshing indicator.
Definition: mmesh.hh:270
bool isInterface(const InterfaceElement &segment) const
Return if element is part of the interface.
Definition: mmesh.hh:607
bool ensureVertexMovement(std::vector< GlobalCoordinate > shifts)
Mark elements such that after movement of vertices no cell degenerates.
Definition: mmesh.hh:1094
HostGrid HostGridType
The hostgrid type.
Definition: mmesh.hh:164
void loadBalance()
Distributes this grid over the available nodes in a distributed machine.
Definition: mmesh.hh:1683
Traits::template Codim< codim >::template Partition< PiType >::LevelIterator lend(int level) const
one past the end on this level
Definition: mmesh.hh:501
typename Traits::template Codim< dimension - 1 >::Entity Edge
The type of a codim dim-1 entity ('edge')
Definition: mmesh.hh:236
MMesh(HostGrid hostgrid, BoundarySegments boundarySegments, BoundarySegments interfaceBoundarySegments, BoundaryIds boundaryIds, InterfaceSegments interfaceSegments)
Constructor that takes additional about interface and boundary.
Definition: mmesh.hh:282
const GridImp * This() const
This pointer to derived class.
Definition: mmesh.hh:304
Traits::template Codim< codim >::template Partition< PiType >::LevelIterator lbegin(int level) const
Iterator to first entity of given codim on level.
Definition: mmesh.hh:493
Intersection asIntersection(const InterfaceEntity &interfaceEntity) const
Return an interface entity as intersection of a MMesh entity.
Definition: mmesh.hh:675
bool ensureInterfaceMovement(std::vector< GlobalCoordinate > shifts)
Mark elements such that after movement of interface vertices no cell degenerates.
Definition: mmesh.hh:920
const Traits::LocalIdSet & localIdSet() const
Access to the LocalIdSet.
Definition: mmesh.hh:425
void insertVertexInCell(const GlobalCoordinate &position)
Insert vertex in cell manually.
Definition: mmesh.hh:796
void refineEdge(const Entity &entity, const std::size_t edgeIndex, const double where=0.5)
Refine edge manually.
Definition: mmesh.hh:768
typename Traits::template Codim< dimension >::Entity Vertex
The type of a codim dim entity ('vertex')
Definition: mmesh.hh:239
void removeVertex(const typename InterfaceGrid::Traits::template Codim< dim - 1 >::Entity &interfaceVertex)
Remove interface vertex manually.
Definition: mmesh.hh:806
size_t numBoundarySegments() const
returns the number of boundary segments within the macro grid
Definition: mmesh.hh:355
int maxLevel() const
Return maximum level defined in this grid.
Definition: mmesh.hh:344
Vertex entity(const HostGridEntity< dimension > &vertexHandle) const
Return the entity corresponding to a vertex handle.
Definition: mmesh.hh:455
void addInterface(const I &intersection, const std::size_t marker=1)
Add wrapped intersection to the interface.
Definition: mmesh.hh:402
HostGridEntity< 1 > FacetHandle
The type of the underlying edge handle.
Definition: mmesh.hh:215
unsigned int ghostSize(int level, int codim) const
Size of the ghost cell layer on a given level.
Definition: mmesh.hh:1676
const Traits::GlobalIdSet & globalIdSet() const
Access to the GlobalIdSet.
Definition: mmesh.hh:420
void postAdapt()
Clean up refinement markers.
Definition: mmesh.hh:1456
MMeshInterfaceIterator< codim, const GridImp > interfaceBegin(bool includeBoundary=false) const
iterator to first interface entity
Definition: mmesh.hh:555
MMeshInterfaceVertexIterator< const GridImp > interfaceVerticesEnd(bool includeBoundary=false) const
one past the end of the sequence of interface entities
Definition: mmesh.hh:582
InterfaceEntity asInterfaceEntity(const OtherIntersection &intersection) const
Return an intersection as a interface grid codim 0 entity.
Definition: mmesh.hh:669
bool markElements()
Mark elements for adaption using the default remeshing indicator.
Definition: mmesh.hh:736
typename Point::R::RT FieldType
The field type.
Definition: mmesh.hh:173
typename Traits::LeafIntersection Intersection
The type of an intersection.
Definition: mmesh.hh:251
Traits::template Codim< codim >::LevelIterator lend(int level) const
one past the end on this level
Definition: mmesh.hh:485
MMeshImpl::MultiId IdType
The type of an id.
Definition: mmesh.hh:176
HostGridEntity< dimension - 1 > EdgeHandle
The type of the underlying edge handle.
Definition: mmesh.hh:218
void moveVertices(const std::vector< GlobalCoordinate > &shifts)
Move vertices.
Definition: mmesh.hh:1421
std::unordered_map< IdType, std::size_t > BoundarySegments
The boundary segment map.
Definition: mmesh.hh:179
MMeshFamily< dim, HostGrid > GridFamily
The grid family type.
Definition: mmesh.hh:167
const BoundaryIds & boundaryIds() const
returns the boundary segment index to boundary id map
Definition: mmesh.hh:363
void moveInterface(const std::vector< GlobalCoordinate > &shifts)
Move interface vertices.
Definition: mmesh.hh:1407
const Entity locate(const GlobalCoordinate &p, const Entity &element={}) const
Locate an entity by coordinate using CGAL's locate.
Definition: mmesh.hh:699
InterfaceEntity asInterfaceEntity(const InterfaceElement &segment) const
Return a codim 1 entity as a interface grid codim 0 entity.
Definition: mmesh.hh:657
unsigned int overlapSize(int level, int codim) const
Size of the overlap on a given level.
Definition: mmesh.hh:1671
std::unique_ptr< GridImp > GridPtrType
The unique pointer to the grid.
Definition: mmesh.hh:198
Entity entity(const HostGridEntity< 0 > &elementHandle) const
Return the entity corresponding to a element handle.
Definition: mmesh.hh:461
RefinementInsertionPointStruct< Point, Edge, IdType, VertexHandle, InterfaceGridConnectedComponent > RefinementInsertionPoint
The type of a refinement insertion point.
Definition: mmesh.hh:267
Intersection asIntersection(const FacetHandle &host) const
Return a host facet as intersection.
Definition: mmesh.hh:687
int size(int codim) const
number of leaf entities per codim in this process
Definition: mmesh.hh:407
Traits::template Codim< codim >::template Partition< PiType >::LeafIterator leafbegin() const
Iterator to first leaf entity of given codim.
Definition: mmesh.hh:521
std::unordered_map< std::size_t, std::size_t > BoundaryIds
The boundary id map.
Definition: mmesh.hh:182
void init(const Grid &grid)
Definition: ratioindicator.hh:62
void update()
Update the distances of all vertices.
Definition: ratioindicator.hh:94
const DistanceType & distance() const
Returns distance object.
Definition: ratioindicator.hh:185
The CutSetTriangulation class This class computes the overlapping polytope of to intersecting triangl...
Some common helper methods.
The MMeshInterfaceConnectedComponent class.
The MMeshInterfaceGridEntity class.
The MMeshInterfaceGridEntitySeed class.
The MMeshInterfaceGridGeometry class and its specializations Inherits from Dune::AffineGeometry.
The MMeshInterfaceGridHierarchicIterator class.
The MMeshIncidentIterator class.
The index and id sets for the MMesh class.
The intersection iterator for the MMesh class.
The MMeshInterfaceGridLeafIterator class.
The MMeshInterfaceIterator class.
EntityIterator< Grid::dimension, Grid, MMeshInterfaceVertexIteratorImp< Grid, Grid::dimension > > MMeshInterfaceVertexIterator
The Entity Iterator alias.
Definition: interfaceiterator.hh:174
EntityIterator< codim, Grid, MMeshInterfaceIteratorImp< codim, Grid, Grid::dimension > > MMeshInterfaceIterator
The Entity Iterator alias.
Definition: interfaceiterator.hh:22
Helpers for conversion from CGAL::Point_x to DUNE::FieldVector.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Mar 16, 23:47, 2025)