• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/export/development/ViennaGrid/release/ViennaGrid-1.0.0/viennagrid/algorithm/volume.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_VOLUME_HPP
00002 #define VIENNAGRID_ALGORITHM_VOLUME_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2011, Institute for Microelectronics,
00006                        Institute for Analysis and Scientific Computing,
00007                        TU Wien.
00008 
00009                             -----------------
00010                      ViennaGrid - The Vienna Grid Library
00011                             -----------------
00012 
00013    Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
00014                  Josef Weinbub                    weinbub@iue.tuwien.ac.at
00015                
00016    (A list of additional contributors can be found in the PDF manual)
00017 
00018    License:      MIT (X11), see file LICENSE in the base directory
00019 ======================================================================= */
00020 
00021 #include <iostream>
00022 #include <sstream>
00023 #include <string>
00024 #include <stdexcept>
00025 
00026 #include "viennagrid/forwards.h"
00027 #include "viennagrid/topology/all.hpp"
00028 #include "viennagrid/algorithm/norm.hpp"
00029 #include "viennagrid/algorithm/spanned_volume.hpp"
00030 
00036 namespace viennagrid
00037 {
00038   namespace detail
00039   {
00040     
00042     template <typename ElementType>
00043     typename ElementType::config_type::numeric_type
00044     volume_impl(ElementType const & cell, viennagrid::point_tag)
00045     {
00046       return typename ElementType::config_type::numeric_type(1);
00047     }
00048     
00050     template <typename ElementType>
00051     typename ElementType::config_type::numeric_type
00052     volume_impl(ElementType const & cell, viennagrid::simplex_tag<1>)
00053     {
00054       typedef typename ElementType::config_type      ConfigType;
00055       typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
00056       typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;
00057       
00058       PointType const & p0 = ncells<0>(cell)[0].point();
00059       PointType const & p1 = ncells<0>(cell)[1].point();
00060       
00061       return norm(p0 - p1);
00062     }
00063     
00065     template <typename ElementType>
00066     typename ElementType::config_type::numeric_type
00067     volume_impl(ElementType const & cell, viennagrid::hypercube_tag<1>)
00068     {
00069       return volume_impl(cell, viennagrid::simplex_tag<1>());
00070     }
00071 
00072     //topologically two-dimensional elements
00074     template <typename ElementType>
00075     typename ElementType::config_type::numeric_type
00076     volume_impl(ElementType const & cell, viennagrid::triangle_tag)
00077     {
00078       typedef typename ElementType::config_type      ConfigType;
00079       typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
00080       typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;
00081       
00082       PointType const & p0 = ncells<0>(cell)[0].point();
00083       PointType const & p1 = ncells<0>(cell)[1].point();
00084       PointType const & p2 = ncells<0>(cell)[2].point();
00085       
00086       return spanned_volume(p0, p1, p2);
00087     }
00088 
00090     template <typename ElementType>
00091     typename ElementType::config_type::numeric_type
00092     volume_impl(ElementType const & cell, viennagrid::quadrilateral_tag)
00093     {
00094       typedef typename ElementType::config_type      ConfigType;
00095       typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
00096       typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;
00097       
00098       PointType const & p0 = ncells<0>(cell)[0].point();
00099       PointType const & p1 = ncells<0>(cell)[1].point();
00100       PointType const & p2 = ncells<0>(cell)[2].point();
00101       PointType const & p3 = ncells<0>(cell)[3].point();
00102       
00103       return spanned_volume(p0, p1, p3) + spanned_volume(p1, p2, p3); //sum up the two triangular parts
00104     }
00105 
00106     //topologically three-dimensional elements
00108     template <typename ElementType>
00109     typename ElementType::config_type::numeric_type
00110     volume_impl(ElementType const & cell, viennagrid::tetrahedron_tag)
00111     {
00112       typedef typename ElementType::config_type      ConfigType;
00113       typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
00114       typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;
00115       
00116       PointType const & p0 = ncells<0>(cell)[0].point();
00117       PointType const & p1 = ncells<0>(cell)[1].point();
00118       PointType const & p2 = ncells<0>(cell)[2].point();
00119       PointType const & p3 = ncells<0>(cell)[3].point();
00120       
00121       return spanned_volume(p0, p1, p2, p3);
00122     }
00123 
00124 
00126     template <typename ElementType>
00127     typename ElementType::config_type::numeric_type
00128     volume_impl(ElementType const & cell, viennagrid::hexahedron_tag)
00129     {
00130       typedef typename ElementType::config_type      ConfigType;
00131       typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
00132       typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;
00133       
00134       PointType const & p0 = ncells<0>(cell)[0].point();
00135       PointType const & p1 = ncells<0>(cell)[1].point();
00136       PointType const & p2 = ncells<0>(cell)[2].point();
00137       PointType const & p3 = ncells<0>(cell)[3].point();
00138       PointType const & p4 = ncells<0>(cell)[4].point();
00139       PointType const & p5 = ncells<0>(cell)[5].point();
00140       PointType const & p6 = ncells<0>(cell)[6].point();
00141       PointType const & p7 = ncells<0>(cell)[7].point();
00142       
00143       //decompose hexahedron into six tetrahedra
00144       return spanned_volume(p0, p1, p3, p4)
00145              + spanned_volume(p4, p1, p3, p7)
00146              + spanned_volume(p4, p1, p7, p5)
00147              + spanned_volume(p1, p2, p3, p7)
00148              + spanned_volume(p1, p2, p7, p5)
00149              + spanned_volume(p5, p2, p7, p6);
00150     }
00151     
00152 
00153     //
00155     template <typename ContainerType>
00156     typename ContainerType::config_type::numeric_type
00157     volume_domainsegment(ContainerType const & d)
00158     {
00159       typedef ContainerType                                      DomainType;
00160       typedef typename ContainerType::config_type::cell_tag      CellTag;
00161       
00162       typedef typename viennagrid::result_of::const_ncell_range<DomainType, CellTag::dim>::type  CellContainer;
00163       typedef typename viennagrid::result_of::iterator<CellContainer>::type         CellIterator;
00164       
00165       typename ContainerType::config_type::numeric_type new_volume = 0;
00166       CellContainer new_cells = viennagrid::ncells<CellTag::dim>(d);
00167       for (CellIterator new_cit = new_cells.begin();
00168                         new_cit != new_cells.end();
00169                       ++new_cit)
00170       {
00171         new_volume += volume(*new_cit);
00172       }
00173       return new_volume;
00174     }
00175   } //namespace detail
00176   
00177   //
00178   // The public interface functions
00179   //
00181   template <typename ElementType>
00182   typename ElementType::config_type::numeric_type
00183   volume(ElementType const & cell)
00184   {
00185     return detail::volume_impl(cell, typename ElementType::tag());
00186   }
00187   
00188   //special case: domain
00190   template <typename ConfigType>
00191   typename ConfigType::numeric_type
00192   volume(domain_t<ConfigType> const & d)
00193   {
00194     return detail::volume_domainsegment(d);
00195   }    
00196   
00197   //special case: segment
00199   template <typename ConfigType>
00200   typename ConfigType::numeric_type
00201   volume(segment_t<ConfigType> const & d)
00202   {
00203     return detail::volume_domainsegment(d);
00204   }
00205   
00206 } //namespace viennagrid
00207 #endif

Generated on Wed Sep 14 2011 19:21:30 for ViennaGrid by  doxygen 1.7.1