GaussianQuadratureRule.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <cmath>
00037
00038 #include "GaussianQuadratureRule.hpp"
00039 #include "Exception.hpp"
00040 #include "UblasCustomFunctions.hpp"
00041
00042 template<unsigned ELEMENT_DIM>
00043 const ChastePoint<ELEMENT_DIM>& GaussianQuadratureRule<ELEMENT_DIM>::rGetQuadPoint(unsigned index) const
00044 {
00045 assert(index < mNumQuadPoints);
00046 return mPoints[index];
00047 }
00048
00049 template<unsigned ELEMENT_DIM>
00050 double GaussianQuadratureRule<ELEMENT_DIM>::GetWeight(unsigned index) const
00051 {
00052 assert(index < mNumQuadPoints);
00053 return mWeights[index];
00054 }
00055
00056 template<unsigned ELEMENT_DIM>
00057 unsigned GaussianQuadratureRule<ELEMENT_DIM>::GetNumQuadPoints() const
00058 {
00059 return mNumQuadPoints;
00060 }
00061
00067 template<>
00068 GaussianQuadratureRule<0>::GaussianQuadratureRule(unsigned quadratureOrder)
00069 {
00070 mNumQuadPoints = 1;
00071 mWeights.push_back(1);
00072 mPoints.push_back(ChastePoint<0>());
00073 }
00074
00080 template<>
00081 GaussianQuadratureRule<1>::GaussianQuadratureRule(unsigned quadratureOrder)
00082 {
00083 switch (quadratureOrder)
00084 {
00085 case 0:
00086 case 1:
00087
00088 mWeights.push_back(1);
00089 mPoints.push_back(ChastePoint<1>(0.5));
00090 break;
00091 case 2:
00092 case 3:
00093
00094 mWeights.push_back(0.5);
00095 mWeights.push_back(0.5);
00096 {
00097 double sqrt_one_third = sqrt(1.0/3.0);
00098 mPoints.push_back(ChastePoint<1>((-sqrt_one_third+1.0)/2.0));
00099 mPoints.push_back(ChastePoint<1>((sqrt_one_third+1.0)/2.0));
00100 }
00101 break;
00102 case 4:
00103 case 5:
00104
00105 mWeights.push_back(5.0/18.0);
00106 mWeights.push_back(4.0/9.0);
00107 mWeights.push_back(5.0/18.0);
00108
00109 {
00110 double sqrt_three_fifths = sqrt(3.0/5.0);
00111 mPoints.push_back(ChastePoint<1>((-sqrt_three_fifths+1.0)/2.0));
00112 mPoints.push_back(ChastePoint<1>(0.5));
00113 mPoints.push_back(ChastePoint<1>((sqrt_three_fifths+1.0)/2.0));
00114 }
00115 break;
00116 default:
00117 EXCEPTION("Gauss quadrature order not supported.");
00118 }
00119 assert(mPoints.size() == mWeights.size());
00120 mNumQuadPoints = mPoints.size();
00121 }
00122
00129 template<>
00130 GaussianQuadratureRule<2>::GaussianQuadratureRule(unsigned quadratureOrder)
00131 {
00132 double one_third = 1.0/3.0;
00133 double one_sixth = 1.0/6.0;
00134 double two_thirds = 2.0/3.0;
00135 switch (quadratureOrder)
00136 {
00137 case 0:
00138 case 1:
00139
00140 mWeights.push_back(0.5);
00141 mPoints.push_back(ChastePoint<2>(one_third, one_third));
00142 break;
00143
00144 case 2:
00145
00146 mWeights.push_back(one_sixth);
00147 mWeights.push_back(one_sixth);
00148 mWeights.push_back(one_sixth);
00149
00150 mPoints.push_back(ChastePoint<2>(two_thirds, one_sixth));
00151 mPoints.push_back(ChastePoint<2>(one_sixth, one_sixth));
00152 mPoints.push_back(ChastePoint<2>(one_sixth, two_thirds));
00153 break;
00154
00155 case 3:
00156
00157
00158 {
00159 double w = 1.0/12.0;
00160 mWeights.push_back(w);
00161 mWeights.push_back(w);
00162 mWeights.push_back(w);
00163 mWeights.push_back(w);
00164 mWeights.push_back(w);
00165 mWeights.push_back(w);
00166
00167 double inverse_tan = atan(0.75);
00168 double cos_third = cos(inverse_tan/3.0);
00169 double sin_third = sin(inverse_tan/3.0);
00170
00171 double a = sin_third/(2*sqrt(3.0)) - cos_third/6.0 + 1.0/3.0;
00172
00173 double b = - sin_third/(2*sqrt(3.0)) - cos_third/6.0 + 1.0/3.0;
00174
00175 double c = cos_third/3.0 + 1.0/3.0;
00176
00177 mPoints.push_back(ChastePoint<2>(a, b));
00178 mPoints.push_back(ChastePoint<2>(a, c));
00179 mPoints.push_back(ChastePoint<2>(b, a));
00180 mPoints.push_back(ChastePoint<2>(b, c));
00181 mPoints.push_back(ChastePoint<2>(c, a));
00182 mPoints.push_back(ChastePoint<2>(c, b));
00183 }
00184 break;
00185 default:
00186 EXCEPTION("Gauss quadrature order not supported.");
00187 }
00188 assert(mPoints.size() == mWeights.size());
00189 mNumQuadPoints = mPoints.size();
00190 }
00191
00197 template<>
00198 GaussianQuadratureRule<3>::GaussianQuadratureRule(unsigned quadratureOrder)
00199 {
00200 switch (quadratureOrder)
00201 {
00202 case 0:
00203 case 1:
00204
00205 mWeights.push_back(1.0/6.0);
00206 mPoints.push_back(ChastePoint<3>(0.25, 0.25, 0.25));
00207 break;
00208
00209 case 2:
00210
00211 {
00212 double sqrt_fifth = 1.0/sqrt(5.0);
00213 double a = (1.0 + 3.0*sqrt_fifth)/4.0;
00214 double b = (1.0 - sqrt_fifth)/4.0;
00215 double w = 1.0/24.0;
00216
00217 mWeights.push_back(w);
00218 mWeights.push_back(w);
00219 mWeights.push_back(w);
00220 mWeights.push_back(w);
00221
00222 mPoints.push_back(ChastePoint<3>(a,b,b));
00223 mPoints.push_back(ChastePoint<3>(b,a,b));
00224 mPoints.push_back(ChastePoint<3>(b,b,a));
00225 mPoints.push_back(ChastePoint<3>(b,b,b));
00226 }
00227 break;
00228
00229 case 3:
00230
00231
00232
00233
00234
00235
00236
00237
00238 {
00239 double root_seventeen = sqrt(17.0);
00240 double root_term = sqrt(1022.0-134.0*root_seventeen);
00241 double b = (55.0 - 3.0*root_seventeen + root_term)/196;
00242 double d = (55.0 - 3.0*root_seventeen - root_term)/196;
00243
00244 double a = 1.0 - 3.0*b;
00245 double c = 1.0 - 3.0*d;
00246
00247
00248 double w1 = (20.0*d*d - 10.0*d + 1.0)/(240.0*(2.0*d*d - d - 2.0*b*b + b));
00249 double w2 = 1.0/24.0 - w1;
00250
00251 mWeights.push_back(w1);
00252 mWeights.push_back(w1);
00253 mWeights.push_back(w1);
00254 mWeights.push_back(w1);
00255
00256 mWeights.push_back(w2);
00257 mWeights.push_back(w2);
00258 mWeights.push_back(w2);
00259 mWeights.push_back(w2);
00260
00261 mPoints.push_back(ChastePoint<3>(a, b, b));
00262 mPoints.push_back(ChastePoint<3>(b, a, b));
00263 mPoints.push_back(ChastePoint<3>(b, b, a));
00264 mPoints.push_back(ChastePoint<3>(b, b, b));
00265
00266 mPoints.push_back(ChastePoint<3>(c, d, d));
00267 mPoints.push_back(ChastePoint<3>(d, c, d));
00268 mPoints.push_back(ChastePoint<3>(d, d, c));
00269 mPoints.push_back(ChastePoint<3>(d, d, d));
00270
00271 }
00272 break;
00273
00274 default:
00275 EXCEPTION("Gauss quadrature order not supported.");
00276 }
00277 assert(mPoints.size() == mWeights.size());
00278 mNumQuadPoints = mPoints.size();
00279 }
00280
00281 template<unsigned ELEMENT_DIM>
00282 GaussianQuadratureRule<ELEMENT_DIM>::GaussianQuadratureRule(unsigned quadratureOrder)
00283 {
00284 EXCEPTION("Gauss quadrature rule not available for this dimension.");
00285 }
00286
00288
00290
00291 template class GaussianQuadratureRule<0>;
00292 template class GaussianQuadratureRule<1>;
00293 template class GaussianQuadratureRule<2>;
00294 template class GaussianQuadratureRule<3>;
00295 template class GaussianQuadratureRule<4>;