00001
00012 #ifndef _TRACTION_BC_BASSO_H_
00013 #define _TRACTION_BC_BASSO_H_
00014
00015
00016 #include <list>
00017
00018
00019 #include "basso.h"
00020 #include "NeumannBC.h"
00021 #include "basic_fem_operations.h"
00022 #include "geometry.h"
00023
00024 namespace basso {
00025
00026
00031 class TractionBC : public NeumannBC {
00032
00033 public:
00034
00035
00036
00037
00046 TractionBC ( list< Element > &elem, const Array< Node > &nodes,
00047 const Array<Dof> &dofs, const nArray &n, Numeric sf=1.0 ) : NeumannBC ( dofs, sf )
00048 { fElement=&elem; fNode=&nodes; mDirection=n; }
00049
00056 TractionBC ( list< Element > &elem, const Array< Node > &nodes,
00057 const Dof &ldof, Numeric sf=1.0 ) : NeumannBC ( ldof, sf ), mDirection(1)
00058 { fElement=&elem; fNode=&nodes; mDirection[0]=1.0; }
00059
00060
00061 virtual ~TractionBC() { }
00062
00063
00064
00065
00066 virtual void ContributeForce( const DofMap &dofmap, nArray &f );
00067
00068 protected:
00069 virtual Numeric Jacobian( list<Element>::const_iterator eItr, const Point &pt );
00070 virtual void GetElementForce( list<Element>::const_iterator eItr, nArray &fe );
00071 virtual void GetElementForceLine2( list<Element>::const_iterator eItr, nArray &fe );
00072 virtual void GetElementForceTria3( list<Element>::const_iterator eItr, nArray &fe );
00073 virtual bool SetElementParameters( list<Element>::const_iterator eItr, int qorder );
00074
00076 QuadratureRule::const_iterator QuadratureBegin() const { return mQuadrature.begin(); }
00078 QuadratureRule::const_iterator QuadratureEnd() const { return mQuadrature.end(); }
00079
00081 list<Element>::const_iterator ElementBegin() const { return fElement->begin(); }
00083 list<Element>::const_iterator ElementEnd() const { return fElement->end(); }
00084
00085 protected:
00086
00088 nArray mDirection;
00090 list< Element > *fElement;
00092 const Array< Node > *fNode;
00093
00095 nMatrix mCoord, mDNxi;
00097 nArray mNa;
00099 int mNne, mSdim, mEdim;
00101 QuadratureRule mQuadrature;
00102
00104 BasisType mLastElemType;
00105 };
00106
00107
00108 void TractionBC::GetElementForceLine2( list<Element>::const_iterator eItr, nArray &fe )
00109 {
00110 int n0=eItr->NodeId(0), n1=eItr->NodeId(1);
00111 Numeric le = dist( Point( (*(this->fNode))[n1] ), Point( (*(this->fNode))[n0] ) );
00112 int i=0;
00113 for ( int n=0; n<2; ++n )
00114 for ( int d=0; d<this->mDofs.size(); ++d )
00115 fe[i++] = 0.5*le*(this->mScaleFactor)*(this->mDirection[d]);
00116 }
00117
00118 void TractionBC::GetElementForceTria3( list<Element>::const_iterator eItr, nArray &fe )
00119 {
00120 int n0=eItr->NodeId(0), n1=eItr->NodeId(1), n2=eItr->NodeId(2);
00121 Numeric ae = area_triangle( Point( (*(this->fNode))[n0] ),
00122 Point( (*(this->fNode))[n1] ), Point( (*(this->fNode))[n2] ) );
00123 int i=0;
00124 for ( int n=0; n<3; ++n )
00125 for ( int d=0; d<this->mDofs.size(); ++d )
00126 fe[i++] = 0.3333333333333333333333*ae*(this->mScaleFactor)*(this->mDirection[d]);
00127 }
00128
00129 void TractionBC::GetElementForce( list<Element>::const_iterator eItr, nArray &fe )
00130 {
00131
00132 int fdim = eItr->NumNodes()*(this->mDofs.size());
00133 resize( fe, fdim );
00134 clear(fe);
00135
00136 if ( eItr->Type() == kLINE2 )
00137 {
00138 GetElementForceLine2( eItr, fe );
00139 return;
00140 }
00141 else if ( eItr->Type() == kTRIA3 )
00142 {
00143 GetElementForceTria3( eItr, fe );
00144 return;
00145 }
00146
00147 SetElementParameters( eItr, eItr->Order() );
00148 Numeric jac;
00149 QuadratureRule::const_iterator qItr;
00150 for ( qItr=QuadratureBegin(); qItr!=QuadratureEnd(); ++qItr )
00151 {
00152 jac = Jacobian( eItr, qItr->Pt() );
00153 int i=0;
00154 for ( int n=0; n<mNne; ++n )
00155 for ( int d=0; d<this->mDofs.size(); ++d )
00156 fe[i++] += (this->mNa[n])*(this->mScaleFactor)*(this->mDirection[d]);
00157 }
00158
00159 }
00160
00161 void TractionBC::ContributeForce( const DofMap &dofmap, nArray &f )
00162 {
00163 nArray fe;
00164 list< Element >::const_iterator eItr;
00165 Element::const_iterator nItr;
00166
00167 for ( eItr=ElementBegin(); eItr!=ElementEnd(); ++eItr )
00168 {
00169 GetElementForce( eItr, fe );
00170 dofmap.Scatter( eItr->Connectivity(), this->mDofs, fe, f );
00171 }
00172 }
00173
00174 Numeric TractionBC::Jacobian( list<Element>::const_iterator eItr, const Point &pt )
00175 {
00176 eItr->DNa( pt, mDNxi );
00177 if ( mEdim==1 )
00178 return jacobian13( mCoord, mDNxi );
00179 else
00180 return jacobian23( mCoord, mDNxi );
00181 }
00182
00183 bool TractionBC::SetElementParameters( list<Element>::const_iterator eItr, int qorder )
00184 {
00185 mSdim = 3;
00186 mEdim = eItr->Dimension();
00187 get_element_coordinates( *(this->fNode), mSdim, eItr->Connectivity(), this->mCoord );
00188 if ( mLastElemType == eItr->Type() )
00189 return false;
00190 mNne = eItr->NumNodes();
00191 resize( mDNxi, mNne, mEdim );
00192 resize( mNa, mNne );
00193 resize( mCoord, mNne, mSdim );
00194 eItr->Quadrature( qorder, mQuadrature );
00195 mLastElemType = eItr->Type();
00196 return true;
00197 }
00198
00199
00200 }
00201
00202 #endif
00203
00204