00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef MECHSYS_FEM_TET10_H
00023 #define MECHSYS_FEM_TET10_H
00024
00025 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #else
00028 #ifndef REAL
00029 #define REAL double
00030 #endif
00031 #endif
00032
00033 #include "fem/ele/element.h"
00034 #include "linalg/vector.h"
00035 #include "linalg/matrix.h"
00036 #include "linalg/laexpr.h"
00037
00038 namespace FEM
00039 {
00040
00041 class Debug;
00042
00043
00044
00045
00046
00047
00048
00049 const int TET10_NNODES=10;
00050 const int TET10_NINTPTS=4;
00051 const int TET10_NFACENODES=6;
00052 const int TET10_NFACEINTPTS=3;
00053 const Element::IntegPoint TET10_INTPTS[]=
00054 {{ 0.5854101966249685, 0.1381966011250105, 0.1381966011250105, 0.04166666666666667 },
00055 { 0.1381966011250105, 0.5854101966249685, 0.1381966011250105, 0.04166666666666667 },
00056 { 0.1381966011250105, 0.1381966011250105, 0.5854101966249685, 0.04166666666666667 },
00057 { 0.1381966011250105, 0.1381966011250105, 0.1381966011250105, 0.04166666666666667 }};
00058 const Element::IntegPoint TET10_FACEINTPTS[]=
00059 {{ 0.166666666666667, 0.166666666666667, 0.0, 0.166666666666667 },
00060 { 0.666666666666667, 0.166666666666667, 0.0, 0.166666666666667 },
00061 { 0.166666666666667, 0.666666666666667, 0.0, 0.166666666666667 }};
00062
00063
00064 class Tet10 : public virtual Element
00065 {
00066 friend class FEM::Debug;
00067 public:
00068
00069 Tet10()
00070 {
00071
00072 _n_nodes = TET10_NNODES;
00073 _n_int_pts = TET10_NINTPTS;
00074 _n_face_nodes = TET10_NFACENODES;
00075 _n_face_int_pts = TET10_NFACEINTPTS;
00076
00077
00078 _connects.resize(_n_nodes);
00079
00080
00081 _a_int_pts = TET10_INTPTS;
00082 }
00083
00084 virtual ~Tet10() {}
00085
00086 void Shape (REAL r, REAL s, REAL t, LinAlg::Vector<REAL> & Shape) const;
00087 void Derivs (REAL r, REAL s, REAL t, LinAlg::Matrix<REAL> & Derivs) const;
00088 REAL BoundDistance(REAL r, REAL s, REAL t) const;
00089 int VTKCellType() const { return 24; }
00090 private:
00091 protected:
00092 void _distrib_val_to_face_nodal_vals(Array<Node*> const & FaceConnects,
00093 REAL const FaceValue ,
00094 LinAlg::Vector<REAL> & NodalValues ) const;
00095 void _face_shape (REAL r, REAL s, LinAlg::Vector<REAL> & AFaceShape) const;
00096 void _face_derivs(REAL r, REAL s, LinAlg::Matrix<REAL> & AFaceDerivs) const;
00097 };
00098
00099
00101
00102
00103 inline void Tet10::_distrib_val_to_face_nodal_vals(Array<Node*> const & FaceConnects,
00104 REAL const FaceValue ,
00105 LinAlg::Vector<REAL> & NodalValues ) const
00106 {
00107
00108 NodalValues.Resize(_n_face_nodes);
00109 NodalValues.SetValues(0.0);
00110 LinAlg::Matrix<REAL> J;
00111 LinAlg::Vector<REAL> face_shape(_n_face_nodes);
00112
00113 for (int i=0; i<_n_face_int_pts; i++)
00114 {
00115 REAL r = TET10_FACEINTPTS[i].r;
00116 REAL s = TET10_FACEINTPTS[i].s;
00117 REAL w = TET10_FACEINTPTS[i].w;
00118 _face_shape(r, s, face_shape);
00119 _face_jacobian(FaceConnects, r, s, J);
00120
00121 NodalValues += FaceValue*face_shape*det(J)*w;
00122
00123 }
00124 }
00125
00126 inline void Tet10::_face_shape(REAL r, REAL s, LinAlg::Vector<REAL> & FaceShape) const
00127 {
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 FaceShape.Resize(6);
00141
00142 REAL u = 1.0 - r - s;
00143
00144 FaceShape(0) = u*(2.0*u - 1.0);
00145 FaceShape(1) = r*(2.0*r - 1.0);
00146 FaceShape(2) = s*(2.0*s - 1.0);
00147 FaceShape(3) = 4.0 * r * u;
00148 FaceShape(4) = 4.0 * r * s;
00149 FaceShape(5) = 4.0 * s * u;
00150 }
00151
00152 inline void Tet10::_face_derivs(REAL r, REAL s, LinAlg::Matrix<REAL> & FaceDerivs) const
00153 {
00154
00155
00156
00157
00158
00159
00160
00161 FaceDerivs.Resize(2,6);
00162
00163
00164 FaceDerivs(0,0) = 4.0*r + 4.0*s - 3.0;
00165 FaceDerivs(0,1) = 4.0*r - 1.0;
00166 FaceDerivs(0,2) = 0.0;
00167 FaceDerivs(0,3) = 4.0 - 8.0*r - 4.0*s;
00168 FaceDerivs(0,4) = 4.0*s;
00169 FaceDerivs(0,5) = -4.0*s;
00170
00171
00172 FaceDerivs(1,0) = 4.0*r + 4.0*s - 3.0;
00173 FaceDerivs(1,1) = 0.0;
00174 FaceDerivs(1,2) = 4.0*s - 1.0;
00175 FaceDerivs(1,3) = -4.0*r;
00176 FaceDerivs(1,4) = 4.0*r;
00177 FaceDerivs(1,5) = 4.0 - 8.0*s - 4.0*r;
00178 }
00179
00180 inline void Tet10::Shape(REAL r, REAL s, REAL t, LinAlg::Vector<REAL> & Shape) const
00181 {
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 Shape.Resize(10);
00217
00218 REAL u = 1.0 - r - s - t;
00219
00220
00221 Shape(0) = u*(2.0*u - 1.0);
00222 Shape(1) = r*(2.0*r - 1.0);
00223 Shape(2) = s*(2.0*s - 1.0);
00224 Shape(3) = t*(2.0*t - 1.0);
00225
00226
00227 Shape(4) = 4.0 * u * r;
00228 Shape(5) = 4.0 * r * s;
00229 Shape(6) = 4.0 * s * u;
00230 Shape(7) = 4.0 * u * t;
00231 Shape(8) = 4.0 * r * t;
00232 Shape(9) = 4.0 * s * t;
00233 }
00234
00235 inline void Tet10::Derivs(REAL r, REAL s, REAL t, LinAlg::Matrix<REAL> & Derivs) const
00236 {
00237
00238
00239
00240
00241
00242
00243
00244 Derivs.Resize(3,10);
00245
00246
00247 Derivs(0,0) = 4.0*(r + s + t) - 3.0;
00248 Derivs(0,1) = 4.0*r - 1.0;
00249 Derivs(0,2) = 0.0;
00250 Derivs(0,3) = 0.0;
00251 Derivs(0,4) = 4.0 - 8.0*r - 4.0*s - 4.0*t;
00252 Derivs(0,5) = 4.0*s;
00253 Derivs(0,6) = -4.0*s;
00254 Derivs(0,7) = -4.0*t;
00255 Derivs(0,8) = 4.0*t;
00256 Derivs(0,9) = 0.0;
00257
00258
00259 Derivs(1,0) = 4.0*(r + s + t) - 3.0;
00260 Derivs(1,1) = 0.0;
00261 Derivs(1,2) = 4.0*s - 1.0;
00262 Derivs(1,3) = 0.0;
00263 Derivs(1,4) = -4.0*r;
00264 Derivs(1,5) = 4.0*r;
00265 Derivs(1,6) = 4.0 - 4.0*r - 8.0*s - 4.0*t;
00266 Derivs(1,7) = -4.0*t;
00267 Derivs(1,8) = 0.0;
00268 Derivs(1,9) = 4.0*t;
00269
00270
00271 Derivs(2,0) = 4.0*(r + s + t) - 3.0;
00272 Derivs(2,1) = 0.0;
00273 Derivs(2,2) = 0.0;
00274 Derivs(2,3) = 4.0*t - 1.0;
00275 Derivs(2,4) = -4.0*r;
00276 Derivs(2,5) = 0.0;
00277 Derivs(2,6) = -4.0*s;
00278 Derivs(2,7) = 4.0 - 4.0*r - 4.0*s - 8.0*t;
00279 Derivs(2,8) = 4.0*r;
00280 Derivs(2,9) = 4.0*s;
00281 }
00282
00283 inline REAL Tet10::BoundDistance(REAL r, REAL s, REAL t) const
00284 {
00285 return std::min(std::min(std::min(r, s), t), 1-r-s-t) ;
00286 }
00287
00288 };
00289
00290 #endif // MECHSYS_FEM_TET10_H
00291
00292