ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_MESH_NEIGHBOR_ITERATION_HPP 00002 #define VIENNAGRID_MESH_NEIGHBOR_ITERATION_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 "viennagrid/mesh/segmentation.hpp" 00017 #include "viennagrid/mesh/coboundary_iteration.hpp" 00018 00022 #include "../forwards.hpp" 00023 00024 namespace viennagrid 00025 { 00026 namespace result_of 00027 { 00028 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT> 00029 struct neighbor_range; 00030 00031 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT> 00032 struct const_neighbor_range; 00033 } 00034 00035 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename WrappedConfigT, typename ElementOrHandleT> 00036 typename result_of::neighbor_range<viennagrid::mesh<WrappedConfigT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type 00037 neighbor_elements(viennagrid::mesh<WrappedConfigT> & mesh_obj, ElementOrHandleT const & element_or_handle); 00038 00039 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename WrappedConfigT, typename ElementOrHandleT> 00040 typename result_of::const_neighbor_range<viennagrid::mesh<WrappedConfigT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type 00041 neighbor_elements(viennagrid::mesh<WrappedConfigT> const & mesh_obj, ElementOrHandleT const & element_or_handle); 00042 00043 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename SegmentationT, typename ElementOrHandleT> 00044 typename result_of::neighbor_range<segment_handle<SegmentationT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type 00045 neighbor_elements(segment_handle<SegmentationT> & segment, ElementOrHandleT const & element_or_handle); 00046 00047 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename SegmentationT, typename ElementOrHandleT> 00048 typename result_of::const_neighbor_range<segment_handle<SegmentationT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type 00049 neighbor_elements(segment_handle<SegmentationT> const & segment, ElementOrHandleT const & element_or_handle); 00050 00051 00052 00053 namespace detail 00054 { 00055 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename ContainerT> 00056 class neighbor_range_wrapper : public container_range_wrapper<ContainerT> 00057 { 00058 public: 00059 neighbor_range_wrapper(ContainerT & container) : container_range_wrapper<ContainerT>(&container) {} 00060 neighbor_range_wrapper(container_range_wrapper<ContainerT> const & base) : container_range_wrapper<ContainerT>(base) {} 00061 00062 template<typename WrappedConfigT, typename ElementOrHandleT> 00063 neighbor_range_wrapper(viennagrid::mesh<WrappedConfigT> & mesh_obj, 00064 ElementOrHandleT const & element_or_handle) : container_range_wrapper<ContainerT>(viennagrid::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(mesh_obj, element_or_handle)) {} 00065 00066 template<typename SegmentationT, typename ElementOrHandleT> 00067 neighbor_range_wrapper(viennagrid::segment_handle<SegmentationT> & segment_obj, 00068 ElementOrHandleT const & element_or_handle) : container_range_wrapper<ContainerT>(viennagrid::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(segment_obj, element_or_handle)) {} 00069 00070 00071 template<typename WrappedConfigT, typename ElementTagT, typename WrappedElementConfigT> 00072 neighbor_range_wrapper(viennagrid::mesh<WrappedConfigT> & mesh_obj, 00073 viennagrid::element<ElementTagT, WrappedElementConfigT> & el) : container_range_wrapper<ContainerT>(viennagrid::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(mesh_obj, viennagrid::handle(mesh_obj, el))) {} 00074 00075 template<typename SegmentationT, typename ElementTagT, typename WrappedElementConfigT> 00076 neighbor_range_wrapper(viennagrid::segment_handle<SegmentationT> & segment_obj, 00077 viennagrid::element<ElementTagT, WrappedElementConfigT> & el) : container_range_wrapper<ContainerT>(viennagrid::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(segment_obj, viennagrid::handle(segment_obj, el))) {} 00078 }; 00079 00080 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename ContainerT> 00081 class neighbor_range_wrapper<ElementTypeOrTagT, ConnectorElementTypeOrTagT, const ContainerT> : public container_range_wrapper<const ContainerT> 00082 { 00083 public: 00084 neighbor_range_wrapper(ContainerT const & container) : container_range_wrapper<const ContainerT>(&container) {} 00085 neighbor_range_wrapper(container_range_wrapper<const ContainerT> const & base) : container_range_wrapper<const ContainerT>(base) {} 00086 00087 template<typename WrappedConfigT, typename ElementOrHandleT> 00088 neighbor_range_wrapper(viennagrid::mesh<WrappedConfigT> const & mesh_obj, 00089 ElementOrHandleT const & element_or_handle) : container_range_wrapper<const ContainerT>(viennagrid::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(mesh_obj, element_or_handle)) {} 00090 00091 template<typename SegmentationT, typename ElementOrHandleT> 00092 neighbor_range_wrapper(viennagrid::segment_handle<SegmentationT> const & segment_obj, 00093 ElementOrHandleT const & element_or_handle) : container_range_wrapper<const ContainerT>(viennagrid::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(segment_obj, element_or_handle)) {} 00094 00095 00096 template<typename WrappedConfigT, typename ElementTagT, typename WrappedElementConfigT> 00097 neighbor_range_wrapper(viennagrid::mesh<WrappedConfigT> const & mesh_obj, 00098 viennagrid::element<ElementTagT, WrappedElementConfigT> const & el) : container_range_wrapper<const ContainerT>(viennagrid::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(mesh_obj, viennagrid::handle(mesh_obj, el))) {} 00099 00100 template<typename SegmentationT, typename ElementTagT, typename WrappedElementConfigT> 00101 neighbor_range_wrapper(viennagrid::segment_handle<SegmentationT> const & segment_obj, 00102 viennagrid::element<ElementTagT, WrappedElementConfigT> const & el) : container_range_wrapper<const ContainerT>(viennagrid::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(segment_obj, viennagrid::handle(segment_obj, el))) {} 00103 }; 00104 } 00105 00106 00107 00108 namespace result_of 00109 { 00111 template<typename mesh_type, typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT> 00112 struct neighbor_view 00113 { 00114 typedef typename viennagrid::result_of::element_tag< ElementTypeOrTagT >::type element_tag; 00115 typedef typename viennagrid::result_of::element_tag< ConnectorElementTypeOrTagT >::type connector_element_tag; 00116 00117 typedef typename viennagrid::detail::result_of::lookup< 00118 typename viennagrid::detail::result_of::lookup< 00119 typename mesh_type::appendix_type, 00120 neighbor_collection_tag 00121 >::type, 00122 viennagrid::static_pair<element_tag, connector_element_tag> 00123 >::type::container_type::value_type type; 00124 }; 00125 00126 template<typename SegmentationT, typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT> 00127 struct neighbor_view< viennagrid::segment_handle<SegmentationT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT > 00128 { 00129 typedef typename neighbor_view< typename viennagrid::segment_handle<SegmentationT>::view_type, ElementTypeOrTagT, ConnectorElementTypeOrTagT >::type type; 00130 }; 00140 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT> 00141 struct neighbor_range 00142 { 00143 // typedef viennagrid::detail::container_range_wrapper< typename neighbor_view<MeshOrSegmentHandleT, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type > type; 00144 typedef viennagrid::detail::neighbor_range_wrapper< ElementTypeOrTagT, ConnectorElementTypeOrTagT, typename neighbor_view<MeshOrSegmentHandleT, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type > type; 00145 }; 00146 00153 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT> 00154 struct const_neighbor_range 00155 { 00156 // typedef viennagrid::detail::container_range_wrapper< const typename neighbor_view<MeshOrSegmentHandleT, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type > type; 00157 typedef viennagrid::detail::neighbor_range_wrapper< ElementTypeOrTagT, ConnectorElementTypeOrTagT, const typename neighbor_view<MeshOrSegmentHandleT, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type > type; 00158 }; 00159 00161 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT> 00162 struct neighbor_range<const MeshOrSegmentHandleT, ElementTypeOrTagT, ConnectorElementTypeOrTagT> 00163 { 00164 typedef typename const_neighbor_range<MeshOrSegmentHandleT, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type type; 00165 }; 00168 } 00169 00170 00171 namespace detail 00172 { 00173 00175 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename mesh_type, typename neigbour_accessor_type> 00176 void create_neighbor_information(mesh_type & mesh_obj, neigbour_accessor_type accessor) 00177 { 00178 typedef typename viennagrid::result_of::element_tag< ElementTypeOrTagT >::type element_tag; 00179 typedef typename viennagrid::result_of::element_tag< ConnectorElementTypeOrTagT >::type connector_element_tag; 00180 00181 typedef typename viennagrid::result_of::element< mesh_type, ElementTypeOrTagT >::type element_type; 00182 00183 typedef typename viennagrid::result_of::element_range< mesh_type, ElementTypeOrTagT >::type element_range_type; 00184 typedef typename viennagrid::result_of::iterator< element_range_type >::type element_range_iterator; 00185 00186 element_range_type elements(mesh_obj); 00187 00188 for ( element_range_iterator it = elements.begin(); it != elements.end(); ++it ) 00189 { 00190 accessor( *it ).clear(); 00191 accessor( *it ).set_base_container( viennagrid::get< element_type >( element_collection(mesh_obj) ) ); 00192 } 00193 00194 typedef typename viennagrid::result_of::element_range< mesh_type, connector_element_tag >::type connector_element_range_type; 00195 typedef typename viennagrid::result_of::iterator< connector_element_range_type >::type connector_element_range_iterator; 00196 00197 connector_element_range_type connector_elements(mesh_obj); 00198 for ( connector_element_range_iterator it = connector_elements.begin(); it != connector_elements.end(); ++it ) 00199 { 00200 typedef typename viennagrid::result_of::coboundary_range< mesh_type, connector_element_tag, element_tag >::type element_on_connector_element_range_type; 00201 typedef typename viennagrid::result_of::iterator< element_on_connector_element_range_type >::type element_on_connector_element_range_iterator; 00202 00203 element_on_connector_element_range_type coboundary_range = viennagrid::coboundary_elements<connector_element_tag, element_tag>( mesh_obj, it.handle() ); 00204 if (coboundary_range.empty()) 00205 continue; 00206 00207 element_on_connector_element_range_iterator jt1 = coboundary_range.begin(); ++jt1; 00208 for (; jt1 != coboundary_range.end(); ++jt1) 00209 { 00210 for (element_on_connector_element_range_iterator jt0 = coboundary_range.begin(); jt0 != jt1; ++jt0) 00211 { 00212 typedef typename viennagrid::result_of::neighbor_view<mesh_type, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type view_type; 00213 view_type & view_obj = accessor( *jt0 ); 00214 00215 typename view_type::iterator kt = view_obj.begin(); 00216 for (; kt != view_obj.end(); ++kt) 00217 if ( kt->id() == jt1->id() ) 00218 break; 00219 00220 if (kt == view_obj.end()) 00221 { 00222 accessor( *jt0 ).insert_handle( jt1.handle() ); 00223 accessor( *jt1 ).insert_handle( jt0.handle() ); 00224 } 00225 } 00226 } 00227 } 00228 } 00229 00230 00232 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename mesh_type> 00233 void create_neighbor_information(mesh_type & mesh_obj) 00234 { 00235 typedef typename viennagrid::result_of::element_tag< ElementTypeOrTagT >::type element_tag; 00236 typedef typename viennagrid::result_of::element_tag< ConnectorElementTypeOrTagT >::type connector_element_tag; 00237 typedef typename viennagrid::result_of::element< mesh_type, ElementTypeOrTagT >::type element_type; 00238 00239 typedef typename viennagrid::detail::result_of::lookup< 00240 typename viennagrid::detail::result_of::lookup< 00241 typename mesh_type::appendix_type, 00242 neighbor_collection_tag 00243 >::type, 00244 viennagrid::static_pair<element_tag, connector_element_tag> 00245 >::type neighbor_container_wrapper_type; 00246 neighbor_container_wrapper_type & neighbor_container_wrapper = detail::neighbor_collection<element_tag, connector_element_tag>(mesh_obj); 00247 00248 create_neighbor_information<ElementTypeOrTagT, ConnectorElementTypeOrTagT>( mesh_obj, viennagrid::make_accessor<element_type>(neighbor_container_wrapper.container) ); 00249 00250 detail::update_change_counter( mesh_obj, neighbor_container_wrapper.change_counter ); 00251 } 00252 00253 00254 00256 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename neigbour_accessor_type, typename ElementTag, typename WrappedConfigT> 00257 viennagrid::detail::container_range_wrapper<typename neigbour_accessor_type::value_type> 00258 neighbor_elements(neigbour_accessor_type accessor, viennagrid::element<ElementTag, WrappedConfigT> & element) 00259 { 00260 typedef viennagrid::detail::container_range_wrapper<typename neigbour_accessor_type::value_type> range_type; 00261 return range_type( accessor( element ) ); 00262 } 00263 00265 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename neigbour_accessor_type, typename ElementTag, typename WrappedConfigT> 00266 viennagrid::detail::container_range_wrapper<const typename neigbour_accessor_type::value_type> 00267 neighbor_elements(neigbour_accessor_type const accessor, viennagrid::element<ElementTag, WrappedConfigT> const & element) 00268 { 00269 typedef viennagrid::detail::container_range_wrapper<const typename neigbour_accessor_type::value_type> range_type; 00270 return range_type( accessor( element ) ); 00271 } 00272 00273 00275 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename neigbour_accessor_type, typename WrappedConfigT, typename ElementOrHandleT> 00276 viennagrid::detail::container_range_wrapper<typename neigbour_accessor_type::value_type> 00277 neighbor_elements(viennagrid::mesh<WrappedConfigT> & mesh_obj, neigbour_accessor_type accessor, ElementOrHandleT & element_or_handle) 00278 { 00279 return neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>( accessor, viennagrid::dereference_handle(mesh_obj, element_or_handle) ); 00280 } 00281 00283 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename neigbour_accessor_type, typename WrappedConfigT, typename ElementOrHandleT> 00284 viennagrid::detail::container_range_wrapper<const typename neigbour_accessor_type::value_type> 00285 neighbor_elements(viennagrid::mesh<WrappedConfigT> const & mesh_obj, neigbour_accessor_type const accessor, ElementOrHandleT const & element_or_handle) 00286 { 00287 return neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>( accessor, viennagrid::dereference_handle(mesh_obj, element_or_handle) ); 00288 } 00289 00290 } 00291 00302 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename WrappedConfigT, typename ElementOrHandleT> 00303 typename result_of::neighbor_range<viennagrid::mesh<WrappedConfigT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type 00304 neighbor_elements(viennagrid::mesh<WrappedConfigT> & mesh_obj, ElementOrHandleT const & element_or_handle) 00305 { 00306 typedef viennagrid::mesh<WrappedConfigT> mesh_type; 00307 typedef typename viennagrid::result_of::element_tag< ElementTypeOrTagT >::type element_tag; 00308 typedef typename viennagrid::result_of::element_tag< ConnectorElementTypeOrTagT >::type connector_element_tag; 00309 typedef typename viennagrid::result_of::element< mesh_type, ElementTypeOrTagT >::type element_type; 00310 00311 typedef typename viennagrid::detail::result_of::lookup< 00312 typename viennagrid::detail::result_of::lookup< 00313 typename mesh_type::appendix_type, 00314 neighbor_collection_tag 00315 >::type, 00316 viennagrid::static_pair<element_tag, connector_element_tag> 00317 >::type neighbor_container_wrapper_type; 00318 neighbor_container_wrapper_type & neighbor_container_wrapper = detail::neighbor_collection<element_tag, connector_element_tag>(mesh_obj); 00319 00320 if ( detail::is_obsolete( mesh_obj, neighbor_container_wrapper.change_counter ) ) 00321 detail::create_neighbor_information<ElementTypeOrTagT, ConnectorElementTypeOrTagT>(mesh_obj); 00322 00323 return detail::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>( viennagrid::make_accessor<element_type>(neighbor_container_wrapper.container), viennagrid::dereference_handle(mesh_obj, element_or_handle) ); 00324 } 00325 00336 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename WrappedConfigT, typename ElementOrHandleT> 00337 typename result_of::const_neighbor_range<viennagrid::mesh<WrappedConfigT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type 00338 neighbor_elements(viennagrid::mesh<WrappedConfigT> const & mesh_obj, ElementOrHandleT const & element_or_handle) 00339 { 00340 typedef viennagrid::mesh<WrappedConfigT> mesh_type; 00341 typedef typename viennagrid::result_of::element_tag< ElementTypeOrTagT >::type element_tag; 00342 typedef typename viennagrid::result_of::element_tag< ConnectorElementTypeOrTagT >::type connector_element_tag; 00343 typedef typename viennagrid::result_of::element< mesh_type, ElementTypeOrTagT >::type element_type; 00344 00345 typedef typename viennagrid::detail::result_of::lookup< 00346 typename viennagrid::detail::result_of::lookup< 00347 typename mesh_type::appendix_type, 00348 neighbor_collection_tag 00349 >::type, 00350 viennagrid::static_pair<element_tag, connector_element_tag> 00351 >::type neighbor_container_wrapper_type; 00352 neighbor_container_wrapper_type const & neighbor_container_wrapper = detail::neighbor_collection<element_tag, connector_element_tag>(mesh_obj); 00353 00354 if ( detail::is_obsolete( mesh_obj, neighbor_container_wrapper.change_counter ) ) 00355 detail::create_neighbor_information<ElementTypeOrTagT, ConnectorElementTypeOrTagT>( const_cast<mesh_type&>(mesh_obj) ); 00356 00357 00358 return detail::neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>( viennagrid::make_accessor<element_type>(neighbor_container_wrapper.container), viennagrid::dereference_handle(mesh_obj, element_or_handle) ); 00359 } 00360 00361 00372 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename SegmentationT, typename ElementOrHandleT> 00373 typename result_of::neighbor_range<segment_handle<SegmentationT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type 00374 neighbor_elements(segment_handle<SegmentationT> & segment, ElementOrHandleT const & element_or_handle) 00375 { 00376 return neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>( segment.view(), element_or_handle ); 00377 } 00378 00389 template<typename ElementTypeOrTagT, typename ConnectorElementTypeOrTagT, typename SegmentationT, typename ElementOrHandleT> 00390 typename result_of::const_neighbor_range<segment_handle<SegmentationT>, ElementTypeOrTagT, ConnectorElementTypeOrTagT>::type 00391 neighbor_elements(segment_handle<SegmentationT> const & segment, ElementOrHandleT const & element_or_handle) 00392 { 00393 return neighbor_elements<ElementTypeOrTagT, ConnectorElementTypeOrTagT>( segment.view(), element_or_handle ); 00394 } 00395 00396 } 00397 00398 00399 #endif