ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/mesh/element_deletion.hpp
Go to the documentation of this file.
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