00001 #ifndef VIENNAFEM_QUADRATURE_TETRAHEDRON_HPP
00002 #define VIENNAFEM_QUADRATURE_TETRAHEDRON_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "viennafem/forwards.h"
00018 #include "viennafem/cell_quan.hpp"
00019
00020 #include "viennamath/forwards.h"
00021 #include "viennamath/expression.hpp"
00022 #include "viennamath/manipulation/substitute.hpp"
00023 #include "viennamath/manipulation/diff.hpp"
00024 #include "viennamath/manipulation/eval.hpp"
00025 #include "viennamath/runtime/numerical_quadrature.hpp"
00026
00027 #include "viennagrid/topology/triangle.hpp"
00028 #include "viennagrid/topology/tetrahedron.hpp"
00029
00034 namespace viennafem
00035 {
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00047 template <typename InterfaceType>
00048 class rt_gauss_quad_element <viennafem::unit_tetrahedron, 1, InterfaceType> : public viennamath::numerical_quadrature_interface<InterfaceType>
00049 {
00050 typedef typename InterfaceType::numeric_type NumericT;
00051 typedef rt_gauss_quad_element <viennafem::unit_tetrahedron, 1, InterfaceType> self_type;
00052 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00053 public:
00054 explicit rt_gauss_quad_element() : p_(3)
00055 {
00056 p_[0] = 1.0/4.0;
00057 p_[1] = 1.0/4.0;
00058 p_[2] = 1.0/4.0;
00059 }
00060
00061 BaseType * clone() const { return new self_type(); }
00062
00063 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00064 viennamath::rt_expr<InterfaceType> const & e,
00065 viennamath::rt_variable<InterfaceType> const & var) const
00066 {
00067 return viennamath::eval(e, p_) / 6.0;
00068 }
00069
00070 private:
00071 std::vector<NumericT> p_;
00072 };
00073
00074
00075
00076
00077
00078
00079
00080
00085 template <typename InterfaceType>
00086 class rt_keast_quad_element <viennafem::unit_tetrahedron, 2, InterfaceType> : public viennamath::numerical_quadrature_interface<InterfaceType>
00087 {
00088 typedef typename InterfaceType::numeric_type NumericT;
00089 typedef rt_keast_quad_element <viennafem::unit_tetrahedron, 2, InterfaceType> self_type;
00090 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00091 public:
00092 enum { num_points = 4 };
00093
00094 explicit rt_keast_quad_element() : abscissas_(num_points, std::vector<numeric_type>(3))
00095 {
00096 abscissas_[0][0] = 0.5854101966249685; abscissas_[0][1] = 0.1381966011250105; abscissas_[0][2] = 0.1381966011250105;
00097 abscissas_[1][0] = 0.1381966011250105; abscissas_[1][1] = 0.1381966011250105; abscissas_[1][2] = 0.1381966011250105;
00098 abscissas_[2][0] = 0.1381966011250105; abscissas_[2][1] = 0.1381966011250105; abscissas_[2][2] = 0.5854101966249685;
00099 abscissas_[3][0] = 0.1381966011250105; abscissas_[3][1] = 0.5854101966249685; abscissas_[3][2] = 0.1381966011250105;
00100 }
00101
00102 BaseType * clone() const { return new self_type(); }
00103
00104 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00105 viennamath::rt_expr<InterfaceType> const & e,
00106 viennamath::rt_variable<InterfaceType> const & var) const
00107 {
00108 NumericT result = 0;
00109 for (std::size_t i=0; i<num_points; ++i)
00110 result += viennamath::eval(e, abscissas_[i]);
00111 return result / 24.0;
00112 }
00113
00114 private:
00115 std::vector<std::vector<NumericT> > abscissas_;
00116 };
00117
00118
00119
00120
00121
00122
00123
00124
00125
00130 template <typename InterfaceType>
00131 class rt_keast_quad_element <viennafem::unit_tetrahedron, 3, InterfaceType> : public viennamath::numerical_quadrature_interface<InterfaceType>
00132 {
00133 typedef typename InterfaceType::numeric_type NumericT;
00134 typedef rt_keast_quad_element <viennafem::unit_tetrahedron, 3, InterfaceType> self_type;
00135 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00136 public:
00137 enum { num_points = 5 };
00138
00139 explicit rt_keast_quad_element() : abscissas_(num_points, std::vector<numeric_type>(3)), weights_(num_points)
00140 {
00141 abscissas_[0][0] = 0.25; abscissas_[0][1] = 0.25; abscissas_[0][2] = 0.25;
00142 abscissas_[1][0] = 0.5; abscissas_[1][1] = 0.1666666666666667; abscissas_[1][2] = 0.1666666666666667;
00143 abscissas_[2][0] = 0.1666666666666667; abscissas_[2][1] = 0.1666666666666667; abscissas_[2][2] = 0.1666666666666667;
00144 abscissas_[3][0] = 0.1666666666666667; abscissas_[3][1] = 0.1666666666666667; abscissas_[3][2] = 0.5;
00145 abscissas_[4][0] = 0.1666666666666667; abscissas_[4][1] = 0.5; abscissas_[4][2] = 0.1666666666666667;
00146
00147 weights_[0] = -0.8;
00148 weights_[1] = 0.45;
00149 weights_[2] = 0.45;
00150 weights_[3] = 0.45;
00151 weights_[4] = 0.45;
00152 }
00153
00154 BaseType * clone() const { return new self_type(); }
00155
00156 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00157 viennamath::rt_expr<InterfaceType> const & e,
00158 viennamath::rt_variable<InterfaceType> const & var) const
00159 {
00160 NumericT result = 0;
00161 for (std::size_t i=0; i<num_points; ++i)
00162 result += weights_[i] * viennamath::eval(e, abscissas_[i]);
00163 return result / 6.0;
00164 }
00165
00166 private:
00167 std::vector<std::vector<NumericT> > abscissas_;
00168 std::vector<NumericT> weights_;
00169 };
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00184 template <typename InterfaceType>
00185 class rt_keast_quad_element <viennafem::unit_tetrahedron, 4, InterfaceType> : public viennamath::numerical_quadrature_interface<InterfaceType>
00186 {
00187 typedef typename InterfaceType::numeric_type NumericT;
00188 typedef rt_keast_quad_element <viennafem::unit_tetrahedron, 4, InterfaceType> self_type;
00189 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00190 public:
00191 enum { num_points = 14 };
00192
00193 explicit rt_keast_quad_element() : abscissas_(num_points, std::vector<numeric_type>(3)), weights_(num_points)
00194 {
00195 abscissas_[0][0] = 0.0; abscissas_[0][1] = 0.5; abscissas_[0][2] = 0.5;
00196 abscissas_[1][0] = 0.5; abscissas_[1][1] = 0.0; abscissas_[1][2] = 0.5;
00197 abscissas_[2][0] = 0.5; abscissas_[2][1] = 0.5; abscissas_[2][2] = 0.0;
00198 abscissas_[3][0] = 0.5; abscissas_[3][1] = 0.0; abscissas_[3][2] = 0.0;
00199 abscissas_[4][0] = 0.0; abscissas_[4][1] = 0.5; abscissas_[4][2] = 0.0;
00200 abscissas_[5][0] = 0.0; abscissas_[5][1] = 0.0; abscissas_[5][2] = 0.5;
00201
00202 abscissas_[6][0] = 0.6984197043243866; abscissas_[6][1] = 0.1005267652252045; abscissas_[6][2] = 0.1005267652252045;
00203 abscissas_[7][0] = 0.1005267652252045; abscissas_[7][1] = 0.1005267652252045; abscissas_[7][2] = 0.1005267652252045;
00204 abscissas_[8][0] = 0.1005267652252045; abscissas_[8][1] = 0.1005267652252045; abscissas_[8][2] = 0.6984197043243866;
00205 abscissas_[9][0] = 0.1005267652252045; abscissas_[9][1] = 0.6984197043243866; abscissas_[9][2] = 0.1005267652252045;
00206 abscissas_[10][0] = 0.0568813795204234; abscissas_[10][1] = 0.3143728734931922; abscissas_[10][2] = 0.3143728734931922;
00207 abscissas_[11][0] = 0.3143728734931922; abscissas_[11][1] = 0.3143728734931922; abscissas_[11][2] = 0.3143728734931922;
00208 abscissas_[12][0] = 0.3143728734931922; abscissas_[12][1] = 0.3143728734931922; abscissas_[12][2] = 0.0568813795204234;
00209 abscissas_[13][0] = 0.3143728734931922; abscissas_[13][1] = 0.0568813795204234; abscissas_[13][2] = 0.3143728734931922;
00210
00211 weights_[0] = 0.0190476190476190;
00212 weights_[1] = 0.0190476190476190;
00213 weights_[2] = 0.0190476190476190;
00214 weights_[3] = 0.0190476190476190;
00215 weights_[4] = 0.0190476190476190;
00216 weights_[5] = 0.0190476190476190;
00217 weights_[6] = 0.0885898247429807;
00218 weights_[7] = 0.0885898247429807;
00219 weights_[8] = 0.0885898247429807;
00220 weights_[9] = 0.0885898247429807;
00221 weights_[10] = 0.1328387466855907;
00222 weights_[11] = 0.1328387466855907;
00223 weights_[12] = 0.1328387466855907;
00224 weights_[13] = 0.1328387466855907;
00225 }
00226
00227 BaseType * clone() const { return new self_type(); }
00228
00229 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00230 viennamath::rt_expr<InterfaceType> const & e,
00231 viennamath::rt_variable<InterfaceType> const & var) const
00232 {
00233 NumericT result = 0;
00234 for (std::size_t i=0; i<num_points; ++i)
00235 result += weights_[i] * viennamath::eval(e, abscissas_[i]);
00236 return result / 6.0;
00237 }
00238
00239 private:
00240 std::vector<std::vector<NumericT> > abscissas_;
00241 std::vector<NumericT> weights_;
00242 };
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00258 template <typename InterfaceType>
00259 class rt_keast_quad_element <viennafem::unit_tetrahedron, 5, InterfaceType> : public viennamath::numerical_quadrature_interface<InterfaceType>
00260 {
00261 typedef typename InterfaceType::numeric_type NumericT;
00262 typedef rt_keast_quad_element <viennafem::unit_tetrahedron, 5, InterfaceType> self_type;
00263 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00264 public:
00265 enum { num_points = 15 };
00266
00267 explicit rt_keast_quad_element() : abscissas_(num_points, std::vector<numeric_type>(3)), weights_(num_points)
00268 {
00269 abscissas_[0][0] = 0.25; abscissas_[0][1] = 0.25; abscissas_[0][2] = 0.25;
00270
00271 abscissas_[1][0] = 0.0; abscissas_[1][1] = 1.0/3.0; abscissas_[1][2] = 1.0/3.0;
00272 abscissas_[2][0] = 1.0/3.0; abscissas_[2][1] = 1.0/3.0; abscissas_[2][2] = 1.0/3.0;
00273 abscissas_[3][0] = 1.0/3.0; abscissas_[3][1] = 1.0/3.0; abscissas_[3][2] = 0.;
00274 abscissas_[4][0] = 1.0/3.0; abscissas_[4][1] = 0.; abscissas_[4][2] = 1.0/3.0;
00275
00276 abscissas_[5][0] = 0.7272727272727273; abscissas_[5][1] = 0.0909090909090909; abscissas_[5][2] = 0.0909090909090909;
00277 abscissas_[6][0] = 0.0909090909090909; abscissas_[6][1] = 0.0909090909090909; abscissas_[6][2] = 0.0909090909090909;
00278 abscissas_[7][0] = 0.0909090909090909; abscissas_[7][1] = 0.0909090909090909; abscissas_[7][2] = 0.7272727272727273;
00279 abscissas_[8][0] = 0.0909090909090909; abscissas_[8][1] = 0.7272727272727273; abscissas_[8][2] = 0.0909090909090909;
00280
00281 abscissas_[ 9][0] = 0.4334498464263357; abscissas_[ 9][1] = 0.0665501535736643; abscissas_[ 9][2] = 0.0665501535736643;
00282 abscissas_[10][0] = 0.0665501535736643; abscissas_[10][1] = 0.4334498464263357; abscissas_[10][2] = 0.0665501535736643;
00283 abscissas_[11][0] = 0.0665501535736643; abscissas_[11][1] = 0.0665501535736643; abscissas_[11][2] = 0.4334498464263357;
00284 abscissas_[12][0] = 0.0665501535736643; abscissas_[12][1] = 0.4334498464263357; abscissas_[12][2] = 0.4334498464263357;
00285 abscissas_[13][0] = 0.4334498464263357; abscissas_[13][1] = 0.0665501535736643; abscissas_[13][2] = 0.4334498464263357;
00286 abscissas_[14][0] = 0.4334498464263357; abscissas_[14][1] = 0.4334498464263357; abscissas_[14][2] = 0.0665501535736643;
00287
00288 weights_[0] = 0.1817020685825351;
00289
00290 weights_[1] = 0.0361607142857143;
00291 weights_[2] = 0.0361607142857143;
00292 weights_[3] = 0.0361607142857143;
00293 weights_[4] = 0.0361607142857143;
00294
00295 weights_[5] = 0.0698714945161738;
00296 weights_[6] = 0.0698714945161738;
00297 weights_[7] = 0.0698714945161738;
00298 weights_[8] = 0.0698714945161738;
00299
00300 weights_[ 9] = 0.0656948493683187;
00301 weights_[10] = 0.0656948493683187;
00302 weights_[11] = 0.0656948493683187;
00303 weights_[12] = 0.0656948493683187;
00304 weights_[13] = 0.0656948493683187;
00305 weights_[14] = 0.0656948493683187;
00306 }
00307
00308 BaseType * clone() const { return new self_type(); }
00309
00310 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00311 viennamath::rt_expr<InterfaceType> const & e,
00312 viennamath::rt_variable<InterfaceType> const & var) const
00313 {
00314 NumericT result = 0;
00315 for (std::size_t i=0; i<num_points; ++i)
00316 result += weights_[i] * viennamath::eval(e, abscissas_[i]);
00317 return result / 6.0;
00318 }
00319
00320 private:
00321 std::vector<std::vector<NumericT> > abscissas_;
00322 std::vector<NumericT> weights_;
00323 };
00324
00325
00326
00327
00328
00329
00330
00335 template <typename InterfaceType>
00336 class rt_keast_quad_element <viennafem::unit_tetrahedron, 6, InterfaceType> : public viennamath::numerical_quadrature_interface<InterfaceType>
00337 {
00338 typedef typename InterfaceType::numeric_type NumericT;
00339 typedef rt_keast_quad_element <viennafem::unit_tetrahedron, 6, InterfaceType> self_type;
00340 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00341 public:
00342 enum { num_points = 24 };
00343
00344 explicit rt_keast_quad_element() : abscissas_(num_points, std::vector<numeric_type>(3)), weights_(num_points)
00345 {
00346 abscissas_[ 0][0] = 0.3561913862225449; abscissas_[ 0][1] = 0.2146028712591517; abscissas_[ 0][2] = 0.2146028712591517;
00347 abscissas_[ 1][0] = 0.2146028712591517; abscissas_[ 1][1] = 0.2146028712591517; abscissas_[ 1][2] = 0.2146028712591517;
00348 abscissas_[ 2][0] = 0.2146028712591517; abscissas_[ 2][1] = 0.2146028712591517; abscissas_[ 2][2] = 0.3561913862225449;
00349 abscissas_[ 3][0] = 0.2146028712591517; abscissas_[ 3][1] = 0.3561913862225449; abscissas_[ 3][2] = 0.2146028712591517;
00350
00351 abscissas_[ 4][0] = 0.8779781243961660; abscissas_[ 4][1] = 0.0406739585346113; abscissas_[ 4][2] = 0.0406739585346113;
00352 abscissas_[ 5][0] = 0.0406739585346113; abscissas_[ 5][1] = 0.0406739585346113; abscissas_[ 5][2] = 0.0406739585346113;
00353 abscissas_[ 6][0] = 0.0406739585346113; abscissas_[ 6][1] = 0.0406739585346113; abscissas_[ 6][2] = 0.8779781243961660;
00354 abscissas_[ 7][0] = 0.0406739585346113; abscissas_[ 7][1] = 0.8779781243961660; abscissas_[ 7][2] = 0.0406739585346113;
00355
00356 abscissas_[ 8][0] = 0.0329863295731731; abscissas_[ 8][1] = 0.3223378901422757; abscissas_[ 8][2] = 0.3223378901422757;
00357 abscissas_[ 9][0] = 0.3223378901422757; abscissas_[ 9][1] = 0.3223378901422757; abscissas_[ 9][2] = 0.3223378901422757;
00358 abscissas_[10][0] = 0.3223378901422757; abscissas_[10][1] = 0.3223378901422757; abscissas_[10][2] = 0.0329863295731731;
00359 abscissas_[11][0] = 0.3223378901422757; abscissas_[11][1] = 0.0329863295731731; abscissas_[11][2] = 0.3223378901422757;
00360
00361 abscissas_[12][0] = 0.2696723314583159; abscissas_[12][1] = 0.0636610018750175; abscissas_[12][2] = 0.0636610018750175;
00362 abscissas_[13][0] = 0.0636610018750175; abscissas_[13][1] = 0.2696723314583159; abscissas_[13][2] = 0.0636610018750175;
00363 abscissas_[14][0] = 0.0636610018750175; abscissas_[14][1] = 0.0636610018750175; abscissas_[14][2] = 0.2696723314583159;
00364 abscissas_[15][0] = 0.6030056647916491; abscissas_[15][1] = 0.0636610018750175; abscissas_[15][2] = 0.0636610018750175;
00365
00366 abscissas_[16][0] = 0.0636610018750175; abscissas_[16][1] = 0.6030056647916491; abscissas_[16][2] = 0.0636610018750175;
00367 abscissas_[17][0] = 0.0636610018750175; abscissas_[17][1] = 0.0636610018750175; abscissas_[17][2] = 0.6030056647916491;
00368 abscissas_[18][0] = 0.0636610018750175; abscissas_[18][1] = 0.2696723314583159; abscissas_[18][2] = 0.6030056647916491;
00369 abscissas_[19][0] = 0.2696723314583159; abscissas_[19][1] = 0.6030056647916491; abscissas_[19][2] = 0.0636610018750175;
00370
00371 abscissas_[20][0] = 0.6030056647916491; abscissas_[20][1] = 0.0636610018750175; abscissas_[20][2] = 0.2696723314583159;
00372 abscissas_[21][0] = 0.0636610018750175; abscissas_[21][1] = 0.6030056647916491; abscissas_[21][2] = 0.2696723314583159;
00373 abscissas_[22][0] = 0.2696723314583159; abscissas_[22][1] = 0.0636610018750175; abscissas_[22][2] = 0.6030056647916491;
00374 abscissas_[23][0] = 0.6030056647916491; abscissas_[23][1] = 0.2696723314583159; abscissas_[23][2] = 0.0636610018750175;
00375
00376 weights_[ 0] = 0.0399227502581679;
00377 weights_[ 1] = 0.0399227502581679;
00378 weights_[ 2] = 0.0399227502581679;
00379 weights_[ 3] = 0.0399227502581679;
00380
00381 weights_[ 4] = 0.0100772110553207;
00382 weights_[ 5] = 0.0100772110553207;
00383 weights_[ 6] = 0.0100772110553207;
00384 weights_[ 7] = 0.0100772110553207;
00385
00386 weights_[ 8] = 0.0553571815436544;
00387 weights_[ 9] = 0.0553571815436544;
00388 weights_[10] = 0.0553571815436544;
00389 weights_[11] = 0.0553571815436544;
00390
00391 weights_[12] = 0.0482142857142857;
00392 weights_[13] = 0.0482142857142857;
00393 weights_[14] = 0.0482142857142857;
00394 weights_[15] = 0.0482142857142857;
00395
00396 weights_[16] = 0.0482142857142857;
00397 weights_[17] = 0.0482142857142857;
00398 weights_[18] = 0.0482142857142857;
00399 weights_[19] = 0.0482142857142857;
00400
00401 weights_[20] = 0.0482142857142857;
00402 weights_[21] = 0.0482142857142857;
00403 weights_[22] = 0.0482142857142857;
00404 weights_[23] = 0.0482142857142857;
00405 }
00406
00407 BaseType * clone() const { return new self_type(); }
00408
00409 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00410 viennamath::rt_expr<InterfaceType> const & e,
00411 viennamath::rt_variable<InterfaceType> const & var) const
00412 {
00413 NumericT result = 0;
00414 for (std::size_t i=0; i<num_points; ++i)
00415 result += weights_[i] * viennamath::eval(e, abscissas_[i]);
00416 return result / 6.0;
00417 }
00418
00419 private:
00420 std::vector<std::vector<NumericT> > abscissas_;
00421 std::vector<NumericT> weights_;
00422 };
00423
00424 }
00425 #endif