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