ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ALGORITHM_GEOMETRY_HPP 00002 #define VIENNAGRID_ALGORITHM_GEOMETRY_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 <limits> 00017 #include "viennagrid/mesh/mesh.hpp" 00018 #include "viennagrid/topology/quadrilateral.hpp" 00019 #include "viennagrid/algorithm/inner_prod.hpp" 00020 #include "viennagrid/algorithm/norm.hpp" 00021 #include "viennagrid/algorithm/cross_prod.hpp" 00022 #include "viennagrid/algorithm/detail/numeric.hpp" 00023 00028 namespace viennagrid 00029 { 00030 00031 namespace detail 00032 { 00034 template<typename PointAccessorT, typename ElementT> 00035 typename PointAccessorT::value_type normal_vector_impl( 00036 PointAccessorT const point_accessor, 00037 ElementT const & element, 00038 viennagrid::vertex_tag, 00039 viennagrid::dimension_tag<1>) 00040 { 00041 typedef typename PointAccessorT::value_type PointType; 00042 00043 (void)point_accessor; (void)element; 00044 return PointType(1.0); 00045 } 00046 00048 template<typename PointAccessorT, typename ElementT> 00049 typename PointAccessorT::value_type normal_vector_impl( 00050 PointAccessorT const point_accessor, 00051 ElementT const & element, 00052 viennagrid::line_tag, 00053 viennagrid::dimension_tag<2>) 00054 { 00055 typedef typename PointAccessorT::value_type PointType; 00056 00057 PointType const & p0 = point_accessor( viennagrid::vertices(element)[0] ); 00058 PointType const & p1 = point_accessor( viennagrid::vertices(element)[1] ); 00059 00060 PointType line = p1-p0; 00061 std::swap(line[0], line[1]); 00062 line[0] = -line[0]; 00063 00064 return line; 00065 } 00066 00068 template<typename PointAccessorT, typename ElementT> 00069 typename PointAccessorT::value_type normal_vector_impl( 00070 PointAccessorT const point_accessor, 00071 ElementT const & element, 00072 viennagrid::triangle_tag, 00073 viennagrid::dimension_tag<3>) 00074 { 00075 typedef typename PointAccessorT::value_type PointType; 00076 00077 PointType const & p0 = point_accessor( viennagrid::vertices(element)[0] ); 00078 PointType const & p1 = point_accessor( viennagrid::vertices(element)[1] ); 00079 PointType const & p2 = point_accessor( viennagrid::vertices(element)[2] ); 00080 00081 return viennagrid::cross_prod( p1-p0, p2-p0 ); 00082 } 00083 00088 template<typename PointAccessorT, typename ElementT> 00089 typename PointAccessorT::value_type normal_vector_impl( 00090 PointAccessorT const point_accessor, 00091 ElementT const & element, 00092 viennagrid::quadrilateral_tag, 00093 viennagrid::dimension_tag<3>) 00094 { 00095 return normal_vector_impl(point_accessor, element, viennagrid::triangle_tag(), viennagrid::dimension_tag<3>()); 00096 } 00097 00098 } 00099 00100 00101 00107 template<typename PointAccessorT, typename ElementT> 00108 typename PointAccessorT::value_type normal_vector( 00109 PointAccessorT const point_accessor, 00110 ElementT const & element ) 00111 { 00112 typedef typename viennagrid::result_of::element_tag<ElementT>::type ElementTag; 00113 typedef typename PointAccessorT::value_type PointType; 00114 typedef viennagrid::dimension_tag< result_of::static_size<PointType>::value > DimensionTag; 00115 00116 return detail::normal_vector_impl( point_accessor, element, ElementTag(), DimensionTag() ); 00117 } 00118 00123 template<typename ElementT> 00124 typename viennagrid::result_of::point<ElementT>::type normal_vector( ElementT const & element ) 00125 { 00126 return normal_vector( default_point_accessor(element), element ); 00127 } 00128 00129 00130 00135 template<typename PointT> 00136 typename viennagrid::result_of::coord<PointT>::type determinant( PointT const & p0) 00137 { 00138 return p0[0]; 00139 } 00140 00146 template<typename PointT> 00147 typename viennagrid::result_of::coord<PointT>::type determinant( PointT const & p0, PointT const & p1 ) 00148 { 00149 return p0[0]*p1[1] - p0[1]*p1[0]; 00150 } 00151 00158 template<typename PointT> 00159 typename viennagrid::result_of::coord<PointT>::type determinant( PointT const & p0, PointT const & p1, PointT const & p2 ) 00160 { 00161 return p0[0]*p1[1]*p2[2] + p1[0]*p2[1]*p0[2] + p2[0]*p0[1]*p1[2] - p0[2]*p1[1]*p2[0] - p1[2]*p2[1]*p0[0] - p2[2]*p0[1]*p1[0]; 00162 } 00163 00164 00170 template<typename PointIteratorT> 00171 std::pair< 00172 typename std::iterator_traits<PointIteratorT>::value_type, 00173 typename std::iterator_traits<PointIteratorT>::value_type 00174 > bounding_box( PointIteratorT it, PointIteratorT const & it_end ) 00175 { 00176 typedef typename std::iterator_traits<PointIteratorT>::value_type PointType; 00177 typedef typename viennagrid::result_of::coord<PointType>::type NumericType; 00178 00179 PointType lower_left; 00180 PointType upper_right; 00181 00182 std::fill( lower_left.begin(), lower_left.end(), std::numeric_limits<NumericType>::max() ); 00183 std::fill( upper_right.begin(), upper_right.end(), - std::numeric_limits<NumericType>::max() ); 00184 //std::fill( upper_right.begin(), upper_right.end(), std::numeric_limits<NumericType>::lowest() ); C++11 00185 00186 for (; it != it_end; ++it ) 00187 { 00188 lower_left = viennagrid::min( lower_left, *it ); 00189 upper_right = viennagrid::max( upper_right, *it ); 00190 } 00191 00192 return std::make_pair( lower_left, upper_right ); 00193 } 00194 00195 00200 template<typename MeshT> 00201 std::pair< 00202 typename viennagrid::result_of::point<MeshT>::type, 00203 typename viennagrid::result_of::point<MeshT>::type 00204 > bounding_box( MeshT const & mesh ) 00205 { 00206 typedef typename viennagrid::result_of::point<MeshT>::type PointType; 00207 typedef typename viennagrid::result_of::coord<MeshT>::type NumericType; 00208 00209 PointType lower_left; 00210 PointType upper_right; 00211 00212 std::fill( lower_left.begin(), lower_left.end(), std::numeric_limits<NumericType>::max() ); 00213 std::fill( upper_right.begin(), upper_right.end(), - std::numeric_limits<NumericType>::max() ); 00214 //std::fill( upper_right.begin(), upper_right.end(), std::numeric_limits<NumericType>::lowest() ); C++11 00215 00216 typedef typename viennagrid::result_of::const_vertex_range<MeshT>::type ConstVertexRangeType; 00217 typedef typename viennagrid::result_of::iterator<ConstVertexRangeType>::type ConstVertexIteratorType; 00218 00219 ConstVertexRangeType vertices(mesh); 00220 for (ConstVertexIteratorType vit = vertices.begin(); vit != vertices.end(); ++vit) 00221 { 00222 lower_left = viennagrid::min( lower_left, viennagrid::point(*vit) ); 00223 upper_right = viennagrid::max( upper_right, viennagrid::point(*vit) ); 00224 } 00225 00226 return std::make_pair( lower_left, upper_right ); 00227 } 00228 00233 template<typename MeshT> 00234 typename viennagrid::result_of::coord<MeshT>::type mesh_size( MeshT const & mesh ) 00235 { 00236 std::pair< 00237 typename viennagrid::result_of::point<MeshT>::type, 00238 typename viennagrid::result_of::point<MeshT>::type 00239 > bb = bounding_box(mesh); 00240 00241 return viennagrid::norm_2(bb.second - bb.first); 00242 } 00243 00250 template<typename VectorIteratorT, typename VectorT> 00251 VectorT orthogonalize_vector( VectorIteratorT it, VectorIteratorT const & end, VectorT vec ) 00252 { 00253 for (; it != end; ++it) 00254 vec -= viennagrid::inner_prod( vec, *it ) / viennagrid::inner_prod( *it, *it ) * (*it); 00255 00256 return vec; 00257 } 00258 00259 00270 template<typename IteratorT, typename NumericConfigT> 00271 std::size_t orthogonalize( IteratorT start, IteratorT end, NumericConfigT nc ) 00272 { 00273 typedef typename std::iterator_traits<IteratorT>::value_type vector_type; 00274 typedef typename viennagrid::result_of::coord<vector_type>::type coord_type; 00275 00276 std::size_t count = 0; 00277 for (IteratorT n = start; n != end;) 00278 { 00279 *n = orthogonalize_vector(start, n, *n); 00280 00281 if ( viennagrid::norm_1(*n) < detail::absolute_tolerance<coord_type>(nc) ) 00282 { 00283 --end; 00284 std::swap(*n, *end); 00285 } 00286 else 00287 { 00288 ++n; 00289 ++count; 00290 } 00291 } 00292 00293 return count; 00294 } 00295 00296 00297 00298 } 00299 00300 #endif 00301