00001
00012 #ifndef _SOLVER_BASSO_H_
00013 #define _SOLVER_BASSO_H_
00014
00015 #include "basso.h"
00016
00017 namespace basso {
00018
00024 template < class KMAT >
00025 class Solver {
00026
00027 public:
00028
00029 typedef KMAT matrix_type;
00030
00031 Solver( KMAT &K, nArray &f )
00032 { Kptr=&K; fptr=&f;
00033 wt=mat_trace(K)/static_cast<Numeric>(f.size());
00034 solved=false;
00035 }
00036
00038 int NumEquations() const { return fptr->size(); }
00039
00043 virtual int Solve( nArray &d ) = 0;
00044
00046 template < class INDX >
00047 int SolveConstrained( nArray &d, INDX &ifix );
00048
00050 int SolveConstrained( nArray &d, iArray &ifix, nArray &ival );
00051
00054 virtual void GetReactionForces( const nArray &d, nArray &freac )
00055 { mult( Kreac, d, freac ); }
00056
00058 bool Solved() const { return solved; }
00059
00060 protected:
00061
00063 template < class INDX >
00064 void GetReactionMatrix( const INDX &ifix );
00065
00067 template < class INDX >
00068 void SetConstraintsOnMatrix( const INDX &ifix );
00069
00071 template < class INDX >
00072 void SetConstraintsOnF( const INDX &ifix );
00073
00075 template < class INDX >
00076 void SetConstraintsOnF( const INDX &ifix, nArray &ival );
00077
00078 protected:
00079 KMAT *Kptr;
00080 nArray *fptr;
00081 KMAT Kreac;
00082 Numeric wt;
00083 bool solved;
00084 };
00085
00086
00087 template < class KMAT> template< class INDX >
00088 void Solver<KMAT>::GetReactionMatrix( const INDX &ifix )
00089 {
00090 int nc=ifix.size(), ndof=mat_nrows(*Kptr);
00091
00092
00093 if ( mat_nrows(Kreac)!=nc || mat_ncols(Kreac)!=ndof )
00094 resize( Kreac, nc, ndof );
00095 typename INDX::const_iterator ifixItr;
00096 int i=0;
00097 for ( ifixItr=ifix.begin(); ifixItr!=ifix.end(); ++ifixItr, ++i ) {
00098 int ii=*ifixItr;
00099 copy ( sub_matrix(*Kptr,sub_interval(ii,1),sub_interval(0,ndof)),
00100 sub_matrix(Kreac,sub_interval(i,1), sub_interval(0,ndof)) );
00101 }
00102 }
00103
00104 template < class KMAT> template< class INDX >
00105 void Solver<KMAT>::SetConstraintsOnMatrix( const INDX &ifix )
00106 {
00107
00108 typename INDX::const_iterator ifixItr;
00109 for ( ifixItr=ifix.begin(); ifixItr!=ifix.end(); ++ifixItr )
00110 {
00111 int ii=*ifixItr;
00112 (*Kptr)(ii,ii)=wt;
00113 for ( int jj=0; jj<NumEquations(); ++jj )
00114 if ( ii != jj)
00115 {
00116 (*Kptr)(ii,jj)=0.0;
00117 (*Kptr)(jj,ii)=0.0;
00118 }
00119 }
00120 }
00121
00122 template < class KMAT> template< class INDX >
00123 void Solver<KMAT>::SetConstraintsOnF( const INDX &ifix )
00124 {
00125 typename INDX::const_iterator ifixItr;
00126 for ( ifixItr=ifix.begin(); ifixItr!=ifix.end(); ++ifixItr )
00127 (*fptr)[*ifixItr]=0.0;
00128 }
00129
00130 template < class KMAT> template< class INDX >
00131 void Solver<KMAT>::SetConstraintsOnF( const INDX &ifix, nArray &ival )
00132 {
00133
00134 mult_add( sub_matrix( *Kptr, sub_interval(0,NumEquations()), sub_index(ifix) ),
00135 scaled(ival,-1.0), *fptr );
00136 typename INDX::const_iterator ifixItr;
00137 int i=0;
00138 for ( ifixItr=ifix.begin(); ifixItr!=ifix.end(); ++ifixItr, ++i )
00139 (*fptr)[*ifixItr]=ival[i]*wt;
00140 }
00141
00142 template < class KMAT> template< class INDX >
00143 int Solver<KMAT>::SolveConstrained( nArray &d, INDX &ifix )
00144 {
00145 GetReactionMatrix( ifix );
00146 SetConstraintsOnMatrix( ifix );
00147 SetConstraintsOnF( ifix );
00148 return Solve(d);
00149 }
00150
00151 template < class KMAT>
00152 int Solver<KMAT>::SolveConstrained( nArray &d, iArray &ifix, nArray &ival )
00153 {
00154 GetReactionMatrix( ifix );
00155 SetConstraintsOnMatrix( ifix, ival );
00156 SetConstraintsOnF( ifix, ival );
00157 return Solve(d);
00158 }
00159
00160 }
00161
00162 #endif