ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/boundary.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_BOUNDARY_HPP
00002 #define VIENNAGRID_ALGORITHM_BOUNDARY_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 <vector>
00017 #include "viennagrid/forwards.hpp"
00018 #include "viennagrid/element/element.hpp"
00019 #include "viennagrid/accessor.hpp"
00020 #include "viennagrid/mesh/segmentation.hpp"
00021 
00022 
00028 namespace viennagrid
00029 {
00030   namespace detail
00031   {
00032 
00034     template <typename MeshT, typename AccessorT>
00035     void detect_boundary(MeshT & mesh_obj, AccessorT boundary_info_accessor)
00036     {
00037       typedef typename viennagrid::result_of::cell_tag<MeshT>::type CellTag;
00038       typedef typename viennagrid::result_of::facet_tag<CellTag>::type FacetTag;
00039 
00040       typedef typename viennagrid::result_of::element<MeshT, CellTag>::type     CellType;
00041 
00042       typedef typename viennagrid::result_of::element_range<MeshT, FacetTag>::type      FacetRange;
00043       typedef typename viennagrid::result_of::iterator<FacetRange>::type                                           FacetIterator;
00044 
00045       typedef typename viennagrid::result_of::element_range<MeshT, CellTag>::type        CellRange;
00046       typedef typename viennagrid::result_of::iterator<CellRange>::type                                            CellIterator;
00047 
00048       typedef typename viennagrid::result_of::element_range<CellType, FacetTag>::type     FacetOnCellRange;
00049       typedef typename viennagrid::result_of::iterator<FacetOnCellRange>::type                           FacetOnCellIterator;
00050 
00051 
00052       FacetRange facets(mesh_obj);
00053 
00054       for (FacetIterator fit = facets.begin();
00055             fit != facets.end();
00056             ++fit)
00057           boundary_info_accessor(*fit) = false;
00058 
00059       //iterate over all cells, over facets there and tag them:
00060       CellRange cells(mesh_obj);
00061       for (CellIterator cit = cells.begin();
00062             cit != cells.end();
00063             ++cit)
00064       {
00065         FacetOnCellRange facets_on_cell(*cit);
00066         for (FacetOnCellIterator focit = facets_on_cell.begin();
00067               focit != facets_on_cell.end();
00068               ++focit)
00069               boundary_info_accessor(*focit) = !boundary_info_accessor(*focit);
00070       }
00071     }
00072 
00073 
00074 
00076     template <typename MeshT, typename SourceAccessorT, typename DestinationAccessorT>
00077     void transfer_boundary_information(MeshT const & mesh_obj,
00078                          SourceAccessorT const source_boundary_info_accessor,
00079                          DestinationAccessorT destination_boundary_info_accessor
00080                         )
00081     {
00082       typedef typename SourceAccessorT::access_type src_element_type;
00083       typedef typename DestinationAccessorT::access_type dst_element_type;
00084 
00085       typedef typename viennagrid::result_of::const_element_range< MeshT, dst_element_type >::type dst_range_type;
00086       typedef typename viennagrid::result_of::iterator< dst_range_type >::type dst_range_iterator;
00087 
00088       dst_range_type dst_elements(mesh_obj);
00089 
00090       for (dst_range_iterator it = dst_elements.begin(); it != dst_elements.end(); ++it)
00091           destination_boundary_info_accessor(*it) = false;
00092 
00093 
00094       typedef typename viennagrid::result_of::const_element_range< MeshT, src_element_type >::type src_range_type;
00095       typedef typename viennagrid::result_of::iterator< src_range_type >::type src_range_iterator;
00096 
00097       src_range_type src_elements(mesh_obj);
00098 
00099       for (src_range_iterator fit = src_elements.begin();
00100           fit != src_elements.end();
00101           ++fit)
00102       {
00103         if ( source_boundary_info_accessor(*fit) )
00104         {
00105           typedef typename viennagrid::result_of::const_element_range< src_element_type, dst_element_type >::type dst_on_src_range_type;
00106           typedef typename viennagrid::result_of::iterator< dst_on_src_range_type >::type dst_on_src_range_iterator;
00107 
00108           dst_on_src_range_type dst_on_src_range(*fit);
00109           for (dst_on_src_range_iterator dosit = dst_on_src_range.begin(); dosit != dst_on_src_range.end(); ++dosit)
00110               destination_boundary_info_accessor(*dosit) = true;
00111         }
00112       }
00113     }
00114 
00115 
00116 
00117 
00119     template<typename MeshT>
00120     class boundary_setter_functor
00121     {
00122     public:
00123       boundary_setter_functor(MeshT & mesh_obj) : mesh_obj_(mesh_obj) {}
00124 
00125       template<typename something>
00126       void operator()( viennagrid::detail::tag<something> )
00127       {
00128         typedef typename viennagrid::result_of::element_tag< something >::type element_tag;
00129         typedef typename viennagrid::result_of::element< MeshT, element_tag >::type element_type;
00130 
00131         typedef typename viennagrid::result_of::cell_tag< MeshT >::type cell_tag;
00132         typedef typename viennagrid::result_of::facet_tag< cell_tag >::type facet_tag;
00133         typedef typename viennagrid::result_of::element< MeshT, facet_tag >::type facet_type;
00134 
00135         typedef typename viennagrid::detail::result_of::lookup<
00136                 typename viennagrid::detail::result_of::lookup<
00137                     typename MeshT::appendix_type,
00138                     boundary_information_collection_tag
00139                   >::type,
00140                   facet_tag
00141                 >::type src_boundary_information_container_wrapper_type;
00142 
00143           src_boundary_information_container_wrapper_type & src_boundary_information_container_wrapper = detail::boundary_information_collection<facet_tag>( mesh_obj_ );
00144 
00145 
00146         typedef typename viennagrid::detail::result_of::lookup<
00147                 typename viennagrid::detail::result_of::lookup<
00148                     typename MeshT::appendix_type,
00149                     boundary_information_collection_tag
00150                   >::type,
00151                   element_tag
00152                 >::type dst_boundary_information_container_wrapper_type;
00153 
00154         dst_boundary_information_container_wrapper_type & dst_boundary_information_container_wrapper = detail::boundary_information_collection<element_tag>( mesh_obj_ );
00155 
00156         transfer_boundary_information(mesh_obj_,
00157                                       viennagrid::make_field<facet_type>( src_boundary_information_container_wrapper.container ),
00158                                       viennagrid::make_field<element_type>( dst_boundary_information_container_wrapper.container ));
00159 
00160         detail::update_change_counter( mesh_obj_, dst_boundary_information_container_wrapper.change_counter );
00161       }
00162     private:
00163 
00164       MeshT & mesh_obj_;
00165     };
00166 
00167 
00169     template<typename WrappedConfigT>
00170     void transfer_boundary_information( mesh<WrappedConfigT> & mesh_obj)
00171     {
00172       typedef mesh<WrappedConfigT> mesh_type;
00173       typedef typename viennagrid::result_of::cell_tag< mesh_type >::type cell_tag;
00174       typedef typename viennagrid::result_of::facet_tag< cell_tag >::type facet_tag;
00175 
00176       typedef typename viennagrid::detail::result_of::erase<
00177           typename viennagrid::detail::result_of::key_typelist<
00178               typename viennagrid::detail::result_of::lookup<
00179                   typename mesh_type::appendix_type,
00180                   boundary_information_collection_tag
00181               >::type::typemap
00182           >::type,
00183           facet_tag
00184       >::type typelist;
00185 
00186       boundary_setter_functor<mesh_type> functor(mesh_obj);
00187 
00188       viennagrid::detail::for_each< typelist >( functor );
00189     }
00190 
00192     template<typename SegmentationT>
00193     void transfer_boundary_information( segment_handle<SegmentationT> & segment )
00194     { transfer_boundary_information( segment.view() ); }
00195 
00196 
00198     template<typename WrappedConfigT>
00199     void detect_boundary( mesh<WrappedConfigT> & mesh_obj)
00200     {
00201       typedef mesh<WrappedConfigT> mesh_type;
00202       typedef typename viennagrid::result_of::cell_tag< mesh_type >::type cell_tag;
00203       typedef typename viennagrid::result_of::facet_tag< cell_tag >::type facet_tag;
00204 
00205       typedef typename viennagrid::result_of::element< mesh_type, facet_tag >::type facet_type;
00206 
00207       typedef typename viennagrid::detail::result_of::lookup<
00208               typename viennagrid::detail::result_of::lookup<
00209                   typename mesh_type::appendix_type,
00210                   boundary_information_collection_tag
00211                 >::type,
00212                 facet_tag
00213               >::type boundary_information_container_wrapper_type;
00214       boundary_information_container_wrapper_type & boundary_information_container_wrapper = detail::boundary_information_collection<facet_tag>(mesh_obj);
00215       detect_boundary( mesh_obj, viennagrid::make_field<facet_type>( boundary_information_container_wrapper.container ) );
00216 
00217       transfer_boundary_information(mesh_obj);
00218       detail::update_change_counter( mesh_obj, boundary_information_container_wrapper.change_counter );
00219     }
00220 
00222     template<typename SegmentationT>
00223     void detect_boundary( segment_handle<SegmentationT> & segment )
00224     { detect_boundary( segment.view() ); }
00225 
00227     template <typename ElementT, typename AccessorT>
00228     bool is_boundary(AccessorT const boundary_info_accessor,
00229                      ElementT const & element)
00230     {
00231       return boundary_info_accessor(element);
00232     }
00233 
00234 
00235   }
00236 
00237 
00243   template <typename WrappedConfigT, typename ElementT>
00244   bool is_boundary(mesh<WrappedConfigT> const & mesh_obj, ElementT const & element)
00245   {
00246     typedef mesh<WrappedConfigT> mesh_type;
00247     typedef typename viennagrid::result_of::element_tag<ElementT>::type element_tag;
00248 
00249     typedef typename viennagrid::detail::result_of::lookup<
00250             typename viennagrid::detail::result_of::lookup<
00251                 typename mesh_type::appendix_type,
00252                 boundary_information_collection_tag
00253               >::type,
00254               element_tag
00255             >::type boundary_information_container_wrapper_type;
00256     boundary_information_container_wrapper_type const & boundary_information_container_wrapper = detail::boundary_information_collection<element_tag>(mesh_obj);
00257 
00258     if (mesh_obj.is_obsolete(boundary_information_container_wrapper.change_counter))
00259       detail::detect_boundary( const_cast<mesh_type&>(mesh_obj) );
00260 
00261     return detail::is_boundary( viennagrid::make_field<ElementT>(boundary_information_container_wrapper.container), element );
00262   }
00263 
00269   template <typename SegmentationT, typename ElementT>
00270   bool is_boundary(segment_handle<SegmentationT> const & segment, ElementT const & element)
00271   { return is_boundary( segment.view(), element ); }
00272 
00273 
00279   template <typename ElementTag1, typename WrappedConfigT1,
00280             typename ElementTag2, typename WrappedConfigT2>
00281   bool is_boundary(viennagrid::element<ElementTag1, WrappedConfigT1> const & host_element,
00282                    viennagrid::element<ElementTag2, WrappedConfigT2> const & element)
00283   {
00284 
00285     typedef typename viennagrid::result_of::const_element_range<viennagrid::element<ElementTag2, WrappedConfigT2>, ElementTag1>::type   BoundaryRange;
00286     typedef typename viennagrid::result_of::iterator<BoundaryRange>::type               BoundaryIterator;
00287 
00288     BoundaryRange bnd_cells(host_element);
00289     for (BoundaryIterator bit = bnd_cells.begin();
00290                           bit != bnd_cells.end();
00291                         ++bit)
00292     {
00293       if (&(*bit) == &element)
00294         return true;
00295     }
00296 
00297     return false;
00298   }
00299 
00300 }
00301 
00302 #endif