34 #include <boost/multi_index_container.hpp>
35 #include <boost/multi_index/member.hpp>
36 #include <boost/multi_index/composite_key.hpp>
37 #include <boost/multi_index/mem_fun.hpp>
38 #include <boost/multi_index/ordered_index.hpp>
40 #include <feel/feelmesh/geoelement.hpp>
45 namespace multi_index = boost::multi_index;
55 template<
typename EntityType,
typename ElementType>
64 typedef typename mpl::if_<mpl::equal_to<mpl::int_<EntityType::nDim>, mpl::int_<EntityType::nRealDim-1> >,
65 mpl::identity<typename mpl::if_<mpl::equal_to<mpl::int_<EntityType::nDim>, mpl::int_<0> >,
66 mpl::identity<GeoElement0D<EntityType::nRealDim, SubFaceOf<ElementType> > >,
67 typename mpl::if_<mpl::equal_to<mpl::int_<EntityType::nDim>, mpl::int_<1> >,
68 mpl::identity<GeoElement1D<EntityType::nRealDim, EntityType, SubFaceOf<ElementType> > >,
69 mpl::identity<GeoElement2D<EntityType::nRealDim, EntityType, SubFaceOf<ElementType> > >
71 mpl::identity<typename mpl::if_<mpl::equal_to<mpl::int_<EntityType::nDim>, mpl::int_<0> >,
72 mpl::identity<GeoElement0D<EntityType::nRealDim, SubFaceOfMany<ElementType> > >,
73 typename mpl::if_<mpl::equal_to<mpl::int_<EntityType::nDim>, mpl::int_<1> >,
74 mpl::identity<GeoElement1D<EntityType::nRealDim, EntityType, SubFaceOfMany<ElementType> > >,
75 mpl::identity<GeoElement2D<EntityType::nRealDim, EntityType, SubFaceOfMany<ElementType> > >
76 >::type>::type> >::type::type::type face_type;
78 typedef multi_index::multi_index_container<
80 multi_index::indexed_by<
83 multi_index::ordered_unique<multi_index::identity<face_type> >,
85 multi_index::ordered_unique<
86 multi_index::composite_key<face_type,
87 multi_index::const_mem_fun<face_type,
89 &face_type::processId>,
90 multi_index::const_mem_fun<face_type,
96 multi_index::ordered_non_unique<multi_index::tag<detail::by_marker>,
97 multi_index::composite_key<
99 multi_index::const_mem_fun<face_type,
102 multi_index::const_mem_fun<face_type,
104 &face_type::processId>
106 multi_index::ordered_non_unique<multi_index::tag<detail::by_marker2>,
107 multi_index::composite_key<
109 multi_index::const_mem_fun<face_type,
111 &face_type::marker2>,
112 multi_index::const_mem_fun<face_type,
114 &face_type::processId>
116 multi_index::ordered_non_unique<multi_index::tag<detail::by_marker3>,
117 multi_index::composite_key<
119 multi_index::const_mem_fun<face_type,
121 &face_type::marker3>,
122 multi_index::const_mem_fun<face_type,
124 &face_type::processId>
127 multi_index::ordered_non_unique<multi_index::tag<detail::by_pid>,
128 multi_index::const_mem_fun<face_type,
130 &face_type::processId> >,
134 multi_index::ordered_non_unique<multi_index::tag<detail::by_interprocessdomain>,
135 multi_index::composite_key<
137 multi_index::const_mem_fun<face_type,
139 &face_type::isInterProcessDomain>,
140 multi_index::const_mem_fun<face_type,
142 &face_type::processId>
146 multi_index::ordered_non_unique<multi_index::tag<detail::by_location>,
147 multi_index::composite_key<
149 multi_index::const_mem_fun<face_type,
151 &face_type::isOnBoundary>,
152 multi_index::const_mem_fun<face_type,
154 &face_type::processId>
160 typedef typename faces_type::iterator face_iterator;
161 typedef typename faces_type::const_iterator face_const_iterator;
162 typedef typename faces_type::template index<detail::by_marker>::type marker_faces;
163 typedef typename faces_type::template index<detail::by_marker2>::type marker2_faces;
164 typedef typename faces_type::template index<detail::by_marker3>::type marker3_faces;
165 typedef typename marker_faces::iterator marker_face_iterator;
166 typedef typename marker_faces::const_iterator marker_face_const_iterator;
167 typedef typename marker2_faces::iterator marker2_face_iterator;
168 typedef typename marker2_faces::const_iterator marker2_face_const_iterator;
169 typedef typename marker3_faces::iterator marker3_face_iterator;
170 typedef typename marker3_faces::const_iterator marker3_face_const_iterator;
172 typedef typename faces_type::template index<detail::by_location>::type location_faces;
173 typedef typename location_faces::iterator location_face_iterator;
174 typedef typename location_faces::const_iterator location_face_const_iterator;
176 typedef typename faces_type::template index<detail::by_pid>::type pid_faces;
177 typedef typename pid_faces::iterator pid_face_iterator;
178 typedef typename pid_faces::const_iterator pid_face_const_iterator;
180 typedef typename faces_type::template index<detail::by_interprocessdomain>::type interprocess_faces;
181 typedef typename interprocess_faces::iterator interprocess_face_iterator;
182 typedef typename interprocess_faces::const_iterator interprocess_face_const_iterator;
193 struct FaceUpdatePoint
199 FaceUpdatePoint( uint16_type index,
typename face_type::point_type
const& pt )
209 void operator()( face_type& e )
212 e.setPoint( M_index, M_pt );
217 typename face_type::point_type
const& M_pt;
225 Faces( WorldComm
const& worldComm = Environment::worldComm() )
227 M_worldCommFaces( worldComm ),
231 Faces( Faces
const & f )
233 M_worldCommFaces( f.M_worldCommFaces ),
250 M_worldCommFaces = e.M_worldCommFaces;
274 faces_type
const&
faces()
const
279 WorldComm
const& worldCommFaces()
const
281 return M_worldCommFaces;
286 return M_faces.empty();
288 bool isBoundaryFace( face_type
const & e )
const
290 return M_faces.find( e )->isOnBoundary();
292 bool isBoundaryFace(
size_type const &
id )
const
294 return M_faces.find( face_type(
id ) )->isOnBoundary();
302 return M_faces.template get<0>().find( face_type( i ) ) !=
303 M_faces.template get<0>().end();
306 face_type
const& face(
size_type i )
const
308 return *M_faces.find( face_type( i ) );
311 face_iterator faceIterator(
size_type i )
const
313 return M_faces.find( face_type( i ) );
316 face_iterator beginFace()
318 return M_faces.begin();
320 face_const_iterator beginFace()
const
322 return M_faces.begin();
324 face_iterator endFace()
326 return M_faces.end();
328 face_const_iterator endFace()
const
330 return M_faces.end();
334 marker_face_iterator beginFaceWithMarker()
336 return M_faces.template get<detail::by_marker>().begin();
338 marker_face_const_iterator beginFaceWithMarker()
const
340 return M_faces.template get<detail::by_marker>().begin();
342 marker_face_iterator endFaceWithMarker()
344 return M_faces.template get<detail::by_marker>().end();
346 marker_face_const_iterator endFaceWithMarker()
const
348 return M_faces.template get<detail::by_marker>().end();
351 marker_face_iterator beginFaceWithMarker(
size_type m )
353 return M_faces.template get<detail::by_marker>().lower_bound( Marker1( m ) );
355 marker_face_const_iterator beginFaceWithMarker(
size_type m )
const
357 return M_faces.template get<detail::by_marker>().lower_bound( Marker1( m ) );
359 marker_face_iterator endFaceWithMarker(
size_type m )
361 return M_faces.template get<detail::by_marker>().upper_bound( Marker1( m ) );
363 marker_face_const_iterator endFaceWithMarker(
size_type m )
const
365 return M_faces.template get<detail::by_marker>().upper_bound( Marker1( m ) );
368 marker2_face_iterator beginFaceWithMarker2()
370 return M_faces.template get<detail::by_marker2>().begin();
372 marker2_face_const_iterator beginFaceWithMarker2()
const
374 return M_faces.template get<detail::by_marker2>().begin();
376 marker2_face_iterator endFaceWithMarker2()
378 return M_faces.template get<detail::by_marker2>().end();
380 marker2_face_const_iterator endFaceWithMarker2()
const
382 return M_faces.template get<detail::by_marker2>().end();
385 marker2_face_iterator beginFaceWithMarker2(
size_type m )
387 return M_faces.template get<detail::by_marker2>().lower_bound( Marker2( m ) );
389 marker2_face_const_iterator beginFaceWithMarker2(
size_type m )
const
391 return M_faces.template get<detail::by_marker2>().lower_bound( Marker2( m ) );
393 marker2_face_iterator endFaceWithMarker2(
size_type m )
395 return M_faces.template get<detail::by_marker2>().upper_bound( Marker2( m ) );
397 marker2_face_const_iterator endFaceWithMarker2(
size_type m )
const
399 return M_faces.template get<detail::by_marker2>().upper_bound( Marker2( m ) );
402 marker3_face_iterator beginFaceWithMarker3()
404 return M_faces.template get<detail::by_marker3>().begin();
406 marker3_face_const_iterator beginFaceWithMarker3()
const
408 return M_faces.template get<detail::by_marker3>().begin();
410 marker3_face_iterator endFaceWithMarker3()
412 return M_faces.template get<detail::by_marker3>().end();
414 marker3_face_const_iterator endFaceWithMarker3()
const
416 return M_faces.template get<detail::by_marker3>().end();
419 marker3_face_iterator beginFaceWithMarker3(
size_type m )
421 return M_faces.template get<detail::by_marker3>().lower_bound( Marker3( m ) );
423 marker3_face_const_iterator beginFaceWithMarker3(
size_type m )
const
425 return M_faces.template get<detail::by_marker3>().lower_bound( Marker3( m ) );
427 marker3_face_iterator endFaceWithMarker3(
size_type m )
429 return M_faces.template get<detail::by_marker3>().upper_bound( Marker3( m ) );
431 marker3_face_const_iterator endFaceWithMarker3(
size_type m )
const
433 return M_faces.template get<detail::by_marker3>().upper_bound( Marker3( m ) );
436 face_iterator beginFaceWithId(
size_type m )
438 return M_faces.lower_bound( face_type( m ) );
440 face_const_iterator beginFaceWithId(
size_type m )
const
442 return M_faces.lower_bound( face_type( m ) );
444 face_iterator endFaceWithId(
size_type m )
446 return M_faces.upper_bound( face_type( m ) );
448 face_const_iterator endFaceWithId(
size_type m )
const
450 return M_faces.upper_bound( face_type( m ) );
457 std::pair<marker_face_iterator, marker_face_iterator>
460 return M_faces.template get<detail::by_marker>().equal_range( boost::make_tuple( Marker1( m ), p ) );
463 std::pair<marker2_face_iterator, marker2_face_iterator>
466 return M_faces.template get<detail::by_marker2>().equal_range( boost::make_tuple( Marker2( m ), p ) );
469 std::pair<marker3_face_iterator, marker3_face_iterator>
472 return M_faces.template get<detail::by_marker3>().equal_range( boost::make_tuple( Marker3( m ), p ) );
480 std::pair<location_face_iterator, location_face_iterator>
481 facesOnBoundary()
const
483 return M_faces.template get<detail::by_location>().equal_range( boost::make_tuple( ON_BOUNDARY ) );
490 std::pair<location_face_iterator, location_face_iterator>
493 return M_faces.template get<detail::by_location>().equal_range( boost::make_tuple( ON_BOUNDARY, p ) );
500 std::pair<location_face_iterator, location_face_iterator>
501 internalFaces()
const
503 return M_faces.template get<detail::by_location>().equal_range( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
510 std::pair<interprocess_face_iterator, interprocess_face_iterator>
511 interProcessFaces()
const
513 return M_faces.template get<detail::by_interprocessdomain>().equal_range( boost::make_tuple(
true, this->worldCommFaces().localRank() ) );
521 std::pair<interprocess_face_iterator, interprocess_face_iterator>
522 intraProcessFaces()
const
524 return M_faces.template get<detail::by_interprocessdomain>().equal_range( boost::make_tuple(
false, this->worldCommFaces().localRank() ) );
532 std::pair<pid_face_iterator, pid_face_iterator>
536 return M_faces.template get<detail::by_pid>().equal_range( p );
547 typename faces_type::template nth_index<0>::type &
550 return M_faces.template get<0>();
559 typename faces_type::template nth_index<0>::type
const&
562 return M_faces.template get<0>();
574 return M_faces.template get<detail::by_marker>();
584 facesByMarker()
const
586 return M_faces.template get<detail::by_marker>();
598 return M_faces.template get<detail::by_marker2>();
608 facesByMarker2()
const
610 return M_faces.template get<detail::by_marker2>();
622 return M_faces.template get<detail::by_marker3>();
632 facesByMarker3()
const
634 return M_faces.template get<detail::by_marker3>();
647 return M_faces.template get<detail::by_location>();
656 location_faces
const&
657 facesByLocation()
const
659 return M_faces.template get<detail::by_location>();
667 location_face_iterator beginInternalFace()
669 return M_faces.template get<detail::by_location>().lower_bound( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
676 location_face_iterator endInternalFace()
678 return M_faces.template get<detail::by_location>().upper_bound( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
686 location_face_const_iterator beginInternalFace()
const
688 return M_faces.template get<detail::by_location>().lower_bound( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
696 location_face_const_iterator endInternalFace()
const
698 return M_faces.template get<detail::by_location>().upper_bound( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
706 location_face_iterator beginFaceOnBoundary()
708 return M_faces.template get<detail::by_location>().lower_bound( boost::make_tuple( ON_BOUNDARY, this->worldCommFaces().localRank() ) );
715 location_face_iterator endFaceOnBoundary()
717 return M_faces.template get<detail::by_location>().upper_bound( boost::make_tuple( ON_BOUNDARY, this->worldCommFaces().localRank() ) );
725 location_face_const_iterator beginFaceOnBoundary()
const
727 return M_faces.template get<detail::by_location>().lower_bound( boost::make_tuple( ON_BOUNDARY, this->worldCommFaces().localRank() ) );
735 location_face_const_iterator endFaceOnBoundary()
const
737 return M_faces.template get<detail::by_location>().upper_bound( boost::make_tuple( ON_BOUNDARY, this->worldCommFaces().localRank() ) );
758 std::pair<face_iterator,bool> addFace( face_type& f )
760 std::pair<face_iterator,bool> ret = M_faces.insert( f );
761 FEELPP_ASSERT( ret.second )( ret.second )( ret.first->id() )( f.id() ).warn(
"face not added to container" );
774 face_iterator eraseFace( face_iterator position )
776 return M_faces.erase( position );
782 void updateMarkersFromElements()
790 auto it = beginFace(), en = endFace();
792 for ( ; it != en; ++it )
796 int tag2_0 = e.isConnectedTo0()?e.element0().marker2().value():-1;
797 int tag2_1 = e.isConnectedTo1()?e.element1().marker2().value():-1;
798 int tag3_0 = e.isConnectedTo0()?e.element0().marker3().value():-1;
799 int tag3_1 = e.isConnectedTo1()?e.element1().marker3().value():-1;
801 if ( ( tag2_0 != -1 && tag2_0 == tag2_1 ) || e.isOnBoundary() )
802 e.setMarker2( tag2_0 );
807 if ( ( tag3_0 != -1 && tag3_0 == tag3_1 ) || e.isOnBoundary() )
808 e.setMarker3( tag3_0 );
817 template<
typename IteratorRange>
818 void updateMarker2WithRangeFaces( IteratorRange
const& range, flag_type flag )
820 typedef typename boost::tuples::template element<1, IteratorRange>::type iterator_range_type;
821 iterator_range_type it, en;
822 boost::tie( boost::tuples::ignore, it, en ) = range;
824 for ( ; it != en; ++it )
825 M_faces.modify( this->faceIterator( it->id() ), [&flag]( face_type& e )
827 e.setMarker2( flag );
831 template<
typename IteratorRange>
832 void updateMarker3WithRangeFaces( IteratorRange
const& range, flag_type flag )
834 typedef typename boost::tuples::template element<1, IteratorRange>::type iterator_range_type;
835 iterator_range_type it, en;
836 boost::tie( boost::tuples::ignore, it, en ) = range;
838 for ( ; it != en; ++it )
839 M_faces.modify( this->faceIterator( it->id() ), [&flag]( face_type& e )
841 e.setMarker3( flag );
845 void setWorldCommFaces( WorldComm
const& _worldComm )
847 M_worldCommFaces = _worldComm;
854 friend class boost::serialization::access;
855 template<
class Archive>
856 void serialize( Archive & ar,
const unsigned int version )
862 WorldComm M_worldCommFaces;
boost::tuple< mpl::size_t< MESH_FACES >, typename MeshTraits< MeshType >::pid_face_const_iterator, typename MeshTraits< MeshType >::pid_face_const_iterator > faces(MeshType const &mesh)
Definition: filters.hpp:933
virtual bool isEmpty() const
Definition: elements.hpp:371
size_t size_type
Indices (starting from 0)
Definition: feelcore/feel.hpp:319
Elements & operator=(Elements const &e)
Definition: elements.hpp:335