ViennaGrid - The Vienna Grid Library
2.1.0
|
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