|
FEBio
1.5.0
|
00001 // FEElement.h: interface for the FEElement class. 00002 // 00004 00005 #if !defined(AFX_FEELEMENT_H__2EE38101_58E2_4FEB_B214_BB71B6FB15FB__INCLUDED_) 00006 #define AFX_FEELEMENT_H__2EE38101_58E2_4FEB_B214_BB71B6FB15FB__INCLUDED_ 00007 00008 #if _MSC_VER > 1000 00009 #pragma once 00010 #endif // _MSC_VER > 1000 00011 00012 #include "FEElementLibrary.h" 00013 #include "FEElementTraits.h" 00014 #include "FEMaterialPoint.h" 00015 #include "FE_enum.h" 00016 #include "FEException.h" 00017 00018 //----------------------------------------------------------------------------- 00021 class FEElementState 00022 { 00023 public: 00025 FEElementState() {} 00026 00028 ~FEElementState() { Clear(); } 00029 00031 FEElementState(const FEElementState& s); 00032 00034 FEElementState& operator = (const FEElementState& s); 00035 00037 void Clear() { for (size_t i=0; i<m_data.size(); ++i) delete m_data[i]; m_data.clear(); } 00038 00040 void Create(int n) { m_data.assign(n, static_cast<FEMaterialPoint*>(0) ); } 00041 00043 FEMaterialPoint*& operator [] (int n) { return m_data[n]; } 00044 00045 private: 00046 vector<FEMaterialPoint*> m_data; 00047 }; 00048 00049 //----------------------------------------------------------------------------- 00051 00053 00054 class FEElement 00055 { 00056 public: 00057 // default constructor 00058 FEElement() : m_pT(0) 00059 { 00060 static int n = 1; 00061 m_nID = n++; 00062 m_gid = -1; 00063 m_nrigid = -1; 00064 } 00065 00066 virtual ~FEElement() {} 00067 00068 bool IsRigid() { return (m_nrigid >= 0); } 00069 00070 // Set the traits of an element 00071 virtual void SetTraits(FEElementTraits* ptraits) 00072 { 00073 m_pT = ptraits; 00074 m_node.resize(Nodes()); 00075 m_State.Create(GaussPoints()); 00076 } 00077 00078 int GaussPoints() const { return m_pT->nint; } 00079 int Nodes() const { return m_pT->neln; } 00080 00081 double* H(int n) { return m_pT->H[n]; } // shape function values 00082 00083 int Type() const { return m_pT->m_ntype; } 00084 00086 int GetMatID() const { return m_mat; } 00087 00089 void SetMatID(int id) { m_mat = id; } 00090 00092 void SetType(int ntype) 00093 { 00094 FEElementLibrary::SetElementTraits(*this, ntype); 00095 } 00096 /* 00097 bool HasNode(int n) 00098 { 00099 int m = m_node.size(); 00100 for (int i=0; i<m; ++i) if (m[i] == n) return true; 00101 return false; 00102 } 00103 */ 00104 00105 void SetMaterialPointData(FEMaterialPoint* pmp, int n) { m_State[n] = pmp; } 00106 00108 double Evaluate(double* fn, int n) 00109 { 00110 double* Hn = H(n); 00111 double f = 0; 00112 const int N = Nodes(); 00113 for (int i=0; i<N; ++i) f += Hn[i]*fn[i]; 00114 return f; 00115 } 00116 00118 vec3d Evaluate(vec3d* vn, int n) 00119 { 00120 double* Hn = H(n); 00121 vec3d v; 00122 const int N = Nodes(); 00123 for (int i=0; i<N; ++i) v += vn[i]*Hn[i]; 00124 return v; 00125 } 00126 00127 protected: 00128 int m_mat; 00129 00130 public: 00131 00132 int m_nrigid; 00133 int m_nID; 00134 int m_gid; // part ID (i.e. index of domain this element belongs to) 00135 00136 // pointer to element traits 00137 FEElementTraits* m_pT; 00138 00139 vector<int> m_node; 00140 00141 FEElementState m_State; 00142 }; 00143 00144 //----------------------------------------------------------------------------- 00146 00147 class FESolidElement : public FEElement 00148 { 00149 public: 00151 FESolidElement(){} 00152 00154 FESolidElement(const FESolidElement& el); 00155 00157 FESolidElement& operator = (const FESolidElement& el); 00158 00159 double* GaussWeights() { return &((FESolidElementTraits*)(m_pT))->gw[0]; } // weights of integration points 00160 00161 double* Gr(int n) { return ((FESolidElementTraits*)(m_pT))->Gr[n]; } // shape function derivative to r 00162 double* Gs(int n) { return ((FESolidElementTraits*)(m_pT))->Gs[n]; } // shape function derivative to s 00163 double* Gt(int n) { return ((FESolidElementTraits*)(m_pT))->Gt[n]; } // shape function derivative to t 00164 00165 double* Grr(int n) { return ((FESolidElementTraits*)(m_pT))->Grr[n]; } // shape function 2nd derivative to rr 00166 double* Gsr(int n) { return ((FESolidElementTraits*)(m_pT))->Gsr[n]; } // shape function 2nd derivative to sr 00167 double* Gtr(int n) { return ((FESolidElementTraits*)(m_pT))->Gtr[n]; } // shape function 2nd derivative to tr 00168 00169 double* Grs(int n) { return ((FESolidElementTraits*)(m_pT))->Grs[n]; } // shape function 2nd derivative to rs 00170 double* Gss(int n) { return ((FESolidElementTraits*)(m_pT))->Gss[n]; } // shape function 2nd derivative to ss 00171 double* Gts(int n) { return ((FESolidElementTraits*)(m_pT))->Gts[n]; } // shape function 2nd derivative to ts 00172 00173 double* Grt(int n) { return ((FESolidElementTraits*)(m_pT))->Grt[n]; } // shape function 2nd derivative to rt 00174 double* Gst(int n) { return ((FESolidElementTraits*)(m_pT))->Gst[n]; } // shape function 2nd derivative to st 00175 double* Gtt(int n) { return ((FESolidElementTraits*)(m_pT))->Gtt[n]; } // shape function 2nd derivative to tt 00176 00178 void Init(bool bflag) 00179 { 00180 int nint = GaussPoints(); 00181 for (int i=0; i<nint; ++i) m_State[i]->Init(bflag); 00182 } 00183 }; 00184 00185 //----------------------------------------------------------------------------- 00187 00188 class FESurfaceElement : public FEElement 00189 { 00190 public: 00191 FESurfaceElement() { m_nelem = -1; m_lid = -1; } 00192 00193 FESurfaceElement(const FESurfaceElement& el) 00194 { 00195 // set the traits of the element 00196 if (el.m_pT) SetTraits(el.m_pT); 00197 00198 // copy base class data 00199 m_mat = el.m_mat; 00200 m_nrigid = el.m_nrigid; 00201 m_node = el.m_node; 00202 m_nID = el.m_nID; 00203 m_gid = el.m_gid; 00204 m_lid = el.m_lid; 00205 00206 // copy surface element data 00207 m_nelem = el.m_nelem; 00208 m_lnode = el.m_lnode; 00209 } 00210 00211 FESurfaceElement& operator = (const FESurfaceElement& el) 00212 { 00213 // make sure the element type is the same 00214 if (m_pT == 0) SetTraits(el.m_pT); 00215 else assert(m_pT == el.m_pT); 00216 00217 // copy base class data 00218 m_mat = el.m_mat; 00219 m_nrigid = el.m_nrigid; 00220 m_node = el.m_node; 00221 m_nID = el.m_nID; 00222 m_gid = el.m_gid; 00223 m_lid = el.m_lid; 00224 00225 // copy surface element data 00226 m_nelem = el.m_nelem; 00227 m_lnode = el.m_lnode; 00228 00229 return (*this); 00230 } 00231 00232 virtual void SetTraits(FEElementTraits* pt) 00233 { 00234 // we don't allocate state data for surface elements 00235 m_pT = pt; 00236 m_node.resize(Nodes()); 00237 m_lnode.resize(Nodes()); 00238 } 00239 double* GaussWeights() { return &((FESurfaceElementTraits*)(m_pT))->gw[0]; } // weights of integration points 00240 double gr(int n) { return ((FESurfaceElementTraits*)(m_pT))->gr[n]; } // integration point coordinate r 00241 double gs(int n) { return ((FESurfaceElementTraits*)(m_pT))->gs[n]; } // integration point coordinate s 00242 00243 double* Gr(int n) { return ((FESurfaceElementTraits*)(m_pT))->Gr[n]; } // shape function derivative to r 00244 double* Gs(int n) { return ((FESurfaceElementTraits*)(m_pT))->Gs[n]; } // shape function derivative to s 00245 00246 double eval(double* d, int n) 00247 { 00248 double* N = H(n); 00249 int ne = Nodes(); 00250 double a = 0; 00251 for (int i=0; i<ne; ++i) a += N[i]*d[i]; 00252 return a; 00253 } 00254 00255 double eval(double* d, double r, double s) 00256 { 00257 int n = Nodes(); 00258 double H[4]; 00259 shape_fnc(H, r, s); 00260 double a = 0; 00261 for (int i=0; i<n; ++i) a += H[i]*d[i]; 00262 return a; 00263 } 00264 00265 vec3d eval(vec3d* d, double r, double s) 00266 { 00267 int n = Nodes(); 00268 double H[4]; 00269 shape_fnc(H, r, s); 00270 vec3d a(0,0,0); 00271 for (int i=0; i<n; ++i) a += d[i]*H[i]; 00272 return a; 00273 } 00274 00275 vec3d eval(vec3d* d, int n) 00276 { 00277 int ne = Nodes(); 00278 double* N = H(n); 00279 vec3d a(0,0,0); 00280 for (int i=0; i<ne; ++i) a += d[i]*N[i]; 00281 return a; 00282 } 00283 00284 double eval_deriv1(double* d, int j) 00285 { 00286 double* Hr = Gr(j); 00287 int n = Nodes(); 00288 double s = 0; 00289 for (int i=0; i<n; ++i) s += Hr[i]*d[i]; 00290 return s; 00291 } 00292 00293 double eval_deriv2(double* d, int j) 00294 { 00295 double* Hs = Gs(j); 00296 int n = Nodes(); 00297 double s = 0; 00298 for (int i=0; i<n; ++i) s += Hs[i]*d[i]; 00299 return s; 00300 } 00301 00302 double eval_deriv1(double* d, double r, double s) 00303 { 00304 double Hr[4], Hs[4]; 00305 shape_deriv(Hr, Hs, r, s); 00306 int n = Nodes(); 00307 double a = 0; 00308 for (int i=0; i<n; ++i) a += Hr[i]*d[i]; 00309 return a; 00310 } 00311 00312 double eval_deriv2(double* d, double r, double s) 00313 { 00314 double Hr[4], Hs[4]; 00315 shape_deriv(Hr, Hs, r, s); 00316 int n = Nodes(); 00317 double a = 0; 00318 for (int i=0; i<n; ++i) a += Hs[i]*d[i]; 00319 return a; 00320 } 00321 00322 void shape_fnc(double* H, double r, double s) 00323 { 00324 int n = Nodes(); 00325 if (n == 4) 00326 { 00327 H[0] = 0.25*(1-r)*(1-s); 00328 H[1] = 0.25*(1+r)*(1-s); 00329 H[2] = 0.25*(1+r)*(1+s); 00330 H[3] = 0.25*(1-r)*(1+s); 00331 } 00332 else if (n==3) 00333 { 00334 H[0] = 1 - r - s; 00335 H[1] = r; 00336 H[2] = s; 00337 } 00338 else assert(false); 00339 } 00340 00341 void shape_deriv(double* Gr, double* Gs, double r, double s) 00342 { 00343 int n = Nodes(); 00344 if (n == 4) 00345 { 00346 Gr[0] = -0.25*(1-s); Gs[0] = -0.25*(1-r); 00347 Gr[1] = 0.25*(1-s); Gs[1] = -0.25*(1+r); 00348 Gr[2] = 0.25*(1+s); Gs[2] = 0.25*(1+r); 00349 Gr[3] = -0.25*(1+s); Gs[3] = 0.25*(1-r); 00350 } 00351 else if (n == 3) 00352 { 00353 Gr[0] = -1; Gs[0] = -1; 00354 Gr[1] = 1; Gs[1] = 0; 00355 Gr[2] = 0; Gs[2] = 1; 00356 } 00357 else assert(false); 00358 } 00359 00361 void project_to_nodes(double* ai, double* ao) 00362 { 00363 int ni = GaussPoints(); 00364 int ne = Nodes(); 00365 assert(ni == ne); // TODO: for now we assume that the number of nodes equals the nr of gauss-points 00366 matrix& Hi = m_pT->Hi; 00367 for (int i=0; i<ne; ++i) 00368 { 00369 ao[i] = 0; 00370 for (int j=0; j<ni; ++j) ao[i] += Hi[i][j]*ai[j]; 00371 } 00372 } 00373 00374 bool HasNode(int n) 00375 { 00376 int l = Nodes(); 00377 for (int i=0; i<l; ++i) 00378 if (m_node[i] == n) return true; 00379 return false; 00380 } 00381 00382 public: 00383 int m_lid; 00384 int m_nelem; 00385 vector<int> m_lnode; 00386 }; 00387 00388 //----------------------------------------------------------------------------- 00390 00393 00394 class FEShellElement : public FEElement 00395 { 00396 public: 00397 FEShellElement(){} 00398 00400 FEShellElement(const FEShellElement& el); 00401 00403 FEShellElement& operator = (const FEShellElement& el); 00404 00405 virtual void SetTraits(FEElementTraits* ptraits) 00406 { 00407 FEElement::SetTraits(ptraits); 00408 m_h0.resize(Nodes()); 00409 } 00410 00411 double* GaussWeights() { return &((FEShellElementTraits*)(m_pT))->gw[0]; } // weights of integration points 00412 00413 double* Hr(int n) { return ((FEShellElementTraits*)(m_pT))->Hr[n]; } // shape function derivative to r 00414 double* Hs(int n) { return ((FEShellElementTraits*)(m_pT))->Hs[n]; } // shape function derivative to s 00415 00416 void Init(bool bflag) 00417 { 00418 int nint = GaussPoints(); 00419 for (int i=0; i<nint; ++i) m_State[i]->Init(bflag); 00420 } 00421 00422 double gr(int n) { return ((FEShellElementTraits*)(m_pT))->gr[n]; } 00423 double gs(int n) { return ((FEShellElementTraits*)(m_pT))->gs[n]; } 00424 double gt(int n) { return ((FEShellElementTraits*)(m_pT))->gt[n]; } 00425 00426 public: 00427 vector<double> m_h0; 00428 }; 00429 00430 //----------------------------------------------------------------------------- 00431 00432 class FETrussElement : public FEElement 00433 { 00434 public: 00435 FETrussElement(){} 00436 00437 FETrussElement(const FETrussElement& el); 00438 00439 FETrussElement& operator = (const FETrussElement& el); 00440 00442 void Init(bool bflag) 00443 { 00444 m_State[0]->Init(bflag); 00445 } 00446 00447 public: 00448 double m_a0; // cross-sectional area 00449 }; 00450 00451 //----------------------------------------------------------------------------- 00453 00454 class FEDiscreteElement : public FEElement 00455 { 00456 public: 00457 FEDiscreteElement(){} 00458 FEDiscreteElement(const FEDiscreteElement& e); 00459 FEDiscreteElement& operator = (const FEDiscreteElement& e); 00460 }; 00461 00462 #endif // !defined(AFX_FEELEMENT_H__2EE38101_58E2_4FEB_B214_BB71B6FB15FB__INCLUDED_)
1.7.5.1