ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/mesh/segmentation.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_SEGMENTATION_HPP
00002 #define VIENNAGRID_SEGMENTATION_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2011-2014, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                      ViennaGrid - The Vienna Grid Library
00011                             -----------------
00012 
00013    License:      MIT (X11), see file LICENSE in the base directory
00014 ======================================================================= */
00015 
00016 #include <limits>
00017 #include <string>
00018 #include <sstream>
00019 
00020 #include "viennagrid/forwards.hpp"
00021 #include "viennagrid/mesh/mesh.hpp"
00022 
00023 #include "viennagrid/accessor.hpp"
00024 
00025 
00031 namespace viennagrid
00032 {
00034   class segment_name_collision_exception : public std::exception
00035   {
00036     public:
00037       virtual const char* what() const throw()
00038       {
00039         std::stringstream ss;
00040         ss << "* ViennaGrid: Collision with segment names: " << collision_name_ << "!";
00041         return ss.str().c_str();
00042       }
00043 
00044       segment_name_collision_exception(std::string cn) : collision_name_(cn) {}
00045 
00046       virtual ~segment_name_collision_exception() throw() {}
00047 
00048     private:
00049       std::string collision_name_;
00050   };
00051 
00056   template<typename WrappedConfigType>
00057   class segment_handle< viennagrid::segmentation<WrappedConfigType> >
00058   {
00059     friend class viennagrid::segmentation<WrappedConfigType>;
00060 
00061   public:
00062 
00063     typedef viennagrid::segmentation<WrappedConfigType> segmentation_type;
00064     typedef typename segmentation_type::segment_id_type segment_id_type;
00065     typedef typename segmentation_type::mesh_type mesh_type;
00066     typedef typename segmentation_type::view_type view_type;
00067 
00068   private:
00069 
00070     typedef typename segmentation_type::segment_type segment_type;
00071 
00073     segment_handle(segment_type & segment_x) : segment_(&segment_x) {}
00074 
00075   public:
00076 
00081     segment_id_type const & id() const { return segment_->id; }
00082 
00087     std::string const & name() const { return segment_->name; }
00088 
00094     void set_name( std::string const & new_name )
00095     {
00096       // name is already present
00097       if (parent().segment_name_map.find(new_name) != parent().segment_name_map.end())
00098         throw segment_name_collision_exception(new_name);
00099 
00100       parent().segment_name_map.erase( name() );
00101       parent().segment_name_map[new_name] = &(parent()(id()));
00102       segment_->name = new_name;
00103     }
00104 
00105 
00110     segmentation_type & parent() { return *(segment_->segmentation_); }
00115     segmentation_type const & parent() const { return *(segment_->segmentation_); }
00116 
00121     view_type & view() { return segment_->view; }
00126     view_type const & view() const { return segment_->view; }
00127 
00132     mesh_type & mesh() { return parent().mesh(); }
00137     mesh_type const & mesh() const { return parent().mesh(); }
00138 
00143     bool operator<( segment_handle const & rhs ) const { return id() < rhs.id(); }
00144 
00145   private:
00146 
00147     segment_type * segment_;
00148   };
00149 
00153   template<typename SegmentationT>
00154   void clear( segment_handle<SegmentationT> & segment_ )
00155   {
00156     segment_.view().clear();
00157   }
00158 
00159   namespace result_of
00160   {
00162     template<typename SegmentationT>
00163     struct change_counter_type< viennagrid::segment_handle<SegmentationT> >
00164     {
00165       typedef typename change_counter_type< typename viennagrid::segment_handle<SegmentationT>::view_type >::type type;
00166     };
00167 
00168     // doxygen docu in mesh.hpp
00169     template<typename SegmentationType, typename element_type_or_tag>
00170     struct is_element_present< viennagrid::segment_handle<SegmentationType>, element_type_or_tag >
00171     {
00172       static const bool value = is_element_present< typename viennagrid::segment_handle<SegmentationType>::view_type, element_type_or_tag>::value;
00173     };
00174 
00175     template<typename SegmentationType, typename element_type_or_tag>
00176     struct is_element_present< const viennagrid::segment_handle<SegmentationType>, element_type_or_tag >
00177     {
00178       static const bool value = is_element_present<viennagrid::segment_handle<SegmentationType>, element_type_or_tag>::value;
00179     };
00180 
00181 
00182     // doxygen docu in forwards.hpp
00183     template<typename segmentation_type>
00184     struct element_collection< viennagrid::segment_handle<segmentation_type> >
00185     {
00186         typedef typename element_collection<typename viennagrid::segment_handle<segmentation_type>::view_type>::type type;
00187     };
00188 
00189     template<typename segmentation_type>
00190     struct element_collection< const viennagrid::segment_handle<segmentation_type> >
00191     {
00192         typedef typename element_collection<const typename viennagrid::segment_handle<segmentation_type>::view_type>::type type;
00193     };
00194 
00195 
00196     // doxygen docu in mesh.hpp
00197     template<typename segmentation_type>
00198     struct point< viennagrid::segment_handle<segmentation_type> >
00199     {
00200         typedef typename point<typename viennagrid::segment_handle<segmentation_type>::mesh_type>::type type;
00201     };
00202 
00203 
00204     // doxygen docu in mesh.hpp
00205     template<typename WrappedConfigT>
00206     struct segment_handle< viennagrid::segmentation<WrappedConfigT> >
00207     {
00208       typedef viennagrid::segment_handle< viennagrid::segmentation<WrappedConfigT> > type;
00209     };
00217     template<typename SegmentationOrSegmentHandleT>
00218     struct segment_id;
00219 
00221     template<typename SegmentationType>
00222     struct segment_id< viennagrid::segment_handle<SegmentationType> >
00223     {
00224       typedef typename viennagrid::segment_handle<SegmentationType>::segment_id_type type;
00225     };
00226 
00227     template<typename WrappedConfigType>
00228     struct segment_id< viennagrid::segmentation<WrappedConfigType> >
00229     {
00230       typedef typename viennagrid::segmentation<WrappedConfigType>::segment_id_type type;
00231     };
00236     template<typename SegmentationT,
00237              typename Element0TypeOrTagT, typename Element1TypeOrTagT,
00238              typename Element2TypeOrTagT, typename Element3TypeOrTagT,
00239              typename Element4TypeOrTagT, typename Element5TypeOrTagT,
00240              typename Element6TypeOrTagT, typename Element7TypeOrTagT,
00241              typename Element8TypeOrTagT, typename Element9TypeOrTagT>
00242     struct mesh_view< viennagrid::segment_handle<SegmentationT>,
00243                       Element0TypeOrTagT, Element1TypeOrTagT, Element2TypeOrTagT, Element3TypeOrTagT, Element4TypeOrTagT,
00244                       Element5TypeOrTagT, Element6TypeOrTagT, Element7TypeOrTagT, Element8TypeOrTagT, Element9TypeOrTagT>
00245     {
00246       typedef typename viennagrid::segment_handle<SegmentationT>::view_type ViewType;
00247 
00248         typedef typename mesh_view<
00249             ViewType,
00250             Element0TypeOrTagT, Element1TypeOrTagT, Element2TypeOrTagT, Element3TypeOrTagT, Element4TypeOrTagT,
00251             Element5TypeOrTagT, Element6TypeOrTagT, Element7TypeOrTagT, Element8TypeOrTagT, Element9TypeOrTagT
00252         >::type type;
00253     };
00255   }
00256 
00257   namespace detail
00258   {
00259 
00261     template<typename SegmentationType>
00262     bool is_obsolete( segment_handle<SegmentationType> const & segment, typename segment_handle<SegmentationType>::view_type::change_counter_type change_counter_to_check )
00263     { return is_obsolete(segment.view(), change_counter_to_check); }
00264 
00266     template<typename SegmentationType>
00267     void update_change_counter( segment_handle<SegmentationType> & segment, typename segment_handle<SegmentationType>::view_type::change_counter_type & change_counter_to_update )
00268     { update_change_counter(segment.view(), change_counter_to_update); }
00269 
00271     template<typename SegmentationType>
00272     void increment_change_counter( segment_handle<SegmentationType> & segment )
00273     { increment_change_counter(segment.view()); }
00274 
00275 
00276 
00278     template<typename SegmentationType>
00279     typename viennagrid::segment_handle<SegmentationType>::view_type::element_collection_type & element_collection( segment_handle<SegmentationType> & segment)
00280     { return element_collection( segment.view() ); }
00281 
00283     template<typename SegmentationType>
00284     typename viennagrid::segment_handle<SegmentationType>::view_type::element_collection_type const & element_collection( segment_handle<SegmentationType> const & segment)
00285     { return element_collection( segment.view() ); }
00286 
00288     template<typename SegmentationType>
00289     typename viennagrid::segment_handle<SegmentationType>::view_type::inserter_type & inserter(segment_handle<SegmentationType> & segment)
00290     { return detail::inserter( segment.view() ); }
00291 
00293     template<typename SegmentationType>
00294     typename viennagrid::segment_handle<SegmentationType>::view_type::inserter_type const & inserter(segment_handle<SegmentationType> const & segment)
00295     { return detail::inserter( segment.view() ); }
00296 
00297 
00299     template<typename SegmentationType>
00300     typename viennagrid::segment_handle<SegmentationType>::view_type::inserter_type::id_generator_type & id_generator(segment_handle<SegmentationType> & segment)
00301     { return id_generator( segment.view() ); }
00302 
00304     template<typename SegmentationType>
00305     typename viennagrid::segment_handle<SegmentationType>::view_type::inserter_type::id_generator_type const & id_generator(segment_handle<SegmentationType> const & segment)
00306     { return id_generator( segment.view() ); }
00307 
00308   }
00309 
00311   template<typename ElementTypeOrTag, typename SegmentationType>
00312   typename viennagrid::result_of::id<
00313     typename viennagrid::result_of::element< segment_handle<SegmentationType>, ElementTypeOrTag>::type
00314   >::type id_upper_bound( segment_handle<SegmentationType> const & segment )
00315   { return id_upper_bound<ElementTypeOrTag>( segment.view() ); }
00316 
00317 
00318 
00319 
00326   template<typename SegmentationT, typename HandleT>
00327   typename detail::result_of::value_type<HandleT>::type &
00328   dereference_handle(segment_handle<SegmentationT> & segment_handle, HandleT const & handle)
00329   {
00330     return dereference_handle( segment_handle.parent().mesh(), handle );
00331   }
00332 
00339   template<typename SegmentationT, typename HandleT>
00340   typename detail::result_of::value_type<HandleT>::type const &
00341   dereference_handle(segment_handle<SegmentationT> const & segment_handle, HandleT const & handle)
00342   {
00343     return dereference_handle( segment_handle.parent().mesh(), handle );
00344   }
00345 
00346 
00347 
00354   template<typename SegmentationT>
00355   mesh_proxy< typename SegmentationT::view_type > make_view(segment_handle<SegmentationT> & segment)
00356   {
00357       return mesh_proxy<typename SegmentationT::view_type>( segment.view() );
00358   }
00359 
00360 
00361 
00369   template<typename SegmentationType>
00370   typename result_of::point< segment_handle<SegmentationType> >::type &
00371   point(segment_handle<SegmentationType> & segment,
00372         typename result_of::vertex< typename SegmentationType::mesh_type >::type & vertex)
00373   { return point( segment.parent().mesh(), vertex ); }
00374 
00382   template<typename SegmentationType>
00383   typename result_of::point< segment_handle<SegmentationType> >::type const &
00384   point( segment_handle<SegmentationType> const & segment,
00385          typename result_of::vertex< typename SegmentationType::mesh_type >::type const & vertex)
00386   { return point( segment.parent().mesh(), vertex ); }
00387 
00395   template<typename SegmentationType>
00396   typename result_of::point< segment_handle<SegmentationType> >::type &
00397   point(segment_handle<SegmentationType> & segment,
00398         typename result_of::vertex_handle< typename SegmentationType::mesh_type >::type vertex_handle)
00399   { return point( segment.parent().mesh(), vertex_handle ); }
00400 
00408   template<typename SegmentationType>
00409   typename result_of::point< segment_handle<SegmentationType> >::type const &
00410   point( segment_handle<SegmentationType> const & segment,
00411          typename result_of::const_vertex_handle< typename SegmentationType::mesh_type >::type vertex_handle)
00412   { return point( segment.parent().mesh(), vertex_handle ); }
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421   namespace result_of
00422   {
00424     template<typename WrappedConfigType>
00425     struct segmentation_mesh_type
00426     {
00427       typedef typename WrappedConfigType::mesh_type type;
00428     };
00429 
00430     template<typename WrappedConfigType>
00431     struct segmentation_view_type
00432     {
00433       typedef typename WrappedConfigType::view_type type;
00434     };
00435 
00436     template<typename WrappedConfigType>
00437     struct segmentation_segment_id_type
00438     {
00439       typedef typename WrappedConfigType::segment_id_type type;
00440     };
00441 
00442     template<typename WrappedConfigType>
00443     struct segmentation_appendix_type
00444     {
00445       typedef typename WrappedConfigType::appendix_type type;
00446     };
00447 
00448     template<typename WrappedConfigType>
00449     struct segmentation_segment_container_tag
00450     {
00451       typedef typename WrappedConfigType::segment_container_tag type;
00452     };
00454   }
00455 
00456 
00457 
00458   namespace config
00459   {
00461     template<typename mesh_type_, typename view_type_, typename segment_id_type_, typename appendix_type_, typename segment_container_tag_>
00462     struct segmentation_config_wrapper_t
00463     {
00464       typedef mesh_type_ mesh_type;
00465       typedef view_type_ view_type;
00466       typedef segment_id_type_ segment_id_type;
00467       typedef appendix_type_ appendix_type;
00468       typedef segment_container_tag_ segment_container_tag;
00469     };
00471   }
00472 
00473 
00475   class segment_id_not_found_exception : public std::exception
00476   {
00477     public:
00478       virtual const char* what() const throw()
00479       {
00480         std::stringstream ss;
00481         ss << "* ViennaGrid: Cannot find segment with ID " << id_ << "!";
00482         return ss.str().c_str();
00483       }
00484 
00485       segment_id_not_found_exception(long id) : id_(id) {}
00486 
00487       virtual ~segment_id_not_found_exception() throw() {}
00488 
00489     private:
00490       long id_;
00491   };
00492 
00493 
00495   class segment_name_not_found_exception : public std::exception
00496   {
00497     public:
00498       virtual const char* what() const throw()
00499       {
00500         std::stringstream ss;
00501         ss << "* ViennaGrid: Cannot find segment  " << name_ << "!";
00502         return ss.str().c_str();
00503       }
00504 
00505       segment_name_not_found_exception(std::string const & name) : name_(name) {}
00506 
00507       virtual ~segment_name_not_found_exception() throw() {}
00508 
00509     private:
00510       std::string name_;
00511   };
00512 
00513 
00515   template<typename WrappedConfigType>
00516   class segmentation
00517   {
00518     friend class segment_handle< segmentation<WrappedConfigType> >;
00519 
00520   public:
00521 
00523     typedef typename result_of::segmentation_mesh_type<WrappedConfigType>::type mesh_type;
00525     typedef typename result_of::segmentation_view_type<WrappedConfigType>::type view_type;
00527     typedef typename result_of::segmentation_segment_id_type<WrappedConfigType>::type segment_id_type;
00529     typedef typename result_of::segmentation_appendix_type<WrappedConfigType>::type appendix_type;
00531     typedef typename result_of::segmentation_segment_container_tag<WrappedConfigType>::type segment_container_tag;
00532 
00534     typedef viennagrid::segmentation<WrappedConfigType> self_type;
00535 
00537     typedef segment_handle<self_type> segment_handle_type;
00538 
00539   private:
00540 
00542     struct segment
00543     {
00544       segment(self_type * segmentation_x, mesh_type & mesh, segment_id_type id_) :
00545         segmentation_(segmentation_x), view( viennagrid::make_view(mesh) ), id(id_) {}
00546 
00547       self_type * segmentation_;
00548 
00549       view_type view;
00550       segment_id_type id;
00551       std::string name;
00552     };
00553 
00555     typedef typename viennagrid::result_of::container< segment, segment_container_tag >::type segment_container_type;
00557     typedef std::map<segment_id_type, segment_handle_type> segment_id_map_type;
00559     typedef std::map<std::string, segment_handle_type*> segment_name_map_type;
00560 
00562     typedef segment segment_type;
00563 
00564   public:
00565 
00566 
00571     segmentation( mesh_type & mesh_x ) : highest_id(-1), mesh_(&mesh_x) { all_elements_ = viennagrid::make_view(*mesh_); }
00572 
00576     void init( mesh_type & mesh_x )
00577     {
00578       highest_id = -1;
00579       mesh_ = &mesh_x;
00580       all_elements_ = viennagrid::make_view(*mesh_);
00581     }
00582 
00583 
00588     mesh_type & mesh() { return *mesh_; }
00593     mesh_type const & mesh() const { return *mesh_; }
00594 
00599     appendix_type & appendix() { return appendix_; }
00604     appendix_type const & appendix() const { return appendix_; }
00605 
00606 
00612     bool segment_present( segment_id_type const & segment_id ) const { return segment_id_map.find(segment_id) != segment_id_map.end(); }
00613 
00614 
00620     segment_handle_type & get_segment( segment_id_type const & segment_id )
00621     {
00622       typename segment_id_map_type::iterator it = segment_id_map.find(segment_id);
00623       assert( it != segment_id_map.end() );
00624       return it->second; // segment already is present
00625     }
00626 
00632     segment_handle_type const & get_segment( segment_id_type const & segment_id ) const
00633     {
00634       typename segment_id_map_type::const_iterator it = segment_id_map.find(segment_id);
00635       assert( it != segment_id_map.end() );
00636       return it->second; // segment already is present
00637     }
00638 
00644     segment_handle_type & get_segment( std::string const & segment_name )
00645     {
00646       typename segment_name_map_type::iterator it = segment_name_map.find(segment_name);
00647       assert( it != segment_name_map.end() );
00648       return *(it->second); // segment already is present
00649     }
00650 
00656     segment_handle_type const & get_segment( std::string const & segment_name ) const
00657     {
00658       typename segment_name_map_type::const_iterator it = segment_name_map.find(segment_name);
00659       assert( it != segment_name_map.end() );
00660       return *(it->second); // segment already is present
00661     }
00662 
00663 
00664 
00665 
00666 
00667 
00673     segment_handle_type & get_make_segment( segment_id_type const & segment_id )
00674     {
00675       typename segment_id_map_type::iterator it = segment_id_map.find(segment_id);
00676 
00677       if (it != segment_id_map.end())
00678           return it->second; // segment already is present
00679 
00680       segments.push_back( segment(this, mesh(), segment_id) );
00681       segment & new_segment = segments.back();
00682 
00683       if ( highest_id < segment_id )
00684           highest_id = segment_id;
00685 
00686       it = segment_id_map.insert( std::make_pair(segment_id, segment_handle_type(new_segment)) ).first;
00687 
00688       std::stringstream ss;
00689       ss << segment_id;
00690       segments.back().name = ss.str();
00691 
00692       if (!segment_name_map.insert(std::make_pair(ss.str(), &it->second)).second)
00693         throw segment_name_collision_exception(ss.str());
00694 
00695       return it->second;
00696     }
00697 
00703     segment_handle_type & get_make_segment( std::string const & segment_name )
00704     {
00705       typename segment_name_map_type::iterator it = segment_name_map.find(segment_name);
00706 
00707       if (it != segment_name_map.end())
00708           return *(it->second); // segment already is present
00709 
00710       segment_handle_type & segment = make_segment();
00711       segment.set_name(segment_name);
00712       return segment;
00713     }
00714 
00715 
00716 
00721     segment_handle_type & make_segment() { return get_make_segment( ++highest_id ); }
00722 
00723 
00724 
00730     segment_handle_type & operator()( segment_id_type const & segment_id ) { return get_make_segment(segment_id); }
00736     segment_handle_type & operator[]( segment_id_type const & segment_id ) { return get_make_segment(segment_id); }
00737 
00743     segment_handle_type const & operator()( segment_id_type const & segment_id ) const { return get_segment(segment_id); }
00749     segment_handle_type const & operator[]( segment_id_type const & segment_id ) const { return get_segment(segment_id); }
00755     segment_handle_type const & at( segment_id_type const & segment_id ) const
00756     {
00757       typename segment_id_map_type::const_iterator it = segment_id_map.find(segment_id);
00758       if( it == segment_id_map.end() )
00759         throw viennagrid::segment_id_not_found_exception(segment_id);
00760       return it->second;
00761     }
00762 
00763 
00764 
00765 
00771     segment_handle_type & operator()( std::string const & segment_name ) { return get_make_segment(segment_name); }
00777     segment_handle_type & operator[]( std::string const & segment_name ) { return get_make_segment(segment_name); }
00778 
00784     segment_handle_type const & operator()( std::string const & segment_name ) const { return get_segment(segment_name); }
00790     segment_handle_type const & operator[]( std::string const & segment_name ) const { return get_segment(segment_name); }
00796     segment_handle_type const & at( std::string const & segment_name ) const
00797     {
00798       typename segment_name_map_type::const_iterator it = segment_name_map.find(segment_name);
00799       if( it == segment_name_map.end() )
00800         throw viennagrid::segment_name_not_found_exception(segment_name);
00801       return it->second;
00802     }
00803 
00804 
00805 
00806 
00807 
00808 
00813     segment_id_type id_upper_bound() const { return highest_id; }
00814 
00815 
00817     class iterator : public segment_id_map_type::iterator
00818     {
00819       typedef typename segment_id_map_type::iterator base;
00820     public:
00821       iterator() {}
00822       iterator(base const & foo) : base(foo) {}
00823 
00824       typedef segment_handle_type           value_type;
00825       typedef segment_handle_type &         reference;
00826       typedef segment_handle_type const &   const_reference;
00827       typedef segment_handle_type *         pointer;
00828       typedef segment_handle_type const *   const_pointer;
00829 
00830       reference       operator* ()       { return base::operator*().second; }
00831       const_reference operator* () const { return base::operator*().second; }
00832 
00833       pointer       operator->()       { return &(operator* ()); }
00834       const_pointer operator->() const { return &(operator* ()); }
00835     };
00836 
00838     class const_iterator : public segment_id_map_type::const_iterator
00839     {
00840       typedef typename segment_id_map_type::const_iterator base;
00841     public:
00842       const_iterator() {}
00843       const_iterator(base const & foo) : base(foo) {}
00844       const_iterator(iterator const & it) : base(it) {}
00845 
00846       typedef segment_handle_type value_type;
00847       typedef segment_handle_type const & reference;
00848       typedef segment_handle_type const * pointer;
00849 
00850       reference operator* () const { return base::operator*().second; }
00851 
00852       pointer operator->() const { return &(operator* ()); }
00853     };
00854 
00859     iterator begin() { return iterator(segment_id_map.begin()); }
00864     iterator end() { return iterator(segment_id_map.end()); }
00865 
00870     const_iterator cbegin() const { return const_iterator(segment_id_map.begin()); }
00875     const_iterator cend() const { return const_iterator(segment_id_map.end()); }
00876 
00881     const_iterator begin() const { return cbegin(); }
00886     const_iterator end() const { return cend(); }
00887 
00892     std::size_t size() const { return segment_id_map.size(); }
00897     bool empty() const { return segment_id_map.empty(); }
00898 
00904     iterator find( segment_id_type const & segment_id ) { return iterator( segment_id_map.find(segment_id) ); }
00910     const_iterator find( segment_id_type const & segment_id ) const { return const_iterator( segment_id_map.find(segment_id) ); }
00911 
00915     void clear()
00916     {
00917       highest_id = -1;
00918       segment_id_map.clear();
00919       segments.clear();
00920       appendix_ = appendix_type();
00921     }
00922 
00923 
00924     view_type & all_elements() { return all_elements_; }
00925     view_type const & all_elements() const { return all_elements_; }
00926 
00927   private:
00928 
00929     view_type all_elements_;
00930 
00931     segment_id_type highest_id;
00932     segment_id_map_type segment_id_map;
00933     segment_name_map_type segment_name_map;
00934 
00935     segment_container_type segments;
00936 
00937     appendix_type appendix_;
00938 
00939     mesh_type * mesh_;
00940   };
00941 
00942 
00946   template<typename WrappedConfigT>
00947   void clear( segmentation<WrappedConfigT> & segmentation_ )
00948   {
00949     segmentation_.clear();
00950   }
00951 
00952 
00953   namespace detail
00954   {
00956     template<typename WrappedConfigT>
00957     typename viennagrid::segmentation<WrappedConfigT>::view_type::element_collection_type &
00958     element_collection( viennagrid::segmentation<WrappedConfigT> & segmentation)
00959     { return element_collection( segmentation.all_elements() ); }
00960 
00962     template<typename WrappedConfigT>
00963     typename viennagrid::segmentation<WrappedConfigT>::view_type::element_collection_type const &
00964     element_collection( viennagrid::segmentation<WrappedConfigT> const & segmentation)
00965     { return element_collection( segmentation.all_elements() ); }
00966   }
00967 
00968 
00969   // doxygen docu in mesh.hpp
00976   template<typename WrappedConfigT, typename HandleT>
00977   typename detail::result_of::value_type<HandleT>::type &
00978   dereference_handle(segmentation<WrappedConfigT> & segmentation_, HandleT const & handle)
00979   {
00980     return dereference_handle( segmentation_.mesh(), handle );
00981   }
00982 
00983   // doxygen docu in mesh.hpp
00990   template<typename WrappedConfigT, typename HandleT>
00991   typename detail::result_of::value_type<HandleT>::type const &
00992   dereference_handle(segmentation<WrappedConfigT> const & segmentation_, HandleT const & handle)
00993   {
00994     return dereference_handle( segmentation_.mesh(), handle );
00995   }
00996 
00997 
00998 
00999 
01000   namespace result_of
01001   {
01003     template<typename WrappedConfigType>
01004     struct mesh<viennagrid::segmentation<WrappedConfigType> >
01005     {
01006       typedef typename viennagrid::segmentation<WrappedConfigType>::mesh_type type;
01007     };
01008 
01010     template<typename SegmentationT>
01011     struct mesh<viennagrid::segment_handle<SegmentationT> >
01012     {
01013       typedef typename viennagrid::segment_handle<SegmentationT>::mesh_type type;
01014     };
01015 
01017     // doxygen docu in mesh.hpp
01018     template<typename WrappedConfigType, typename element_type_or_tag>
01019     struct is_element_present< viennagrid::segmentation<WrappedConfigType>, element_type_or_tag >
01020     {
01021       static const bool value = is_element_present< typename viennagrid::segmentation<WrappedConfigType>::mesh_type, element_type_or_tag>::value;
01022     };
01023 
01024     template<typename WrappedConfigType, typename element_type_or_tag>
01025     struct is_element_present< const viennagrid::segmentation<WrappedConfigType>, element_type_or_tag >
01026     {
01027       static const bool value = is_element_present<viennagrid::segmentation<WrappedConfigType>, element_type_or_tag>::value;
01028     };
01029 
01030 
01031     // doxygen docu in forwards.hpp
01032     template<typename segmentation_type>
01033     struct element_collection< viennagrid::segmentation<segmentation_type> >
01034     {
01035       typedef typename element_collection<typename viennagrid::segmentation<segmentation_type>::view_type>::type type;
01036     };
01037 
01038     template<typename segmentation_type>
01039     struct element_collection< const viennagrid::segmentation<segmentation_type> >
01040     {
01041       typedef typename element_collection<const typename viennagrid::segmentation<segmentation_type>::view_type>::type type;
01042     };
01043 
01044 
01045     // doxygen docu in mesh.hpp
01046     template<typename segmentation_type>
01047     struct point< viennagrid::segmentation<segmentation_type> >
01048     {
01049       typedef typename point<typename viennagrid::segmentation<segmentation_type>::mesh_type>::type type;
01050     };
01051 
01052 
01053 
01054     // doxygen docu in forwards.hpp
01055     template<typename segmentation_type, typename element_type_or_tag>
01056     struct element< viennagrid::segmentation<segmentation_type>, element_type_or_tag >
01057     {
01058       typedef typename element<typename viennagrid::segmentation<segmentation_type>::view_type, element_type_or_tag>::type type;
01059     };
01060 
01061     // doxygen docu in forwards.hpp
01062     template<typename segmentation_type, typename element_type_or_tag>
01063     struct handle< viennagrid::segmentation<segmentation_type>, element_type_or_tag >
01064     {
01065       typedef typename handle<typename viennagrid::segmentation<segmentation_type>::view_type, element_type_or_tag>::type type;
01066     };
01067 
01068     // doxygen docu in forwards.hpp
01069     template<typename segmentation_type, typename element_type_or_tag>
01070     struct const_handle< viennagrid::segmentation<segmentation_type>, element_type_or_tag >
01071     {
01072       typedef typename const_handle<typename viennagrid::segmentation<segmentation_type>::view_type, element_type_or_tag>::type type;
01073     };
01074 
01075 
01076     // doxygen docu in forwards.hpp
01077     template<typename segmentation_type, typename element_type_or_tag>
01078     struct element_range< viennagrid::segmentation<segmentation_type>, element_type_or_tag >
01079     {
01080       typedef typename element_range<typename viennagrid::segmentation<segmentation_type>::view_type, element_type_or_tag>::type type;
01081     };
01082 
01083     // doxygen docu in forwards.hpp
01084 
01085     template<typename segmentation_type, typename element_type_or_tag>
01086     struct const_element_range< viennagrid::segmentation<segmentation_type>, element_type_or_tag >
01087     {
01088       typedef typename const_element_range<typename viennagrid::segmentation<segmentation_type>::view_type, element_type_or_tag>::type type;
01089     };
01090 
01091     // doxygen docu in forwards.hpp
01092     template<typename segmentation_type>
01093     struct cell_tag< viennagrid::segmentation<segmentation_type> >
01094     {
01095       typedef typename cell_tag< typename viennagrid::segmentation<segmentation_type>::view_type >::type type;
01096     };
01098   }
01099 
01100 
01101   namespace detail
01102   {
01103 
01105     template<typename segment_id_type_, typename segment_element_info_type_ = viennagrid::null_type>
01106     struct element_segment_mapping
01107     {
01108       typedef segment_id_type_ segment_id_type;
01109       typedef segment_element_info_type_ segment_element_info_type;
01110 
01111       element_segment_mapping() {}
01112       element_segment_mapping( segment_id_type const & segment_id_ ) : segment_id(segment_id_) {}
01113 
01114       segment_id_type segment_id;
01115       segment_element_info_type segment_element_info;
01116     };
01117 
01118 
01120     template<typename element_segment_mapping_type, typename container_tag = viennagrid::std_vector_tag>
01121     struct segment_info_t
01122     {
01123       typedef typename element_segment_mapping_type::segment_id_type segment_id_type;
01124       typedef typename element_segment_mapping_type::segment_element_info_type segment_element_info_type;
01125 
01126       typedef typename viennagrid::result_of::container<element_segment_mapping_type, container_tag>::type element_segment_mapping_container_type;
01127 
01128 
01129       class const_iterator : public element_segment_mapping_container_type::const_iterator
01130       {
01131         typedef typename element_segment_mapping_container_type::const_iterator base;
01132       public:
01133         const_iterator() {}
01134         const_iterator(base const & foo) : base(foo) {}
01135 
01136         typedef segment_id_type           value_type;
01137         typedef segment_id_type &         reference;
01138         typedef segment_id_type const &   const_reference;
01139         typedef segment_id_type *         pointer;
01140         typedef segment_id_type const *   const_pointer;
01141 
01142         const_reference operator* () const { return base::operator*().segment_id; }
01143         const_pointer operator->() const { return &(operator* ()); }
01144       };
01145 
01146       const_iterator cbegin() const { return const_iterator(element_segment_mapping_container.begin()); }
01147       const_iterator cend()   const { return const_iterator(element_segment_mapping_container.end()); }
01148 
01149       const_iterator begin() const { return cbegin(); }
01150       const_iterator end()   const { return cend(); }
01151 
01152       std::size_t size() const { return element_segment_mapping_container.size(); }
01153 
01154       bool empty() const { return element_segment_mapping_container.empty(); }
01155 
01156       bool is_equal( segment_info_t const & other ) const
01157       {
01158         if ( size() != other.size() )
01159           return false;
01160 
01161         std::vector<segment_id_type> this_segment_ids( size() );
01162         std::vector<segment_id_type> other_segment_ids( other.size() );
01163 
01164         std::copy( begin(), end(), this_segment_ids.begin() );
01165         std::copy( other.begin(), other.end(), other_segment_ids.begin() );
01166 
01167         std::sort( this_segment_ids.begin(), this_segment_ids.end() );
01168         std::sort( other_segment_ids.begin(), other_segment_ids.end() );
01169 
01170         return this_segment_ids == other_segment_ids;
01171       }
01172 
01173 
01174       element_segment_mapping_container_type element_segment_mapping_container;
01175     };
01176 
01177 
01179     struct element_segment_mapping_tag;
01180 
01181     template<typename SegmentationT>
01182     typename viennagrid::detail::result_of::lookup<
01183             typename SegmentationT::appendix_type,
01184             element_segment_mapping_tag
01185         >::type & element_segment_mapping_collection( SegmentationT & segmentation )
01186     {
01187       return viennagrid::get<element_segment_mapping_tag>( segmentation.appendix() );
01188     }
01189 
01190     template<typename SegmentationT>
01191     typename viennagrid::detail::result_of::lookup<
01192             typename SegmentationT::appendix_type,
01193             element_segment_mapping_tag
01194         >::type const & element_segment_mapping_collection( SegmentationT const & segmentation )
01195     {
01196       return viennagrid::get<element_segment_mapping_tag>( segmentation.appendix() );
01197     }
01198 
01199 
01200     template<typename segment_handle_type>
01201     typename viennagrid::detail::result_of::lookup<
01202             typename segment_handle_type::segmentation_type::appendix_type,
01203             element_segment_mapping_tag
01204         >::type & element_segment_mapping_collection( segment_handle_type & segment )
01205     {
01206       return element_segment_mapping_collection( segment.parent() );
01207     }
01208 
01209     template<typename segment_handle_type>
01210     typename viennagrid::detail::result_of::lookup<
01211             typename segment_handle_type::segmentation_type::appendix_type,
01212             element_segment_mapping_tag
01213         >::type const & element_segment_mapping_collection( segment_handle_type const & segment )
01214     {
01215       return element_segment_mapping_collection( segment.parent() );
01216     }
01217 
01218 
01219 
01220 
01222     template<typename container_type_, typename ChangeCounterType>
01223     struct segment_interface_information_wrapper
01224     {
01225       typedef container_type_ container_type;
01226       typedef ChangeCounterType change_counter_type;
01227 
01228       segment_interface_information_wrapper() : seg0_change_counter(0), seg1_change_counter(0) {}
01229 
01230       change_counter_type seg0_change_counter;
01231       change_counter_type seg1_change_counter;
01232 
01233       container_type container;
01234     };
01235 
01236 
01238     template<typename segment_id_type, typename container_type_, typename ChangeCounterType>
01239     struct interface_information_wrapper
01240     {
01241       typedef container_type_ container_type;
01242       typedef segment_interface_information_wrapper<container_type, ChangeCounterType> segment_interface_information_wrapper_type;
01243       typedef std::pair<segment_id_type, segment_id_type> key_type;
01244       typedef std::map< key_type, segment_interface_information_wrapper_type > map_type;
01245 
01246       interface_information_wrapper() {}
01247 
01248       template<typename segment_handle_type>
01249       segment_interface_information_wrapper_type & get_interface_wrapper_impl( segment_handle_type const & seg0, segment_handle_type const & seg1 ) const
01250       {
01251         assert( seg0.id() != seg1.id() );
01252 
01253         key_type key( std::min(seg0.id(), seg1.id()), std::max(seg0.id(), seg1.id()) );
01254 
01255         return interface_flags[ key ];
01256       }
01257 
01258       template<typename segment_handle_type>
01259       segment_interface_information_wrapper_type & get_interface_wrapper( segment_handle_type const & seg0, segment_handle_type const & seg1 )
01260       { return get_interface_wrapper_impl(seg0, seg1); }
01261 
01262       template<typename segment_handle_type>
01263       segment_interface_information_wrapper_type const & get_interface_wrapper( segment_handle_type const & seg0, segment_handle_type const & seg1 ) const
01264       { return get_interface_wrapper_impl(seg0, seg1); }
01265 
01266       mutable map_type interface_flags;
01267     };
01268 
01269 
01270 
01271     template<typename element_tag, typename segment_handle_type>
01272     typename viennagrid::detail::result_of::lookup<
01273         typename viennagrid::detail::result_of::lookup<
01274             typename segment_handle_type::segmentation_type::appendix_type,
01275             interface_information_collection_tag
01276         >::type,
01277         element_tag
01278     >::type::segment_interface_information_wrapper_type &
01279     interface_information_collection( segment_handle_type & seg0, segment_handle_type & seg1 )
01280     { return viennagrid::get<element_tag>( viennagrid::get<interface_information_collection_tag>( seg0.parent().appendix() ) ).get_interface_wrapper(seg0, seg1); }
01281 
01282     template<typename element_tag, typename segment_handle_type>
01283     typename viennagrid::detail::result_of::lookup<
01284         typename viennagrid::detail::result_of::lookup<
01285             typename segment_handle_type::segmentation_type::appendix_type,
01286             interface_information_collection_tag
01287         >::type,
01288         element_tag
01289     >::type::segment_interface_information_wrapper_type const &
01290     interface_information_collection( segment_handle_type const & seg0, segment_handle_type const & seg1 )
01291     { return viennagrid::get<element_tag>( viennagrid::get<interface_information_collection_tag>( seg0.parent().appendix() ) ).get_interface_wrapper(seg0, seg1); }
01292 
01293 
01294 
01295 
01296     namespace result_of
01297     {
01299       template<typename segment_id_type, typename interface_information_container_tag, typename ChangeCounterType, typename element_taglist>
01300       struct interface_information_collection_typemap_impl;
01301 
01302       template<typename segment_id_type, typename interface_information_container_tag, typename ChangeCounterType>
01303       struct interface_information_collection_typemap_impl<segment_id_type, interface_information_container_tag, ChangeCounterType, viennagrid::null_type>
01304       {
01305         typedef viennagrid::null_type type;
01306       };
01307 
01308       template<typename segment_id_type, typename interface_information_container_tag, typename ChangeCounterType, typename element_tag, typename tail>
01309       struct interface_information_collection_typemap_impl<segment_id_type, interface_information_container_tag, ChangeCounterType, viennagrid::typelist<element_tag, tail> >
01310       {
01311         typedef typename viennagrid::result_of::container<bool, interface_information_container_tag >::type base_container;
01312 
01313         typedef viennagrid::typelist<
01314             viennagrid::static_pair<
01315                 element_tag,
01316                 interface_information_wrapper<segment_id_type, base_container, ChangeCounterType>
01317             >,
01318             typename interface_information_collection_typemap_impl<segment_id_type, interface_information_container_tag, ChangeCounterType, tail>::type
01319         > type;
01320       };
01321 
01322 
01323       template<typename element_taglist, typename segment_id_type, typename interface_information_container_tag, typename ChangeCounterType>
01324       struct interface_information_collection_typemap
01325       {
01326         typedef typename viennagrid::result_of::cell_tag_from_typelist<element_taglist>::type cell_tag;
01327         typedef typename viennagrid::detail::result_of::erase< element_taglist, cell_tag>::type element_typelist_without_cell_tag;
01328 
01329         typedef typename interface_information_collection_typemap_impl<segment_id_type, interface_information_container_tag, ChangeCounterType, element_typelist_without_cell_tag>::type type;
01330       };
01331     }
01332 
01333     namespace result_of
01334     {
01336       template<typename segment_element_info_container_typemap, typename segment_id_type, typename container_tag, typename segment_info_container_tag>
01337       struct segmentation_info_container_typemap;
01338 
01339       template<typename segment_id_type, typename container_tag, typename segment_info_container_tag>
01340       struct segmentation_info_container_typemap< viennagrid::null_type, segment_id_type, container_tag, segment_info_container_tag >
01341       {
01342         typedef viennagrid::null_type type;
01343       };
01344 
01345       template<typename element_tag, typename segment_info_type, typename tail, typename segment_id_type, typename container_tag, typename segment_info_container_tag>
01346       struct segmentation_info_container_typemap< viennagrid::typelist<viennagrid::static_pair<element_tag, segment_info_type>, tail>, segment_id_type, container_tag, segment_info_container_tag >
01347       {
01348         typedef viennagrid::static_pair< element_tag, segment_info_type > key_type;
01349         typedef typename viennagrid::result_of::container< std::pair<segment_id_type, segment_info_type>, segment_info_container_tag>::type segment_info_container;
01350         typedef typename viennagrid::result_of::container<segment_info_container, container_tag>::type container_type;
01351 
01352         typedef viennagrid::typelist<
01353             viennagrid::static_pair<
01354                 element_tag,
01355                 container_type
01356             >,
01357             typename segmentation_info_container_typemap<tail, segment_id_type, container_tag, segment_info_container_tag>::type
01358         > type;
01359       };
01360 
01361 
01363       template<typename element_typelist, typename segment_id_type, typename container_tag = viennagrid::std_deque_tag>
01364       struct trivial_segmentation_appendix;
01365 
01366       template<typename segment_id_type,typename container_tag>
01367       struct trivial_segmentation_appendix< viennagrid::null_type, segment_id_type, container_tag >
01368       {
01369         typedef viennagrid::null_type type;
01370       };
01371 
01372       template<typename element_type, typename tail, typename segment_id_type, typename container_tag>
01373       struct trivial_segmentation_appendix< viennagrid::typelist<element_type, tail>, segment_id_type, container_tag >
01374       {
01375         typedef viennagrid::typelist<
01376             viennagrid::static_pair<
01377                 element_type,
01378                 typename viennagrid::result_of::container<
01379                     segment_info_t< element_segment_mapping<segment_id_type> >,
01380                     container_tag
01381                 >::type
01382             >,
01383             typename trivial_segmentation_appendix<tail, segment_id_type, container_tag>::type
01384         > type;
01385       };
01386     } //namespace result_of
01387   } //namespace detail
01388 
01389   namespace result_of
01390   {
01391 
01399     template<typename MeshT,
01400              typename ViewT = typename viennagrid::result_of::mesh_view<MeshT>::type,
01401              typename SegmentIDType = int,
01402              typename AppendixType =
01403                 viennagrid::collection<
01404                     typename viennagrid::make_typemap<
01405                         viennagrid::detail::element_segment_mapping_tag,
01406                         viennagrid::collection<
01407                             typename viennagrid::detail::result_of::trivial_segmentation_appendix<
01408                                 typename viennagrid::result_of::element_typelist<MeshT>::type,
01409                                 SegmentIDType
01410                             >::type
01411                         >,
01412 
01413 
01414                         interface_information_collection_tag,
01415                         viennagrid::collection<
01416                           typename viennagrid::detail::result_of::interface_information_collection_typemap<
01417                             typename viennagrid::result_of::element_taglist<MeshT>::type,
01418                             SegmentIDType,
01419                             viennagrid::std_vector_tag,
01420                             typename viennagrid::result_of::change_counter_type<MeshT>::type
01421                           >::type
01422                         >
01423 
01424                     >::type
01425                 >,
01426             typename view_container_tag = viennagrid::std_deque_tag >
01427     struct segmentation
01428     {
01429       typedef config::segmentation_config_wrapper_t<MeshT, ViewT, SegmentIDType, AppendixType, view_container_tag> WrappedConfigType;
01430 
01431       typedef viennagrid::segmentation<WrappedConfigType> type;
01432     };
01433 
01435     template<typename SegmentationT>
01436     struct segmentation< viennagrid::segment_handle<SegmentationT> >
01437     {
01438       typedef SegmentationT  type;
01439     };
01440 
01441     template<typename SegmentationT>
01442     struct segmentation< viennagrid::segment_handle<const SegmentationT> >
01443     {
01444       typedef SegmentationT  type;
01445     };
01446 
01447 
01455     template<typename MeshT,
01456              typename ViewT =
01457               typename viennagrid::result_of::mesh_view_from_typelist<
01458                 MeshT,
01459                 typename viennagrid::make_typelist<typename viennagrid::result_of::cell<MeshT>::type>::type,
01460                 viennagrid::make_typemap<default_tag, std_deque_tag>::type
01461               >::type,
01462              typename SegmentIDType = int,
01463              typename AppendixType =
01464                 viennagrid::collection<
01465                     typename viennagrid::make_typemap<
01466                         viennagrid::detail::element_segment_mapping_tag,
01467                         viennagrid::collection<
01468                             typename viennagrid::detail::result_of::trivial_segmentation_appendix<
01469                                 typename viennagrid::result_of::element_typelist<MeshT>::type,
01470                                 SegmentIDType
01471                             >::type
01472                         >,
01473 
01474 
01475                         interface_information_collection_tag,
01476                         viennagrid::collection<
01477                           typename viennagrid::detail::result_of::interface_information_collection_typemap<
01478                             typename viennagrid::result_of::element_taglist<MeshT>::type,
01479                             SegmentIDType,
01480                             viennagrid::std_vector_tag,
01481                             typename viennagrid::result_of::change_counter_type<MeshT>::type
01482                           >::type
01483                         >
01484 
01485                     >::type
01486                 >,
01487             typename view_container_tag = viennagrid::std_deque_tag >
01488     struct cell_only_segmentation
01489     {
01490       typedef config::segmentation_config_wrapper_t<MeshT, ViewT, SegmentIDType, AppendixType, view_container_tag> WrappedConfigType;
01491 
01492       typedef viennagrid::segmentation<WrappedConfigType> type;
01493     };
01494 
01495 
01496 
01497 
01505     template<typename MeshT,
01506              typename ViewT = typename viennagrid::result_of::mesh_view<MeshT>::type,
01507              typename SegmentIDType = int,
01508              typename AppendixType =
01509               viennagrid::collection<
01510                 typename viennagrid::make_typemap<
01511                     viennagrid::detail::element_segment_mapping_tag,
01512                     viennagrid::collection<
01513                         typename viennagrid::detail::result_of::modify<
01514                             typename viennagrid::detail::result_of::trivial_segmentation_appendix<
01515                                 typename viennagrid::result_of::element_typelist<MeshT>::type,
01516                                 SegmentIDType
01517                             >::type,
01518                             viennagrid::static_pair<
01519                                 typename viennagrid::result_of::element< MeshT, viennagrid::triangle_tag >::type,
01520                                 typename viennagrid::result_of::container<
01521                                     viennagrid::detail::segment_info_t< viennagrid::detail::element_segment_mapping<SegmentIDType, bool> >,
01522                                     viennagrid::std_deque_tag
01523                                 >::type
01524                             >
01525                         >::type
01526                     >,
01527 
01528                     interface_information_collection_tag,
01529                     viennagrid::collection<
01530                       typename viennagrid::detail::result_of::interface_information_collection_typemap<
01531                         typename viennagrid::result_of::element_taglist<MeshT>::type,
01532                         SegmentIDType,
01533                         viennagrid::std_vector_tag,
01534                         typename viennagrid::result_of::change_counter_type<MeshT>::type
01535                       >::type
01536                     >
01537 
01538                 >::type
01539             >,
01540             typename view_container_tag = viennagrid::std_deque_tag >
01541     struct oriented_3d_hull_segmentation
01542     {
01543       typedef config::segmentation_config_wrapper_t<MeshT, ViewT, SegmentIDType, AppendixType, view_container_tag> WrappedConfigType;
01544 
01545       typedef viennagrid::segmentation<WrappedConfigType> type;
01546     };
01547 
01548   }
01549 
01550 
01551 
01552   namespace detail
01553   {
01554 
01555 
01557     template<typename segment_handle_type, typename element_segment_mapping_type, typename container_tag>
01558     bool is_in_segment( segment_handle_type const & segment, segment_info_t<element_segment_mapping_type, container_tag> const & segment_info )
01559     {
01560       typedef typename segment_info_t<element_segment_mapping_type, container_tag>::element_segment_mapping_container_type element_segment_mapping_container_type;
01561 
01562       for (typename element_segment_mapping_container_type::const_iterator it = segment_info.element_segment_mapping_container.begin();
01563             it != segment_info.element_segment_mapping_container.end();
01564             ++it)
01565       {
01566         if (it->segment_id == segment.id()) return true;
01567       }
01568 
01569       return false;
01570     }
01571 
01573     template< typename segment_handle_type, typename accessor_type, typename element_type >
01574     bool is_in_segment( segment_handle_type const & segment, accessor_type const accessor, element_type const & element )
01575     {
01576       return is_in_segment( segment, accessor(element) );
01577     }
01578   }
01579 
01589   template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
01590   bool is_in_segment( SegmentHandleT const & segment, viennagrid::element<ElementTagT, WrappedConfigT> const & element )
01591   {
01592     typedef viennagrid::element<ElementTagT, WrappedConfigT> element_type;
01593     return detail::is_in_segment( segment, viennagrid::make_accessor<element_type>( element_segment_mapping_collection(segment) ), element );
01594   }
01595 
01596 
01601   template<typename SegmentInfoT>
01602   struct segment_id_range_t
01603   {
01604   public:
01605 
01606     segment_id_range_t(SegmentInfoT & segment_info) : segment_info_(&segment_info) {}
01607 
01609     typedef typename SegmentInfoT::const_iterator         iterator;
01611     typedef typename SegmentInfoT::const_iterator   const_iterator;
01612 
01617     iterator begin() { return segment_info_->begin(); }
01622     iterator end() { return segment_info_->end(); }
01623 
01628     const_iterator cbegin() { return segment_info_->cbegin(); }
01633     const_iterator cend() { return segment_info_->cend(); }
01634 
01639     const_iterator begin() const { return segment_info_->begin(); }
01644     const_iterator end() const { return segment_info_->end(); }
01645 
01650     std::size_t size() const { return segment_info_->size(); }
01651 
01656     bool empty() const { return segment_info_->empty(); }
01657 
01663     std::size_t is_equal( segment_id_range_t<SegmentInfoT> const & other ) const { return segment_info_->is_equal(*other.segment_info_); }
01664 
01665   private:
01666     SegmentInfoT * segment_info_;
01667   };
01668 
01669   namespace result_of
01670   {
01676     template<typename SegmentationT, typename ElementTypeOrTagT>
01677     struct segment_id_range
01678     {
01679       typedef typename viennagrid::result_of::element_tag<ElementTypeOrTagT>::type ElementTagT;
01680       typedef typename viennagrid::result_of::element<SegmentationT, ElementTagT>::type ElementType;
01681 
01682       typedef typename viennagrid::detail::result_of::lookup<
01683           typename SegmentationT::appendix_type,
01684           viennagrid::detail::element_segment_mapping_tag
01685       >::type ElementSegmentMappingCollectionType;
01686 
01687       typedef typename viennagrid::result_of::container_of<
01688         ElementSegmentMappingCollectionType,
01689         ElementType
01690       >::type ElementSegmentMappingContainerType;
01691 
01692       typedef segment_id_range_t<const typename ElementSegmentMappingContainerType::value_type> type;
01693     };
01694 
01696     template<typename SegmentationT, typename ElementTypeOrTagT>
01697     struct segment_id_range< viennagrid::segment_handle<SegmentationT>, ElementTypeOrTagT >
01698     {
01699       typedef typename segment_id_range<SegmentationT, ElementTypeOrTagT>::type type;
01700     };
01702   }
01703 
01713   template<typename SegmentationT, typename ElementTagT, typename WrappedConfigT>
01714   typename result_of::segment_id_range< SegmentationT, viennagrid::element<ElementTagT, WrappedConfigT> >::type segment_ids( SegmentationT const & segmentation, viennagrid::element<ElementTagT, WrappedConfigT> const & element )
01715   {
01716     typedef typename result_of::segment_id_range< SegmentationT, viennagrid::element<ElementTagT, WrappedConfigT> >::type SegmentIDRangeType;
01717     typedef viennagrid::element<ElementTagT, WrappedConfigT> ElementType;
01718     return SegmentIDRangeType( viennagrid::make_field<ElementType>( viennagrid::detail::element_segment_mapping_collection(segmentation) )(element) );
01719   }
01720 
01721 
01722 
01723   namespace detail
01724   {
01725 
01727     template<typename segment_handle_type, typename element_segment_mapping_type, typename container_tag>
01728     typename element_segment_mapping_type::segment_element_info_type *
01729     segment_element_info( segment_handle_type const & segment, segment_info_t<element_segment_mapping_type, container_tag> & segment_info )
01730     {
01731       typedef typename segment_info_t<element_segment_mapping_type, container_tag>::element_segment_mapping_container_type element_segment_mapping_container_type;
01732 
01733       for (typename element_segment_mapping_container_type::iterator it = segment_info.element_segment_mapping_container.begin();
01734             it != segment_info.element_segment_mapping_container.end();
01735             ++it)
01736       {
01737         if (it->segment_id == segment.id())
01738           return &(it->segment_element_info);
01739       }
01740 
01741       return NULL;
01742     }
01743 
01745     template<typename segment_handle_type, typename element_segment_mapping_type, typename container_tag>
01746     typename element_segment_mapping_type::segment_element_info_type const *
01747     segment_element_info( segment_handle_type const & segment, segment_info_t<element_segment_mapping_type, container_tag> const & segment_info )
01748     {
01749       typedef typename segment_info_t<element_segment_mapping_type, container_tag>::element_segment_mapping_container_type element_segment_mapping_container_type;
01750 
01751       for (typename element_segment_mapping_container_type::const_iterator it = segment_info.element_segment_mapping_container.begin();
01752             it != segment_info.element_segment_mapping_container.end();
01753             ++it)
01754       {
01755         if (it->segment_id == segment.id())
01756           return &(it->segment_element_info);
01757       }
01758 
01759       return NULL;
01760     }
01761 
01763     template< typename segment_handle_type, typename accessor_type, typename element_type >
01764     typename accessor_type::value_type::segment_element_info_type *
01765     segment_element_info( segment_handle_type & segment, accessor_type accessor, element_type const & element )
01766     {
01767       return segment_element_info( segment, accessor(element) );
01768     }
01769 
01771     template< typename segment_handle_type, typename accessor_type, typename element_type >
01772     typename accessor_type::value_type::segment_element_info_type const *
01773     segment_element_info( segment_handle_type const & segment, const accessor_type accessor, element_type const & element )
01774     {
01775       return segment_element_info( segment, accessor(element) );
01776     }
01777   }
01778 
01788   template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
01789   typename viennagrid::result_of::container_of<
01790       typename viennagrid::detail::result_of::lookup<
01791           typename SegmentHandleT::segmentation_type::appendix_type,
01792           viennagrid::detail::element_segment_mapping_tag
01793       >::type,
01794       viennagrid::element<ElementTagT, WrappedConfigT>
01795   >::type::value_type::segment_element_info_type const *
01796   segment_element_info( SegmentHandleT const & segment, viennagrid::element<ElementTagT, WrappedConfigT> const & element )
01797   {
01798     typedef viennagrid::element<ElementTagT, WrappedConfigT> element_type;
01799     return detail::segment_element_info( segment, viennagrid::make_accessor<element_type>( element_segment_mapping_collection(segment) ), element );
01800   }
01801 
01811   template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
01812   typename viennagrid::result_of::container_of<
01813       typename viennagrid::detail::result_of::lookup<
01814           typename SegmentHandleT::segmentation_type::appendix_type,
01815           viennagrid::detail::element_segment_mapping_tag
01816       >::type,
01817       viennagrid::element<ElementTagT, WrappedConfigT>
01818   >::type::value_type::segment_element_info_type *
01819   segment_element_info( SegmentHandleT & segment, viennagrid::element<ElementTagT, WrappedConfigT> const & element )
01820   {
01821     typedef viennagrid::element<ElementTagT, WrappedConfigT> element_type;
01822     return detail::segment_element_info( segment, viennagrid::make_accessor<element_type>( element_segment_mapping_collection(segment) ), element );
01823   }
01824 
01825 
01826   namespace detail
01827   {
01829     template<typename segment_handle_type, typename element_segment_mapping_type, typename container_tag>
01830     void add(segment_handle_type & segment,
01831              segment_info_t<element_segment_mapping_type, container_tag> & segment_info)
01832     {
01833       typedef typename segment_info_t<element_segment_mapping_type, container_tag>::element_segment_mapping_container_type element_segment_mapping_container_type;
01834 
01835       for (typename element_segment_mapping_container_type::const_iterator it = segment_info.element_segment_mapping_container.begin();
01836             it != segment_info.element_segment_mapping_container.end();
01837             ++it)
01838       {
01839         if (it->segment_id == segment.id()) return;
01840       }
01841 
01842       segment_info.element_segment_mapping_container.push_back( element_segment_mapping_type(segment.id()) );
01843       increment_change_counter( segment.view() );
01844     }
01845 
01847     template< typename segment_handle_type, typename accessor_type, typename element_type >
01848     void add( segment_handle_type & segment, accessor_type accessor, element_type & element )
01849     {
01850       return add( segment, accessor(element) );
01851     }
01852   }
01853 
01854 
01855 
01856   namespace detail
01857   {
01859     template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
01860     void simple_add( SegmentHandleT & segment, viennagrid::element<ElementTagT, WrappedConfigT> & element )
01861     {
01862       typedef viennagrid::element<ElementTagT, WrappedConfigT> ElementType;
01863 
01864       viennagrid::elements<ElementType>( segment.view() ).insert_unique_handle( viennagrid::handle( segment.parent().mesh(), element ) );
01865       viennagrid::elements<ElementType>( segment.parent().all_elements() ).insert_unique_handle( viennagrid::handle( segment.parent().mesh(), element ) );
01866       add( segment, viennagrid::make_accessor<ElementType>( detail::element_segment_mapping_collection(segment) ), element );
01867     }
01868 
01870     template<typename SegmentT>
01871     struct add_functor
01872     {
01873       add_functor(SegmentT & segment_) : segment(segment_) {}
01874 
01875       template<typename BoundaryElementT>
01876       void operator()( BoundaryElementT & boundary_element )
01877       {
01878         detail::simple_add(segment, boundary_element);
01879       }
01880 
01881       SegmentT & segment;
01882     };
01883 
01885     template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
01886     void simple_unchecked_add( SegmentHandleT & segment, viennagrid::element<ElementTagT, WrappedConfigT> & element )
01887     {
01888       typedef viennagrid::element<ElementTagT, WrappedConfigT> ElementType;
01889 
01890       viennagrid::elements<ElementType>( segment.view() ).insert_handle( viennagrid::handle( segment.parent().mesh(), element ) );
01891       viennagrid::elements<ElementType>( segment.parent().all_elements() ).insert_handle( viennagrid::handle( segment.parent().mesh(), element ) );
01892       add( segment, viennagrid::make_accessor<ElementType>( detail::element_segment_mapping_collection(segment) ), element );
01893     }
01894 
01896     template<typename SegmentT>
01897     struct unchecked_add_functor
01898     {
01899       unchecked_add_functor(SegmentT & segment_) : segment(segment_) {}
01900 
01901       template<typename BoundaryElementT>
01902       void operator()( BoundaryElementT & boundary_element )
01903       {
01904         detail::simple_unchecked_add(segment, boundary_element);
01905       }
01906 
01907       SegmentT & segment;
01908     };
01909   }
01910 
01911 
01912 
01913 
01914 
01923   template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
01924   void add( SegmentHandleT & segment, viennagrid::element<ElementTagT, WrappedConfigT> & element )
01925   {
01926     typedef viennagrid::element<ElementTagT, WrappedConfigT> ElementType;
01927 
01928     detail::simple_add(segment, element);
01929 
01930     typedef typename ElementType::boundary_cell_typelist BoundaryElementTypelist;
01931     typedef typename viennagrid::result_of::element_typelist<SegmentHandleT>::type SegmentTypelist;
01932     typedef typename viennagrid::detail::result_of::intersection<BoundaryElementTypelist, SegmentTypelist>::type ForEachTypelist;
01933 
01934     detail::add_functor<SegmentHandleT> af(segment);
01935     for_each_boundary_element<ForEachTypelist>( element, af );
01936   }
01937 
01945   template<typename SegmentHandleT, typename ElementHandleT>
01946   void add( SegmentHandleT & segment, ElementHandleT element_handle )
01947   { viennagrid::add( segment, viennagrid::dereference_handle(segment, element_handle) ); }
01948 
01949 
01950 
01960   template<typename WrappedConfigT, typename ElementTagT, typename WrappedElementConfigT>
01961   void add( segmentation<WrappedConfigT> & segmentation_obj,
01962             typename segmentation<WrappedConfigT>::segment_id_type segment_id,
01963             viennagrid::element<ElementTagT, WrappedElementConfigT> & element)
01964   { add( segmentation_obj[segment_id], element ); }
01965 
01974   template<typename WrappedConfigT, typename ElementHandleT>
01975   void add( segmentation<WrappedConfigT> & segmentation_obj,
01976             typename segmentation<WrappedConfigT>::segment_id_type segment_id,
01977             ElementHandleT element_handle)
01978   { add( segmentation_obj[segment_id], element_handle ); }
01979 
01980 
01992   template<typename WrappedConfigT, typename SegmentIDIteratorT, typename ElementTagT, typename WrappedElementConfigT>
01993   void add( segmentation<WrappedConfigT> & segmentation_obj,
01994             SegmentIDIteratorT segment_ids_it, SegmentIDIteratorT const & segment_ids_end,
01995             viennagrid::element<ElementTagT, WrappedElementConfigT> & element)
01996   {
01997     for (; segment_ids_it != segment_ids_end; ++segment_ids_it)
01998       add( segmentation_obj[*segment_ids_it], element );
01999   }
02000 
02011   template<typename WrappedConfigT, typename SegmentIDIteratorT, typename ElementHandleT>
02012   void add( segmentation<WrappedConfigT> & segmentation_obj,
02013             SegmentIDIteratorT segment_ids_it, SegmentIDIteratorT const & segment_ids_end,
02014             ElementHandleT element_handle)
02015   {
02016     for (; segment_ids_it != segment_ids_end; ++segment_ids_it)
02017       add( segmentation_obj[*segment_ids_it], element_handle );
02018   }
02019 
02020 
02029   template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
02030   void unchecked_add( SegmentHandleT & segment, viennagrid::element<ElementTagT, WrappedConfigT> & element )
02031   {
02032     typedef viennagrid::element<ElementTagT, WrappedConfigT> ElementType;
02033 
02034     detail::simple_unchecked_add(segment, element);
02035 
02036     typedef typename ElementType::boundary_cell_typelist BoundaryElementTypelist;
02037     typedef typename viennagrid::result_of::element_typelist<SegmentHandleT>::type SegmentTypelist;
02038     typedef typename viennagrid::detail::result_of::intersection<BoundaryElementTypelist, SegmentTypelist>::type ForEachTypelist;
02039 
02040     detail::unchecked_add_functor<SegmentHandleT> uaf(segment);
02041     for_each_boundary_element<ForEachTypelist>( element, uaf );
02042   }
02043 
02051   template<typename SegmentHandleT, typename ElementHandleT>
02052   void unchecked_add( SegmentHandleT & segment, ElementHandleT element_handle )
02053   { viennagrid::unchecked_add( segment, viennagrid::dereference_handle(segment, element_handle) ); }
02054 
02055 
02056   namespace detail
02057   {
02058 
02059 
02061     template<typename SegmentHandleT, typename ElementSegmentMappingT, typename ContainerTagT>
02062     void erase( SegmentHandleT & segment, segment_info_t<ElementSegmentMappingT, ContainerTagT> & segment_info )
02063     {
02064       typedef typename segment_info_t<ElementSegmentMappingT, ContainerTagT>::element_segment_mapping_container_type element_segment_mapping_container_type;
02065 
02066       for (typename element_segment_mapping_container_type::iterator it = segment_info.element_segment_mapping_container.begin();
02067                                                                      it != segment_info.element_segment_mapping_container.end();
02068                                                                    ++it)
02069       {
02070         if (it->segment_id == segment.id())
02071         {
02072           segment_info.element_segment_mapping_container.erase(it);
02073           increment_change_counter( segment.view() );
02074           return;
02075         }
02076       }
02077     }
02078 
02080     template< typename SegmentHandleT, typename AccessorT, typename ElementT >
02081     void erase( SegmentHandleT & segment, AccessorT accessor, ElementT const & element )
02082     {
02083       return erase( segment, accessor(element) );
02084     }
02085 
02086 
02087 //   template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
02088 //   bool non_recursive_erase( SegmentHandleT & segment, viennagrid::element<ElementTagT, WrappedConfigT> & element )
02089 //   {
02090 //     typedef viennagrid::element<ElementTagT, WrappedConfigT> element_type;
02091 //     viennagrid::elements<element_type>( segment.view() ).erase_handle( viennagrid::handle( segment.parent().mesh(), element ) );
02092 //     return erase( segment, viennagrid::make_accessor<element_type>( element_segment_mapping_collection(segment) ), element );
02093 //   }
02094 
02095     template<typename SegmentHandleT>
02096     struct non_recursive_erase_functor
02097     {
02098       non_recursive_erase_functor(SegmentHandleT & segment_) : segment(segment_) {}
02099 
02100       template<typename ElementT>
02101       void operator() ( ElementT & element )
02102       {
02103         // erasing element from segment view
02104         viennagrid::elements<ElementT>( segment.view() ).erase_handle( viennagrid::handle( segment.parent().mesh(), element ) );
02105         // erasing element from segment-element information
02106         erase( segment, viennagrid::make_accessor<ElementT>( element_segment_mapping_collection(segment) ), element );
02107 
02108         if (segment_ids(segment.parent(), element).empty())
02109           viennagrid::elements<ElementT>( segment.parent().all_elements() ).erase_handle( viennagrid::handle( segment.parent().mesh(), element ) );
02110       }
02111 
02112       SegmentHandleT & segment;
02113     };
02114   }
02115 
02116 
02117 
02127   template<typename SegmentationType, typename ElementTagT, typename WrappedConfigT>
02128   typename result_of::handle<segment_handle<SegmentationType>, viennagrid::element<ElementTagT, WrappedConfigT> >::type
02129   handle(segment_handle<SegmentationType> & mesh_or_segment, viennagrid::element<ElementTagT, WrappedConfigT> & element)
02130   { return get< viennagrid::element<ElementTagT, WrappedConfigT> >(detail::element_collection(mesh_or_segment)).handle( element ); }
02131 
02141   template<typename SegmentationType, typename ElementTagT, typename WrappedConfigT>
02142   typename result_of::const_handle<segment_handle<SegmentationType>, viennagrid::element<ElementTagT, WrappedConfigT> >::type
02143   handle(segment_handle<SegmentationType> const & mesh_or_segment, viennagrid::element<ElementTagT, WrappedConfigT> const & element)
02144   { return get< viennagrid::element<ElementTagT, WrappedConfigT> >(detail::element_collection(mesh_or_segment)).handle( element ); }
02145 
02146 
02156   template<typename SegmentHandleT, typename ElementTagT, typename WrappedConfigT>
02157   void erase( SegmentHandleT & segment, viennagrid::element<ElementTagT, WrappedConfigT> & element )
02158   {
02159     typedef typename viennagrid::result_of::mesh_view<SegmentHandleT>::type ToEraseViewT;
02160     ToEraseViewT elements_to_erase = viennagrid::make_view(segment);
02161     viennagrid::mark_referencing_elements( segment, elements_to_erase, viennagrid::handle(segment, element) );
02162 
02163     detail::non_recursive_erase_functor<SegmentHandleT> functor( segment );
02164     viennagrid::for_each(elements_to_erase, functor);
02165   }
02166 
02167 
02168   namespace detail
02169   {
02170 
02172     template<bool generate_id, bool call_callback, typename SegmentationType, typename ElementTag, typename WrappedConfigType>
02173     std::pair<
02174                 typename viennagrid::result_of::container_of<
02175                     typename viennagrid::result_of::element_collection< viennagrid::segment_handle<SegmentationType> >::type,
02176                     viennagrid::element<ElementTag, WrappedConfigType>
02177                 >::type::handle_type,
02178                 bool
02179             >
02180     push_element( viennagrid::segment_handle<SegmentationType> & segment, viennagrid::element<ElementTag, WrappedConfigType> const & element)
02181     {
02182       std::pair<
02183               typename viennagrid::result_of::container_of<
02184                   typename viennagrid::result_of::element_collection< viennagrid::segment_handle<SegmentationType> >::type,
02185                   viennagrid::element<ElementTag, WrappedConfigType>
02186               >::type::handle_type,
02187               bool
02188           > result = push_element<generate_id, call_callback>( segment.view(), element );
02189 
02190       viennagrid::add( segment, viennagrid::dereference_handle(segment, result.first) );
02191       return result;
02192     }
02193   }
02194 
02195 
02196 
02197 
02205   template<typename ViewT, typename HandleT>
02206   void add_single_handle( ViewT & view_or_segment, HandleT handle )
02207   {
02208     typedef typename detail::result_of::value_type<HandleT>::type value_type;
02209     value_type & element = dereference_handle(view_or_segment, handle);
02210 
02211     typedef typename viennagrid::result_of::element_range< ViewT, value_type >::type range_type;
02212     typedef typename viennagrid::result_of::iterator<range_type>::type iterator_type;
02213 
02214     iterator_type it = find( view_or_segment, element.id() );
02215     if ( it == elements<value_type>(view_or_segment).end() )
02216       viennagrid::get<value_type>( detail::element_collection(view_or_segment) ).insert_handle( handle );
02217 
02218     viennagrid::detail::increment_change_counter(view_or_segment);
02219   }
02220 
02221 
02222 
02223 
02224 
02225 
02226 
02227   namespace detail
02228   {
02230     template<typename SourceMeshT, typename SourceSegmentationT,
02231             typename DestinationMeshT, typename DestinationSegmentationT>
02232     struct copy_segmentation_functor
02233     {
02234       copy_segmentation_functor(SourceMeshT const & src_mesh_, SourceSegmentationT const & src_segmentation_,
02235                                 DestinationMeshT & dst_mesh_, DestinationSegmentationT & dst_segmentation_) :
02236                                 src_mesh(src_mesh_), src_segmentation(src_segmentation_),
02237                                 dst_mesh(dst_mesh_), dst_segmentation(dst_segmentation_) {}
02238 
02239       template<typename DestinationElementT>
02240       void operator()( DestinationElementT & dst_element )
02241       {
02242         typedef typename viennagrid::result_of::element_tag<DestinationElementT>::type ElementTag;
02243         typedef typename viennagrid::result_of::const_element_range<SourceMeshT, ElementTag>::type ConstSourceElementRangeType;
02244         typedef typename viennagrid::result_of::iterator<ConstSourceElementRangeType>::type ConstSourceElementIteratorType;
02245 
02246         ConstSourceElementIteratorType src_eit = viennagrid::find( src_mesh, dst_element.id() );
02247 
02248         typedef typename viennagrid::result_of::element<SourceMeshT, ElementTag>::type SourceElementType;
02249         typedef typename viennagrid::result_of::segment_id_range<SourceSegmentationT, SourceElementType>::type SegmentIDRangeType;
02250         typedef typename viennagrid::result_of::iterator<SegmentIDRangeType>::type SegmentIDIteratorType;
02251         SegmentIDRangeType segment_ids = viennagrid::segment_ids(src_segmentation, *src_eit);
02252         for (SegmentIDIteratorType sit = segment_ids.begin(); sit != segment_ids.end(); ++sit)
02253         {
02254           viennagrid::add( dst_segmentation.get_make_segment(*sit), dst_element );
02255         }
02256       }
02257 
02258       SourceMeshT const & src_mesh;
02259       SourceSegmentationT const & src_segmentation;
02260 
02261       DestinationMeshT & dst_mesh;
02262       DestinationSegmentationT & dst_segmentation;
02263     };
02264   }
02265 
02266 
02274   template<typename SourceMeshT, typename SourceSegmentationT,
02275            typename DestinationMeshT, typename DestinationSegmentationT>
02276   void copy_segmentation(SourceMeshT const & src_mesh_, SourceSegmentationT const & src_segmentation_,
02277                          DestinationMeshT & dst_mesh_, DestinationSegmentationT & dst_segmentation_)
02278   {
02279     detail::copy_segmentation_functor<SourceMeshT, SourceSegmentationT, DestinationMeshT, DestinationSegmentationT> functor( src_mesh_, src_segmentation_, dst_mesh_, dst_segmentation_ );
02280     viennagrid::for_each(dst_mesh_, functor);
02281   }
02282 
02283 
02284 }
02285 
02286 
02287 
02288 
02289 #endif