ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/inner_prod.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_INNERPROD_HPP
00002 #define VIENNAGRID_ALGORITHM_INNERPROD_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/forwards.hpp"
00017 #include "viennagrid/point.hpp"
00018 
00023 namespace viennagrid
00024 {
00025 
00026   namespace detail
00027   {
00028     template <typename PointT,
00029               long dim = viennagrid::result_of::dimension<PointT>::value>
00030     struct inner_prod_impl;
00031 
00032     //
00033     // 1d
00034     //
00036     template <typename PointT>
00037     struct inner_prod_impl<PointT, 1>
00038     {
00039       typedef typename viennagrid::result_of::coord<PointT>::type    value_type;
00040 
00041       template <typename PointT2>
00042       static value_type apply(PointT const & p1,
00043                               PointT2 const & p2)
00044       {
00045         return p1[0] * p2[0];
00046       }
00047     };
00048 
00049     //
00050     // 2d
00051     //
00053     template <typename PointT>
00054     struct inner_prod_impl<PointT, 2>
00055     {
00056       typedef typename viennagrid::result_of::coord<PointT>::type    value_type;
00057 
00058       template <typename PointT2>
00059       static value_type apply(PointT const & p1,
00060                               PointT2 const & p2)
00061       {
00062         return p1[0] * p2[0] + p1[1] * p2[1];
00063       }
00064     };
00065 
00066     //
00067     // 3d
00068     //
00070     template <typename PointT>
00071     struct inner_prod_impl<PointT, 3>
00072     {
00073       typedef typename viennagrid::result_of::coord<PointT>::type    value_type;
00074 
00075       template <typename PointT2>
00076       static value_type apply(PointT const & p1,
00077                               PointT2 const & p2)
00078       {
00079         return p1[0] * p2[0] + p1[1] * p2[1] + p1[2] * p2[2];
00080       }
00081     };
00082   }
00083 
00085   template<typename PointT1, typename PointT2, typename CoordinateSystemT1, typename CoordinateSystemT2>
00086   typename viennagrid::result_of::coord<PointT1>::type
00087   inner_prod_impl(PointT1 const & p1, PointT2 const & p2, CoordinateSystemT1 const &, CoordinateSystemT2 const &)
00088   {
00089     typedef typename result_of::cartesian_point<PointT1>::type   CartesianPoint1;
00090 
00091     return detail::inner_prod_impl<CartesianPoint1>::apply(to_cartesian(p1), to_cartesian(p2));
00092   }
00093 
00095   template<typename PointT1, typename PointT2, int d>
00096   typename viennagrid::result_of::coord<PointT1>::type
00097   inner_prod_impl(PointT1 const & p1, PointT2 const & p2, cartesian_cs<d>, cartesian_cs<d>)
00098   {
00099     return detail::inner_prod_impl<PointT1>::apply(p1, p2);
00100   }
00101 
00107   template<typename PointT1, typename PointT2>
00108   typename viennagrid::result_of::coord<PointT1>::type
00109   inner_prod(PointT1 const & p1, PointT2 const & p2)
00110   {
00111     return inner_prod_impl(p1,
00112                            p2,
00113                            typename result_of::coordinate_system<PointT1>::type(),
00114                            typename result_of::coordinate_system<PointT2>::type());
00115   }
00116 
00117 }
00118 
00119 #endif