ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_MESH_COBOUNDARY_ITERATION_HPP 00002 #define VIENNAGRID_MESH_COBOUNDARY_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/forwards.hpp" 00017 #include "viennagrid/storage/forwards.hpp" 00018 #include "viennagrid/mesh/mesh.hpp" 00019 #include "viennagrid/accessor.hpp" 00020 00025 namespace viennagrid 00026 { 00027 namespace result_of 00028 { 00029 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT> 00030 struct coboundary_range; 00031 00032 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT> 00033 struct const_coboundary_range; 00034 } 00035 00036 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename WrappedConfigT, typename ElementOrHandleT> 00037 typename result_of::coboundary_range<viennagrid::mesh<WrappedConfigT>, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type 00038 coboundary_elements(viennagrid::mesh<WrappedConfigT> & mesh_obj, ElementOrHandleT const & element_or_handle); 00039 00040 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename WrappedConfigT, typename ElementOrHandleT> 00041 typename result_of::const_coboundary_range<viennagrid::mesh<WrappedConfigT>, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type 00042 coboundary_elements(viennagrid::mesh<WrappedConfigT> const & mesh_obj, ElementOrHandleT const & element_or_handle); 00043 00044 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename SegmentationT, typename element_or_handle_type> 00045 typename result_of::coboundary_range<segment_handle<SegmentationT>, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type 00046 coboundary_elements(segment_handle<SegmentationT> & segment, element_or_handle_type const & element_or_handle); 00047 00048 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename SegmentationT, typename element_or_handle_type> 00049 typename result_of::const_coboundary_range<segment_handle<SegmentationT>, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type 00050 coboundary_elements(segment_handle<SegmentationT> const & segment, element_or_handle_type const & element_or_handle); 00051 00052 00053 00054 00055 00056 namespace detail 00057 { 00058 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename ContainerT> 00059 class coboundary_range_wrapper : public container_range_wrapper<ContainerT> 00060 { 00061 public: 00062 coboundary_range_wrapper(ContainerT & container) : container_range_wrapper<ContainerT>(&container) {} 00063 coboundary_range_wrapper(container_range_wrapper<ContainerT> const & base) : container_range_wrapper<ContainerT>(base) {} 00064 00065 template<typename WrappedConfigT, typename ElementOrHandleT> 00066 coboundary_range_wrapper(viennagrid::mesh<WrappedConfigT> & mesh_obj, 00067 ElementOrHandleT const & element_or_handle) : container_range_wrapper<ContainerT>(viennagrid::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>(mesh_obj, element_or_handle)) {} 00068 00069 template<typename SegmentationT, typename ElementOrHandleT> 00070 coboundary_range_wrapper(viennagrid::segment_handle<SegmentationT> & segment_obj, 00071 ElementOrHandleT const & element_or_handle) : container_range_wrapper<ContainerT>(viennagrid::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>(segment_obj, element_or_handle)) {} 00072 00073 00074 template<typename WrappedConfigT, typename ElementTagT, typename WrappedElementConfigT> 00075 coboundary_range_wrapper(viennagrid::mesh<WrappedConfigT> & mesh_obj, 00076 viennagrid::element<ElementTagT, WrappedElementConfigT> & element) : container_range_wrapper<ContainerT>(viennagrid::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>(mesh_obj, viennagrid::handle(mesh_obj, element))) {} 00077 00078 template<typename SegmentationT, typename ElementTagT, typename WrappedElementConfigT> 00079 coboundary_range_wrapper(viennagrid::segment_handle<SegmentationT> & segment_obj, 00080 viennagrid::element<ElementTagT, WrappedElementConfigT> & element) : container_range_wrapper<ContainerT>(viennagrid::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>(segment_obj, viennagrid::handle(segment_obj, element))) {} 00081 }; 00082 00083 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename ContainerT> 00084 class coboundary_range_wrapper<ElementTypeOrTagT, CoboundaryTypeOrTagT, const ContainerT> : public container_range_wrapper<const ContainerT> 00085 { 00086 public: 00087 coboundary_range_wrapper(ContainerT const & container) : container_range_wrapper<const ContainerT>(&container) {} 00088 coboundary_range_wrapper(container_range_wrapper<const ContainerT> const & base) : container_range_wrapper<const ContainerT>(base) {} 00089 00090 template<typename WrappedConfigT, typename ElementOrHandleT> 00091 coboundary_range_wrapper(viennagrid::mesh<WrappedConfigT> const & mesh_obj, 00092 ElementOrHandleT const & element_or_handle) : container_range_wrapper<const ContainerT>(viennagrid::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>(mesh_obj, element_or_handle)) {} 00093 00094 template<typename SegmentationT, typename ElementOrHandleT> 00095 coboundary_range_wrapper(viennagrid::segment_handle<SegmentationT> const & segment_obj, 00096 ElementOrHandleT const & element_or_handle) : container_range_wrapper<const ContainerT>(viennagrid::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>(segment_obj, element_or_handle)) {} 00097 00098 00099 template<typename WrappedConfigT, typename ElementTagT, typename WrappedElementConfigT> 00100 coboundary_range_wrapper(viennagrid::mesh<WrappedConfigT> const & mesh_obj, 00101 viennagrid::element<ElementTagT, WrappedElementConfigT> const & element) : container_range_wrapper<const ContainerT>(viennagrid::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>(mesh_obj, viennagrid::handle(mesh_obj, element))) {} 00102 00103 template<typename SegmentationT, typename ElementTagT, typename WrappedElementConfigT> 00104 coboundary_range_wrapper(viennagrid::segment_handle<SegmentationT> const & segment_obj, 00105 viennagrid::element<ElementTagT, WrappedElementConfigT> const & element) : container_range_wrapper<const ContainerT>(viennagrid::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>(segment_obj, viennagrid::handle(segment_obj, element))) {} 00106 }; 00107 } 00108 00109 00110 namespace result_of 00111 { 00113 template<typename mesh_type, typename element_type_or_tag, typename coboundary_type_or_tag> 00114 struct coboundary_view 00115 { 00116 typedef typename viennagrid::result_of::element_tag< element_type_or_tag >::type element_tag; 00117 typedef typename viennagrid::result_of::element_tag< coboundary_type_or_tag >::type coboundary_tag; 00118 00119 typedef typename viennagrid::detail::result_of::lookup< 00120 typename viennagrid::detail::result_of::lookup< 00121 typename mesh_type::appendix_type, 00122 coboundary_collection_tag 00123 >::type, 00124 viennagrid::static_pair<element_tag, coboundary_tag> 00125 >::type::container_type::value_type type; 00126 }; 00127 00128 template<typename SegmentationType, typename element_type_or_tag, typename coboundary_type_or_tag> 00129 struct coboundary_view< viennagrid::segment_handle<SegmentationType>, element_type_or_tag, coboundary_type_or_tag > 00130 { 00131 typedef typename coboundary_view< typename viennagrid::segment_handle<SegmentationType>::view_type, element_type_or_tag, coboundary_type_or_tag >::type type; 00132 }; 00142 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT> 00143 struct coboundary_range 00144 { 00145 //typedef viennagrid::detail::container_range_wrapper< typename coboundary_view<MeshOrSegmentHandleT, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type > type; 00146 typedef viennagrid::detail::coboundary_range_wrapper< ElementTypeOrTagT, CoboundaryTypeOrTagT, typename coboundary_view<MeshOrSegmentHandleT, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type > type; 00147 }; 00148 00155 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT> 00156 struct const_coboundary_range 00157 { 00158 // typedef viennagrid::detail::container_range_wrapper< const typename coboundary_view<MeshOrSegmentHandleT, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type > type; 00159 typedef viennagrid::detail::coboundary_range_wrapper< ElementTypeOrTagT, CoboundaryTypeOrTagT, const typename coboundary_view<MeshOrSegmentHandleT, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type > type; 00160 }; 00161 00163 template<typename MeshOrSegmentHandleT, typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT> 00164 struct coboundary_range<const MeshOrSegmentHandleT, ElementTypeOrTagT, CoboundaryTypeOrTagT> 00165 { 00166 typedef typename const_coboundary_range<MeshOrSegmentHandleT, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type type; 00167 }; 00169 } 00170 00171 namespace detail 00172 { 00173 00175 template<typename element_type_or_tag, typename coboundary_type_or_tag, typename MeshT, typename coboundary_accessor_type> 00176 void create_coboundary_information(MeshT & mesh_obj, coboundary_accessor_type accessor) 00177 { 00178 typedef typename viennagrid::result_of::element_tag< element_type_or_tag >::type element_tag; 00179 00180 typedef typename viennagrid::result_of::element< MeshT, coboundary_type_or_tag >::type coboundary_type; 00181 00182 typedef typename viennagrid::result_of::element_range< MeshT, element_type_or_tag >::type element_range_type; 00183 typedef typename viennagrid::result_of::iterator< element_range_type >::type element_range_iterator; 00184 00185 element_range_type elements(mesh_obj); 00186 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< coboundary_type >( element_collection(mesh_obj) ) ); 00192 } 00193 00194 00195 typedef typename viennagrid::result_of::element_range< MeshT, coboundary_type_or_tag >::type coboundary_element_range_type; 00196 typedef typename viennagrid::result_of::iterator< coboundary_element_range_type >::type coboundary_element_range_iterator; 00197 00198 coboundary_element_range_type coboundary_elements(mesh_obj); 00199 for (coboundary_element_range_iterator it = coboundary_elements.begin(); it != coboundary_elements.end(); ++it) 00200 { 00201 typedef typename viennagrid::result_of::element_range< coboundary_type, element_tag >::type element_on_coboundary_element_range_type; 00202 typedef typename viennagrid::result_of::iterator< element_on_coboundary_element_range_type >::type element_on_coboundary_element_range_iterator; 00203 00204 element_on_coboundary_element_range_type elements_on_coboundary_element( *it ); 00205 for (element_on_coboundary_element_range_iterator jt = elements_on_coboundary_element.begin(); jt != elements_on_coboundary_element.end(); ++jt) 00206 accessor.at( *jt ).insert_handle( it.handle() ); 00207 } 00208 } 00209 00210 template<typename element_type_or_tag, typename coboundary_type_or_tag, typename WrappedConfigT, typename ElementTypelistT, typename ContainerConfigT, typename coboundary_accessor_type> 00211 void create_coboundary_information(viennagrid::mesh< viennagrid::detail::decorated_mesh_view_config<WrappedConfigT, ElementTypelistT, ContainerConfigT> > & mesh_obj, coboundary_accessor_type accessor) 00212 { 00213 typedef viennagrid::mesh< viennagrid::detail::decorated_mesh_view_config<WrappedConfigT, ElementTypelistT, ContainerConfigT> > ViewType; 00214 typedef typename viennagrid::result_of::element_tag< element_type_or_tag >::type element_tag; 00215 00216 typedef typename viennagrid::result_of::element< ViewType, coboundary_type_or_tag >::type coboundary_type; 00217 00218 typedef typename viennagrid::result_of::element_range< ViewType, element_type_or_tag >::type element_range_type; 00219 typedef typename viennagrid::result_of::iterator< element_range_type >::type element_range_iterator; 00220 00221 element_range_type elements(mesh_obj); 00222 00223 00224 for ( element_range_iterator it = elements.begin(); it != elements.end(); ++it ) 00225 { 00226 accessor( *it ).clear(); 00227 accessor( *it ).set_base_container( viennagrid::get< coboundary_type >( element_collection(mesh_obj) ) ); 00228 } 00229 00230 00231 typedef typename viennagrid::result_of::element_range< ViewType, coboundary_type_or_tag >::type coboundary_element_range_type; 00232 typedef typename viennagrid::result_of::iterator< coboundary_element_range_type >::type coboundary_element_range_iterator; 00233 00234 coboundary_element_range_type coboundary_elements(mesh_obj); 00235 for (coboundary_element_range_iterator it = coboundary_elements.begin(); it != coboundary_elements.end(); ++it) 00236 { 00237 typedef typename viennagrid::result_of::element_range< coboundary_type, element_tag >::type element_on_coboundary_element_range_type; 00238 typedef typename viennagrid::result_of::iterator< element_on_coboundary_element_range_type >::type element_on_coboundary_element_range_iterator; 00239 00240 element_on_coboundary_element_range_type elements_on_coboundary_element( *it ); 00241 for (element_on_coboundary_element_range_iterator jt = elements_on_coboundary_element.begin(); jt != elements_on_coboundary_element.end(); ++jt) 00242 { 00243 // is this line needed?? 00244 // if ( viennagrid::find(mesh_obj, *jt) != viennagrid::elements<element_type_or_tag>(mesh_obj).end() ) 00245 accessor.at( *jt ).insert_handle( it.handle() ); 00246 } 00247 } 00248 } 00249 00250 00251 00252 00253 00255 template<typename element_type_or_tag, typename coboundary_type_or_tag, typename mesh_type> 00256 void create_coboundary_information(mesh_type & mesh_obj) 00257 { 00258 typedef typename viennagrid::result_of::element_tag< element_type_or_tag >::type element_tag; 00259 typedef typename viennagrid::result_of::element_tag< coboundary_type_or_tag >::type coboundary_tag; 00260 typedef typename viennagrid::result_of::element< mesh_type, element_type_or_tag >::type element_type; 00261 00262 typedef typename viennagrid::detail::result_of::lookup< 00263 typename viennagrid::detail::result_of::lookup< 00264 typename mesh_type::appendix_type, 00265 coboundary_collection_tag 00266 >::type, 00267 viennagrid::static_pair<element_tag, coboundary_tag> 00268 >::type coboundary_container_wrapper_type; 00269 00270 coboundary_container_wrapper_type & coboundary_container_wrapper = detail::coboundary_collection<element_tag, coboundary_tag>(mesh_obj);//viennagrid::storage::detail::get< viennagrid::static_pair<element_tag, coboundary_tag> > ( mesh_obj.coboundary_collection() ); 00271 00272 create_coboundary_information<element_type_or_tag, coboundary_type_or_tag>( mesh_obj, viennagrid::make_accessor<element_type>(coboundary_container_wrapper.container) ); 00273 detail::update_change_counter( mesh_obj, coboundary_container_wrapper.change_counter ); 00274 } 00275 00276 00277 00278 00279 00280 00281 00282 00283 00284 00285 00287 template<typename ElementTypeOrTagT, typename coboundary_type_or_tag, typename coboundary_accessor_type, typename ElementTag, typename WrappedConfigType> 00288 viennagrid::detail::container_range_wrapper<typename coboundary_accessor_type::value_type> 00289 coboundary_elements(coboundary_accessor_type accessor, viennagrid::element<ElementTag, WrappedConfigType> & element) 00290 { 00291 typedef viennagrid::detail::container_range_wrapper<typename coboundary_accessor_type::value_type> range_type; 00292 return range_type( accessor( element ) ); 00293 } 00294 00296 template<typename ElementTypeOrTagT, typename coboundary_type_or_tag, typename coboundary_accessor_type, typename ElementTag, typename WrappedConfigType> 00297 viennagrid::detail::container_range_wrapper<const typename coboundary_accessor_type::value_type> 00298 coboundary_elements(coboundary_accessor_type const accessor, viennagrid::element<ElementTag, WrappedConfigType> const & element) 00299 { 00300 typedef viennagrid::detail::container_range_wrapper<const typename coboundary_accessor_type::value_type> range_type; 00301 return range_type( accessor( element ) ); 00302 } 00303 00304 00306 template<typename element_type_or_tag, typename coboundary_type_or_tag, typename coboundary_accessor_type, typename WrappedConfigType, typename element_or_handle_type> 00307 viennagrid::detail::container_range_wrapper<typename coboundary_accessor_type::value_type> 00308 coboundary_elements(viennagrid::mesh<WrappedConfigType> & mesh_obj, coboundary_accessor_type accessor, element_or_handle_type & hendl) 00309 { 00310 return coboundary_elements<element_type_or_tag, coboundary_type_or_tag>( accessor, viennagrid::dereference_handle(mesh_obj, hendl) ); 00311 } 00312 00314 template<typename element_type_or_tag, typename coboundary_type_or_tag, typename coboundary_accessor_type, typename WrappedConfigType, typename element_or_handle_type> 00315 viennagrid::detail::container_range_wrapper<const typename coboundary_accessor_type::value_type> 00316 coboundary_elements(viennagrid::mesh<WrappedConfigType> const & mesh_obj, coboundary_accessor_type const accessor, element_or_handle_type const & hendl) 00317 { 00318 return coboundary_elements<element_type_or_tag, coboundary_type_or_tag>( accessor, viennagrid::dereference_handle(mesh_obj, hendl) ); 00319 } 00320 00321 } 00322 00323 00324 00335 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename WrappedConfigT, typename ElementOrHandleT> 00336 typename result_of::coboundary_range<viennagrid::mesh<WrappedConfigT>, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type 00337 coboundary_elements(viennagrid::mesh<WrappedConfigT> & mesh_obj, ElementOrHandleT const & element_or_handle) 00338 { 00339 typedef viennagrid::mesh<WrappedConfigT> mesh_type; 00340 typedef typename viennagrid::result_of::element_tag< ElementTypeOrTagT >::type element_tag; 00341 typedef typename viennagrid::result_of::element_tag< CoboundaryTypeOrTagT >::type coboundary_tag; 00342 typedef typename viennagrid::result_of::element< mesh_type, ElementTypeOrTagT >::type element_type; 00343 00344 typedef typename viennagrid::detail::result_of::lookup< 00345 typename viennagrid::detail::result_of::lookup< 00346 typename mesh_type::appendix_type, 00347 coboundary_collection_tag 00348 >::type, 00349 viennagrid::static_pair<element_tag, coboundary_tag> 00350 >::type coboundary_container_wrapper_type; 00351 coboundary_container_wrapper_type & coboundary_container_wrapper = detail::coboundary_collection<element_tag, coboundary_tag>(mesh_obj); 00352 00353 if ( detail::is_obsolete(mesh_obj, coboundary_container_wrapper.change_counter) ) 00354 detail::create_coboundary_information<ElementTypeOrTagT, CoboundaryTypeOrTagT>(mesh_obj); 00355 00356 return detail::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>( viennagrid::make_accessor<element_type>(coboundary_container_wrapper.container), viennagrid::dereference_handle(mesh_obj, element_or_handle) ); 00357 } 00358 00369 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename WrappedConfigT, typename ElementOrHandleT> 00370 typename result_of::const_coboundary_range<viennagrid::mesh<WrappedConfigT>, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type 00371 coboundary_elements(viennagrid::mesh<WrappedConfigT> const & mesh_obj, ElementOrHandleT const & element_or_handle) 00372 { 00373 typedef viennagrid::mesh<WrappedConfigT> mesh_type; 00374 typedef typename viennagrid::result_of::element_tag< ElementTypeOrTagT >::type element_tag; 00375 typedef typename viennagrid::result_of::element_tag< CoboundaryTypeOrTagT >::type coboundary_tag; 00376 typedef typename viennagrid::result_of::element< mesh_type, ElementTypeOrTagT >::type element_type; 00377 00378 typedef typename viennagrid::detail::result_of::lookup< 00379 typename viennagrid::detail::result_of::lookup< 00380 typename mesh_type::appendix_type, 00381 coboundary_collection_tag 00382 >::type, 00383 viennagrid::static_pair<element_tag, coboundary_tag> 00384 >::type coboundary_container_wrapper_type; 00385 coboundary_container_wrapper_type const & coboundary_container_wrapper = detail::coboundary_collection<element_tag, coboundary_tag>(mesh_obj); 00386 00387 if ( detail::is_obsolete(mesh_obj, coboundary_container_wrapper.change_counter) ) 00388 detail::create_coboundary_information<ElementTypeOrTagT, CoboundaryTypeOrTagT>( const_cast<mesh_type&>(mesh_obj) ); 00389 00390 return detail::coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>( viennagrid::make_accessor<element_type>(coboundary_container_wrapper.container), viennagrid::dereference_handle(mesh_obj, element_or_handle) ); 00391 } 00392 00393 00394 00405 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename SegmentationT, typename element_or_handle_type> 00406 typename result_of::coboundary_range<segment_handle<SegmentationT>, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type 00407 coboundary_elements(segment_handle<SegmentationT> & segment, element_or_handle_type const & element_or_handle) 00408 { 00409 return coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>( segment.view(), element_or_handle ); 00410 } 00411 00422 template<typename ElementTypeOrTagT, typename CoboundaryTypeOrTagT, typename SegmentationT, typename element_or_handle_type> 00423 typename result_of::const_coboundary_range<segment_handle<SegmentationT>, ElementTypeOrTagT, CoboundaryTypeOrTagT>::type 00424 coboundary_elements(segment_handle<SegmentationT> const & segment, element_or_handle_type const & element_or_handle) 00425 { 00426 return coboundary_elements<ElementTypeOrTagT, CoboundaryTypeOrTagT>( segment.view(), element_or_handle ); 00427 } 00428 00429 } 00430 00431 #endif