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
00043 template <unsigned ELEM_DIM>
00044 double QuadraticBasisFunction<ELEM_DIM>::ComputeBasisFunction(const ChastePoint<ELEM_DIM> &rPoint, unsigned basisIndex)
00045 {
00046 assert(ELEM_DIM < 4 && ELEM_DIM >= 0);
00047 double x, y, z;
00048 switch(ELEM_DIM)
00049 {
00050 case 0:
00051 assert(basisIndex == 0);
00052 return 1.0;
00053 break;
00054
00055 case 1:
00056 x = rPoint[0];
00057 switch (basisIndex)
00058 {
00059 case 0:
00060 return 2.0*(x-1.0)*(x-0.5);
00061 break;
00062 case 1:
00063 return 2.0*x*(x-0.5);
00064 break;
00065 case 2:
00066 return 4.0*x*(1.0-x);
00067 break;
00068 default:
00069 NEVER_REACHED;
00070 }
00071 break;
00072
00073 case 2:
00074 x = rPoint[0];
00075 y = rPoint[1];
00076 switch (basisIndex)
00077 {
00078 case 0:
00079 return 2.0 * (1.0 - x - y) * (0.5 - x - y);
00080 break;
00081 case 1:
00082 return 2.0*x*(x-0.5);
00083 break;
00084 case 2:
00085 return 2.0*y*(y-0.5);
00086 break;
00087 case 3:
00088 return 4.0 * y * x;
00089 break;
00090 case 4:
00091 return 4.0 * (1.0 - x - y) * y;
00092 break;
00093 case 5:
00094 return 4.0 * (1.0 - x - y) * x;
00095 break;
00096 default:
00097 NEVER_REACHED;
00098 }
00099 break;
00100
00101 case 3:
00102 x = rPoint[0];
00103 y = rPoint[1];
00104 z = rPoint[2];
00105 switch (basisIndex)
00106 {
00107 case 0:
00108 return 2.0 * (1.0 - x - y - z) * (0.5 - x - y - z);
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 2.0*z*(z-0.5);
00118 break;
00119 case 4:
00120 return 4.0 * (1.0 - x - y - z) * x;
00121 break;
00122 case 5:
00123 return 4 * x * y;
00124 break;
00125 case 6:
00126 return 4.0 * (1.0 - x - y - z) * y;
00127 break;
00128 case 7:
00129 return 4.0 * (1.0 - x - y - z) * z;
00130 break;
00131 case 8:
00132 return 4.0 * x * z;
00133 break;
00134 case 9:
00135 return 4.0 * y * z;
00136 break;
00137 default:
00138 NEVER_REACHED;
00139 }
00140 break;
00141 }
00142 return 0.0;
00143 }
00144
00145
00146
00157 template <unsigned ELEM_DIM>
00158 c_vector<double, ELEM_DIM> QuadraticBasisFunction<ELEM_DIM>::ComputeBasisFunctionDerivative(const ChastePoint<ELEM_DIM> &rPoint, unsigned basisIndex)
00159 {
00160 c_vector<double, ELEM_DIM> gradN;
00161 assert(ELEM_DIM < 4 && ELEM_DIM > 0);
00162
00163 double x, y, z;
00164 switch(ELEM_DIM)
00165 {
00166 case 1:
00167 x=rPoint[0];
00168 switch (basisIndex)
00169 {
00170 case 0:
00171 gradN(0) = 4.0*x-3.0;
00172 break;
00173 case 1:
00174 gradN(0) = 4.0*x-1.0;
00175 break;
00176 case 2:
00177 gradN(0) = 4.0-8.0*x;
00178 break;
00179 default:
00180 NEVER_REACHED;
00181 }
00182 break;
00183
00184 case 2:
00185 x = rPoint[0];
00186 y = rPoint[1];
00187 switch (basisIndex)
00188 {
00189 case 0:
00190 gradN(0) = -3.0 + 4.0*x + 4.0*y;
00191 gradN(1) = -3.0 + 4.0*x + 4.0*y;
00192 break;
00193 case 1:
00194 gradN(0) = 4.0*x - 1.0;
00195 gradN(1) = 0.0;
00196 break;
00197 case 2:
00198 gradN(0) = 0.0;
00199 gradN(1) = 4.0*y - 1.0;
00200 break;
00201 case 3:
00202 gradN(0) = 4.0*y;
00203 gradN(1) = 4.0*x;
00204 break;
00205 case 4:
00206 gradN(0) = -4.0*y;
00207 gradN(1) = 4.0-4.0*x-8.0*y;
00208 break;
00209 case 5:
00210 gradN(0) = 4.0-8.0*x-4.0*y;
00211 gradN(1) = -4.0*x;
00212 break;
00213 default:
00214 NEVER_REACHED;
00215 }
00216 break;
00217
00218 case 3:
00219 x = rPoint[0];
00220 y = rPoint[1];
00221 z = rPoint[2];
00222 switch (basisIndex)
00223 {
00224 case 0:
00225 gradN(0) = -3.0 + 4.0*(x+y+z);
00226 gradN(1) = -3.0 + 4.0*(x+y+z);
00227 gradN(2) = -3.0 + 4.0*(x+y+z);
00228 break;
00229 case 1:
00230 gradN(0) = 4.0*x-1.0;
00231 gradN(1) = 0;
00232 gradN(2) = 0;
00233 break;
00234 case 2:
00235 gradN(0) = 0;
00236 gradN(1) = 4.0*y-1.0;
00237 gradN(2) = 0;
00238 break;
00239 case 3:
00240 gradN(0) = 0;
00241 gradN(1) = 0;
00242 gradN(2) = 4.0*z-1.0;
00243 break;
00244 case 4:
00245 gradN(0) = 4.0-8.0*x-4.0*y-4.0*z;
00246 gradN(1) = -4.0*x;
00247 gradN(2) = -4.0*x;
00248 break;
00249 case 5:
00250 gradN(0) = 4.0*y;
00251 gradN(1) = 4.0*x;
00252 gradN(2) = 0.0;
00253 break;
00254 case 6:
00255 gradN(0) = -4.0*y;
00256 gradN(1) = 4.0-4.0*x-8.0*y-4.0*z;
00257 gradN(2) = -4.0*y;
00258 break;
00259 case 7:
00260 gradN(0) = -4.0*z;
00261 gradN(1) = -4.0*z;
00262 gradN(2) = 4.0-4.0*x-4.0*y-8.0*z;
00263 break;
00264 case 8:
00265 gradN(0) = 4.0*z;
00266 gradN(1) = 0;
00267 gradN(2) = 4.0*x;
00268 break;
00269 case 9:
00270 gradN(0) = 0;
00271 gradN(1) = 4.0*z;
00272 gradN(2) = 4.0*y;
00273 break;
00274 default:
00275 NEVER_REACHED;
00276 }
00277 break;
00278 }
00279 return gradN;
00280 }
00281
00282
00290 template <unsigned ELEM_DIM>
00291 void QuadraticBasisFunction<ELEM_DIM>::ComputeBasisFunctions(const ChastePoint<ELEM_DIM> &rPoint,
00292 c_vector<double, (ELEM_DIM+1)*(ELEM_DIM+2)/2>& rReturnValue)
00293 {
00294 assert(ELEM_DIM < 4 && ELEM_DIM >= 0);
00295
00296 for(unsigned i=0;i<(ELEM_DIM+1)*(ELEM_DIM+2)/2;i++)
00297 {
00298 rReturnValue(i) = ComputeBasisFunction(rPoint,i);
00299 }
00300
00301 }
00302
00303
00304
00314 template <unsigned ELEM_DIM>
00315 void QuadraticBasisFunction<ELEM_DIM>::ComputeBasisFunctionDerivatives(const ChastePoint<ELEM_DIM> &rPoint,
00316 c_matrix<double, ELEM_DIM, (ELEM_DIM+1)*(ELEM_DIM+2)/2>& rReturnValue)
00317 {
00318 assert(ELEM_DIM < 4 && ELEM_DIM > 0);
00319
00320 for (unsigned j=0;j<(ELEM_DIM+1)*(ELEM_DIM+2)/2;j++)
00321 {
00322 matrix_column<c_matrix<double, ELEM_DIM, (ELEM_DIM+1)*(ELEM_DIM+2)/2> > column(rReturnValue, j);
00323 column = ComputeBasisFunctionDerivative(rPoint, j);
00324 }
00325 }
00326
00340 template <unsigned ELEM_DIM>
00341 void QuadraticBasisFunction<ELEM_DIM>::ComputeTransformedBasisFunctionDerivatives(const ChastePoint<ELEM_DIM> &rPoint,
00342 const c_matrix<double, ELEM_DIM, ELEM_DIM> &rInverseJacobian,
00343 c_matrix<double, ELEM_DIM, (ELEM_DIM+1)*(ELEM_DIM+2)/2>& rReturnValue)
00344 {
00345 assert(ELEM_DIM < 4 && ELEM_DIM > 0);
00346
00347 ComputeBasisFunctionDerivatives(rPoint, rReturnValue);
00348 rReturnValue = prod(trans(rInverseJacobian), rReturnValue);
00349 }
00350
00351
00353
00355
00356 template class QuadraticBasisFunction<0>;
00357 template class QuadraticBasisFunction<1>;
00358 template class QuadraticBasisFunction<2>;
00359 template class QuadraticBasisFunction<3>;
00360