ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/extract_boundary.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_EXTRACT_BOUNDARY_HPP
00002 #define VIENNAGRID_ALGORITHM_EXTRACT_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 "viennagrid/mesh/element_creation.hpp"
00017 #include "viennagrid/mesh/mesh_operations.hpp"
00018 #include "viennagrid/algorithm/boundary.hpp"
00019 
00024 namespace viennagrid
00025 {
00032   template<typename HullTypeOrTagT, typename VolumeMeshT, typename HullMeshT>
00033   void extract_boundary(VolumeMeshT const & volume_mesh,
00034                         HullMeshT & hull_mesh)
00035   {
00036     viennagrid::clear(hull_mesh);
00037 
00038     typedef typename viennagrid::result_of::point<VolumeMeshT>::type            VolumePointType;
00039 
00040     typedef typename viennagrid::result_of::const_element_range<VolumeMeshT, HullTypeOrTagT>::type    HullRangeType;
00041     typedef typename viennagrid::result_of::iterator<HullRangeType>::type                                   HullRangeIterator;
00042 
00043     typedef typename viennagrid::result_of::element<VolumeMeshT, HullTypeOrTagT>::type    VolumeHullElement;
00044     typedef typename viennagrid::result_of::element<HullMeshT, HullTypeOrTagT>::type      HullHullElement;
00045 
00046     viennagrid::vertex_copy_map<VolumeMeshT, HullMeshT> vertex_map(hull_mesh);
00047 
00048     HullRangeType hull_elements( volume_mesh );
00049     for (HullRangeIterator hit = hull_elements.begin(); hit != hull_elements.end(); ++hit)
00050     {
00051       VolumeHullElement const & hull_element = *hit;
00052 
00053       if ( viennagrid::is_boundary( volume_mesh, hull_element ) )
00054       {
00055         typedef typename viennagrid::result_of::vertex_handle<HullMeshT>::type HullVertexHandleType;
00056 
00057         std::vector<HullVertexHandleType> vertices( viennagrid::vertices(hull_element).size() );
00058         for (std::size_t i = 0; i < viennagrid::vertices(hull_element).size(); ++i)
00059           vertices[i] = vertex_map(viennagrid::vertices(hull_element)[i]);
00060 
00061         viennagrid::make_element<HullHullElement>( hull_mesh, vertices.begin(), vertices.end() );
00062       }
00063     }
00064   }
00065 
00071   template<typename VolumeMeshT, typename HullMeshT>
00072   void extract_boundary(VolumeMeshT const & volume_mesh,
00073                         HullMeshT & hull_mesh )
00074   {
00075     typedef typename viennagrid::result_of::facet_tag<VolumeMeshT>::type FacetTag;
00076     extract_boundary<FacetTag>(volume_mesh, hull_mesh);
00077   }
00078 
00079 
00088   template<typename HullTypeOrTagT, typename VolumeMeshT, typename VolumeSegmentationT, typename HullMeshT, typename HullSegmentationT>
00089   void extract_boundary(VolumeMeshT const & volume_mesh,
00090                         VolumeSegmentationT const & volume_segmentation,
00091                         HullMeshT & hull_mesh,
00092                         HullSegmentationT & hull_segmentation )
00093   {
00094     typedef typename viennagrid::result_of::element_tag<HullTypeOrTagT>::type HullTagType;
00095 
00096     viennagrid::clear(hull_mesh);
00097     viennagrid::clear(hull_segmentation);
00098 
00099     if (volume_segmentation.size() == 0)
00100       extract_boundary<HullTagType>(volume_mesh, hull_mesh);
00101 
00102     typedef typename viennagrid::result_of::segment_handle<VolumeSegmentationT>::type    VolumeSegmentHandleType;
00103     typedef typename viennagrid::result_of::point<VolumeMeshT>::type            VolumePointType;
00104 
00105     typedef typename viennagrid::result_of::segment_handle<HullSegmentationT>::type      HullSegmentHandleType;
00106 
00107 
00108     typedef typename viennagrid::result_of::element<VolumeSegmentHandleType, HullTagType>::type    VolumeHullElementType;
00109     typedef typename viennagrid::result_of::element<HullSegmentHandleType, HullTagType>::type     HullCellElementType;
00110 
00111     typedef typename viennagrid::result_of::id<VolumeHullElementType>::type VolumeHullElementIDType;
00112     typedef typename viennagrid::result_of::handle<HullSegmentHandleType, HullTagType>::type HullCellElementHandleType;
00113 
00114     typedef typename viennagrid::result_of::vertex_id<VolumeMeshT>::type VolumeVertexIDType;
00115     typedef typename viennagrid::result_of::vertex_handle<HullSegmentHandleType>::type HullVertexHandleType;
00116 
00117     viennagrid::vertex_copy_map<VolumeMeshT, HullMeshT> vertex_map(hull_mesh);
00118     std::map< VolumeHullElementIDType, HullCellElementHandleType > hull_element_map;
00119 
00120     for (typename VolumeSegmentationT::const_iterator sit = volume_segmentation.begin(); sit != volume_segmentation.end(); ++sit)
00121     {
00122       VolumeSegmentHandleType const & volume_segment = *sit;
00123       HullSegmentHandleType & hull_segment = hull_segmentation( volume_segment.id() );
00124 
00125       typedef typename viennagrid::result_of::const_element_range<VolumeSegmentHandleType, HullTagType>::type    HullRangeType;
00126       typedef typename viennagrid::result_of::iterator<HullRangeType>::type                                   HullRangeIterator;
00127 
00128       HullRangeType hull_elements( volume_segment );
00129       for (HullRangeIterator hit = hull_elements.begin(); hit != hull_elements.end(); ++hit)
00130       {
00131         VolumeHullElementType const & hull_element = *hit;
00132 
00133         if ( viennagrid::is_boundary( volume_segment, hull_element ) )
00134         {
00135           typename std::map< VolumeHullElementIDType, HullCellElementHandleType >::iterator hemit = hull_element_map.find( hit->id() );
00136           if ( hemit != hull_element_map.end() )
00137           {
00138             viennagrid::add( hull_segment, viennagrid::dereference_handle(hull_segment, hemit->second) );
00139           }
00140           else
00141           {
00142             typedef typename viennagrid::result_of::const_vertex_range<VolumeHullElementType>::type ConstVertexOnHullElementRangeType;
00143             typedef typename viennagrid::result_of::iterator<ConstVertexOnHullElementRangeType>::type ConstVertexOnHullElementIteratorType;
00144 
00145             ConstVertexOnHullElementRangeType vertices_on_hull_element( hull_element );
00146             std::vector<HullVertexHandleType> vertex_handles;
00147 
00148             for (ConstVertexOnHullElementIteratorType vit = vertices_on_hull_element.begin(); vit != vertices_on_hull_element.end(); ++vit)
00149               vertex_handles.push_back( vertex_map(*vit) );
00150 
00151             hull_element_map[hit->id()] = viennagrid::make_element<HullCellElementType>( hull_segment, vertex_handles.begin(), vertex_handles.end() );
00152           }
00153         }
00154       }
00155     }
00156   }
00157 
00158 
00166   template<typename VolumeMeshT, typename VolumeSegmentationT, typename HullMeshT, typename HullSegmentationT>
00167   void extract_boundary(VolumeMeshT const & volume_mesh,
00168                         VolumeSegmentationT const & volume_segmentation,
00169                         HullMeshT & hull_mesh,
00170                         HullSegmentationT & hull_segmentation )
00171   {
00172     typedef typename viennagrid::result_of::facet_tag<VolumeMeshT>::type FacetTag;
00173     extract_boundary<FacetTag>(volume_mesh, volume_segmentation, hull_mesh, hull_segmentation);
00174   }
00175 }
00176 
00177 #endif