QuadraticBasisFunction.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 #include <boost/numeric/ublas/matrix.hpp>
00030 #include <boost/numeric/ublas/matrix_proxy.hpp>
00031
00032 #include "QuadraticBasisFunction.hpp"
00033 #include "Exception.hpp"
00034
00044 double QuadraticBasisFunction<0>::ComputeBasisFunction(const ChastePoint<0>& rPoint, unsigned basisIndex)
00045 {
00046 assert(basisIndex == 0);
00047 return 1.0;
00048 }
00049
00057 void QuadraticBasisFunction<0>::ComputeBasisFunctions(const ChastePoint<0>& rPoint,
00058 c_vector<double, 1>& rReturnValue)
00059 {
00060 rReturnValue(0) = ComputeBasisFunction(rPoint, 0);
00061 }
00062
00072 template <unsigned ELEMENT_DIM>
00073 double QuadraticBasisFunction<ELEMENT_DIM>::ComputeBasisFunction(const ChastePoint<ELEMENT_DIM>& rPoint, unsigned basisIndex)
00074 {
00075 assert(ELEMENT_DIM < 4 && ELEMENT_DIM >= 0);
00076 double x, y, z;
00077 switch (ELEMENT_DIM)
00078 {
00079 case 0:
00080 assert(basisIndex == 0);
00081 return 1.0;
00082 break;
00083
00084 case 1:
00085 x = rPoint[0];
00086 switch (basisIndex)
00087 {
00088 case 0:
00089 return 2.0*(x-1.0)*(x-0.5);
00090 break;
00091 case 1:
00092 return 2.0*x*(x-0.5);
00093 break;
00094 case 2:
00095 return 4.0*x*(1.0-x);
00096 break;
00097 default:
00098 NEVER_REACHED;
00099 }
00100 break;
00101
00102 case 2:
00103 x = rPoint[0];
00104 y = rPoint[1];
00105 switch (basisIndex)
00106 {
00107 case 0:
00108 return 2.0 * (1.0 - x - y) * (0.5 - x - y);
00109 break;
00110 case 1:
00111 return 2.0*x*(x-0.5);
00112 break;
00113 case 2:
00114 return 2.0*y*(y-0.5);
00115 break;
00116 case 3:
00117 return 4.0 * y * x;
00118 break;
00119 case 4:
00120 return 4.0 * (1.0 - x - y) * y;
00121 break;
00122 case 5:
00123 return 4.0 * (1.0 - x - y) * x;
00124 break;
00125 default:
00126 NEVER_REACHED;
00127 }
00128 break;
00129
00130 case 3:
00131 x = rPoint[0];
00132 y = rPoint[1];
00133 z = rPoint[2];
00134 switch (basisIndex)
00135 {
00136 case 0:
00137 return 2.0 * (1.0 - x - y - z) * (0.5 - x - y - z);
00138 break;
00139 case 1:
00140 return 2.0*x*(x-0.5);
00141 break;
00142 case 2:
00143 return 2.0*y*(y-0.5);
00144 break;
00145 case 3:
00146 return 2.0*z*(z-0.5);
00147 break;
00148 case 4:
00149 return 4.0 * (1.0 - x - y - z) * x;
00150 break;
00151 case 5:
00152 return 4 * x * y;
00153 break;
00154 case 6:
00155 return 4.0 * (1.0 - x - y - z) * y;
00156 break;
00157 case 7:
00158 return 4.0 * (1.0 - x - y - z) * z;
00159 break;
00160 case 8:
00161 return 4.0 * x * z;
00162 break;
00163 case 9:
00164 return 4.0 * y * z;
00165 break;
00166 default:
00167 NEVER_REACHED;
00168 }
00169 break;
00170 }
00171 return 0.0;
00172 }
00173
00184 template <unsigned ELEMENT_DIM>
00185 c_vector<double, ELEMENT_DIM> QuadraticBasisFunction<ELEMENT_DIM>::ComputeBasisFunctionDerivative(const ChastePoint<ELEMENT_DIM>& rPoint, unsigned basisIndex)
00186 {
00187 c_vector<double, ELEMENT_DIM> gradN;
00188 assert(ELEMENT_DIM < 4 && ELEMENT_DIM > 0);
00189
00190 double x, y, z;
00191 switch (ELEMENT_DIM)
00192 {
00193 case 1:
00194 x = rPoint[0];
00195 switch (basisIndex)
00196 {
00197 case 0:
00198 gradN(0) = 4.0*x-3.0;
00199 break;
00200 case 1:
00201 gradN(0) = 4.0*x-1.0;
00202 break;
00203 case 2:
00204 gradN(0) = 4.0-8.0*x;
00205 break;
00206 default:
00207 NEVER_REACHED;
00208 }
00209 break;
00210
00211 case 2:
00212 x = rPoint[0];
00213 y = rPoint[1];
00214 switch (basisIndex)
00215 {
00216 case 0:
00217 gradN(0) = -3.0 + 4.0*x + 4.0*y;
00218 gradN(1) = -3.0 + 4.0*x + 4.0*y;
00219 break;
00220 case 1:
00221 gradN(0) = 4.0*x - 1.0;
00222 gradN(1) = 0.0;
00223 break;
00224 case 2:
00225 gradN(0) = 0.0;
00226 gradN(1) = 4.0*y - 1.0;
00227 break;
00228 case 3:
00229 gradN(0) = 4.0*y;
00230 gradN(1) = 4.0*x;
00231 break;
00232 case 4:
00233 gradN(0) = -4.0*y;
00234 gradN(1) = 4.0-4.0*x-8.0*y;
00235 break;
00236 case 5:
00237 gradN(0) = 4.0-8.0*x-4.0*y;
00238 gradN(1) = -4.0*x;
00239 break;
00240 default:
00241 NEVER_REACHED;
00242 }
00243 break;
00244
00245 case 3:
00246 x = rPoint[0];
00247 y = rPoint[1];
00248 z = rPoint[2];
00249 switch (basisIndex)
00250 {
00251 case 0:
00252 gradN(0) = -3.0 + 4.0*(x+y+z);
00253 gradN(1) = -3.0 + 4.0*(x+y+z);
00254 gradN(2) = -3.0 + 4.0*(x+y+z);
00255 break;
00256 case 1:
00257 gradN(0) = 4.0*x-1.0;
00258 gradN(1) = 0;
00259 gradN(2) = 0;
00260 break;
00261 case 2:
00262 gradN(0) = 0;
00263 gradN(1) = 4.0*y-1.0;
00264 gradN(2) = 0;
00265 break;
00266 case 3:
00267 gradN(0) = 0;
00268 gradN(1) = 0;
00269 gradN(2) = 4.0*z-1.0;
00270 break;
00271 case 4:
00272 gradN(0) = 4.0-8.0*x-4.0*y-4.0*z;
00273 gradN(1) = -4.0*x;
00274 gradN(2) = -4.0*x;
00275 break;
00276 case 5:
00277 gradN(0) = 4.0*y;
00278 gradN(1) = 4.0*x;
00279 gradN(2) = 0.0;
00280 break;
00281 case 6:
00282 gradN(0) = -4.0*y;
00283 gradN(1) = 4.0-4.0*x-8.0*y-4.0*z;
00284 gradN(2) = -4.0*y;
00285 break;
00286 case 7:
00287 gradN(0) = -4.0*z;
00288 gradN(1) = -4.0*z;
00289 gradN(2) = 4.0-4.0*x-4.0*y-8.0*z;
00290 break;
00291 case 8:
00292 gradN(0) = 4.0*z;
00293 gradN(1) = 0;
00294 gradN(2) = 4.0*x;
00295 break;
00296 case 9:
00297 gradN(0) = 0;
00298 gradN(1) = 4.0*z;
00299 gradN(2) = 4.0*y;
00300 break;
00301 default:
00302 NEVER_REACHED;
00303 }
00304 break;
00305 }
00306 return gradN;
00307 }
00308
00316 template <unsigned ELEMENT_DIM>
00317 void QuadraticBasisFunction<ELEMENT_DIM>::ComputeBasisFunctions(const ChastePoint<ELEMENT_DIM>& rPoint,
00318 c_vector<double, (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2>& rReturnValue)
00319 {
00320 assert(ELEMENT_DIM < 4 && ELEMENT_DIM >= 0);
00321
00322 for (unsigned i=0; i<(ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2; i++)
00323 {
00324 rReturnValue(i) = ComputeBasisFunction(rPoint, i);
00325 }
00326 }
00327
00337 template <unsigned ELEMENT_DIM>
00338 void QuadraticBasisFunction<ELEMENT_DIM>::ComputeBasisFunctionDerivatives(const ChastePoint<ELEMENT_DIM>& rPoint,
00339 c_matrix<double, ELEMENT_DIM, (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2>& rReturnValue)
00340 {
00341 assert(ELEMENT_DIM < 4 && ELEMENT_DIM > 0);
00342
00343 for (unsigned j=0; j<(ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2; j++)
00344 {
00345 matrix_column<c_matrix<double, ELEMENT_DIM, (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2> > column(rReturnValue, j);
00346 column = ComputeBasisFunctionDerivative(rPoint, j);
00347 }
00348 }
00349
00363 template <unsigned ELEMENT_DIM>
00364 void QuadraticBasisFunction<ELEMENT_DIM>::ComputeTransformedBasisFunctionDerivatives(const ChastePoint<ELEMENT_DIM>& rPoint,
00365 const c_matrix<double, ELEMENT_DIM, ELEMENT_DIM>& rInverseJacobian,
00366 c_matrix<double, ELEMENT_DIM, (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2>& rReturnValue)
00367 {
00368 assert(ELEMENT_DIM < 4 && ELEMENT_DIM > 0);
00369
00370 ComputeBasisFunctionDerivatives(rPoint, rReturnValue);
00371 rReturnValue = prod(trans(rInverseJacobian), rReturnValue);
00372 }
00373
00375
00377
00378 template class QuadraticBasisFunction<1>;
00379 template class QuadraticBasisFunction<2>;
00380 template class QuadraticBasisFunction<3>;