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