ViennaGrid - The Vienna Grid Library
2.1.0
|
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