00001
00012 #ifndef _FORUMULATION_BASSO_H_
00013 #define _FORUMULATION_BASSO_H_
00014
00015
00016 #include <list>
00017
00018
00019 #include "basso.h"
00020 #include "Element.h"
00021 #include "Node.h"
00022 #include "Material.h"
00023 #include "DofMap.h"
00024 #include "basic_fem_operations.h"
00025
00026 namespace basso {
00027
00028
00036 class Formulation {
00037
00038 public:
00039
00040
00041
00042
00044 Formulation( list< Element > &elem, const Array< Node > &nodes )
00045 {
00046 fDofMap = 0;
00047 fElement = &elem; fNode = &nodes;
00048 mLastElemType = kNONE;
00049 Initialize();
00050 }
00051
00052 virtual ~Formulation() { }
00053
00054
00056 int NumNodes() const { return vect_size(*fNode); }
00057
00059 int NumElements() const { return fElement->size(); }
00060
00062 virtual int NumLocalDofs() const = 0;
00063
00067 virtual void ActivateDofs( DofMap &dofmap );
00068
00072 virtual const Array<Dof> &ActiveDofs() const { return activeLocalDofs; }
00073
00077 virtual void ContributeStiffnessMatrix( DynamicCSRMatrix &K );
00078
00082 virtual void ContributeMassMatrix( DynamicCSRMatrix &M );
00083
00084 protected:
00086 virtual void GetElementStiffnessMatrix( nMatrix &ke, list<Element>::const_iterator eItr );
00087
00089 virtual void GetElementMassMatrix( nMatrix &me, list<Element>::const_iterator eItr );
00090
00092 QuadratureRule::const_iterator QuadratureBegin() const { return mQuadrature.begin(); }
00094 QuadratureRule::const_iterator QuadratureEnd() const { return mQuadrature.end(); }
00095
00097 list<Element>::const_iterator ElementBegin() const { return fElement->begin(); }
00099 list<Element>::const_iterator ElementEnd() const { return fElement->end(); }
00100
00107 virtual Numeric SetDNx( list<Element>::const_iterator eItr, const Point &pt );
00108
00110 void Initialize( ) { }
00111
00118 virtual bool SetElementParameters( list<Element>::const_iterator eItr, int qorder=2 );
00119
00121 virtual Numeric MassFactor() const { return 1.0; }
00122
00124 virtual Numeric StiffnessFactor() const { return 1.0; }
00125
00126 protected:
00127 list< Element > *fElement;
00128 const Array< Node > *fNode;
00129 Array<Dof> activeLocalDofs;
00130
00131 nMatrix mDNxi, mDNx, mCoord;
00132 nArray mNa;
00133 int mNne, mSdim;
00134 QuadratureRule mQuadrature;
00135
00136 DofMap *fDofMap;
00137
00138 BasisType mLastElemType;
00139
00140 };
00141
00142 void Formulation::ActivateDofs( DofMap &dofmap )
00143 {
00144 fDofMap=&dofmap;
00145 list< Element >::const_iterator eItr;
00146 Element::const_iterator nItr;
00147 for ( eItr=this->fElement->begin(); eItr!=this->fElement->end(); ++eItr )
00148 for ( nItr=eItr->begin(); nItr!=eItr->end(); ++nItr )
00149 for ( int s=0; s<NumLocalDofs(); ++s )
00150 fDofMap->AddNodalDof( *nItr, this->activeLocalDofs[s] );
00151 fDofMap->RenumberGlobalDofs();
00152 }
00153
00154 void Formulation::ContributeMassMatrix( DynamicCSRMatrix &M )
00155 {
00156 if ( fDofMap==0 )
00157 {
00158 WarningMessage("Formulation::ContributeMassMatrix","DofMap not set");
00159 return;
00160 }
00161 nMatrix me;
00162
00163 list< Element >::const_iterator eItr;
00164 QuadratureRule::const_iterator qItr;
00165 Element::const_iterator nItr;
00166 for ( eItr=this->fElement->begin(); eItr!=this->fElement->end(); ++eItr )
00167 {
00168 GetElementMassMatrix( me, eItr );
00169 this->fDofMap->Scatter( eItr->Connectivity(), activeLocalDofs, me, M );
00170 }
00171 }
00172
00173 void Formulation::ContributeStiffnessMatrix( DynamicCSRMatrix &K )
00174 {
00175 if ( fDofMap==0 )
00176 {
00177 WarningMessage("Formulation::ContributeStiffnessMatrix","DofMap not set");
00178 return;
00179 }
00180 nMatrix ke;
00181
00182 list< Element >::const_iterator eItr;
00183 QuadratureRule::const_iterator qItr;
00184 Element::const_iterator nItr;
00185 for ( eItr=this->fElement->begin(); eItr!=this->fElement->end(); ++eItr )
00186 {
00187 GetElementStiffnessMatrix( ke, eItr );
00188 this->fDofMap->Scatter( eItr->Connectivity(), activeLocalDofs, ke, K );
00189 }
00190 }
00191
00192 void Formulation::GetElementStiffnessMatrix( nMatrix &ke, list<Element>::const_iterator eItr )
00193 {
00194 SetElementParameters( eItr, 2*(eItr->Order()-1) );
00195 int kdim = eItr->NumNodes()*NumLocalDofs();
00196 resize( ke, kdim, kdim );
00197 clear(ke);
00198 Numeric jac;
00199 QuadratureRule::const_iterator qItr;
00200 for ( qItr=QuadratureBegin(); qItr!=QuadratureEnd(); ++qItr )
00201 {
00202 jac = SetDNx( eItr, qItr->Pt() );
00203 femmult_add( this->mDNx, transposed( this->mDNx ), StiffnessFactor()*jac*qItr->Wt(), ke );
00204 }
00205
00206 }
00207
00208 void Formulation::GetElementMassMatrix( nMatrix &me, list<Element>::const_iterator eItr )
00209 {
00210 SetElementParameters( eItr, 2*(eItr->Order()) );
00211 int mdim = eItr->NumNodes()*NumLocalDofs();
00212 resize( me, mdim, mdim );
00213 clear(me);
00214 Numeric jac;
00215 QuadratureRule::const_iterator qItr;
00216 for ( qItr=QuadratureBegin(); qItr!=QuadratureEnd(); ++qItr )
00217 {
00218 eItr->Na( qItr->Pt(), this->mNa );
00219 eItr->DNa( qItr->Pt(), this->mDNxi );
00220 jac = jacobian( this->mCoord, this->mDNxi );
00221 for ( int I=0; I<mNne; ++I )
00222 for ( int J=0; J<mNne; ++J )
00223 for ( int s=0; s<NumLocalDofs(); ++s )
00224 me( NumLocalDofs()*I+s, NumLocalDofs()*J+s ) += mNa[I]*mNa[J]*MassFactor()*jac*qItr->Wt();
00225 }
00226
00227 }
00228
00229 Numeric Formulation::SetDNx( list<Element>::const_iterator eItr, const Point &pt )
00230 {
00231 nMatrix DNxi( eItr->NumNodes(), eItr->Dimension() );
00232 eItr->DNa( pt, DNxi );
00233 return grad_shape( mCoord, DNxi, mDNx );
00234 }
00235
00236 bool Formulation::SetElementParameters( list<Element>::const_iterator eItr, int qorder )
00237 {
00238 mSdim = eItr->Dimension();
00239 get_element_coordinates( *(this->fNode), mSdim, eItr->Connectivity(), this->mCoord );
00240 if ( mLastElemType == eItr->Type() )
00241 return false;
00242 mNne = eItr->NumNodes();
00243 resize( mDNxi, mNne, mSdim );
00244 resize( mDNx, mNne, mSdim );
00245 resize( mNa, mNne );
00246 resize( mCoord, mNne, mSdim );
00247 eItr->Quadrature( qorder, mQuadrature );
00248 mLastElemType = eItr->Type();
00249 return true;
00250 }
00251
00252 }
00253
00254 #endif
00255
00256