Loading [MathJax]/extensions/tex2jax.js

dune-mmesh (1.4)

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