ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ELEMENT_DELETION_HPP 00002 #define VIENNAGRID_ELEMENT_DELETION_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 "viennagrid/forwards.hpp" 00017 #include "viennagrid/storage/container_collection.hpp" 00018 #include "viennagrid/mesh/mesh.hpp" 00019 #include "viennagrid/mesh/segmentation.hpp" 00020 #include "viennagrid/mesh/coboundary_iteration.hpp" 00021 #include "viennagrid/mesh/mesh_operations.hpp" 00022 #include <iterator> 00023 00024 00030 namespace viennagrid 00031 { 00032 namespace detail 00033 { 00035 template<typename MeshT, typename ToSwtichElementHandleT> 00036 struct switch_handle_functor 00037 { 00038 typedef typename viennagrid::detail::result_of::value_type<ToSwtichElementHandleT>::type to_switch_element_type; 00039 00040 switch_handle_functor(MeshT & mesh_obj, ToSwtichElementHandleT from, ToSwtichElementHandleT to) : mesh_obj_(mesh_obj), from_(from), to_(to) {} 00041 00042 template<typename ParentElementTypeOrTagT> 00043 void operator() ( viennagrid::detail::tag<ParentElementTypeOrTagT> ) 00044 { 00045 typedef typename viennagrid::result_of::element<MeshT, ParentElementTypeOrTagT>::type ParentElementType; 00046 typedef typename viennagrid::result_of::element_range<MeshT, ParentElementTypeOrTagT>::type ParentElementRangeType; 00047 typedef typename viennagrid::result_of::iterator<ParentElementRangeType>::type ParentElementRangeIterator; 00048 00049 ParentElementRangeType parent_elements(mesh_obj_); 00050 for (ParentElementRangeIterator it = parent_elements.begin(); it != parent_elements.end(); ++it) 00051 { 00052 typedef typename viennagrid::result_of::element_range<ParentElementType, to_switch_element_type>::type ToSwitchElementRangeType; 00053 typedef typename viennagrid::result_of::iterator<ToSwitchElementRangeType>::type ToSwitchElementRangeIterator; 00054 00055 ToSwitchElementRangeType to_switch_elements(*it); 00056 for (ToSwitchElementRangeIterator jt = to_switch_elements.begin(); jt != to_switch_elements.end(); ++jt) 00057 { 00058 if (jt.handle() == from_) 00059 { 00060 jt.handle() = to_; 00061 } 00062 } 00063 } 00064 } 00065 00066 MeshT & mesh_obj_; 00067 ToSwtichElementHandleT from_; 00068 ToSwtichElementHandleT to_; 00069 }; 00070 00071 00073 template<typename MeshT, typename HandleT> 00074 void switch_handle( MeshT & mesh_obj, HandleT old_handle, HandleT new_handle) 00075 { 00076 typedef typename viennagrid::detail::result_of::value_type<HandleT>::type ToSwitchElementType; 00077 typedef typename viennagrid::result_of::referencing_element_typelist<MeshT, ToSwitchElementType>::type ParentElementTypelist; 00078 00079 switch_handle_functor<MeshT, HandleT> functor(mesh_obj, old_handle, new_handle); 00080 00081 viennagrid::detail::for_each<ParentElementTypelist>( functor ); 00082 } 00083 00084 00086 template<typename MeshT, typename MeshViewT> 00087 struct erase_functor 00088 { 00089 erase_functor(MeshT & mesh_obj, MeshViewT & view_to_erase) : mesh_obj_(mesh_obj), view_to_erase_(view_to_erase) {} 00090 00091 template<typename ElementT> 00092 void operator()( viennagrid::detail::tag<ElementT> ) 00093 { 00094 typedef typename viennagrid::result_of::element_range<MeshViewT, ElementT>::type ToEraseElementRangeType; 00095 typedef typename viennagrid::result_of::iterator<ToEraseElementRangeType>::type ToEraseElementRangeIterator; 00096 00097 typedef typename viennagrid::result_of::handle<MeshT, ElementT>::type ElementHandle; 00098 typedef typename viennagrid::result_of::element_range<MeshT, ElementT>::type ElementRangeType; 00099 typedef typename viennagrid::result_of::iterator<ElementRangeType>::type ElementRangeIterator; 00100 00101 typedef typename viennagrid::result_of::id<ElementT>::type id_type; 00102 00103 // std::vector< std::pair<element_range_iterator, element_range_iterator> > swtiching_map; 00104 00105 std::deque<id_type> ids_to_erase; 00106 00107 ToEraseElementRangeType elements_to_erase(view_to_erase_); 00108 for (ToEraseElementRangeIterator it = elements_to_erase.begin(); it != elements_to_erase.end(); ++it) 00109 ids_to_erase.push_back( it->id() ); 00110 00111 ElementRangeType elements(mesh_obj_); 00112 00113 for (typename std::deque<id_type>::iterator it = ids_to_erase.begin(); it != ids_to_erase.end(); ++it) 00114 { 00115 ElementRangeIterator to_erase_it = find( mesh_obj_, *it ); 00116 ElementRangeIterator back_it = --elements.end(); 00117 00118 if (back_it != to_erase_it) 00119 { 00120 ElementHandle old_handle = back_it.handle(); 00121 std::swap( *back_it, *to_erase_it ); 00122 ElementHandle new_handle = to_erase_it.handle(); 00123 00124 switch_handle( mesh_obj_, old_handle, new_handle ); 00125 } 00126 00127 elements.erase( back_it ); 00128 } 00129 } 00130 00131 MeshT & mesh_obj_; 00132 MeshViewT & view_to_erase_; 00133 }; 00134 } //namespace detail 00135 00136 00144 template<typename WrappedConfigT, typename ToEraseViewT> 00145 void erase_elements(viennagrid::mesh<WrappedConfigT> & mesh_obj, ToEraseViewT & elements_to_erase) 00146 { 00147 typedef viennagrid::mesh<WrappedConfigT> MeshType; 00148 00149 typedef typename viennagrid::detail::result_of::reverse< 00150 typename viennagrid::result_of::element_typelist<ToEraseViewT>::type 00151 >::type SegmentElementTypelist; 00152 00153 detail::erase_functor<MeshType, ToEraseViewT> functor( mesh_obj, elements_to_erase ); 00154 viennagrid::detail::for_each<SegmentElementTypelist>(functor); 00155 00156 viennagrid::detail::increment_change_counter(mesh_obj); 00157 } 00158 00159 namespace detail 00160 { 00161 template<typename MeshViewT> 00162 struct erase_from_view_functor 00163 { 00164 erase_from_view_functor(MeshViewT & view_obj) : view_(view_obj) {} 00165 00166 template<typename ElementT> 00167 void operator() (ElementT & element) 00168 { 00169 // std::cout << "Erasing " << element << std::endl; 00170 viennagrid::elements<ElementT>(view_).erase_handle( viennagrid::handle(view_, element) ); 00171 } 00172 00173 MeshViewT & view_; 00174 }; 00175 } 00176 00182 template <typename WrappedConfigType, typename ElementTypeList, typename ContainerConfig, typename ToEraseViewT> 00183 void erase_elements(viennagrid::mesh< viennagrid::detail::decorated_mesh_view_config<WrappedConfigType, ElementTypeList, ContainerConfig> > & view_obj, ToEraseViewT & elements_to_erase) 00184 { 00185 typedef viennagrid::mesh< viennagrid::detail::decorated_mesh_view_config<WrappedConfigType, ElementTypeList, ContainerConfig> > ViewType; 00186 00187 detail::erase_from_view_functor<ViewType> functor( view_obj ); 00188 viennagrid::for_each(elements_to_erase, functor); 00189 00190 viennagrid::detail::increment_change_counter(view_obj); 00191 } 00192 00193 00194 00196 template<typename MeshT, typename MeshViewT, typename HandleT> 00197 void mark_erase_elements( MeshT & mesh_obj, MeshViewT & elements_to_erase, HandleT host_element ) 00198 { 00199 typedef typename viennagrid::detail::result_of::value_type<HandleT>::type ElementType; 00200 viennagrid::elements<ElementType>(elements_to_erase).insert_unique_handle( host_element ); 00201 00202 mark_referencing_elements(mesh_obj, elements_to_erase, host_element); 00203 } 00204 00205 00213 template<typename MeshT, typename HandleT> 00214 void erase_element(MeshT & mesh_obj, HandleT element_to_erase) 00215 { 00216 typedef typename viennagrid::result_of::mesh_view<MeshT>::type ToEraseViewType; 00217 ToEraseViewType elements_to_erase = viennagrid::make_view(mesh_obj); 00218 viennagrid::mark_erase_elements( mesh_obj, elements_to_erase, element_to_erase ); 00219 viennagrid::erase_elements(mesh_obj, elements_to_erase); 00220 } 00221 00222 00223 } 00224 00225 00226 #endif 00227