Go to the documentation of this file.00001 #ifndef VIENNAGRID_ALGORITHM_VOLUME_HPP
00002 #define VIENNAGRID_ALGORITHM_VOLUME_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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);
00104 }
00105
00106
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
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 }
00176
00177
00178
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
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
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 }
00207 #endif