ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/interface.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_INTERFACE_HPP
00002 #define VIENNAGRID_ALGORITHM_INTERFACE_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/algorithm/norm.hpp"
00019 #include "viennagrid/algorithm/centroid.hpp"
00020 #include "viennagrid/algorithm/boundary.hpp"
00021 
00027 namespace viennagrid
00028 {
00029   namespace detail
00030   {
00032     template< bool BoundaryStorageB>
00033     struct detect_interface_impl;
00034 
00035     template<>
00036     struct detect_interface_impl<false>
00037     {
00038       template <typename AccessorT, typename MeshT1, typename MeshT2>
00039       static void detect(AccessorT,
00040                         MeshT1 const &,
00041                         MeshT2 const &)
00042       {
00043         typename MeshT1::ERROR_CANNOT_DETECT_INTERFACE_BECAUSE_FACETS_ARE_DISABLED error_obj;
00044         (void)error_obj;
00045       }
00046     };
00047 
00048     template<>
00049     struct detect_interface_impl<true>
00050     {
00051       template <typename AccessorT, typename MeshT1, typename MeshT2>
00052       static void detect(AccessorT accessor,
00053                         MeshT1 const & seg0,
00054                         MeshT2 const & seg1)
00055       {
00056         typedef typename viennagrid::result_of::cell_tag<MeshT1>::type CellTag;
00057         typedef typename viennagrid::result_of::element<MeshT1, typename CellTag::facet_tag>::type   FacetType;
00058         typedef typename viennagrid::result_of::const_handle<MeshT1, typename CellTag::facet_tag>::type   ConstFacetHandleType;
00059 
00060         typedef typename viennagrid::result_of::const_element_range<MeshT1, typename CellTag::facet_tag>::type      FacetRange;
00061         typedef typename viennagrid::result_of::iterator<FacetRange>::type                                           FacetIterator;
00062 
00063         std::set<ConstFacetHandleType>  facets_ptrs_seg0;
00064 
00065         //
00066         // Step 1: Write facets of segment 1 to a map:
00067         //
00068         FacetRange facets_seg0(seg0);
00069         for (FacetIterator fit = facets_seg0.begin();
00070               fit != facets_seg0.end();
00071               ++fit)
00072         {
00073           const FacetType & facet = *fit;
00074 
00075           if (is_boundary(seg0, facet))
00076             facets_ptrs_seg0.insert( fit.handle() );
00077         }
00078 
00079         //
00080         // Step 2: Compare facet in segment 2 with those stored in the map
00081         //
00082         FacetRange facets_seg1(seg1);
00083         for (FacetIterator fit = facets_seg1.begin();
00084               fit != facets_seg1.end();
00085               ++fit)
00086         {
00087           const FacetType & facet = *fit;
00088 
00089           if (facets_ptrs_seg0.find( fit.handle() ) != facets_ptrs_seg0.end()) accessor(facet) = true;
00090         }
00091 
00092       }
00093     };
00094 
00095 
00097     template<typename SegmentationT>
00098     class interface_setter_functor
00099     {
00100     public:
00101       typedef segment_handle<SegmentationT> SegmentHandleType;
00102 
00103       interface_setter_functor(SegmentHandleType & seg0_, SegmentHandleType & seg1_) : seg0(seg0_), seg1(seg1_) {}
00104 
00105       template<typename something>
00106       void operator()( viennagrid::detail::tag<something> )
00107       {
00108         typedef typename viennagrid::result_of::element_tag< something >::type element_tag;
00109         typedef typename viennagrid::result_of::element< SegmentHandleType, element_tag >::type element_type;
00110 
00111         typedef typename viennagrid::result_of::cell_tag< SegmentHandleType >::type cell_tag;
00112         typedef typename viennagrid::result_of::facet_tag< cell_tag >::type facet_tag;
00113         typedef typename viennagrid::result_of::element< SegmentHandleType, facet_tag >::type facet_type;
00114 
00115         typedef typename viennagrid::detail::result_of::lookup<
00116                 typename viennagrid::detail::result_of::lookup<
00117                     typename SegmentationT::appendix_type,
00118                     interface_information_collection_tag
00119                   >::type,
00120                   facet_tag
00121                 >::type::segment_interface_information_wrapper_type src_interface_information_container_wrapper_type;
00122 
00123           src_interface_information_container_wrapper_type & src_interface_information_container_wrapper = interface_information_collection<facet_tag>( seg0, seg1 );
00124     //             viennagrid::dense_container_accessor_t< const typename src_interface_information_container_wrapper_type::container_type, facet_type > src_accessor( src_interface_information_container_wrapper.container );
00125 
00126 
00127 
00128 
00129         typedef typename viennagrid::detail::result_of::lookup<
00130                 typename viennagrid::detail::result_of::lookup<
00131                     typename SegmentationT::appendix_type,
00132                     interface_information_collection_tag
00133                   >::type,
00134                   element_tag
00135                 >::type::segment_interface_information_wrapper_type dst_interface_information_container_wrapper_type;
00136 
00137         dst_interface_information_container_wrapper_type & dst_interface_information_container_wrapper = interface_information_collection<element_tag>( seg0, seg1 );
00138         typename viennagrid::result_of::accessor< typename dst_interface_information_container_wrapper_type::container_type, element_type >::type dst_accessor( dst_interface_information_container_wrapper.container );
00139 
00140         transfer_boundary_information(seg0, viennagrid::make_field<facet_type>(src_interface_information_container_wrapper.container), dst_accessor);
00141         transfer_boundary_information(seg1, viennagrid::make_field<facet_type>(src_interface_information_container_wrapper.container), dst_accessor);
00142 
00143         detail::update_change_counter( seg0, dst_interface_information_container_wrapper.seg0_change_counter );
00144         detail::update_change_counter( seg1, dst_interface_information_container_wrapper.seg1_change_counter );
00145       }
00146     private:
00147 
00148       SegmentHandleType & seg0;
00149       SegmentHandleType & seg1;
00150     };
00151 
00152 
00153 
00155     template<typename SegmentationT>
00156     void transfer_interface_information( segment_handle<SegmentationT> & seg0, segment_handle<SegmentationT> & seg1 )
00157     {
00158       assert( &seg0.parent() == &seg1.parent() );
00159 
00160       typedef segment_handle<SegmentationT> segment_handle_type;
00161       typedef typename viennagrid::result_of::cell_tag< segment_handle_type >::type cell_tag;
00162       typedef typename viennagrid::result_of::facet_tag< cell_tag >::type facet_tag;
00163 
00164       typedef typename viennagrid::detail::result_of::erase<
00165           typename viennagrid::detail::result_of::key_typelist<
00166               typename viennagrid::detail::result_of::lookup<
00167                   typename SegmentationT::appendix_type,
00168                   interface_information_collection_tag
00169               >::type::typemap
00170           >::type,
00171           facet_tag
00172       >::type typelist;
00173 
00174       interface_setter_functor<SegmentationT> functor(seg0, seg1);
00175 
00176       viennagrid::detail::for_each< typelist >( functor );
00177     }
00178 
00179 
00180 
00181 
00182 
00183 
00185     template <typename SegmentationT, typename AccessorT>
00186     void detect_interface(segment_handle<SegmentationT> & seg0,
00187                           segment_handle<SegmentationT> & seg1,
00188                           AccessorT accessor)
00189     {
00190       assert( &seg0.parent() == &seg1.parent() );
00191 
00192       typedef typename viennagrid::result_of::cell_tag< segment_handle<SegmentationT> >::type CellTag;
00193       typedef typename viennagrid::result_of::element< segment_handle<SegmentationT>, CellTag>::type CellType;
00194 
00195       viennagrid::detail::detect_interface_impl< viennagrid::result_of::has_boundary<CellType, typename CellTag::facet_tag>::value >::detect(accessor, seg0, seg1);
00196     }
00197 
00199     template <typename ElementT, typename AccessorT>
00200     bool is_interface(AccessorT const accessor,
00201                       ElementT const & el)
00202     { return accessor(el); }
00203 
00204 
00205   }
00206 
00212   template <typename SegmentationT>
00213   void detect_interface(segment_handle<SegmentationT> & seg0,
00214                         segment_handle<SegmentationT> & seg1)
00215   {
00216     assert( &seg0.parent() == &seg1.parent() );
00217 
00218     typedef typename result_of::cell_tag< segment_handle<SegmentationT> >::type CellTag;
00219     typedef typename result_of::facet_tag<CellTag>::type FacetTag;
00220     typedef typename result_of::element< segment_handle<SegmentationT>, FacetTag >::type FacetType;
00221 
00222     typedef typename viennagrid::detail::result_of::lookup<
00223             typename viennagrid::detail::result_of::lookup<
00224                 typename SegmentationT::appendix_type,
00225                 interface_information_collection_tag
00226               >::type,
00227               FacetTag
00228             >::type::segment_interface_information_wrapper_type interface_information_container_wrapper_type;
00229     interface_information_container_wrapper_type & interface_information_container_wrapper = detail::interface_information_collection<FacetTag>( seg0, seg1 );
00230 
00231 
00232     detail::detect_interface( seg0, seg1, viennagrid::make_field<FacetType>(interface_information_container_wrapper.container) );
00233 
00234     transfer_interface_information( seg0, seg1 );
00235     detail::update_change_counter( seg0, interface_information_container_wrapper.seg0_change_counter );
00236     detail::update_change_counter( seg1, interface_information_container_wrapper.seg1_change_counter );
00237   }
00238 
00239 
00240 
00247   template <typename SegmentationT, typename ElementT>
00248   bool is_interface(segment_handle<SegmentationT> const & seg0,
00249                     segment_handle<SegmentationT> const & seg1,
00250                     ElementT const & element)
00251   {
00252     assert( &seg0.parent() == &seg1.parent() );
00253 
00254     typedef segment_handle<SegmentationT> SegmentHandleType;
00255 
00256     typedef typename viennagrid::result_of::element_tag<ElementT>::type element_tag;
00257 
00258 
00259     typedef typename viennagrid::detail::result_of::lookup<
00260             typename viennagrid::detail::result_of::lookup<
00261                 typename SegmentationT::appendix_type,
00262                 interface_information_collection_tag
00263               >::type,
00264               element_tag
00265             >::type::segment_interface_information_wrapper_type interface_information_container_wrapper_type;
00266     interface_information_container_wrapper_type const & interface_information_container_wrapper = detail::interface_information_collection<element_tag>( seg0, seg1 );
00267 
00268     if ( (detail::is_obsolete(seg0, interface_information_container_wrapper.seg0_change_counter)) ||
00269          (detail::is_obsolete(seg1, interface_information_container_wrapper.seg1_change_counter) ))
00270         detect_interface( const_cast<SegmentHandleType&>(seg0), const_cast<SegmentHandleType&>(seg1) );
00271 
00272     return detail::is_interface( viennagrid::make_field<ElementT>(interface_information_container_wrapper.container), element );
00273   }
00274 
00275 }
00276 
00277 #endif