ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ALGORITHM_CENTROID_HPP 00002 #define VIENNAGRID_ALGORITHM_CENTROID_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/topology/all.hpp" 00023 #include "viennagrid/algorithm/volume.hpp" //for mesh/segment centroid 00024 #include "viennagrid/accessor.hpp" 00025 00030 namespace viennagrid 00031 { 00032 namespace detail 00033 { 00034 // 00035 // Calculation of centroid 00036 // 00038 template <typename PointAccessorT, typename ElementT> 00039 typename PointAccessorT::value_type 00040 centroid(PointAccessorT const accessor, ElementT const & cell, viennagrid::triangle_tag) 00041 { 00042 typedef typename PointAccessorT::value_type PointType; 00043 typedef typename viennagrid::result_of::coord<PointType>::type CoordType; 00044 00045 typedef typename viennagrid::result_of::const_element_range<ElementT, vertex_tag>::type VertexOnCellRange; 00046 typedef typename viennagrid::result_of::iterator<VertexOnCellRange>::type VertexOnCellIterator; 00047 00048 PointType p0(0.0, 0.0); 00049 00050 VertexOnCellRange vertices = viennagrid::elements<vertex_tag>(cell); 00051 for (VertexOnCellIterator vocit = vertices.begin(); 00052 vocit != vertices.end(); 00053 ++vocit) 00054 p0 += accessor(*vocit); 00055 00056 p0 /= static_cast<CoordType>(vertices.size()); 00057 00058 return p0; 00059 } 00060 00061 //tetrahedron can reuse the algorithm defined for a triangle 00063 template <typename PointAccessorT, typename ElementT> 00064 typename PointAccessorT::value_type 00065 centroid(PointAccessorT const accessor, ElementT const & cell, viennagrid::tetrahedron_tag) 00066 { 00067 return centroid(accessor, cell, viennagrid::triangle_tag()); 00068 } 00069 00070 // 00071 // Note: This works for rectangles only, but not for general quadrilateral 00072 // 00074 template <typename PointAccessorT, typename ElementT> 00075 typename PointAccessorT::value_type 00076 centroid(PointAccessorT const accessor, ElementT const & cell, viennagrid::quadrilateral_tag) 00077 { 00078 return centroid(accessor, cell, viennagrid::triangle_tag()); 00079 } 00080 00081 // 00082 // Note: This works for cuboids only, but not for general hexahedra 00083 // 00085 template <typename PointAccessorT, typename ElementT> 00086 typename PointAccessorT::value_type 00087 centroid(PointAccessorT const accessor, ElementT const & cell, viennagrid::hexahedron_tag) 00088 { 00089 return centroid(accessor, cell, viennagrid::triangle_tag()); 00090 } 00091 00092 00093 //a line can reuse the algorithm defined for a triangle 00095 template <typename PointAccessorT, typename ElementT> 00096 typename PointAccessorT::value_type 00097 centroid(PointAccessorT const accessor, ElementT const & cell, viennagrid::simplex_tag<1>) 00098 { 00099 return centroid(accessor, cell, viennagrid::triangle_tag()); 00100 } 00101 00102 00104 template <typename PointAccessorT, typename ElementT> 00105 typename PointAccessorT::value_type 00106 centroid(PointAccessorT const accessor, ElementT const & cell, viennagrid::hypercube_tag<1>) 00107 { 00108 return centroid(accessor, cell, viennagrid::triangle_tag()); 00109 } 00110 00111 00112 //a point is degenerate and returns its location 00114 template <typename PointAccessorT, typename ElementT> 00115 typename PointAccessorT::value_type 00116 centroid(PointAccessorT const accessor, ElementT const & cell, viennagrid::vertex_tag) 00117 { 00118 return accessor(cell); 00119 } 00120 00121 00122 00124 template <typename ElementTOrTag, typename MeshSegmentHandleType, typename PointAccessorT> 00125 typename viennagrid::result_of::point<MeshSegmentHandleType>::type 00126 centroid_mesh(MeshSegmentHandleType const & mesh_obj, PointAccessorT const point_accessor) 00127 { 00128 typedef typename viennagrid::result_of::element_tag<ElementTOrTag>::type ElementTag; 00129 typedef typename viennagrid::result_of::point<MeshSegmentHandleType>::type PointType; 00130 typedef typename viennagrid::result_of::const_element_range<MeshSegmentHandleType, 00131 ElementTag>::type CellRange; 00132 typedef typename viennagrid::result_of::iterator<CellRange>::type CellIterator; 00133 00134 PointType result = 0; 00135 double volume = 0; 00136 00137 CellRange cells = viennagrid::elements<ElementTag>(mesh_obj); 00138 for (CellIterator cit = cells.begin(); cit != cells.end(); ++cit) 00139 { 00140 double vol_cell = viennagrid::volume( point_accessor, *cit ); 00141 result += vol_cell * centroid( point_accessor, *cit); 00142 volume += vol_cell; 00143 } 00144 00145 return result / volume; 00146 } 00147 00148 } //namespace detail 00149 00150 00151 00157 template <typename PointAccessorT, typename ElementT> 00158 typename PointAccessorT::value_type 00159 centroid(PointAccessorT const accessor, ElementT const & element) 00160 { 00161 return detail::centroid( accessor, element, typename ElementT::tag()); 00162 } 00163 00168 template <typename ElementTag, typename WrappedConfigT> 00169 typename viennagrid::result_of::point< viennagrid::element<ElementTag,WrappedConfigT> >::type 00170 centroid(viennagrid::element<ElementTag,WrappedConfigT> const & element) 00171 { 00172 return detail::centroid( default_point_accessor(element), element, ElementTag()); 00173 } 00174 00175 00176 00183 template<typename ElementTOrTagT, typename WrappedConfigT, typename PointAccessorT> 00184 typename viennagrid::result_of::point< mesh<WrappedConfigT> >::type 00185 centroid(mesh<WrappedConfigT> const & mesh_obj, PointAccessorT const point_accessor) 00186 { 00187 return detail::centroid_mesh<ElementTOrTagT>(mesh_obj, point_accessor); 00188 } 00189 00195 template<typename WrappedConfigT, typename PointAccessorT> 00196 typename viennagrid::result_of::point< mesh<WrappedConfigT> >::type 00197 centroid(mesh<WrappedConfigT> const & mesh_obj, PointAccessorT const point_accessor) 00198 { 00199 typedef typename viennagrid::result_of::cell_tag< mesh<WrappedConfigT> >::type CellTag; 00200 return detail::centroid_mesh<CellTag>(mesh_obj, point_accessor); 00201 } 00202 00203 00209 template<typename ElementTOrTagT, typename WrappedConfigT> 00210 typename viennagrid::result_of::point< mesh<WrappedConfigT> >::type 00211 centroid(mesh<WrappedConfigT> const & mesh_obj) 00212 { 00213 return centroid<ElementTOrTagT>(mesh_obj, default_point_accessor(mesh_obj)); 00214 } 00215 00220 template<typename WrappedConfigT> 00221 typename viennagrid::result_of::point< mesh<WrappedConfigT> >::type 00222 centroid(mesh<WrappedConfigT> const & mesh_obj) 00223 { 00224 typedef typename viennagrid::result_of::cell_tag< mesh<WrappedConfigT> >::type CellTag; 00225 return centroid<CellTag>(mesh_obj, default_point_accessor(mesh_obj)); 00226 } 00227 00228 00235 template<typename ElementTOrTagT, typename SegmentationT, typename PointAccessorT> 00236 typename viennagrid::result_of::point< segment_handle<SegmentationT> >::type 00237 centroid(segment_handle<SegmentationT> const & segment, PointAccessorT const point_accessor) 00238 { 00239 return detail::centroid_mesh<ElementTOrTagT>(segment, point_accessor); 00240 } 00241 00247 template<typename SegmentationT, typename PointAccessorT> 00248 typename viennagrid::result_of::point< segment_handle<SegmentationT> >::type 00249 centroid(segment_handle<SegmentationT> const & segment, PointAccessorT const point_accessor) 00250 { 00251 typedef typename viennagrid::result_of::cell_tag< segment_handle<SegmentationT> >::type CellTag; 00252 return detail::centroid_mesh<CellTag>(segment, point_accessor); 00253 } 00254 00255 00261 template<typename ElementTOrTagT, typename SegmentationT> 00262 typename viennagrid::result_of::point< segment_handle<SegmentationT> >::type 00263 centroid(segment_handle<SegmentationT> const & segment) 00264 { 00265 return centroid<ElementTOrTagT>(segment, default_point_accessor(segment)); 00266 } 00267 00272 template<typename SegmentationT> 00273 typename viennagrid::result_of::point< segment_handle<SegmentationT> >::type 00274 centroid(segment_handle<SegmentationT> const & segment) 00275 { 00276 typedef typename viennagrid::result_of::cell_tag< segment_handle<SegmentationT> >::type CellTag; 00277 return centroid<CellTag>(segment, default_point_accessor(segment)); 00278 } 00279 } //namespace viennagrid 00280 #endif