Logo  0.95.0-final
Finite Element Embedded Library and Language in C++
Feel++ Feel++ on Github Feel++ community
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
faces.hpp
Go to the documentation of this file.
1 /* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
2 
3  This file is part of the Feel library
4 
5  Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
6  Date: 2005-09-03
7 
8  Copyright (C) 2005,2006 EPFL
9  Copyright (C) 2007,2010 Université Joseph Fourier
10 
11  This library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU Lesser General Public
13  License as published by the Free Software Foundation; either
14  version 3.0 of the License, or (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public
22  License along with this library; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
30 #ifndef __faces_H
31 #define __faces_H 1
32 
33 
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>
39 
40 #include <feel/feelmesh/geoelement.hpp>
42 
43 namespace Feel
44 {
45 namespace multi_index = boost::multi_index;
46 
48 
55 template<typename EntityType, typename ElementType>
56 class Faces
57 {
58 public:
59 
60 
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> > >
70  >::type>::type>,
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;
77 
78  typedef multi_index::multi_index_container<
79  face_type,
80  multi_index::indexed_by<
81  // sort by employee::operator<
82 #if 1
83  multi_index::ordered_unique<multi_index::identity<face_type> >,
84 #else
85  multi_index::ordered_unique<
86  multi_index::composite_key<face_type,
87  multi_index::const_mem_fun<face_type,
88  uint16_type,
89  &face_type::processId>,
90  multi_index::const_mem_fun<face_type,
91  size_type,
92  &face_type::id> > >,
93 #endif
94 
95  // sort by less<int> on marker
96  multi_index::ordered_non_unique<multi_index::tag<detail::by_marker>,
97  multi_index::composite_key<
98  face_type,
99  multi_index::const_mem_fun<face_type,
100  Marker1 const&,
101  &face_type::marker>,
102  multi_index::const_mem_fun<face_type,
103  uint16_type,
104  &face_type::processId>
105  > >,
106  multi_index::ordered_non_unique<multi_index::tag<detail::by_marker2>,
107  multi_index::composite_key<
108  face_type,
109  multi_index::const_mem_fun<face_type,
110  Marker2 const&,
111  &face_type::marker2>,
112  multi_index::const_mem_fun<face_type,
113  uint16_type,
114  &face_type::processId>
115  > >,
116  multi_index::ordered_non_unique<multi_index::tag<detail::by_marker3>,
117  multi_index::composite_key<
118  face_type,
119  multi_index::const_mem_fun<face_type,
120  Marker3 const&,
121  &face_type::marker3>,
122  multi_index::const_mem_fun<face_type,
123  uint16_type,
124  &face_type::processId>
125  > >,
126  // sort by less<int> on processId
127  multi_index::ordered_non_unique<multi_index::tag<detail::by_pid>,
128  multi_index::const_mem_fun<face_type,
129  uint16_type,
130  &face_type::processId> >,
131 
132 
133  // sort by less<int> on boundary
134  multi_index::ordered_non_unique<multi_index::tag<detail::by_interprocessdomain>,
135  multi_index::composite_key<
136  face_type,
137  multi_index::const_mem_fun<face_type,
138  bool,
139  &face_type::isInterProcessDomain>,
140  multi_index::const_mem_fun<face_type,
141  uint16_type,
142  &face_type::processId>
143  >
144  >,
145  // sort by less<int> on boundary
146  multi_index::ordered_non_unique<multi_index::tag<detail::by_location>,
147  multi_index::composite_key<
148  face_type,
149  multi_index::const_mem_fun<face_type,
150  bool,
151  &face_type::isOnBoundary>,
152  multi_index::const_mem_fun<face_type,
153  uint16_type,
154  &face_type::processId>
155  >
156  > >
157  > faces_type;
158 
159 
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;
171 
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;
175 
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;
179 
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;
184 
193  struct FaceUpdatePoint
194  {
199  FaceUpdatePoint( uint16_type index, typename face_type::point_type const& pt )
200  :
201  M_index( index ),
202  M_pt( pt )
203  {}
204 
209  void operator()( face_type& e )
210  {
211  //VLOG(1) << "FaceUpdatePoint] update point index " << M_index << " with "<< M_pt.id() << "\n";
212  e.setPoint( M_index, M_pt );
213  //VLOG(1) << "FaceUpdatePoint] update point "<< e.point(M_index).id() << "\n";
214  }
215  private:
216  uint16_type M_index;
217  typename face_type::point_type const& M_pt;
218 
219  };
220 
224 
225  Faces( WorldComm const& worldComm = Environment::worldComm() )
226  :
227  M_worldCommFaces( worldComm ),
228  M_faces()
229  {}
230 
231  Faces( Faces const & f )
232  :
233  M_worldCommFaces( f.M_worldCommFaces ),
234  M_faces( f.M_faces )
235  {}
236 
237  virtual ~Faces()
238  {}
239 
241 
245 
246  Faces& operator=( Faces const& e )
247  {
248  if ( this != &e )
249  {
250  M_worldCommFaces = e.M_worldCommFaces;
251  M_faces = e.M_faces;
252  }
253 
254  return *this;
255  }
256 
258 
262 
266  faces_type & faces()
267  {
268  return M_faces;
269  }
270 
274  faces_type const& faces() const
275  {
276  return M_faces;
277  }
278 
279  WorldComm const& worldCommFaces() const
280  {
281  return M_worldCommFaces;
282  }
283 
284  virtual bool isEmpty() const
285  {
286  return M_faces.empty();
287  }
288  bool isBoundaryFace( face_type const & e ) const
289  {
290  return M_faces.find( e )->isOnBoundary();
291  }
292  bool isBoundaryFace( size_type const & id ) const
293  {
294  return M_faces.find( face_type( id ) )->isOnBoundary();
295  }
296 
300  bool hasFace( size_type i ) const
301  {
302  return M_faces.template get<0>().find( face_type( i ) ) !=
303  M_faces.template get<0>().end();
304  }
305 
306  face_type const& face( size_type i ) const
307  {
308  return *M_faces.find( face_type( i ) );
309  }
310 
311  face_iterator faceIterator( size_type i ) const
312  {
313  return M_faces.find( face_type( i ) );
314  }
315 
316  face_iterator beginFace()
317  {
318  return M_faces.begin();
319  }
320  face_const_iterator beginFace() const
321  {
322  return M_faces.begin();
323  }
324  face_iterator endFace()
325  {
326  return M_faces.end();
327  }
328  face_const_iterator endFace() const
329  {
330  return M_faces.end();
331  }
332 
333 
334  marker_face_iterator beginFaceWithMarker()
335  {
336  return M_faces.template get<detail::by_marker>().begin();
337  }
338  marker_face_const_iterator beginFaceWithMarker() const
339  {
340  return M_faces.template get<detail::by_marker>().begin();
341  }
342  marker_face_iterator endFaceWithMarker()
343  {
344  return M_faces.template get<detail::by_marker>().end();
345  }
346  marker_face_const_iterator endFaceWithMarker() const
347  {
348  return M_faces.template get<detail::by_marker>().end();
349  }
350 
351  marker_face_iterator beginFaceWithMarker( size_type m )
352  {
353  return M_faces.template get<detail::by_marker>().lower_bound( Marker1( m ) );
354  }
355  marker_face_const_iterator beginFaceWithMarker( size_type m ) const
356  {
357  return M_faces.template get<detail::by_marker>().lower_bound( Marker1( m ) );
358  }
359  marker_face_iterator endFaceWithMarker( size_type m )
360  {
361  return M_faces.template get<detail::by_marker>().upper_bound( Marker1( m ) );
362  }
363  marker_face_const_iterator endFaceWithMarker( size_type m ) const
364  {
365  return M_faces.template get<detail::by_marker>().upper_bound( Marker1( m ) );
366  }
367 
368  marker2_face_iterator beginFaceWithMarker2()
369  {
370  return M_faces.template get<detail::by_marker2>().begin();
371  }
372  marker2_face_const_iterator beginFaceWithMarker2() const
373  {
374  return M_faces.template get<detail::by_marker2>().begin();
375  }
376  marker2_face_iterator endFaceWithMarker2()
377  {
378  return M_faces.template get<detail::by_marker2>().end();
379  }
380  marker2_face_const_iterator endFaceWithMarker2() const
381  {
382  return M_faces.template get<detail::by_marker2>().end();
383  }
384 
385  marker2_face_iterator beginFaceWithMarker2( size_type m )
386  {
387  return M_faces.template get<detail::by_marker2>().lower_bound( Marker2( m ) );
388  }
389  marker2_face_const_iterator beginFaceWithMarker2( size_type m ) const
390  {
391  return M_faces.template get<detail::by_marker2>().lower_bound( Marker2( m ) );
392  }
393  marker2_face_iterator endFaceWithMarker2( size_type m )
394  {
395  return M_faces.template get<detail::by_marker2>().upper_bound( Marker2( m ) );
396  }
397  marker2_face_const_iterator endFaceWithMarker2( size_type m ) const
398  {
399  return M_faces.template get<detail::by_marker2>().upper_bound( Marker2( m ) );
400  }
401 
402  marker3_face_iterator beginFaceWithMarker3()
403  {
404  return M_faces.template get<detail::by_marker3>().begin();
405  }
406  marker3_face_const_iterator beginFaceWithMarker3() const
407  {
408  return M_faces.template get<detail::by_marker3>().begin();
409  }
410  marker3_face_iterator endFaceWithMarker3()
411  {
412  return M_faces.template get<detail::by_marker3>().end();
413  }
414  marker3_face_const_iterator endFaceWithMarker3() const
415  {
416  return M_faces.template get<detail::by_marker3>().end();
417  }
418 
419  marker3_face_iterator beginFaceWithMarker3( size_type m )
420  {
421  return M_faces.template get<detail::by_marker3>().lower_bound( Marker3( m ) );
422  }
423  marker3_face_const_iterator beginFaceWithMarker3( size_type m ) const
424  {
425  return M_faces.template get<detail::by_marker3>().lower_bound( Marker3( m ) );
426  }
427  marker3_face_iterator endFaceWithMarker3( size_type m )
428  {
429  return M_faces.template get<detail::by_marker3>().upper_bound( Marker3( m ) );
430  }
431  marker3_face_const_iterator endFaceWithMarker3( size_type m ) const
432  {
433  return M_faces.template get<detail::by_marker3>().upper_bound( Marker3( m ) );
434  }
435 
436  face_iterator beginFaceWithId( size_type m )
437  {
438  return M_faces.lower_bound( face_type( m ) );
439  }
440  face_const_iterator beginFaceWithId( size_type m ) const
441  {
442  return M_faces.lower_bound( face_type( m ) );
443  }
444  face_iterator endFaceWithId( size_type m )
445  {
446  return M_faces.upper_bound( face_type( m ) );
447  }
448  face_const_iterator endFaceWithId( size_type m ) const
449  {
450  return M_faces.upper_bound( face_type( m ) );
451  }
452 
457  std::pair<marker_face_iterator, marker_face_iterator>
458  facesWithMarker( size_type m, size_type p ) const
459  {
460  return M_faces.template get<detail::by_marker>().equal_range( boost::make_tuple( Marker1( m ), p ) );
461  }
462 
463  std::pair<marker2_face_iterator, marker2_face_iterator>
464  facesWithMarker2( size_type m, size_type p ) const
465  {
466  return M_faces.template get<detail::by_marker2>().equal_range( boost::make_tuple( Marker2( m ), p ) );
467  }
468 
469  std::pair<marker3_face_iterator, marker3_face_iterator>
470  facesWithMarker3( size_type m, size_type p ) const
471  {
472  return M_faces.template get<detail::by_marker3>().equal_range( boost::make_tuple( Marker3( m ), p ) );
473  }
474 
475 
480  std::pair<location_face_iterator, location_face_iterator>
481  facesOnBoundary() const
482  {
483  return M_faces.template get<detail::by_location>().equal_range( boost::make_tuple( ON_BOUNDARY ) );
484  }
485 
490  std::pair<location_face_iterator, location_face_iterator>
491  facesOnBoundary( size_type p ) const
492  {
493  return M_faces.template get<detail::by_location>().equal_range( boost::make_tuple( ON_BOUNDARY, p ) );
494  }
495 
500  std::pair<location_face_iterator, location_face_iterator>
501  internalFaces() const
502  {
503  return M_faces.template get<detail::by_location>().equal_range( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
504  }
505 
510  std::pair<interprocess_face_iterator, interprocess_face_iterator>
511  interProcessFaces() const
512  {
513  return M_faces.template get<detail::by_interprocessdomain>().equal_range( boost::make_tuple( true, this->worldCommFaces().localRank() ) );
514  }
515 
516 #if 0
517 
521  std::pair<interprocess_face_iterator, interprocess_face_iterator>
522  intraProcessFaces() const
523  {
524  return M_faces.template get<detail::by_interprocessdomain>().equal_range( boost::make_tuple( false, this->worldCommFaces().localRank() ) );
525  }
526 #endif
527 
532  std::pair<pid_face_iterator, pid_face_iterator>
533  //std::pair<face_iterator, face_iterator>
534  facesWithProcessId( size_type p ) const
535  {
536  return M_faces.template get<detail::by_pid>().equal_range( p );
537  }
538  //{ return M_faces.template get<detail::by_pid>().equal_range( boost::make_tuple(/*this->worldCommFaces().localRank()*/p) ); }
539  //{ return M_faces.template get<0>().equal_range( boost::make_tuple(/*this->worldCommFaces().localRank()*/p) ); }
540 
547  typename faces_type::template nth_index<0>::type &
548  facesById()
549  {
550  return M_faces.template get<0>();
551  }
552 
559  typename faces_type::template nth_index<0>::type const&
560  facesById() const
561  {
562  return M_faces.template get<0>();
563  }
564 
571  marker_faces &
572  facesByMarker()
573  {
574  return M_faces.template get<detail::by_marker>();
575  }
576 
583  marker_faces const&
584  facesByMarker() const
585  {
586  return M_faces.template get<detail::by_marker>();
587  }
588 
595  marker2_faces &
596  facesByMarker2()
597  {
598  return M_faces.template get<detail::by_marker2>();
599  }
600 
607  marker2_faces const&
608  facesByMarker2() const
609  {
610  return M_faces.template get<detail::by_marker2>();
611  }
612 
619  marker3_faces &
620  facesByMarker3()
621  {
622  return M_faces.template get<detail::by_marker3>();
623  }
624 
631  marker3_faces const&
632  facesByMarker3() const
633  {
634  return M_faces.template get<detail::by_marker3>();
635  }
636 
637 
644  location_faces &
645  facesByLocation()
646  {
647  return M_faces.template get<detail::by_location>();
648  }
649 
656  location_faces const&
657  facesByLocation() const
658  {
659  return M_faces.template get<detail::by_location>();
660  }
661 
667  location_face_iterator beginInternalFace()
668  {
669  return M_faces.template get<detail::by_location>().lower_bound( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
670  }
676  location_face_iterator endInternalFace()
677  {
678  return M_faces.template get<detail::by_location>().upper_bound( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
679  }
680 
686  location_face_const_iterator beginInternalFace() const
687  {
688  return M_faces.template get<detail::by_location>().lower_bound( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
689  }
690 
696  location_face_const_iterator endInternalFace() const
697  {
698  return M_faces.template get<detail::by_location>().upper_bound( boost::make_tuple( INTERNAL, this->worldCommFaces().localRank() ) );
699  }
700 
706  location_face_iterator beginFaceOnBoundary()
707  {
708  return M_faces.template get<detail::by_location>().lower_bound( boost::make_tuple( ON_BOUNDARY, this->worldCommFaces().localRank() ) );
709  }
715  location_face_iterator endFaceOnBoundary()
716  {
717  return M_faces.template get<detail::by_location>().upper_bound( boost::make_tuple( ON_BOUNDARY, this->worldCommFaces().localRank() ) );
718  }
719 
725  location_face_const_iterator beginFaceOnBoundary() const
726  {
727  return M_faces.template get<detail::by_location>().lower_bound( boost::make_tuple( ON_BOUNDARY, this->worldCommFaces().localRank() ) );
728  }
729 
735  location_face_const_iterator endFaceOnBoundary() const
736  {
737  return M_faces.template get<detail::by_location>().upper_bound( boost::make_tuple( ON_BOUNDARY, this->worldCommFaces().localRank() ) );
738  }
739 
741 
745 
746 
748 
752 
758  std::pair<face_iterator,bool> addFace( face_type& f )
759  {
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" );
762  return ret;
763  }
764 
774  face_iterator eraseFace( face_iterator position )
775  {
776  return M_faces.erase( position );
777  }
778 
782  void updateMarkersFromElements()
783  {
784  //pid_face_iterator it;
785  //pid_face_iterator en
786  //face_iterator it;
787  //face_iterator en;
788  //boost::tie( it, en ) = facesWithProcessId( this->worldCommFaces().localRank() );
789 
790  auto it = beginFace(), en = endFace();
791 
792  for ( ; it != en; ++it )
793  M_faces.modify( it,
794  []( face_type& e )
795  {
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;
800 
801  if ( ( tag2_0 != -1 && tag2_0 == tag2_1 ) || e.isOnBoundary() )
802  e.setMarker2( tag2_0 );
803 
804  else
805  e.setMarker3( 0 );
806 
807  if ( ( tag3_0 != -1 && tag3_0 == tag3_1 ) || e.isOnBoundary() )
808  e.setMarker3( tag3_0 );
809 
810  else
811  e.setMarker3( 0 );
812  } );
813 
814  }
815 
816 
817  template<typename IteratorRange>
818  void updateMarker2WithRangeFaces( IteratorRange const& range, flag_type flag )
819  {
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;
823 
824  for ( ; it != en; ++it )
825  M_faces.modify( this->faceIterator( it->id() ), [&flag]( face_type& e )
826  {
827  e.setMarker2( flag );
828  } );
829  }
830 
831  template<typename IteratorRange>
832  void updateMarker3WithRangeFaces( IteratorRange const& range, flag_type flag )
833  {
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;
837 
838  for ( ; it != en; ++it )
839  M_faces.modify( this->faceIterator( it->id() ), [&flag]( face_type& e )
840  {
841  e.setMarker3( flag );
842  } );
843  }
844 
845  void setWorldCommFaces( WorldComm const& _worldComm )
846  {
847  M_worldCommFaces = _worldComm;
848  }
849 
851 
852 private:
853 
854  friend class boost::serialization::access;
855  template<class Archive>
856  void serialize( Archive & ar, const unsigned int version )
857  {
858  ar & M_faces;
859  }
860 
861 private:
862  WorldComm M_worldCommFaces;
863  faces_type M_faces;
864 };
866 } // Feel
867 #endif /* __faces_H */

Generated on Fri Oct 25 2013 14:24:09 for Feel++ by doxygen 1.8.4