ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/geometry.hpp
Go to the documentation of this file.
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