ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_MESH_HPP 00002 #define VIENNAGRID_MESH_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 <typeinfo> 00017 #include "viennagrid/forwards.hpp" 00018 00019 #include "viennagrid/meta/algorithm.hpp" 00020 00021 #include "viennagrid/storage/id_generator.hpp" 00022 #include "viennagrid/storage/inserter.hpp" 00023 #include "viennagrid/storage/algorithm.hpp" 00024 00025 #include "viennagrid/config/element_config.hpp" 00026 #include "viennagrid/config/mesh_config.hpp" 00027 00028 #include "viennagrid/element/element_view.hpp" 00029 00035 namespace viennagrid 00036 { 00037 namespace detail 00038 { 00040 template<typename SourceWrappedConfigT, typename DestinationWrappedConfigT> 00041 void fix_handles( viennagrid::mesh<SourceWrappedConfigT> const & source_mesh_obj, viennagrid::mesh<DestinationWrappedConfigT> & destination_mesh ); 00042 00044 template<typename container_collection_type> 00045 class view_mesh_setter 00046 { 00047 public: 00048 00049 view_mesh_setter(container_collection_type & mesh_obj) : mesh_obj_(mesh_obj) {} 00050 00051 template<typename container_type> 00052 void operator()( container_type & container ) 00053 { 00054 typedef typename container_type::value_type value_type; 00055 container.set_base_container( viennagrid::get<value_type>(mesh_obj_) ); 00056 } 00057 00058 private: 00059 container_collection_type & mesh_obj_; 00060 }; 00061 00062 00064 template<typename container_type_, typename change_counter_type> 00065 struct coboundary_container_wrapper 00066 { 00067 typedef container_type_ container_type; 00068 coboundary_container_wrapper() : change_counter(0) {} 00069 00070 change_counter_type change_counter; 00071 container_type container; 00072 }; 00073 00075 template<typename container_type_, typename change_counter_type> 00076 struct neighbor_container_wrapper 00077 { 00078 typedef container_type_ container_type; 00079 neighbor_container_wrapper() : change_counter(0) {} 00080 00081 change_counter_type change_counter; 00082 container_type container; 00083 }; 00084 00086 template<typename container_type_, typename change_counter_type> 00087 struct boundary_information_wrapper 00088 { 00089 typedef container_type_ container_type; 00090 boundary_information_wrapper() : change_counter(0) {} 00091 00092 change_counter_type change_counter; 00093 container_type container; 00094 }; 00095 00096 } 00097 00098 namespace result_of 00099 { 00101 template<typename ElementTypelistT, typename ContainerTypemapT> 00102 struct filter_element_container; 00103 00104 template<typename ContainerTypemapT> 00105 struct filter_element_container<viennagrid::null_type, ContainerTypemapT> 00106 { 00107 typedef viennagrid::null_type type; 00108 }; 00109 00110 template<typename ElementT, typename TailT, typename ContainerTypemapT> 00111 struct filter_element_container<viennagrid::typelist< ElementT, TailT> , ContainerTypemapT> 00112 { 00113 typedef typename viennagrid::detail::result_of::find<ContainerTypemapT, ElementT>::type result_type; 00114 00115 typedef typename filter_element_container<TailT, ContainerTypemapT>::type new_tail; 00116 00117 typedef typename viennagrid::detail::IF< 00118 viennagrid::detail::EQUAL< result_type, viennagrid::not_found >::value, 00119 new_tail, 00120 viennagrid::typelist< 00121 result_type, 00122 new_tail 00123 > 00124 >::type type; 00125 }; 00126 00127 00129 template <typename WrappedConfigT> 00130 struct mesh_element_collection_type 00131 { 00132 typedef typename config::result_of::element_collection< WrappedConfigT >::type type; 00133 }; 00134 00135 template <typename WrappedMeshConfigType, typename ElementTypeList, typename ContainerConfig> 00136 struct mesh_element_collection_type< viennagrid::detail::decorated_mesh_view_config<WrappedMeshConfigType, ElementTypeList, ContainerConfig> > 00137 { 00138 typedef typename WrappedMeshConfigType::type MeshConfigType; 00139 00140 typedef typename mesh_element_collection_type<WrappedMeshConfigType>::type full_mesh_element_collection_type; 00141 00142 typedef typename filter_element_container<ElementTypeList, typename full_mesh_element_collection_type::typemap>::type view_container_collection_typemap; 00143 typedef typename viennagrid::result_of::view_collection<view_container_collection_typemap, ContainerConfig>::type type; 00144 }; 00145 00147 template <typename WrappedConfigT> 00148 struct mesh_appendix_type 00149 { 00150 typedef typename WrappedConfigT::type ConfigType; 00151 00152 typedef collection< typename viennagrid::result_of::coboundary_container_collection_typemap<WrappedConfigT>::type > coboundary_collection_type; 00153 typedef collection< typename viennagrid::result_of::neighbor_container_collection_typemap< WrappedConfigT>::type > neighbor_collection_type; 00154 typedef collection< typename viennagrid::result_of::boundary_information_collection_typemap<WrappedConfigT>::type > boundary_information_type; 00155 00156 typedef typename viennagrid::collection< 00157 typename viennagrid::make_typemap< 00158 00159 coboundary_collection_tag, 00160 coboundary_collection_type, 00161 00162 neighbor_collection_tag, 00163 neighbor_collection_type, 00164 00165 boundary_information_collection_tag, 00166 boundary_information_type 00167 00168 >::type 00169 > type; 00170 }; 00171 00172 template <typename WrappedMeshConfigT, typename ElementTypeListT, typename ContainerConfigT> 00173 struct mesh_appendix_type< viennagrid::detail::decorated_mesh_view_config<WrappedMeshConfigT, ElementTypeListT, ContainerConfigT> > 00174 { 00175 typedef typename mesh_appendix_type<WrappedMeshConfigT>::type type; 00176 }; 00177 00178 00180 template <typename WrappedConfigT> 00181 struct mesh_change_counter_type 00182 { 00183 typedef typename config::result_of::query<WrappedConfigT, long, config::mesh_change_counter_tag>::type type; 00184 }; 00185 00186 template <typename WrappedMeshConfigT, typename ElementTypeList, typename ContainerConfig> 00187 struct mesh_change_counter_type< viennagrid::detail::decorated_mesh_view_config<WrappedMeshConfigT, ElementTypeList, ContainerConfig> > 00188 { 00189 typedef typename config::result_of::query<WrappedMeshConfigT, long, config::mesh_change_counter_tag>::type type; 00190 }; 00191 00192 00194 template <typename WrappedConfigType> 00195 struct mesh_inserter_type 00196 { 00197 typedef typename config::result_of::element_collection<WrappedConfigType>::type element_collection_type; 00198 typedef typename viennagrid::result_of::id_generator<WrappedConfigType>::type id_generator_type; 00199 typedef typename mesh_change_counter_type<WrappedConfigType>::type change_counter_type; 00200 00201 typedef typename viennagrid::result_of::physical_inserter<element_collection_type, change_counter_type, id_generator_type>::type type; 00202 }; 00203 00204 template <typename WrappedMeshConfigT, typename ElementTypeList, typename ContainerConfig> 00205 struct mesh_inserter_type< viennagrid::detail::decorated_mesh_view_config<WrappedMeshConfigT, ElementTypeList, ContainerConfig> > 00206 { 00207 typedef viennagrid::detail::decorated_mesh_view_config<WrappedMeshConfigT, ElementTypeList, ContainerConfig> argument_type; 00208 typedef WrappedMeshConfigT ConfigType; 00209 00210 typedef typename mesh_element_collection_type<argument_type>::type view_container_collection_type; 00211 typedef typename mesh_inserter_type<WrappedMeshConfigT>::type full_mesh_inserter_type; 00212 typedef typename mesh_change_counter_type<WrappedMeshConfigT>::type change_counter_type; 00213 00214 typedef typename viennagrid::result_of::recursive_inserter<view_container_collection_type, change_counter_type, full_mesh_inserter_type>::type type; 00215 }; 00217 } 00218 00223 template <typename WrappedConfigType> 00224 class mesh 00225 { 00226 typedef viennagrid::mesh<WrappedConfigType> self_type; 00227 00228 public: 00229 typedef WrappedConfigType wrapped_config_type; 00230 typedef typename WrappedConfigType::type config_type; 00231 00232 00233 typedef typename result_of::mesh_element_collection_type<WrappedConfigType>::type element_collection_type; 00234 typedef typename result_of::mesh_appendix_type<WrappedConfigType>::type appendix_type; 00235 typedef typename result_of::mesh_change_counter_type<WrappedConfigType>::type change_counter_type; 00236 typedef typename result_of::mesh_inserter_type<WrappedConfigType>::type inserter_type; 00237 00238 00240 mesh() : inserter( element_container_collection, change_counter_ ), change_counter_(0) {} 00241 00247 template<typename OtherWrappedConfigT> 00248 mesh( mesh_proxy<viennagrid::mesh<OtherWrappedConfigT> > proxy ) : change_counter_(0) 00249 { 00250 typedef typename viennagrid::mesh<OtherWrappedConfigT>::element_collection_type other_element_collection_type; 00251 00252 detail::view_mesh_setter< other_element_collection_type > functor(proxy.mesh_obj_->element_collection()); 00253 viennagrid::detail::for_each(element_container_collection, functor); 00254 00255 inserter = inserter_type( element_container_collection, change_counter_,proxy.mesh_obj_->get_inserter() ); 00256 } 00257 00258 ~mesh() {} 00259 00260 00265 mesh(const mesh & other) : element_container_collection(other.element_container_collection), appendix_(other.appendix_), inserter(other.inserter), change_counter_(other.change_counter_) 00266 { 00267 inserter.set_mesh_info( element_container_collection, change_counter_ ); 00268 increment_change_counter(); 00269 00270 detail::fix_handles(other, *this); 00271 } 00272 00278 mesh & operator=( mesh const & other) 00279 { 00280 // element_container_collection = element_collection_type(); 00281 element_container_collection = other.element_container_collection; 00282 00283 appendix_ = other.appendix_; 00284 inserter = other.inserter; 00285 change_counter_ = other.change_counter_; 00286 00287 inserter.set_mesh_info( element_container_collection, change_counter_ ); 00288 increment_change_counter(); 00289 00290 detail::fix_handles(other, *this); 00291 return *this; 00292 } 00293 00297 void clear() 00298 { 00299 *this = mesh(); 00300 } 00301 00302 public: 00303 00304 // TODO no direct access to collection! 00305 00307 element_collection_type & element_collection() { return element_container_collection; } 00308 element_collection_type const & element_collection() const { return element_container_collection; } 00309 00311 appendix_type & appendix() { return appendix_; } 00312 appendix_type const & appendix() const { return appendix_; } 00313 00315 inserter_type & get_inserter() { return inserter; } 00316 inserter_type const & get_inserter() const { return inserter; } 00317 00319 bool is_obsolete( change_counter_type change_counter_to_check ) const { return change_counter_to_check != change_counter_; } 00320 void update_change_counter( change_counter_type & change_counter_to_update ) const { change_counter_to_update = change_counter_; } 00321 void increment_change_counter() { ++change_counter_; } 00322 00323 protected: 00324 element_collection_type element_container_collection; 00325 00326 appendix_type appendix_; 00327 inserter_type inserter; 00328 00329 change_counter_type change_counter_; 00330 }; 00331 00335 template<typename WrappedConfigT> 00336 void clear( mesh<WrappedConfigT> & mesh_ ) 00337 { 00338 mesh_.clear(); 00339 } 00340 00341 00342 namespace result_of 00343 { 00348 template<typename WrappedConfigType> 00349 struct mesh 00350 { 00351 typedef viennagrid::mesh<WrappedConfigType> type; 00352 }; 00353 } 00354 00355 00356 namespace detail 00357 { 00358 00360 template<typename WrappedConfigType> 00361 bool is_obsolete( viennagrid::mesh<WrappedConfigType> const & mesh_obj, typename viennagrid::mesh<WrappedConfigType>::change_counter_type change_counter_to_check ) 00362 { return mesh_obj.is_obsolete( change_counter_to_check ); } 00363 00365 template<typename WrappedConfigType> 00366 void update_change_counter( viennagrid::mesh<WrappedConfigType> & mesh_obj, typename viennagrid::mesh<WrappedConfigType>::change_counter_type & change_counter_to_update ) 00367 { mesh_obj.update_change_counter( change_counter_to_update ); } 00368 00370 template<typename WrappedConfigType> 00371 void increment_change_counter( viennagrid::mesh<WrappedConfigType> & mesh_obj) 00372 { mesh_obj.increment_change_counter(); } 00373 00374 00375 00376 00377 00378 00379 00380 00381 00383 template<typename element_tag, typename coboundary_tag, typename mesh_type> 00384 typename viennagrid::detail::result_of::lookup< 00385 typename viennagrid::detail::result_of::lookup< 00386 typename mesh_type::appendix_type, 00387 coboundary_collection_tag 00388 >::type, 00389 viennagrid::static_pair<element_tag, coboundary_tag> 00390 >::type & 00391 coboundary_collection( mesh_type & mesh_obj) 00392 { return viennagrid::get< viennagrid::static_pair<element_tag, coboundary_tag> >( viennagrid::get<coboundary_collection_tag>( mesh_obj.appendix() ) );} 00393 00395 template<typename element_tag, typename coboundary_tag, typename mesh_type> 00396 typename viennagrid::detail::result_of::lookup< 00397 typename viennagrid::detail::result_of::lookup< 00398 typename mesh_type::appendix_type, 00399 coboundary_collection_tag 00400 >::type, 00401 viennagrid::static_pair<element_tag, coboundary_tag> 00402 >::type const & 00403 coboundary_collection( mesh_type const & mesh_obj) 00404 { return viennagrid::get< viennagrid::static_pair<element_tag, coboundary_tag> >( viennagrid::get<coboundary_collection_tag>( mesh_obj.appendix() ) );} 00405 00406 00408 template<typename element_tag, typename connector_element_tag, typename mesh_type> 00409 typename viennagrid::detail::result_of::lookup< 00410 typename viennagrid::detail::result_of::lookup< 00411 typename mesh_type::appendix_type, 00412 neighbor_collection_tag 00413 >::type, 00414 viennagrid::static_pair<element_tag, connector_element_tag> 00415 >::type & 00416 neighbor_collection( mesh_type & mesh_obj) 00417 { return viennagrid::get< viennagrid::static_pair<element_tag, connector_element_tag> >( viennagrid::get<neighbor_collection_tag>( mesh_obj.appendix() ) ); } 00418 00420 template<typename element_tag, typename connector_element_tag, typename mesh_type> 00421 typename viennagrid::detail::result_of::lookup< 00422 typename viennagrid::detail::result_of::lookup< 00423 typename mesh_type::appendix_type, 00424 neighbor_collection_tag 00425 >::type, 00426 viennagrid::static_pair<element_tag, connector_element_tag> 00427 >::type const & 00428 neighbor_collection( mesh_type const & mesh_obj) 00429 { return viennagrid::get< viennagrid::static_pair<element_tag, connector_element_tag> >( viennagrid::get<neighbor_collection_tag>( mesh_obj.appendix() ) ); } 00430 00431 00433 template<typename element_tag, typename mesh_type> 00434 typename viennagrid::detail::result_of::lookup< 00435 typename viennagrid::detail::result_of::lookup< 00436 typename mesh_type::appendix_type, 00437 boundary_information_collection_tag 00438 >::type, 00439 element_tag 00440 >::type & 00441 boundary_information_collection( mesh_type & mesh_obj) 00442 { return viennagrid::get<element_tag>( viennagrid::get<boundary_information_collection_tag>( mesh_obj.appendix() ) ); } 00443 00445 template<typename element_tag, typename mesh_type> 00446 typename viennagrid::detail::result_of::lookup< 00447 typename viennagrid::detail::result_of::lookup< 00448 typename mesh_type::appendix_type, 00449 boundary_information_collection_tag 00450 >::type, 00451 element_tag 00452 >::type const & 00453 boundary_information_collection( mesh_type const & mesh_obj) 00454 { return viennagrid::get<element_tag>( viennagrid::get<boundary_information_collection_tag>( mesh_obj.appendix() ) ); } 00455 } 00456 } 00457 00458 00459 namespace viennagrid 00460 { 00461 namespace result_of 00462 { 00464 template<typename TypemapT> 00465 struct container_collection_typemap< viennagrid::collection<TypemapT> > 00466 { 00467 typedef TypemapT type; 00468 }; 00469 00470 template<typename TypemapT> 00471 struct container_collection_typemap< const viennagrid::collection<TypemapT> > 00472 { 00473 typedef TypemapT type; 00474 }; 00475 00476 template<typename KeyT, typename ValueT, typename TailT> 00477 struct container_collection_typemap< viennagrid::typelist< viennagrid::static_pair<KeyT, ValueT>, TailT > > 00478 { 00479 typedef viennagrid::typelist< viennagrid::static_pair<KeyT, ValueT>, TailT > type; 00480 }; 00481 00482 00483 // doxygen docu in forwards.hpp 00484 template<typename TypemapT> 00485 struct element_collection< collection<TypemapT> > 00486 { 00487 typedef collection<TypemapT> type; 00488 }; 00489 00490 template<typename WrappedConfigT> 00491 struct element_collection< viennagrid::mesh<WrappedConfigT> > 00492 { 00493 typedef typename viennagrid::mesh<WrappedConfigT>::element_collection_type type; 00494 }; 00495 00496 template<typename WrappedConfigT> 00497 struct element_collection< const viennagrid::mesh<WrappedConfigT> > 00498 { 00499 typedef typename viennagrid::mesh<WrappedConfigT>::element_collection_type type; 00500 }; 00508 template<typename SomethingT> 00509 struct element_typelist 00510 { 00511 typedef typename element_collection<SomethingT>::type container_collection; 00512 typedef typename viennagrid::detail::result_of::key_typelist<typename container_collection::typemap >::type type; 00513 }; 00514 00516 template<typename HostElementT> 00517 struct element_typelist_for_element; 00518 00519 template<> 00520 struct element_typelist_for_element<viennagrid::null_type> 00521 { 00522 typedef viennagrid::null_type type; 00523 }; 00524 00525 template<typename HeadT, typename TailT> 00526 struct element_typelist_for_element< viennagrid::typelist<HeadT, TailT> > 00527 { 00528 typedef typename HeadT::first BoundaryContainerType; 00529 typedef typename BoundaryContainerType::value_type CurrentElementType; 00530 00531 typedef viennagrid::typelist< 00532 CurrentElementType, 00533 typename element_typelist_for_element<TailT>::type 00534 > type; 00535 }; 00536 00537 template<typename ElementTagT, typename WrappedConfigT> 00538 struct element_typelist< viennagrid::element<ElementTagT, WrappedConfigT> > 00539 { 00540 typedef typename viennagrid::element<ElementTagT, WrappedConfigT>::bnd_cell_container_typelist bnd_cell_container_typelist; 00541 typedef typename element_typelist_for_element<bnd_cell_container_typelist>::type type; 00542 }; 00549 template<typename SomethingT> 00550 struct element_taglist 00551 { 00552 typedef typename viennagrid::detail::TRANSFORM< 00553 result_of::element_tag, 00554 typename element_typelist<SomethingT>::type 00555 >::type type; 00556 }; 00557 00558 00564 template<typename HostElementT, typename BoundaryElementTypeOrTagT> 00565 struct is_boundary 00566 { 00567 typedef typename result_of::element_tag<BoundaryElementTypeOrTagT>::type BoundaryElementTag; 00568 static const bool value = 00569 detail::result_of::index_of< 00570 typename element_taglist<HostElementT>::type, 00571 BoundaryElementTag 00572 >::value != -1; 00573 }; 00574 00575 00577 template<typename AllElementsTypelistT, typename ElementT> 00578 struct referencing_element_typelist_impl; 00579 00580 template<typename ElementT> 00581 struct referencing_element_typelist_impl<viennagrid::null_type, ElementT> 00582 { 00583 typedef viennagrid::null_type type; 00584 }; 00585 00586 template<typename HeadT, typename TailT, typename ElementT> 00587 struct referencing_element_typelist_impl< viennagrid::typelist<HeadT, TailT>, ElementT > 00588 { 00589 typedef typename referencing_element_typelist_impl<TailT, ElementT>::type tail_typelist; 00590 00591 typedef typename viennagrid::detail::IF< 00592 is_boundary<HeadT, ElementT>::value, 00593 viennagrid::typelist<HeadT, tail_typelist>, 00594 tail_typelist 00595 >::type type; 00596 }; 00604 template<typename SomethingT, typename ElementTypeOrTagT> 00605 struct referencing_element_typelist 00606 { 00607 typedef typename element<SomethingT, ElementTypeOrTagT>::type ElementType; 00608 typedef typename element_typelist<SomethingT>::type AllElementsTypelist; 00609 typedef typename referencing_element_typelist_impl<AllElementsTypelist, ElementType>::type type; 00610 }; 00611 00612 00614 template<typename SomethingT> 00615 struct change_counter_type; 00616 00618 template<typename WrappedConfigT> 00619 struct change_counter_type< viennagrid::mesh<WrappedConfigT> > 00620 { 00621 typedef typename viennagrid::mesh<WrappedConfigT>::change_counter_type type; 00622 }; 00624 } 00625 00626 namespace detail 00627 { 00629 template <typename WrappedConfigType, typename ElementTypeList, typename ContainerConfig> 00630 class decorated_mesh_view_config 00631 { 00632 private: 00633 typedef typename config::result_of::element_collection< WrappedConfigType >::type element_collection_type; 00634 typedef typename viennagrid::result_of::id_generator<WrappedConfigType>::type id_generator_type; 00635 00636 typedef typename viennagrid::result_of::filter_element_container<ElementTypeList, typename element_collection_type::typemap>::type view_container_collection_typemap; 00637 typedef typename viennagrid::result_of::view_collection<view_container_collection_typemap, ContainerConfig>::type view_container_collection_type; 00638 00639 00640 public: 00641 typedef view_container_collection_typemap type; 00642 00643 typedef WrappedConfigType mesh_config_type; 00644 }; 00645 00647 template <typename WrappedConfigType, typename E, typename C, typename ElementTypeList, typename ContainerConfig> 00648 class decorated_mesh_view_config< decorated_mesh_view_config<WrappedConfigType, E, C>, ElementTypeList, ContainerConfig> 00649 { 00650 private: 00651 typedef typename config::result_of::element_collection< WrappedConfigType >::type element_collection_type; 00652 typedef typename viennagrid::result_of::id_generator<WrappedConfigType>::type id_generator_type; 00653 00654 typedef typename viennagrid::result_of::filter_element_container<ElementTypeList, typename element_collection_type::typemap>::type view_container_collection_typemap; 00655 typedef typename viennagrid::result_of::view_collection<view_container_collection_typemap, ContainerConfig>::type view_container_collection_type; 00656 00657 00658 public: 00659 typedef view_container_collection_typemap type; 00660 00661 typedef typename decorated_mesh_view_config<WrappedConfigType, E, C>::mesh_config_type mesh_config_type; 00662 }; 00663 } 00664 00665 00666 namespace result_of 00667 { 00674 template< 00675 typename MeshT, 00676 typename ElementTypelistT = 00677 typename viennagrid::detail::result_of::key_typelist< 00678 typename element_collection<MeshT>::type::typemap 00679 >::type, 00680 typename ContainerConfigT = 00681 default_view_container_config 00682 > 00683 struct mesh_view_from_typelist 00684 { 00685 typedef viennagrid::mesh< viennagrid::detail::decorated_mesh_view_config<typename MeshT::wrapped_config_type, ElementTypelistT, ContainerConfigT> > type; 00686 }; 00687 00688 00703 template<typename MeshT, 00704 typename Element0TypeOrTagT = viennagrid::null_type, typename Element1TypeOrTagT = viennagrid::null_type, 00705 typename Element2TypeOrTagT = viennagrid::null_type, typename Element3TypeOrTagT = viennagrid::null_type, 00706 typename Element4TypeOrTagT = viennagrid::null_type, typename Element5TypeOrTagT = viennagrid::null_type, 00707 typename Element6TypeOrTagT = viennagrid::null_type, typename Element7TypeOrTagT = viennagrid::null_type, 00708 typename Element8TypeOrTagT = viennagrid::null_type, typename Element9TypeOrTagT = viennagrid::null_type> 00709 struct mesh_view 00710 { 00711 typedef typename mesh_view_from_typelist< 00712 MeshT, 00713 typename viennagrid::make_typelist< 00714 typename element<MeshT, Element0TypeOrTagT>::type, 00715 typename element<MeshT, Element1TypeOrTagT>::type, 00716 typename element<MeshT, Element2TypeOrTagT>::type, 00717 typename element<MeshT, Element3TypeOrTagT>::type, 00718 typename element<MeshT, Element4TypeOrTagT>::type, 00719 typename element<MeshT, Element5TypeOrTagT>::type, 00720 typename element<MeshT, Element6TypeOrTagT>::type, 00721 typename element<MeshT, Element7TypeOrTagT>::type, 00722 typename element<MeshT, Element8TypeOrTagT>::type, 00723 typename element<MeshT, Element9TypeOrTagT>::type 00724 >::type 00725 >::type type; 00726 }; 00727 00729 template<typename WrappedConfigT> 00730 struct mesh_view<viennagrid::mesh<WrappedConfigT>, 00731 viennagrid::null_type, viennagrid::null_type, viennagrid::null_type, viennagrid::null_type, viennagrid::null_type, 00732 viennagrid::null_type, viennagrid::null_type, viennagrid::null_type, viennagrid::null_type, viennagrid::null_type> 00733 { 00734 typedef typename mesh_view_from_typelist< viennagrid::mesh<WrappedConfigT> >::type type; 00735 }; 00737 } 00738 00739 namespace detail 00740 { 00742 template<typename container_collection_type> 00743 class handle_mesh_functor 00744 { 00745 public: 00746 00747 handle_mesh_functor(container_collection_type & collection_) : collection(collection_) {} 00748 00749 template<typename container_type> 00750 void operator()( container_type & container ) 00751 { 00752 typedef typename container_type::value_type value_type; 00753 detail::handle( viennagrid::get<value_type>(collection), container); 00754 } 00755 00756 00757 private: 00758 container_collection_type & collection; 00759 }; 00760 } 00761 00762 00763 00764 namespace detail 00765 { 00766 00768 template<typename ConfigType> 00769 typename viennagrid::mesh<ConfigType>::element_collection_type & 00770 element_collection( viennagrid::mesh<ConfigType> & mesh_obj) 00771 { return mesh_obj.element_collection(); } 00772 00774 template<typename ConfigType> 00775 typename viennagrid::mesh<ConfigType>::element_collection_type const & 00776 element_collection( viennagrid::mesh<ConfigType> const & mesh_obj) 00777 { return mesh_obj.element_collection(); } 00778 00779 00781 template<typename ConfigType> 00782 typename viennagrid::mesh<ConfigType>::inserter_type & 00783 inserter(viennagrid::mesh<ConfigType> & mesh_obj) 00784 { return mesh_obj.get_inserter(); } 00785 00787 template<typename ConfigType> 00788 typename viennagrid::mesh<ConfigType>::inserter_type const & 00789 inserter(viennagrid::mesh<ConfigType> const & mesh_obj) 00790 { return mesh_obj.get_inserter(); } 00791 00792 00794 template<typename ConfigType> 00795 typename viennagrid::mesh<ConfigType>::inserter_type::id_generator_type & 00796 id_generator(viennagrid::mesh<ConfigType> & mesh_obj) 00797 { return inserter(mesh_obj).get_id_generator(); } 00798 00800 template<typename ConfigType> 00801 typename viennagrid::mesh<ConfigType>::inserter_type::id_generator_type const & 00802 id_generator(viennagrid::mesh<ConfigType> const & mesh_obj) 00803 { return inserter(mesh_obj).get_id_generator(); } 00804 00805 } 00806 00807 00815 template<typename MeshT, typename ViewT> 00816 void handle_mesh(MeshT & mesh_obj, ViewT & view_obj) 00817 { 00818 detail::handle_mesh_functor< typename result_of::element_collection<MeshT>::type > functor( detail::element_collection(mesh_obj) ); 00819 viennagrid::detail::for_each( detail::element_collection(view_obj), functor); 00820 } 00821 00822 00830 template<typename ElementTypeOrTag, typename MeshOrSegmentHandleT> 00831 typename viennagrid::result_of::id< typename viennagrid::result_of::element<MeshOrSegmentHandleT, ElementTypeOrTag>::type >::type 00832 id_upper_bound( MeshOrSegmentHandleT const & mesh_or_segment ) 00833 { 00834 return detail::id_generator(mesh_or_segment).max_id( viennagrid::detail::tag<ElementTypeOrTag>() ); 00835 } 00836 00837 00838 00847 template<typename WrappedMeshConfigT, typename HandleT> 00848 typename viennagrid::detail::result_of::value_type<HandleT>::type & 00849 dereference_handle(mesh<WrappedMeshConfigT> & mesh_obj, HandleT const & handle) 00850 { 00851 typedef typename viennagrid::detail::result_of::value_type<HandleT>::type value_type; 00852 return get<value_type>(viennagrid::detail::element_collection(mesh_obj)).dereference_handle( handle ); 00853 } 00854 00863 template<typename WrappedMeshConfigT, typename HandleT> 00864 typename viennagrid::detail::result_of::value_type<HandleT>::type const & 00865 dereference_handle(mesh<WrappedMeshConfigT> const & mesh_obj, HandleT const & handle) 00866 { 00867 typedef typename viennagrid::detail::result_of::value_type<HandleT>::type value_type; 00868 return get<value_type>(viennagrid::detail::element_collection(mesh_obj)).dereference_handle( handle ); 00869 } 00870 00871 00881 template<typename MeshOrSegmentHandleT, typename ElementTagT, typename WrappedConfigT> 00882 typename result_of::handle<MeshOrSegmentHandleT, viennagrid::element<ElementTagT, WrappedConfigT> >::type 00883 handle(MeshOrSegmentHandleT & mesh_or_segment, viennagrid::element<ElementTagT, WrappedConfigT> & element) 00884 { return get< viennagrid::element<ElementTagT, WrappedConfigT> >(detail::element_collection(mesh_or_segment)).handle( element ); } 00885 00895 template<typename MeshOrSegmentHandleT, typename ElementTagT, typename WrappedConfigT> 00896 typename result_of::const_handle<MeshOrSegmentHandleT, viennagrid::element<ElementTagT, WrappedConfigT> >::type 00897 handle(MeshOrSegmentHandleT const & mesh_or_segment, viennagrid::element<ElementTagT, WrappedConfigT> const & element) 00898 { return get< viennagrid::element<ElementTagT, WrappedConfigT> >(detail::element_collection(mesh_or_segment)).handle( element ); } 00899 00900 00901 00902 00903 00904 00915 template<typename ElementTagT, typename WrappedConfigT, typename BoundaryHandleT> 00916 typename viennagrid::result_of::vertex_handle< viennagrid::element<ElementTagT, WrappedConfigT> >::type 00917 local_vertex( 00918 viennagrid::element<ElementTagT, WrappedConfigT> & host_element, 00919 BoundaryHandleT const & boundary_element_handle, 00920 std::size_t index) 00921 { 00922 typedef typename viennagrid::detail::result_of::value_type<BoundaryHandleT>::type element_type_2; 00923 element_type_2 & bnd_kcell = viennagrid::dereference_handle(host_element, boundary_element_handle); 00924 return viennagrid::vertices(bnd_kcell).handle_at(host_element.global_to_local_orientation(boundary_element_handle, index)); 00925 } 00926 00937 template<typename ElementTagT, typename WrappedConfigT, typename BoundaryHandleT> 00938 typename viennagrid::result_of::const_vertex_handle< viennagrid::element<ElementTagT, WrappedConfigT> >::type 00939 local_vertex( 00940 viennagrid::element<ElementTagT, WrappedConfigT> const & host_element, 00941 BoundaryHandleT const & boundary_element_handle, 00942 std::size_t index) 00943 { 00944 typedef typename viennagrid::detail::result_of::value_type<BoundaryHandleT>::type element_type_2; 00945 element_type_2 const & bnd_kcell = viennagrid::dereference_handle(host_element, boundary_element_handle); 00946 return viennagrid::vertices(bnd_kcell).handle_at(host_element.global_to_local_orientation(boundary_element_handle, index)); 00947 } 00948 00949 00950 namespace detail 00951 { 00953 template<typename ContainerT> 00954 class dereference_handle_comparator 00955 { 00956 public: 00957 00958 dereference_handle_comparator(ContainerT const & container_) : container(container_) {} 00959 00960 template<typename HandleT> 00961 bool operator() ( HandleT h1, HandleT h2 ) 00962 { 00963 return &viennagrid::dereference_handle( container, h1 ) < &viennagrid::dereference_handle( container, h2 ); 00964 } 00965 00966 private: 00967 ContainerT const & container; 00968 }; 00969 } 00970 00971 } 00972 00973 00974 00975 namespace viennagrid 00976 { 00977 00978 namespace result_of 00979 { 00985 template<typename MeshViewOrSegmentHandleT, typename ElementTypeOrTagT> 00986 struct is_element_present; 00987 00989 template<typename WrappedConfigType, typename element_type_or_tag> 00990 struct is_element_present< viennagrid::mesh<WrappedConfigType>, element_type_or_tag > 00991 { 00992 typedef typename viennagrid::result_of::element_tag<element_type_or_tag>::type tag; 00993 static const bool value = config::result_of::is_element_present<WrappedConfigType, tag>::value; 00994 }; 00995 00996 template<typename WrappedConfigType, typename element_type_or_tag> 00997 struct is_element_present< const viennagrid::mesh<WrappedConfigType>, element_type_or_tag > 00998 { 00999 static const bool value = is_element_present<viennagrid::mesh<WrappedConfigType>, element_type_or_tag>::value; 01000 }; 01001 01002 01003 01004 01006 template<typename typelist, typename element_tag> 01007 struct is_element_present_helper; 01008 01009 template<typename element_tag> 01010 struct is_element_present_helper<null_type, element_tag> 01011 { 01012 static const bool value = false; 01013 }; 01014 01015 template<typename element_type, typename tail, typename element_tag> 01016 struct is_element_present_helper< typelist<element_type, tail>, element_tag> 01017 { 01018 static const bool value = 01019 viennagrid::detail::EQUAL< 01020 typename element_type::tag, 01021 element_tag 01022 >::value || 01023 is_element_present_helper<tail, element_tag>::value; 01024 }; 01025 01026 01027 template <typename WrappedMeshConfigType, typename ElementTypeList, typename ContainerConfig, typename element_type_or_tag> 01028 struct is_element_present< viennagrid::mesh< viennagrid::detail::decorated_mesh_view_config<WrappedMeshConfigType, ElementTypeList, ContainerConfig> >, element_type_or_tag > 01029 { 01030 typedef typename viennagrid::result_of::element_tag<element_type_or_tag>::type tag; 01031 static const bool value = is_element_present_helper<ElementTypeList, tag>::value; 01032 }; 01033 01034 template <typename WrappedMeshConfigType, typename ElementTypeList, typename ContainerConfig, typename element_type_or_tag> 01035 struct is_element_present< const viennagrid::mesh< viennagrid::detail::decorated_mesh_view_config<WrappedMeshConfigType, ElementTypeList, ContainerConfig> >, element_type_or_tag > 01036 { 01037 static const bool value = is_element_present<viennagrid::mesh< viennagrid::detail::decorated_mesh_view_config<WrappedMeshConfigType, ElementTypeList, ContainerConfig> >, element_type_or_tag>::value; 01038 }; 01049 template<typename MeshSegmentHandleType, typename element_type_or_tag> 01050 struct element 01051 { 01052 typedef typename detail::STATIC_ASSERT< is_element_present<MeshSegmentHandleType, element_type_or_tag>::value >::type ERROR_ELEMENT_IS_NOT_PRESENT_IN_MESH; 01053 typedef typename element< typename element_collection< MeshSegmentHandleType >::type, element_type_or_tag >::type type; 01054 }; 01055 01061 template<typename MeshSegmentHandleType, typename element_type_or_tag> 01062 struct handle 01063 { 01064 typedef typename detail::STATIC_ASSERT< is_element_present<MeshSegmentHandleType, element_type_or_tag>::value >::type ERROR_ELEMENT_IS_NOT_PRESENT_IN_MESH; 01065 typedef typename handle< typename element_collection< MeshSegmentHandleType >::type, element_type_or_tag >::type type; 01066 }; 01067 01073 template<typename MeshSegmentHandleType, typename element_type_or_tag> 01074 struct const_handle 01075 { 01076 typedef typename detail::STATIC_ASSERT< is_element_present<MeshSegmentHandleType, element_type_or_tag>::value >::type ERROR_ELEMENT_IS_NOT_PRESENT_IN_MESH; 01077 typedef typename const_handle< typename element_collection< MeshSegmentHandleType >::type, element_type_or_tag >::type type; 01078 }; 01079 01085 template<typename MeshSegmentHandleType, typename element_type_or_tag> 01086 struct element_range 01087 { 01088 typedef typename detail::STATIC_ASSERT< is_element_present<MeshSegmentHandleType, element_type_or_tag>::value >::type ERROR_ELEMENT_IS_NOT_PRESENT_IN_MESH; 01089 typedef typename element_range< typename element_collection< MeshSegmentHandleType >::type, element_type_or_tag >::type type; 01090 }; 01091 01097 template<typename MeshSegmentHandleType, typename element_type_or_tag> 01098 struct const_element_range 01099 { 01100 typedef typename detail::STATIC_ASSERT< is_element_present<MeshSegmentHandleType, element_type_or_tag>::value >::type ERROR_ELEMENT_IS_NOT_PRESENT_IN_MESH; 01101 typedef typename const_element_range< typename element_collection< MeshSegmentHandleType >::type, element_type_or_tag >::type type; 01102 }; 01103 01104 01106 template<typename typemap> 01107 struct topologic_cell_dimension_impl; 01108 01109 template<> 01110 struct topologic_cell_dimension_impl<viennagrid::null_type> 01111 { 01112 static const int value = -1; 01113 }; 01114 01115 template<typename element_type, typename element_container_type, typename tail> 01116 struct topologic_cell_dimension_impl< viennagrid::typelist< viennagrid::static_pair<element_type, element_container_type>, tail > > 01117 { 01118 static const int tail_cell_dimension = topologic_cell_dimension_impl<tail>::value; 01119 static const int current_element_dimension = topologic_dimension<element_type>::value; 01120 01121 static const int value = (tail_cell_dimension > current_element_dimension) ? tail_cell_dimension : current_element_dimension; 01122 }; 01129 template<typename something> 01130 struct topologic_cell_dimension 01131 { 01132 static const int value = topologic_cell_dimension_impl< 01133 typename container_collection_typemap< 01134 typename element_collection<something>::type 01135 >::type 01136 >::value; 01137 }; 01138 01139 01140 01141 01142 01144 template<typename typemap, int topologic_dimension> 01145 struct elements_of_topologic_dim_impl; 01146 01147 template<int topologic_dimension> 01148 struct elements_of_topologic_dim_impl< viennagrid::null_type, topologic_dimension > 01149 { 01150 typedef viennagrid::null_type type; 01151 }; 01152 01153 template<typename element_type, typename element_container_type, typename tail, int topologic_dimension> 01154 struct elements_of_topologic_dim_impl< viennagrid::typelist< viennagrid::static_pair<element_type, element_container_type>, tail >, topologic_dimension > 01155 { 01156 typedef typename elements_of_topologic_dim_impl<tail, topologic_dimension>::type tail_typelist; 01157 01158 typedef typename viennagrid::detail::IF< 01159 viennagrid::result_of::topologic_dimension<element_type>::value == topologic_dimension, 01160 typename viennagrid::detail::result_of::push_back<tail_typelist, element_type>::type, 01161 tail_typelist 01162 >::type type; 01163 }; 01171 template<typename something, int topologic_dimension> 01172 struct elements_of_topologic_dim 01173 { 01174 typedef typename elements_of_topologic_dim_impl< 01175 typename container_collection_typemap< 01176 typename element_collection<something>::type 01177 >::type, 01178 topologic_dimension>::type type; 01179 }; 01180 01181 01182 01187 template<typename something> 01188 struct cells 01189 { 01190 typedef typename elements_of_topologic_dim< 01191 something, 01192 topologic_cell_dimension<something>::value 01193 >::type type; 01194 }; 01195 01196 01201 template<typename something> 01202 struct cell 01203 { 01204 typedef typename cells<something>::type all_cell_types; 01205 typedef typename viennagrid::detail::STATIC_ASSERT< viennagrid::detail::result_of::size<all_cell_types>::value == 1 >::type static_assert_typedef; 01206 01207 typedef typename viennagrid::detail::result_of::at<all_cell_types,0>::type type; 01208 }; 01209 01214 template<typename something> 01215 struct cell_tag 01216 { 01217 typedef typename element_tag< typename cell<something>::type >::type type; 01218 }; 01219 } 01220 01221 01222 namespace detail 01223 { 01225 template<typename MeshSegmentHandleT, typename FunctorT> 01226 struct for_each_element_functor 01227 { 01228 for_each_element_functor( MeshSegmentHandleT & d, FunctorT f ) : f_(f), mesh_(d) {} 01229 01230 template<typename element_type> 01231 void operator() ( viennagrid::detail::tag<element_type> ) 01232 { 01233 typedef typename viennagrid::result_of::element_range<MeshSegmentHandleT, element_type>::type element_range_type; 01234 typedef typename viennagrid::result_of::iterator<element_range_type>::type element_range_iterator; 01235 01236 element_range_type range(mesh_); 01237 for (element_range_iterator it = range.begin(); it != range.end(); ++it) 01238 f_(*it); 01239 } 01240 01241 template<typename element_type> 01242 void operator() ( viennagrid::detail::tag<element_type> ) const 01243 { 01244 typedef typename viennagrid::result_of::const_element_range<MeshSegmentHandleT, element_type>::type element_range_type; 01245 typedef typename viennagrid::result_of::iterator<element_range_type>::type element_range_iterator; 01246 01247 element_range_type range(mesh_); 01248 for (element_range_iterator it = range.begin(); it != range.end(); ++it) 01249 f_(*it); 01250 } 01251 01252 FunctorT f_; 01253 MeshSegmentHandleT & mesh_; 01254 }; 01255 } 01256 01257 01266 template<int TopologicDimensionV, typename MeshSegmentHandleT, typename FunctorT> 01267 void for_each( MeshSegmentHandleT & mesh_or_segment, FunctorT f ) 01268 { 01269 detail::for_each_element_functor<MeshSegmentHandleT, FunctorT> for_each_functor(mesh_or_segment, f); 01270 typedef typename viennagrid::result_of::elements_of_topologic_dim<MeshSegmentHandleT, TopologicDimensionV>::type ElementTypelist; 01271 01272 viennagrid::detail::for_each<ElementTypelist>( for_each_functor ); 01273 } 01274 01283 template<int TopologicDimensionV, typename MeshSegmentHandleT, typename FunctorT> 01284 void for_each( MeshSegmentHandleT const & mesh_or_segment, FunctorT f ) 01285 { 01286 detail::for_each_element_functor<const MeshSegmentHandleT, FunctorT> for_each_functor(mesh_or_segment, f); 01287 typedef typename viennagrid::result_of::elements_of_topologic_dim<MeshSegmentHandleT, TopologicDimensionV>::type ElementTypelist; 01288 01289 viennagrid::detail::for_each<ElementTypelist>( for_each_functor ); 01290 } 01291 01292 01300 template<typename MeshSegmentHandleT, typename FunctorT> 01301 void for_each( MeshSegmentHandleT & mesh_or_segment, FunctorT f ) 01302 { 01303 detail::for_each_element_functor<MeshSegmentHandleT, FunctorT> for_each_functor(mesh_or_segment, f); 01304 typedef typename viennagrid::result_of::element_typelist<MeshSegmentHandleT>::type ElementTypelist; 01305 01306 viennagrid::detail::for_each<ElementTypelist>( for_each_functor ); 01307 } 01308 01316 template<typename MeshSegmentHandleT, typename FunctorT> 01317 void for_each( MeshSegmentHandleT const & mesh_or_segment, FunctorT f ) 01318 { 01319 detail::for_each_element_functor<const MeshSegmentHandleT, FunctorT> for_each_functor(mesh_or_segment, f); 01320 typedef typename viennagrid::result_of::element_typelist<MeshSegmentHandleT>::type ElementTypelist; 01321 01322 viennagrid::detail::for_each<ElementTypelist>( for_each_functor ); 01323 } 01324 01325 01326 01327 01328 01329 01330 01331 // doxygen docu in forwards.hpp 01332 template<typename ElementTypeOrTagT, typename WrappedConfigType> 01333 typename result_of::element_range<viennagrid::mesh<WrappedConfigType>, ElementTypeOrTagT>::type 01334 elements(viennagrid::mesh<WrappedConfigType> & mesh_obj) 01335 { return elements<ElementTypeOrTagT>( detail::element_collection(mesh_obj) ); } 01336 01337 // doxygen docu in forwards.hpp 01338 template<typename ElementTypeOrTagT, typename WrappedConfigType> 01339 typename result_of::const_element_range<viennagrid::mesh<WrappedConfigType>, ElementTypeOrTagT>::type 01340 elements(viennagrid::mesh<WrappedConfigType> const & mesh_obj) 01341 { return elements<ElementTypeOrTagT>( detail::element_collection(mesh_obj) ); } 01342 01343 01344 01345 01346 01347 01348 01349 01350 01351 01352 01353 01354 01355 01364 template<typename MeshSegmentHandleT, typename ElementTagT, typename WrappedConfigT> 01365 typename viennagrid::result_of::iterator< typename viennagrid::result_of::element_range<MeshSegmentHandleT, ElementTagT>::type >::type 01366 find(MeshSegmentHandleT & mesh_or_segment, element<ElementTagT, WrappedConfigT> const & element ) 01367 { 01368 return viennagrid::elements<ElementTagT>(mesh_or_segment).find(element); 01369 } 01370 01379 template<typename MeshSegmentHandleT, typename ElementTagT, typename WrappedConfigT> 01380 typename viennagrid::result_of::const_iterator< typename viennagrid::result_of::element_range<MeshSegmentHandleT, ElementTagT>::type >::type 01381 find(MeshSegmentHandleT const & mesh_or_segment, element<ElementTagT, WrappedConfigT> const & element ) 01382 { 01383 return viennagrid::elements<ElementTagT>(mesh_or_segment).find(element); 01384 } 01385 01386 01387 01388 01397 template<typename MeshSegmentHandleT, typename IDT> 01398 typename viennagrid::result_of::iterator< typename viennagrid::result_of::element_range<MeshSegmentHandleT, typename IDT::value_type::tag>::type >::type 01399 find(MeshSegmentHandleT & mesh_or_segment, IDT id ) 01400 { 01401 typedef typename IDT::value_type element_type; 01402 typedef typename element_type::tag element_tag; 01403 01404 return viennagrid::elements<element_tag>(mesh_or_segment).find(id); 01405 } 01406 01415 template<typename MeshSegmentHandleT, typename IDT> 01416 typename viennagrid::result_of::const_iterator< typename viennagrid::result_of::element_range<MeshSegmentHandleT, typename IDT::value_type::tag>::type >::type 01417 find(MeshSegmentHandleT const & mesh_or_segment, IDT id ) 01418 { 01419 typedef typename IDT::value_type element_type; 01420 typedef typename element_type::tag element_tag; 01421 01422 return viennagrid::elements<element_tag>(mesh_or_segment).find(id); 01423 } 01424 01433 template<typename MeshSegmentHandleT, typename HandleT> 01434 typename viennagrid::result_of::iterator< typename viennagrid::result_of::element_range<MeshSegmentHandleT, typename detail::result_of::value_type<HandleT>::type >::type >::type 01435 find_by_handle(MeshSegmentHandleT & mesh_or_segment, HandleT handle) 01436 { 01437 typedef typename detail::result_of::value_type<HandleT>::type element_type; 01438 typedef typename element_type::tag element_tag; 01439 typedef typename viennagrid::result_of::element_range<MeshSegmentHandleT, element_tag>::type RangeType; 01440 typedef typename viennagrid::result_of::iterator<RangeType>::type RangeIterator; 01441 01442 RangeType range = viennagrid::elements<element_tag>(mesh_or_segment); 01443 for (RangeIterator it = range.begin(); it != range.end(); ++it) 01444 { 01445 if ( it.handle() == handle ) 01446 return it; 01447 } 01448 01449 return range.end(); 01450 } 01451 01460 template<typename MeshSegmentHandleT, typename HandleT> 01461 typename viennagrid::result_of::const_iterator< typename viennagrid::result_of::const_element_range<MeshSegmentHandleT, typename detail::result_of::value_type<HandleT>::type >::type >::type 01462 find_by_handle(MeshSegmentHandleT const & mesh_or_segment, HandleT handle) 01463 { 01464 typedef typename detail::result_of::value_type<HandleT>::type element_type; 01465 typedef typename element_type::tag element_tag; 01466 typedef typename viennagrid::result_of::const_element_range<MeshSegmentHandleT, element_tag>::type RangeType; 01467 typedef typename viennagrid::result_of::const_iterator<RangeType>::type RangeIterator; 01468 01469 RangeType range = viennagrid::elements<element_tag>(mesh_or_segment); 01470 for (RangeIterator it = range.begin(); it != range.end(); ++it) 01471 { 01472 if ( it.handle() == handle ) 01473 return it; 01474 } 01475 01476 return range.end(); 01477 } 01478 01479 01480 01481 01491 template<typename ElementTag, typename WrappedConfigType, typename VertexHandleType> 01492 void set_vertex( 01493 viennagrid::element<ElementTag, WrappedConfigType> & element, 01494 VertexHandleType vertex_handle, 01495 unsigned int pos) 01496 { 01497 element.container( viennagrid::dimension_tag<0>() ).set_handle( vertex_handle, pos ); 01498 } 01499 01500 01501 namespace detail 01502 { 01504 template<bool generate_id, bool call_callback, typename mesh_type, typename ElementTag, typename WrappedConfigType> 01505 std::pair< 01506 typename viennagrid::result_of::container_of< 01507 typename viennagrid::result_of::element_collection<mesh_type>::type, 01508 viennagrid::element<ElementTag, WrappedConfigType> 01509 >::type::handle_type, 01510 bool 01511 > 01512 push_element( mesh_type & mesh_obj, viennagrid::element<ElementTag, WrappedConfigType> const & element) 01513 { 01514 return detail::inserter(mesh_obj).template insert<generate_id, call_callback>(element); 01515 } 01516 } 01517 01518 01519 namespace result_of 01520 { 01521 01523 template<typename ConfigType> 01524 struct point< viennagrid::mesh<ConfigType> > 01525 { 01526 typedef typename viennagrid::result_of::vertex< viennagrid::mesh<ConfigType> >::type::appendix_type type; 01527 }; 01528 01529 template<typename ConfigType> 01530 struct point< const viennagrid::mesh<ConfigType> > 01531 { 01532 typedef typename viennagrid::result_of::vertex< viennagrid::mesh<ConfigType> >::type::appendix_type type; 01533 }; 01534 01535 template<typename ElementTag, typename WrappedConfigType> 01536 struct point< viennagrid::element<ElementTag, WrappedConfigType> > 01537 { 01538 typedef typename viennagrid::result_of::vertex< viennagrid::element<ElementTag, WrappedConfigType> >::type::appendix_type type; 01539 }; 01540 01541 template<typename ElementTag, typename WrappedConfigType> 01542 struct point< const viennagrid::element<ElementTag, WrappedConfigType> > 01543 { 01544 typedef typename viennagrid::result_of::vertex< viennagrid::element<ElementTag, WrappedConfigType> >::type::appendix_type type; 01545 }; 01547 } 01548 01549 01556 template<typename WrappedConfigT> 01557 typename result_of::point< viennagrid::mesh<WrappedConfigT> >::type & 01558 point(viennagrid::mesh<WrappedConfigT> & /*mesh*/, typename result_of::vertex< viennagrid::mesh<WrappedConfigT> >::type & vertex) 01559 { return vertex.appendix(); } 01560 01567 template<typename WrappedConfigT> 01568 typename result_of::point< viennagrid::mesh<WrappedConfigT> >::type const & 01569 point(mesh<WrappedConfigT> const & /*mesh*/, typename result_of::vertex< viennagrid::mesh<WrappedConfigT> >::type const & vertex) 01570 { return vertex.appendix(); } 01571 01572 01580 template<typename WrappedConfigT> 01581 typename result_of::point< viennagrid::mesh<WrappedConfigT> >::type & 01582 point(mesh<WrappedConfigT> & mesh_obj, typename result_of::vertex_handle< viennagrid::mesh<WrappedConfigT> >::type vertex_handle) 01583 { return dereference_handle(mesh_obj, vertex_handle).appendix(); } 01584 01592 template<typename WrappedConfigT> 01593 typename result_of::point< viennagrid::mesh<WrappedConfigT> >::type const & 01594 point(mesh<WrappedConfigT> const & mesh_obj, typename result_of::const_vertex_handle< viennagrid::mesh<WrappedConfigT> >::type vertex_handle) 01595 { return dereference_handle(mesh_obj, vertex_handle).appendix(); } 01596 01597 01604 template<typename VertexT> 01605 typename result_of::point< VertexT >::type & 01606 point(VertexT & vertex) 01607 { return default_point_accessor(vertex)(vertex); } 01608 01615 template<typename VertexT> 01616 typename result_of::point< VertexT >::type const & 01617 point(VertexT const & vertex) 01618 { return default_point_accessor(vertex)(vertex); } 01619 01620 01621 01622 namespace detail 01623 { 01624 01626 template<typename MeshT, typename SourceElementT, typename DestinationElementT> 01627 struct copy_element_setters 01628 { 01629 copy_element_setters(MeshT & mesh_obj, SourceElementT const & source_element, DestinationElementT & destination_element) : 01630 mesh_obj_(mesh_obj), source_element_(source_element), destination_element_(destination_element) {} 01631 01632 template<typename BoundaryElementT> 01633 void operator() ( viennagrid::detail::tag<BoundaryElementT> ) 01634 { 01635 typedef typename viennagrid::result_of::const_element_range<SourceElementT, BoundaryElementT>::type SourceBoundaryElementRangeType; 01636 typedef typename viennagrid::result_of::iterator<SourceBoundaryElementRangeType>::type SourceBoundaryElementRangeIterator; 01637 01638 typedef typename viennagrid::result_of::element_range<SourceElementT, BoundaryElementT>::type DestinationBoundaryElementRangeType; 01639 typedef typename viennagrid::result_of::iterator<DestinationBoundaryElementRangeType>::type DestinationBoundaryElementRangeIterator; 01640 01641 SourceBoundaryElementRangeType source_boundary_elements(source_element_); 01642 DestinationBoundaryElementRangeType destination_boundary_elements(destination_element_); 01643 01644 SourceBoundaryElementRangeIterator sit = source_boundary_elements.begin(); 01645 DestinationBoundaryElementRangeIterator dit = destination_boundary_elements.begin(); 01646 01647 for (; sit != source_boundary_elements.end(); ++sit, ++dit) 01648 { 01649 dit.handle() = viennagrid::find( mesh_obj_, sit->id() ).handle(); 01650 } 01651 } 01652 01653 MeshT & mesh_obj_; 01654 SourceElementT const & source_element_; 01655 DestinationElementT & destination_element_; 01656 }; 01657 01658 01660 template<typename ElementTypelistT> 01661 struct fix_handle_helper; 01662 01663 template<> 01664 struct fix_handle_helper< null_type > 01665 { 01666 template<typename SourceWrappedConfigT, typename DestinationWrappedConfigT> 01667 static void fix_handles( viennagrid::mesh<SourceWrappedConfigT> const &, viennagrid::mesh<DestinationWrappedConfigT> & ) 01668 {} 01669 }; 01670 01671 01672 template<typename SourceElementT, typename TailT> 01673 struct fix_handle_helper< typelist<SourceElementT, TailT> > 01674 { 01675 template<typename SourceWrappedConfigT, typename DestinationWrappedConfigT> 01676 static void fix_handles( viennagrid::mesh<SourceWrappedConfigT> const & source_mesh_obj, viennagrid::mesh<DestinationWrappedConfigT> & destination_mesh_obj ) 01677 { 01678 typedef typename viennagrid::result_of::element_tag<SourceElementT>::type ElementTag; 01679 01680 typedef viennagrid::mesh<SourceWrappedConfigT> SourceMeshType; 01681 typedef viennagrid::mesh<DestinationWrappedConfigT> DestinationMeshType; 01682 01683 typedef typename viennagrid::result_of::const_element_range<SourceMeshType, SourceElementT>::type SourceElementRangeType; 01684 typedef typename viennagrid::result_of::iterator<SourceElementRangeType>::type SourceElementRangeIterator; 01685 01686 typedef typename viennagrid::result_of::element_range<DestinationMeshType, SourceElementT>::type DestinationElementRangeType; 01687 typedef typename viennagrid::result_of::iterator<DestinationElementRangeType>::type DestinationElementRangeIterator; 01688 01689 01690 typedef typename viennagrid::result_of::element<SourceMeshType, ElementTag>::type SourceElementType; 01691 typedef typename viennagrid::result_of::element<DestinationMeshType, ElementTag>::type DestinationElementType; 01692 //typedef typename viennagrid::result_of::handle<DestinationMeshType, ElementTag>::type DestinationElementHandleType; 01693 01694 SourceElementRangeType source_elements(source_mesh_obj); 01695 DestinationElementRangeType destination_elements(destination_mesh_obj); 01696 01697 DestinationElementRangeIterator dit = destination_elements.begin(); 01698 for (SourceElementRangeIterator sit = source_elements.begin(); sit != source_elements.end(); ++sit, ++dit) 01699 { 01700 SourceElementType const & source_element = *sit; 01701 DestinationElementType & destination_element = *dit; 01702 01703 if (source_element.id() != destination_element.id()) 01704 { 01705 std::cout << "ERROR in fix_handles: destination element id != source element id" << std::endl; 01706 continue; 01707 } 01708 // DestinationElementHandleType handle = viennagrid::push_element<false, false>(destination_mesh_obj, destination_element).first; 01709 01710 typedef typename viennagrid::result_of::boundary_element_typelist<SourceElementT>::type BoundaryElementTypelist; 01711 typedef typename viennagrid::result_of::element_typelist<DestinationMeshType>::type DestinationElementTypelist; 01712 01713 typedef typename viennagrid::detail::result_of::intersection< 01714 BoundaryElementTypelist, 01715 DestinationElementTypelist 01716 >::type ElementTypelist; 01717 01718 detail::copy_element_setters<DestinationMeshType, SourceElementT, DestinationElementType> setter( destination_mesh_obj, source_element, destination_element ); 01719 viennagrid::detail::for_each<ElementTypelist>(setter); 01720 } 01721 01722 fix_handle_helper<TailT>::fix_handles( source_mesh_obj, destination_mesh_obj ); 01723 } 01724 }; 01725 01727 template<typename SourceWrappedConfigT, typename DestinationWrappedConfigT> 01728 void fix_handles( viennagrid::mesh<SourceWrappedConfigT> const & source_mesh_obj, viennagrid::mesh<DestinationWrappedConfigT> & destination_mesh ) 01729 { 01730 typedef viennagrid::mesh<SourceWrappedConfigT> SourceMeshType; 01731 typedef viennagrid::mesh<DestinationWrappedConfigT> DestinationMeshType; 01732 01733 typedef typename viennagrid::result_of::element_typelist<SourceMeshType>::type SourceTypelist; 01734 typedef typename viennagrid::result_of::element_typelist<DestinationMeshType>::type DestinationTypelist; 01735 01736 typedef typename viennagrid::detail::result_of::intersection< 01737 SourceTypelist, 01738 DestinationTypelist 01739 >::type ElementTypelist; 01740 01741 fix_handle_helper<ElementTypelist>::fix_handles( source_mesh_obj, destination_mesh ); 01742 } 01743 01744 } //namespace detail 01745 } 01746 01747 #endif