1 #ifndef DUNE_FEM_GRIDPART_FILTEREDGRIDPART_HH
2 #define DUNE_FEM_GRIDPART_FILTEREDGRIDPART_HH
3 
4 //- system includes
5 #include <cassert>
6 #include <memory>
7 
8 //- dune-grid includes
9 #include <dune/grid/common/datahandleif.hh>
10 #include <dune/grid/common/gridview.hh>
11 
12 //- dune-fem includes
13 #include <dune/fem/gridpart/adaptiveleafindexset.hh>
14 #include <dune/fem/gridpart/common/gridpart.hh>
15 #include <dune/fem/gridpart/common/metatwistutility.hh>
16 #include <dune/fem/gridpart/filteredgridpart/capabilities.hh>
17 #include <dune/fem/gridpart/filteredgridpart/datahandle.hh>
18 #include <dune/fem/gridpart/filteredgridpart/intersection.hh>
19 #include <dune/fem/gridpart/filteredgridpart/intersectioniterator.hh>
20 #include <dune/fem/gridpart/filteredgridpart/iterator.hh>
21 
22 
23 namespace Dune
24 {
25 
26   namespace Fem
27   {
28 
29     // Forward declarations
30     // --------------------
31 
32     template< class HostGridPartImp, class FilterImp, bool useFilteredIndexSet = false >
33     class FilteredGridPart;
34 
35 
36 
37     // FilteredGridPartIndexSetSelector
38     // --------------------------------
39 
40     template < class FilteredGP, class HostGP, bool useFilteredIndexSet >
41     struct FilteredGridPartIndexSetSelector
42     {
43       typedef AdaptiveLeafIndexSet< FilteredGP > IndexSetType;
44 
createDune::Fem::FilteredGridPartIndexSetSelector45       static IndexSetType *create(const FilteredGP &gridPart)
46       {
47         return new IndexSetType( gridPart );
48       }
49 
50       template < class IndexSetPtr >
51       static const IndexSetType&
indexSetDune::Fem::FilteredGridPartIndexSetSelector52       indexSet ( const FilteredGP &gridPart, const std::unique_ptr< IndexSetPtr >& idxSetPtr )
53       {
54         assert( idxSetPtr );
55         return *idxSetPtr;
56       }
57     };
58 
59 
60     // FilteredGridPartIndexSetSelector
61     // specialization for non-filtered index set,
62     // i.e. host index set
63     // -----------------------------------------
64 
65     template< class FilteredGP, class HostGP >
66     struct FilteredGridPartIndexSetSelector< FilteredGP, HostGP, false >
67     {
68       typedef typename HostGP::IndexSetType IndexSetType;
69 
createDune::Fem::FilteredGridPartIndexSetSelector70       static IndexSetType *create(const FilteredGP &gridPart)
71       {
72         return nullptr;
73       }
74 
75       template < class IndexSetPtr >
76       static const IndexSetType&
indexSetDune::Fem::FilteredGridPartIndexSetSelector77       indexSet ( const FilteredGP &gridPart, const std::unique_ptr< IndexSetPtr >& )
78       {
79         return gridPart.hostGridPart().indexSet();
80       }
81     };
82 
83 
84 
85     // EntityGridTypeGetter
86     // --------------------
87 
88     template< class Entity >
89     struct EntityGridTypeGetter;
90 
91     template< int codim, int dim, class Grid, template< int, int, class > class Impl >
92     struct EntityGridTypeGetter< Dune::Entity< codim, dim, Grid, Impl > >
93     {
94       typedef Grid Type;
95     };
96 
97     template< class Entity >
98     struct EntityGridTypeGetter< const Entity >
99     {
100       typedef typename EntityGridTypeGetter< Entity >::Type Type;
101     };
102 
103 
104 
105     // FilteredGridPartTraits
106     // ----------------------
107 
108     template< class HostGridPartImp, class FilterImp, bool useFilteredIndexSet >
109     struct FilteredGridPartTraits
110     {
111       //! \brief type of grid part
112       typedef FilteredGridPart< HostGridPartImp, FilterImp, useFilteredIndexSet > GridPartType;
113 
114       struct GridPartFamily
115       {
116         typedef FilterImp Filter;
117         typedef HostGridPartImp HostGridPart;
118 
119         static const int dimension = HostGridPart::dimension;
120         static const int dimensionworld = HostGridPart::dimensionworld;
121 
122         typedef typename HostGridPart::ctype ctype;
123 
124         typedef FilteredGridPartIntersectionIterator< const GridPartFamily > IntersectionIteratorImpl;
125         typedef FilteredGridPartIntersection< Filter, typename HostGridPart::IntersectionType > IntersectionImpl;
126 
127         typedef Dune::IntersectionIterator< const GridPartFamily, IntersectionIteratorImpl, IntersectionImpl > IntersectionIterator;
128         typedef Dune::Intersection< const GridPartFamily, IntersectionImpl > Intersection;
129 
130         template< int codim >
131         struct Codim
132         {
133           typedef typename HostGridPart::template Codim< codim >::GeometryType Geometry;
134           typedef typename HostGridPart::template Codim< codim >::LocalGeometryType LocalGeometry;
135 
136           typedef typename HostGridPart::template Codim< codim >::EntityType Entity;
137           typedef typename HostGridPart::template Codim< codim >::EntitySeedType EntitySeed;
138         };
139       };
140 
141       //! \brief grid part imp
142       typedef HostGridPartImp HostGridPartType;
143 
144       //! \brief type of grid
145       typedef typename HostGridPartType::GridType GridType;
146 
147       /** \brief The type of the corresponding TwistUtility */
148       typedef MetaTwistUtility< typename HostGridPartType :: TwistUtilityType >  TwistUtilityType ;
149 
150       //! \brief export filter type
151       typedef FilterImp FilterType;
152 
153       //! \brief type of entity
154       typedef typename FilterType::EntityType EntityType;
155 
156       //! \brief index set use in this gridpart
157       typedef FilteredGridPartIndexSetSelector< GridPartType, HostGridPartType, useFilteredIndexSet > IndexSetSelectorType;
158 
159       //! \brief index set use in this gridpart
160       typedef typename IndexSetSelectorType::IndexSetType IndexSetType;
161 
162       //! \brief of host grid part intersection iterator type
163       typedef typename HostGridPartType::Traits::IntersectionIteratorType HostIntersectionIteratorType;
164 
165       //! \brief type of intersection iterator
166       typedef typename GridPartFamily::IntersectionIterator IntersectionIteratorType;
167 
168       //! \brief type of intersection
169       typedef typename GridPartFamily::Intersection IntersectionType;
170 
171       //! \brief struct providing types of the iterators on codimension cd
172       template< int codim >
173       struct Codim
174       {
175         typedef typename HostGridPartType::template Codim< codim >::GeometryType GeometryType;
176         typedef typename HostGridPartType::template Codim< codim >::LocalGeometryType LocalGeometryType;
177 
178         typedef typename HostGridPartType::template Codim< codim >::EntityType EntityType;
179         typedef typename HostGridPartType::template Codim< codim >::EntitySeedType EntitySeedType;
180 
181         template< PartitionIteratorType pitype >
182         struct Partition
183         {
184           typedef Dune::EntityIterator< codim, typename EntityGridTypeGetter< EntityType >::Type, FilteredGridPartIterator< codim, pitype, GridPartType > > IteratorType;
185         };
186 
187         typedef typename Partition< InteriorBorder_Partition >::IteratorType IteratorType;
188       };
189 
190       typedef typename HostGridPartType::CollectiveCommunicationType CollectiveCommunicationType;
191 
192       //! \brief maximum partition type, the index set provides indices for
193       static const PartitionIteratorType indexSetPartitionType = HostGridPartType::indexSetPartitionType;
194 
195       static const InterfaceType indexSetInterfaceType = HostGridPartType::indexSetInterfaceType;
196 
197       //! \brief is true if grid on this view only has conforming intersections
198       static const bool conforming = HostGridPartType::Traits::conforming;
199     };
200 
201 
202 
203     //***************************************************************************
204     //
205     // FilteredGridPart
206     //
207     /** @addtogroup FilterGridPart
208      A FilteredGridPart is a subset of a GridPart and a GridPart itself.
209      The entities that belong to the FilteredGrid are defined by a
210      filter class.
211 
212      Note that codim 0 entities have a method hasBoundaryIntersection().
213      In general, this method will be inconsistent with the intersections
214      returned by the filtered gridpart since entities are not wrapped.
215     **/
216 
217     /** @ingroup FilterGridPart
218      @brief
219      A FilteredGridPart allows to extract a set of entities from a grid
220      satisfying a given constrainted defined through a filter class.
221     **/
222 
223 
224     template< class HostGridPartImp, class FilterImp, bool useFilteredIndexSet >
225     class FilteredGridPart
226     : public GridPartInterface< FilteredGridPartTraits< HostGridPartImp, FilterImp, useFilteredIndexSet > >
227     , public AddGridView< FilteredGridPartTraits< HostGridPartImp, FilterImp, useFilteredIndexSet > >
228     {
229       // type of this
230       typedef FilteredGridPart< HostGridPartImp, FilterImp, useFilteredIndexSet > ThisType;
231       typedef AddGridView< FilteredGridPartTraits< HostGridPartImp, FilterImp, useFilteredIndexSet > > AddGridViewType;
232 
233     public:
234       //- Public typedefs and enums
235       //! \brief traits class
236       typedef FilteredGridPartTraits< HostGridPartImp, FilterImp, useFilteredIndexSet > Traits;
237 
238       //! \brief type of filter
239       typedef FilterImp FilterType;
240 
241       // type of host grid part
242       typedef typename Traits::HostGridPartType HostGridPartType;
243 
244       //! \brief grid type
245       typedef typename Traits::GridType GridType;
246 
247       //! \brief index set type
248       typedef typename Traits::IndexSetType IndexSetType;
249 
250       //! \brief intersection iterator type
251       typedef typename Traits:: IntersectionIteratorType IntersectionIteratorType;
252 
253       //! \brief intersection type
254       typedef typename IntersectionIteratorType::Intersection IntersectionType;
255 
256       typedef typename Traits::CollectiveCommunicationType CollectiveCommunicationType;
257 
258       typedef typename AddGridViewType::GridViewType GridViewType;
259 
260       //! \brief grid part typedefs, use those of traits
261       template< int codim >
262       struct Codim : public Traits :: template Codim< codim >
263       {};
264 
265     private:
266       typedef typename Traits::IndexSetSelectorType IndexSetSelectorType;
267 
268       typedef typename Codim< 0 >::EntityType EntityType;
269 
270     public:
271       //- Public methods
272       //! \brief constructor
FilteredGridPart(HostGridPartType & hostGridPart,const FilterType & filter)273       FilteredGridPart ( HostGridPartType &hostGridPart, const FilterType &filter )
274       : AddGridViewType( this ),
275         hostGridPart_( hostGridPart ),
276         filter_( filter ),
277         indexSetPtr_( IndexSetSelectorType::create( *this ) )
278       {
279       }
280 
FilteredGridPart(HostGridPartType & hostGridPart,const FilterType & filter,const GridViewType * gridView)281       FilteredGridPart ( HostGridPartType &hostGridPart, const FilterType &filter, const GridViewType *gridView)
282       : AddGridViewType( gridView ),
283         hostGridPart_( hostGridPart ),
284         filter_( filter ),
285         indexSetPtr_( IndexSetSelectorType::create( *this ) )
286       {
287       }
288 
289       //! \brief copy constructor
FilteredGridPart(const FilteredGridPart & other)290       FilteredGridPart ( const FilteredGridPart &other )
291       : AddGridViewType( other ),
292         hostGridPart_( other.hostGridPart_ ),
293         filter_( other.filter_ ),
294         indexSetPtr_ ( IndexSetSelectorType::create( *this ) )
295       { }
296 
297       //! \brief return const reference to underlying grid
grid() const298       const GridType &grid () const
299       {
300         return hostGridPart().grid();
301       }
302 
303       //! \brief return reference to underlying grid
grid()304       GridType &grid ()
305       {
306         return hostGridPart().grid();
307       }
308 
309       //! \brief return index set of this grid part
310       //         if IndexSetType is from host grid part the original index set is returned
indexSet() const311       const IndexSetType &indexSet() const
312       {
313         return IndexSetSelectorType::indexSet( *this, indexSetPtr_ );
314       }
315 
316       //! \brief Begin iterator on the leaf level
317       template< int codim >
begin() const318       typename Codim< codim >::IteratorType begin () const
319       {
320         return begin< codim, InteriorBorder_Partition >();
321       }
322 
323       //! \brief Begin iterator on the leaf level
324       template< int codim, PartitionIteratorType pitype >
begin() const325       typename Codim< codim >::template Partition< pitype >::IteratorType begin () const
326       {
327         typedef typename Codim< codim >::template Partition< pitype >::IteratorType IteratorType;
328         typedef FilteredGridPartIterator< codim, pitype, ThisType > IteratorImpl;
329         return IteratorType( IteratorImpl( *this, hostGridPart().template begin< codim, pitype >() ) );
330       }
331 
332       //! \brief Begin iterator on the leaf level
333       template< int codim >
end() const334       typename Codim< codim >::IteratorType end () const
335       {
336         return end< codim, InteriorBorder_Partition >();
337       }
338 
339       //! \brief End iterator on the leaf level
340       template< int codim, PartitionIteratorType pitype >
end() const341       typename Codim< codim >::template Partition< pitype >::IteratorType end () const
342       {
343         typedef typename Codim< codim >::template Partition< pitype >::IteratorType IteratorType;
344         typedef FilteredGridPartIterator< codim, pitype, ThisType > IteratorImpl;
345         return IteratorType( IteratorImpl( *this, hostGridPart().template end< codim, pitype >() ) );
346       }
347 
348       //! \brief Returns maxlevel of the grid
level() const349       int level () const
350       {
351         return hostGridPart().level();
352       }
353 
354       //! \brief ibegin of corresponding intersection iterator for given entity
ibegin(const EntityType & entity) const355       IntersectionIteratorType ibegin ( const EntityType &entity ) const
356       {
357         typedef typename IntersectionIteratorType::Implementation IntersectionIteratorImpl;
358         return IntersectionIteratorType( IntersectionIteratorImpl( filter(), hostGridPart().ibegin( entity ) ) );
359       }
360 
361       //! \brief iend of corresponding intersection iterator for given entity
iend(const EntityType & entity) const362       IntersectionIteratorType iend ( const EntityType &entity ) const
363       {
364         typedef typename IntersectionIteratorType::Implementation IntersectionIteratorImpl;
365         return IntersectionIteratorType( IntersectionIteratorImpl( filter(), hostGridPart().iend( entity ) ) );
366       }
367 
368       //! \brief boundary id
boundaryId(const IntersectionType & intersection) const369       int boundaryId ( const IntersectionType &intersection ) const
370       {
371         return hostGridPart().boundaryId( intersection.impl().hostIntersection() );
372       }
373 
comm() const374       const CollectiveCommunicationType &comm () const { return hostGridPart_.comm(); }
375 
376       //! \brief corresponding communication method for this grid part
377       template < class DataHandleImp, class DataType >
communicate(CommDataHandleIF<DataHandleImp,DataType> & dataHandle,InterfaceType iftype,CommunicationDirection dir) const378       void communicate ( CommDataHandleIF< DataHandleImp, DataType > &dataHandle,
379                          InterfaceType iftype, CommunicationDirection dir ) const
380       {
381         typedef CommDataHandleIF< DataHandleImp, DataType >  HostHandleType;
382         FilteredGridPartDataHandle< HostHandleType, ThisType > handleWrapper( dataHandle, *this );
383         hostGridPart().communicate( handleWrapper, iftype, dir );
384       }
385 
386       /** \copydoc GridPartInterface::entity(const EntitySeed &seed) const */
387       template < class EntitySeed >
388       typename Codim< EntitySeed::codimension >::EntityType
entity(const EntitySeed & seed) const389       entity ( const EntitySeed &seed ) const
390       {
391         return hostGridPart().entity( seed );
392       }
393 
394       //! \brief return reference to filter
filter() const395       const FilterType &filter () const
396       {
397         return filter_;
398       }
399 
400       //! \brief return reference to filter
filter()401       FilterType &filter ()
402       {
403         return filter_;
404       }
405 
406       template< class Entity >
contains(const Entity & entity) const407       bool contains ( const Entity &entity ) const
408       {
409         return filter().contains( entity );
410       }
411 
hostGridPart()412       HostGridPartType &hostGridPart ()
413       {
414         return hostGridPart_;
415       }
416 
hostGridPart() const417       const HostGridPartType &hostGridPart () const
418       {
419         return hostGridPart_;
420       }
421 
422       /** \copydoc GridPartInterface::convert(const Entity &entity) const */
423       template <class Entity>
convert(const Entity & entity) const424       const Entity& convert ( const Entity &entity ) const
425       {
426         return hostGridPart().convert( entity );
427       }
428 
429     private:
430       HostGridPartType &hostGridPart_;
431       FilterType filter_;
432       std::unique_ptr< IndexSetType > indexSetPtr_;
433     };
434 
435   } // namespace Fem
436 
437 } // namespace Dune
438 
439 #endif // #ifndef DUNE_FEM_GRIDPART_FILTEREDGRIDPART_HH
440