ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/mesh/mesh.hpp
Go to the documentation of this file.
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