ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/mesh/mesh_operations.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_MESH_OPERATIONS_HPP
00002 #define VIENNAGRID_MESH_OPERATIONS_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/mesh/mesh.hpp"
00018 #include "viennagrid/mesh/segmentation.hpp"
00019 #include "viennagrid/mesh/element_creation.hpp"
00020 #include "viennagrid/mesh/coboundary_iteration.hpp"
00021 #include "viennagrid/functors.hpp"
00022 
00027 namespace viennagrid
00028 {
00029 
00035   template<typename SrcMeshT, typename DstMeshT>
00036   class vertex_copy_map
00037   {
00038   public:
00043     vertex_copy_map( DstMeshT & dst_mesh_ ) : dst_mesh(dst_mesh_) {}
00044 
00045     typedef typename viennagrid::result_of::coord<DstMeshT>::type DstNumericType;
00046 
00047     typedef typename viennagrid::result_of::vertex<SrcMeshT>::type SrcVertexType;
00048     typedef typename viennagrid::result_of::vertex_id<SrcMeshT>::type SrcVertexIDType;
00049 
00050     typedef typename viennagrid::result_of::vertex<DstMeshT>::type DstVertexType;
00051     typedef typename viennagrid::result_of::vertex_handle<DstMeshT>::type DstVertexHandleType;
00052 
00058     DstVertexHandleType operator()( SrcVertexType const & src_vertex, DstNumericType tolerance = 0.0 )
00059     {
00060       typename std::map<SrcVertexIDType, DstVertexHandleType>::iterator vit = vertex_map.find( src_vertex.id() );
00061       if (vit != vertex_map.end())
00062         return vit->second;
00063       else
00064       {
00065         DstVertexHandleType vh = viennagrid::make_unique_vertex( dst_mesh, viennagrid::point(src_vertex), tolerance );
00066         vertex_map[src_vertex.id()] = vh;
00067         return vh;
00068       }
00069     }
00070 
00076     template<typename ElementTagT, typename WrappedConfigT>
00077     typename viennagrid::result_of::handle<DstMeshT, ElementTagT>::type copy_element( element<ElementTagT, WrappedConfigT> const & el, DstNumericType tolerance = 0.0 )
00078     {
00079       typedef element<ElementTagT, WrappedConfigT> ElementType;
00080       typedef typename viennagrid::result_of::const_vertex_range<ElementType>::type ConstVerticesOnElementRangeType;
00081       typedef typename viennagrid::result_of::iterator<ConstVerticesOnElementRangeType>::type ConstVerticesOnElementIteratorType;
00082 
00083       std::vector<DstVertexHandleType> vertex_handles;
00084 
00085       ConstVerticesOnElementRangeType vertices(el);
00086       for (ConstVerticesOnElementIteratorType vit = vertices.begin(); vit != vertices.end(); ++vit)
00087         vertex_handles.push_back( (*this)(*vit, tolerance) );
00088 
00089       return viennagrid::make_element<ElementTagT>( dst_mesh, vertex_handles.begin(), vertex_handles.end() );
00090     }
00091 
00092   private:
00093 
00094     DstMeshT & dst_mesh;
00095     std::map<SrcVertexIDType, DstVertexHandleType> vertex_map;
00096   };
00097 
00098 
00099 
00100 
00107   template<typename SrcMeshT, typename DstMeshT, typename ToCopyFunctorT>
00108   void copy(SrcMeshT const & src_mesh, DstMeshT & dst_mesh, ToCopyFunctorT functor)
00109   {
00110     dst_mesh.clear();
00111 
00112     viennagrid::vertex_copy_map<SrcMeshT, DstMeshT> vertex_map(dst_mesh);
00113 
00114     //typedef typename viennagrid::result_of::cell<SrcMeshT>::type CellType;
00115     //typedef typename viennagrid::result_of::coord<SrcMeshT>::type NumericType;
00116 
00117     typedef typename viennagrid::result_of::const_cell_range<SrcMeshT>::type ConstCellRangeType;
00118     typedef typename viennagrid::result_of::iterator<ConstCellRangeType>::type ConstCellIteratorType;
00119 
00120     //typedef typename viennagrid::result_of::cell_handle<DstMeshT>::type CellHandleType;
00121 
00122     ConstCellRangeType cells(src_mesh);
00123     for (ConstCellIteratorType cit = cells.begin(); cit != cells.end(); ++cit)
00124     {
00125       if ( functor(*cit) )
00126         vertex_map.copy_element(*cit );
00127     }
00128   }
00129 
00138   template<typename SrcMeshT, typename SrcSegmentationT, typename DstMeshT, typename DstSegmentationT, typename ToCopyFunctorT>
00139   void copy(SrcMeshT const & src_mesh, SrcSegmentationT const & src_segmentation,
00140             DstMeshT       & dst_mesh, DstSegmentationT       & dst_segmentation,
00141             ToCopyFunctorT functor)
00142   {
00143     dst_mesh.clear();
00144     dst_segmentation.clear();
00145 
00146     viennagrid::vertex_copy_map<SrcMeshT, DstMeshT> vertex_map(dst_mesh);
00147 
00148     //typedef typename viennagrid::result_of::cell<SrcMeshT>::type CellType;
00149     //typedef typename viennagrid::result_of::coord<SrcMeshT>::type NumericType;
00150 
00151     typedef typename viennagrid::result_of::const_cell_range<SrcMeshT>::type ConstCellRangeType;
00152     typedef typename viennagrid::result_of::iterator<ConstCellRangeType>::type ConstCellIteratorType;
00153 
00154     typedef typename viennagrid::result_of::cell_handle<DstMeshT>::type CellHandleType;
00155 
00156     ConstCellRangeType cells(src_mesh);
00157     for (ConstCellIteratorType cit = cells.begin(); cit != cells.end(); ++cit)
00158     {
00159       if ( functor(*cit) )
00160       {
00161         CellHandleType cell_handle = vertex_map.copy_element(*cit );
00162         viennagrid::add( dst_segmentation, viennagrid::segment_ids( src_segmentation, *cit ).begin(), viennagrid::segment_ids( src_segmentation, *cit ).end(), cell_handle );
00163       }
00164     }
00165   }
00166 
00167   namespace detail
00168   {
00170     template<typename MeshT, typename ToEraseViewT, typename HandleT, typename ReferencingElementTypelist =
00171         typename viennagrid::result_of::referencing_element_typelist<MeshT, typename viennagrid::detail::result_of::value_type<HandleT>::type >::type >
00172     struct mark_referencing_elements_impl;
00173 
00174     template<typename MeshT, typename ToEraseViewT, typename HandleT, typename CoboundaryElementT, typename TailT>
00175     struct mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, viennagrid::typelist<CoboundaryElementT, TailT> >
00176     {
00177       static void mark(MeshT & mesh_obj, ToEraseViewT & mesh_view, HandleT host_element)
00178       {
00179         //typedef viennagrid::typelist<CoboundaryElementT, TailT> ReferencingElementTypelist;
00180         typedef typename viennagrid::detail::result_of::value_type<HandleT>::type HostElementType;
00181 
00182         //typedef typename viennagrid::result_of::handle<MeshT, CoboundaryElementT>::type CoboundaryElementHandle;
00183         typedef typename viennagrid::result_of::coboundary_range<MeshT, HostElementType, CoboundaryElementT>::type CoboundaryElementRangeType;
00184         typedef typename viennagrid::result_of::iterator<CoboundaryElementRangeType>::type CoboundaryElementRangeIterator;
00185 
00186         typedef typename viennagrid::result_of::element_range<ToEraseViewT, CoboundaryElementT>::type CoboundaryElementViewRangeType;
00187 
00188         CoboundaryElementRangeType coboundary_elements = viennagrid::coboundary_elements<HostElementType, CoboundaryElementT>(mesh_obj, host_element);
00189         for (CoboundaryElementRangeIterator it = coboundary_elements.begin(); it != coboundary_elements.end(); ++it)
00190         {
00191           CoboundaryElementViewRangeType view_elements( mesh_view );
00192           if ( viennagrid::find_by_handle(mesh_view, it.handle()) == view_elements.end() )
00193           {
00194             view_elements.insert_unique_handle( it.handle() );
00195           }
00196         }
00197 
00198         mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, TailT>::mark(mesh_obj, mesh_view, host_element);
00199       }
00200     };
00201 
00203     template<typename MeshT, typename ToEraseViewT, typename HandleT>
00204     struct mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, viennagrid::null_type >
00205     {
00206       static void mark(MeshT &, ToEraseViewT &, HandleT) {}
00207     };
00208 
00209   } //namespace detail
00210 
00220   template<typename MeshT, typename MeshViewT, typename HandleT>
00221   void mark_referencing_elements( MeshT & mesh_obj, MeshViewT & element_view, HandleT host_element )
00222   {
00223     detail::mark_referencing_elements_impl<MeshT, MeshViewT, HandleT>::mark(mesh_obj, element_view, host_element);
00224   }
00225 
00226 }
00227 
00228 #endif