00001
00010 #ifndef _TETRA10_BASIS_BASSO_H_
00011 #define _TETRA10_BASIS_BASSO_H_
00012
00013 #include "basso.h"
00014 #include "Basis.h"
00015 #include "quadrature_rules.h"
00016
00017 namespace basso {
00018
00031 class Tetra10Basis : public Basis {
00032
00033 public:
00034
00035
00036 Tetra10Basis() { }
00037
00038
00039 virtual ~Tetra10Basis() { }
00040
00041
00042 virtual BasisType Type() const { return kTETRA10; }
00043 virtual BasisShape Shape() const { return kTETRAHEDRA; }
00044 virtual int NumNodes() const { return 10; }
00045 virtual int NumEdges() const { return 6; }
00046 virtual int NumFaces() const { return 4; }
00047 virtual int Dimension() const { return 3; }
00048 virtual int Order() const { return 2; }
00049
00050 virtual void ParentCoord( Array< Point > &xi ) const;
00051 virtual Point Centroid() const { return Point( 0.1666666666666666667, 0.1666666666666666667, 0.1666666666666666667 ); }
00052 virtual void NumNodesOnFaces( iArray &nn_face ) const;
00053 virtual void NumNodesOnEdges( iArray &nn_edge ) const;
00054 virtual void NodesOnFace ( int f, iArray &face_nodeids ) const;
00055 virtual void NodesOnEdge ( int e, iArray &edge_nodeids ) const;
00056 virtual void FaceBasisType( Array<BasisType> &face_basis ) const;
00057 virtual void EdgeBasisType( Array< BasisType > &edge_basis ) const;
00058
00059 virtual void Quadrature( int order, QuadratureRule &qrule ) const;
00060
00061 virtual void Na( const Point &p, nArray &shapefunct ) const { shape_tetra10(shapefunct,p.x(),p.y(),p.z()); }
00062 virtual void DNa( const Point &p, nMatrix &gshape ) const { dshape_tetra10(gshape,p.x(),p.y(),p.z()); }
00063 virtual void Na( nArray &shapefunct ) const { Na( Centroid(), shapefunct ); }
00064 virtual void DNa( nMatrix &grad_shape ) const { DNa( Centroid(), grad_shape ); }
00065
00066 private:
00067
00068 };
00069
00070 void Tetra10Basis::ParentCoord( Array< Point > &xi ) const
00071 {
00072 #ifdef ALLOW_DYNAMIC_RESIZE
00073 if ( xi.size()!=NumNodes() )
00074 xi.resize(NumNodes());
00075 #endif
00076 xi[0]=Point(0.0,0.0,0.0);
00077 xi[1]=Point(1.0,0.0,0.0);
00078 xi[2]=Point(0.0,1.0,0.0);
00079 xi[3]=Point(0.0,0.0,1.0);
00080 xi[4]=Point(0.5,0.0,0.0);
00081 xi[5]=Point(0.5,0.5,0.0);
00082 xi[6]=Point(0.0,0.5,0.0);
00083 xi[7]=Point(0.0,0.0,0.5);
00084 xi[8]=Point(0.5,0.0,0.5);
00085 xi[9]=Point(0.0,0.5,0.5);
00086 }
00087
00088 void Tetra10Basis::NumNodesOnFaces( iArray &nn_face ) const
00089 {
00090 #ifdef ALLOW_DYNAMIC_RESIZE
00091 if ( nn_face.size()!=NumEdges() )
00092 nn_face.resize( NumEdges() );
00093 #endif
00094 for ( int i=0; i<NumFaces(); ++i )
00095 nn_face[i]=6;
00096 }
00097
00098 void Tetra10Basis::NumNodesOnEdges( iArray &nn_edge ) const
00099 {
00100 #ifdef ALLOW_DYNAMIC_RESIZE
00101 if ( nn_edge.size()!=NumEdges() )
00102 nn_edge.resize( NumEdges() );
00103 #endif
00104 for ( int i=0; i<NumEdges(); ++i )
00105 nn_edge[i]=3;
00106 }
00107
00108 void Tetra10Basis::NodesOnFace ( int f, iArray &face_nodeids ) const
00109 {
00110 #ifdef ALLOW_DYNAMIC_RESIZE
00111 if ( face_nodeids.size()!=6 )
00112 face_nodeids.resize(6);
00113 #endif
00114 switch (f) {
00115
00116 case 0:
00117 face_nodeids[0]=1; face_nodeids[1]=2; face_nodeids[2]=3;
00118 face_nodeids[3]=5; face_nodeids[4]=9; face_nodeids[5]=8;
00119 break;
00120
00121 case 1:
00122 face_nodeids[0]=3; face_nodeids[1]=2; face_nodeids[2]=0;
00123 face_nodeids[3]=9; face_nodeids[4]=6; face_nodeids[5]=7;
00124 break;
00125
00126 case 2:
00127 face_nodeids[0]=3; face_nodeids[1]=0; face_nodeids[2]=1;
00128 face_nodeids[3]=7; face_nodeids[4]=4; face_nodeids[5]=8;
00129 break;
00130
00131 case 3:
00132 face_nodeids[0]=2; face_nodeids[1]=1; face_nodeids[2]=0;
00133 face_nodeids[3]=5; face_nodeids[4]=4; face_nodeids[5]=6;
00134 break;
00135
00136 default:
00137 WarningMessage("Tetra10Basis::NodesOnFace","face id out of range");
00138 break;
00139
00140 }
00141 }
00142
00143 void Tetra10Basis::NodesOnEdge ( int e, iArray &edge_nodeids ) const
00144 {
00145 #ifdef ALLOW_DYNAMIC_RESIZE
00146 if ( edge_nodeids.size()!=3 )
00147 edge_nodeids.resize(3);
00148 #endif
00149
00150 switch (e) {
00151
00152 case 0:
00153 edge_nodeids[0]=0; edge_nodeids[1]=1; edge_nodeids[2]=4;
00154 break;
00155
00156 case 1:
00157 edge_nodeids[0]=1; edge_nodeids[1]=2; edge_nodeids[2]=5;
00158 break;
00159
00160 case 2:
00161 edge_nodeids[0]=2; edge_nodeids[1]=0; edge_nodeids[2]=6;
00162 break;
00163
00164 case 3:
00165 edge_nodeids[0]=3; edge_nodeids[1]=0; edge_nodeids[2]=7;
00166 break;
00167
00168 case 4:
00169 edge_nodeids[0]=3; edge_nodeids[1]=2; edge_nodeids[2]=9;
00170 break;
00171
00172 case 5:
00173 edge_nodeids[0]=3; edge_nodeids[1]=1; edge_nodeids[2]=8;
00174 break;
00175
00176 default:
00177 WarningMessage("Tetra10Basis::NodesOnFace","face id out of range");
00178 break;
00179
00180 }
00181 }
00182
00183 void Tetra10Basis::FaceBasisType( Array< BasisType > &face_basis ) const
00184 {
00185 #ifdef ALLOW_DYNAMIC_RESIZE
00186 if ( face_basis.size()!=NumFaces() )
00187 face_basis.resize(NumFaces());
00188 #endif
00189 for ( int i=0; i<NumEdges(); ++i )
00190 face_basis[i]=kTRIA6;
00191 }
00192
00193 void Tetra10Basis::EdgeBasisType( Array< BasisType > &edge_basis ) const
00194 {
00195 #ifdef ALLOW_DYNAMIC_RESIZE
00196 if ( edge_basis.size()!=NumEdges() )
00197 edge_basis.resize(NumEdges());
00198 #endif
00199 for ( int i=0; i<NumEdges(); ++i )
00200 edge_basis[i]=kLINE3;
00201 }
00202
00203 void Tetra10Basis::Quadrature( int order, QuadratureRule &qrule ) const
00204 {
00205
00206 int npts;
00207 if ( order<=1 )
00208 npts=1;
00209 else if ( order<=2 )
00210 npts=4;
00211 else if ( order<=3 )
00212 npts=5;
00213 else {
00214 npts=5;
00215 WarningMessage("Tetra10Basis::Quadrature( int order )","quadrature order >3");
00216 }
00217
00218 if ( vect_size(qrule)!=npts )
00219 resize(qrule,npts);
00220
00221 quadrature_tetra( qrule );
00222
00223 }
00224
00225 }
00226
00227 #endif
00228
00229