FEBio  1.5.0
FEBio/FEElement.h
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_)