ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ALGORITHM_SURFACE_HPP 00002 #define VIENNAGRID_ALGORITHM_SURFACE_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 <iostream> 00017 #include <sstream> 00018 #include <string> 00019 #include <stdexcept> 00020 00021 #include "viennagrid/forwards.hpp" 00022 #include "viennagrid/algorithm/volume.hpp" 00023 #include "viennagrid/algorithm/boundary.hpp" 00024 00030 namespace viennagrid 00031 { 00032 namespace detail 00033 { 00035 template <typename ElementTypeOrTag, typename MeshT> 00036 typename viennagrid::result_of::coord< MeshT >::type 00037 surface_meshsegment(MeshT const & mesh_obj) 00038 { 00039 typedef typename viennagrid::result_of::const_element_range<MeshT, ElementTypeOrTag>::type ElementRange; 00040 typedef typename viennagrid::result_of::iterator<ElementRange>::type ElementIterator; 00041 00042 typename viennagrid::result_of::coord<MeshT>::type result = 0; 00043 00044 ElementRange facets(mesh_obj); 00045 for (ElementIterator fit = facets.begin(); 00046 fit != facets.end(); 00047 ++fit) 00048 { 00049 if (is_boundary(mesh_obj, *fit)) 00050 result += viennagrid::volume(*fit); 00051 } 00052 return result; 00053 } 00054 } //namespace detail 00055 00056 00057 00058 // 00059 // The public interface functions 00060 // 00062 template <typename PointAccessorT, typename ElementTag, typename WrappedConfigT> 00063 typename viennagrid::result_of::coord< typename PointAccessorT::value_type >::type 00064 surface(PointAccessorT const accessor, viennagrid::element<ElementTag, WrappedConfigT> const & element) 00065 { 00066 typedef typename viennagrid::result_of::const_facet_range< viennagrid::element<ElementTag, WrappedConfigT> >::type ElementBoundaryRange; 00067 typedef typename viennagrid::result_of::iterator<ElementBoundaryRange>::type ElementBoundaryIterator; 00068 00069 typedef typename viennagrid::result_of::coord< typename PointAccessorT::value_type >::type value_type; 00070 00071 value_type result = 0; 00072 00073 ElementBoundaryRange boundary = viennagrid::facets(element); 00074 for (ElementBoundaryIterator ebit = boundary.begin(); 00075 ebit != boundary.end(); 00076 ++ebit) 00077 { 00078 result += viennagrid::volume(accessor, *ebit); 00079 } 00080 00081 return result; 00082 } 00083 00085 template < typename ElementTag, typename WrappedConfigT> 00086 typename viennagrid::result_of::coord< viennagrid::element<ElementTag, WrappedConfigT> >::type 00087 surface( viennagrid::element<ElementTag, WrappedConfigT> const & element) 00088 { 00089 return surface( default_point_accessor(element), element ); 00090 } 00091 00092 00093 00094 //special case: mesh 00096 template <typename ElementTypeOrTag, typename WrappedConfigT> 00097 typename viennagrid::result_of::coord< mesh<WrappedConfigT> >::type 00098 surface(mesh<WrappedConfigT> const & d) 00099 { 00100 return detail::surface_meshsegment<ElementTypeOrTag>(d); 00101 } 00102 00104 template <typename WrappedConfigT> 00105 typename viennagrid::result_of::coord< mesh<WrappedConfigT> >::type 00106 surface(mesh<WrappedConfigT> const & d) 00107 { 00108 typedef typename viennagrid::result_of::cell_tag< mesh<WrappedConfigT> >::type CellTag; 00109 return detail::surface_meshsegment< typename viennagrid::result_of::facet_tag<CellTag>::type>(d); 00110 } 00111 00113 template<typename SegmentationT> 00114 typename viennagrid::result_of::coord< typename SegmentationT::mesh_type >::type 00115 surface(segment_handle<SegmentationT> const & segment) 00116 { 00117 typedef typename viennagrid::result_of::cell_tag< typename SegmentationT::mesh_type >::type CellTag; 00118 return detail::surface_meshsegment< typename viennagrid::result_of::facet_tag<CellTag>::type >(segment); 00119 } 00120 00121 00122 00124 template<typename BoundaryElementTTag, typename MeshT, typename ElementT> 00125 typename viennagrid::result_of::handle<MeshT, BoundaryElementTTag>::type 00126 smallest_boundary_volume( MeshT & mesh_obj, ElementT & element ) 00127 { 00128 typedef typename viennagrid::result_of::coord<MeshT>::type numeric_type; 00129 typedef typename viennagrid::result_of::handle<ElementT, BoundaryElementTTag>::type boundary_element_handle; 00130 typedef typename viennagrid::result_of::element_range<ElementT, BoundaryElementTTag>::type boundary_element_range_type; 00131 typedef typename viennagrid::result_of::iterator<boundary_element_range_type>::type boundary_element_range_iterator; 00132 00133 boundary_element_range_type boundary_elements( element ); 00134 boundary_element_range_iterator it = boundary_elements.begin(); 00135 00136 boundary_element_handle best_handle = it.handle(); 00137 numeric_type best_volume = viennagrid::volume( mesh_obj, *it ); 00138 00139 for (; it != boundary_elements.end(); ++it) 00140 { 00141 numeric_type volume = viennagrid::volume( mesh_obj, *it ); 00142 if (volume < best_volume) 00143 { 00144 best_handle = it.handle(); 00145 best_volume = volume; 00146 } 00147 } 00148 00149 return best_handle; 00150 } 00151 00153 template<typename BoundaryElementTTag, typename MeshT, typename ElementT> 00154 typename viennagrid::result_of::const_handle<MeshT, BoundaryElementTTag>::type 00155 smallest_boundary_volume( MeshT const & mesh_obj, ElementT const & element ) 00156 { 00157 typedef typename viennagrid::result_of::coord<MeshT>::type numeric_type; 00158 typedef typename viennagrid::result_of::const_handle<ElementT, BoundaryElementTTag>::type boundary_element_handle; 00159 typedef typename viennagrid::result_of::const_element_range<ElementT, BoundaryElementTTag>::type boundary_element_range_type; 00160 typedef typename viennagrid::result_of::iterator<boundary_element_range_type>::type boundary_element_range_iterator; 00161 00162 boundary_element_range_type boundary_elements( element ); 00163 boundary_element_range_iterator it = boundary_elements.begin(); 00164 00165 boundary_element_handle best_handle = it.handle(); 00166 numeric_type best_volume = viennagrid::volume( mesh_obj, *it ); 00167 00168 for (; it != boundary_elements.end(); ++it) 00169 { 00170 numeric_type volume = viennagrid::volume( mesh_obj, *it ); 00171 if (volume < best_volume) 00172 { 00173 best_handle = it.handle(); 00174 best_volume = volume; 00175 } 00176 } 00177 00178 return best_handle; 00179 } 00180 00182 template<typename BoundaryElementTTag, typename MeshT, typename ElementT> 00183 typename viennagrid::result_of::handle<MeshT, BoundaryElementTTag>::type largest_boundary_volume( MeshT & mesh_obj, ElementT & element ) 00184 { 00185 typedef typename viennagrid::result_of::coord<MeshT>::type numeric_type; 00186 typedef typename viennagrid::result_of::handle<ElementT, BoundaryElementTTag>::type boundary_element_handle; 00187 typedef typename viennagrid::result_of::element_range<ElementT, BoundaryElementTTag>::type boundary_element_range_type; 00188 typedef typename viennagrid::result_of::iterator<boundary_element_range_type>::type boundary_element_range_iterator; 00189 00190 boundary_element_range_type boundary_elements( element ); 00191 boundary_element_range_iterator it = boundary_elements.begin(); 00192 00193 boundary_element_handle best_handle = it.handle(); 00194 numeric_type best_volume = viennagrid::volume( mesh_obj, *it ); 00195 00196 for (; it != boundary_elements.end(); ++it) 00197 { 00198 numeric_type volume = viennagrid::volume( mesh_obj, *it ); 00199 if (volume > best_volume) 00200 { 00201 best_handle = it.handle(); 00202 best_volume = volume; 00203 } 00204 } 00205 00206 return best_handle; 00207 } 00208 00210 template<typename BoundaryElementTTag, typename MeshT, typename ElementT> 00211 typename viennagrid::result_of::const_handle<MeshT, BoundaryElementTTag>::type largest_boundary_volume( MeshT const & mesh_obj, ElementT const & element ) 00212 { 00213 typedef typename viennagrid::result_of::coord<MeshT>::type numeric_type; 00214 typedef typename viennagrid::result_of::const_handle<ElementT, BoundaryElementTTag>::type boundary_element_handle; 00215 typedef typename viennagrid::result_of::const_element_range<ElementT, BoundaryElementTTag>::type boundary_element_range_type; 00216 typedef typename viennagrid::result_of::iterator<boundary_element_range_type>::type boundary_element_range_iterator; 00217 00218 boundary_element_range_type boundary_elements( element ); 00219 boundary_element_range_iterator it = boundary_elements.begin(); 00220 00221 boundary_element_handle best_handle = it.handle(); 00222 numeric_type best_volume = viennagrid::volume( mesh_obj, *it ); 00223 00224 for (; it != boundary_elements.end(); ++it) 00225 { 00226 numeric_type volume = viennagrid::volume( mesh_obj, *it ); 00227 if (volume > best_volume) 00228 { 00229 best_handle = it.handle(); 00230 best_volume = volume; 00231 } 00232 } 00233 00234 return best_handle; 00235 } 00236 00237 00238 } //namespace viennagrid 00239 #endif