Go to the documentation of this file.00001 #ifndef VIENNAFEM_QUADRATURE_QUADRILATERAL_HPP
00002 #define VIENNAFEM_QUADRATURE_QUADRILATERAL_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
00046
00047
00048
00049
00050
00051
00052
00054 template <typename InterfaceType>
00055 class rt_gauss_quad_element <viennafem::unit_square, 1, InterfaceType>
00056 : public viennamath::numerical_quadrature_interface<InterfaceType>
00057 {
00058 typedef typename InterfaceType::numeric_type NumericT;
00059 typedef rt_gauss_quad_element <viennafem::unit_square, 1, InterfaceType> self_type;
00060 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00061 public:
00062 enum { num_points = 1 };
00063
00064 explicit rt_gauss_quad_element() : p_(2)
00065 {
00066 p_[0] = 0.5;
00067 p_[1] = 0.5;
00068 }
00069
00070 BaseType * clone() const { return new self_type(); }
00071
00072 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00073 viennamath::rt_expr<InterfaceType> const & e,
00074 viennamath::rt_variable<InterfaceType> const & var) const
00075 {
00076 return viennamath::eval(e, p_);
00077 }
00078
00079 private:
00080 std::vector<NumericT> p_;
00081 };
00082
00083
00084
00085
00086
00087
00088
00090 template <typename InterfaceType>
00091 class rt_gauss_quad_element <viennafem::unit_square, 3, InterfaceType>
00092 : public viennamath::numerical_quadrature_interface<InterfaceType>
00093 {
00094 typedef typename InterfaceType::numeric_type NumericT;
00095 typedef rt_gauss_quad_element <viennafem::unit_square, 3, InterfaceType> self_type;
00096 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00097 public:
00098 enum { num_points = 4 };
00099
00100 explicit rt_gauss_quad_element() : abscissas_(num_points, std::vector<numeric_type>(2))
00101 {
00102 abscissas_[0][0] = 0.7886751345948125; abscissas_[0][1] = 0.7886751345948125;
00103 abscissas_[1][0] = 0.7886751345948125; abscissas_[1][1] = 0.2113248654051875;
00104 abscissas_[2][0] = 0.2113248654051875; abscissas_[2][1] = 0.7886751345948125;
00105 abscissas_[3][0] = 0.2113248654051875; abscissas_[3][1] = 0.2113248654051875;
00106 }
00107
00108 BaseType * clone() const { return new self_type(); }
00109
00110 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00111 viennamath::rt_expr<InterfaceType> const & e,
00112 viennamath::rt_variable<InterfaceType> const & var) const
00113 {
00114 NumericT result = 0;
00115 for (std::size_t i=0; i<num_points; ++i)
00116 result += viennamath::eval(e, abscissas_[i]);
00117 return 0.25 * result;
00118 }
00119
00120 private:
00121 std::vector<std::vector<NumericT> > abscissas_;
00122 };
00123
00124
00125
00126
00127
00128
00129
00131 template <typename InterfaceType>
00132 class rt_gauss_quad_element <viennafem::unit_square, 5, InterfaceType>
00133 : public viennamath::numerical_quadrature_interface<InterfaceType>
00134 {
00135 typedef typename InterfaceType::numeric_type NumericT;
00136 typedef rt_gauss_quad_element <viennafem::unit_square, 5, InterfaceType> self_type;
00137 typedef viennamath::numerical_quadrature_interface<InterfaceType> BaseType;
00138 public:
00139 enum { num_points = 9 };
00140
00141 explicit rt_gauss_quad_element() : abscissas_(num_points, std::vector<numeric_type>(2)), weights_(num_points)
00142 {
00143 abscissas_[0][0] = 0.11270166537925829786; abscissas_[0][1] = 0.11270166537925829786;
00144 abscissas_[1][0] = 0.11270166537925829786; abscissas_[1][1] = 0.5;
00145 abscissas_[2][0] = 0.11270166537925829786; abscissas_[2][1] = 0.88729833462074170214;
00146 abscissas_[3][0] = 0.5; abscissas_[3][1] = 0.11270166537925829786;
00147 abscissas_[4][0] = 0.5; abscissas_[4][1] = 0.5;
00148 abscissas_[5][0] = 0.5; abscissas_[5][1] = 0.88729833462074170214;
00149 abscissas_[6][0] = 0.88729833462074170214; abscissas_[6][1] = 0.11270166537925829786;
00150 abscissas_[7][0] = 0.88729833462074170214; abscissas_[7][1] = 0.5;
00151 abscissas_[8][0] = 0.88729833462074170214; abscissas_[8][1] = 0.88729833462074170214;
00152
00153 weights_[0] = (5.0 * 5.0) / (18.0 * 18.0);
00154 weights_[1] = (5.0 * 8.0) / (18.0 * 18.0);
00155 weights_[2] = (5.0 * 5.0) / (18.0 * 18.0);
00156
00157 weights_[3] = (8.0 * 5.0) / (18.0 * 18.0);
00158 weights_[4] = (8.0 * 8.0) / (18.0 * 18.0);
00159 weights_[5] = (8.0 * 5.0) / (18.0 * 18.0);
00160
00161 weights_[6] = (5.0 * 5.0) / (18.0 * 18.0);
00162 weights_[7] = (5.0 * 8.0) / (18.0 * 18.0);
00163 weights_[8] = (5.0 * 5.0) / (18.0 * 18.0);
00164 }
00165
00166 BaseType * clone() const { return new self_type(); }
00167
00168 NumericT eval(viennamath::rt_interval<InterfaceType> const & interv,
00169 viennamath::rt_expr<InterfaceType> const & e,
00170 viennamath::rt_variable<InterfaceType> const & var) const
00171 {
00172 NumericT result = 0;
00173 for (std::size_t i=0; i<num_points; ++i)
00174 result += weights_[i] * viennamath::eval(e, abscissas_[i]);
00175 return result;
00176 }
00177
00178 private:
00179 std::vector<std::vector<NumericT> > abscissas_;
00180 std::vector<NumericT> weights_;
00181 };
00182
00183
00184
00185
00186
00187
00188
00189
00191 template <typename InterfaceType>
00192 viennamath::numerical_quadrature quadrature_for_reference_cell(viennafem::unit_square const &,
00193 std::size_t order)
00194 {
00195 switch (order)
00196 {
00197 case 1: return viennamath::numerical_quadrature(new rt_gauss_quad_element <viennafem::unit_square, 1, InterfaceType>());
00198 case 2:
00199 case 3: return viennamath::numerical_quadrature(new rt_gauss_quad_element <viennafem::unit_square, 3, InterfaceType>());
00200 case 4:
00201 case 5: return viennamath::numerical_quadrature(new rt_gauss_quad_element <viennafem::unit_square, 5, InterfaceType>());
00202 }
00203
00204 std::cout << "Cannot find quadrature rule for order " << order << " - fallback to order 5." << std::endl;
00205 return viennamath::numerical_quadrature(new rt_gauss_quad_element <viennafem::unit_square, 5, InterfaceType>());
00206 }
00207
00208 }
00209 #endif