/Users/jack/Code/basso_dev/inc/DofMap.h

Go to the documentation of this file.
00001 
00012 #ifndef _DOF_MAP_BASSO_H_
00013 #define _DOF_MAP_BASSO_H_
00014 
00015 
00016 // std includes
00017 
00018 // Basso includes
00019 #include "basso.h"
00020 
00021 namespace basso {
00022         
00023         
00031 class DofMap {
00032         
00033 public:
00040         DofMap( int nn=0, int maxnl=0 );
00041         
00049         int GlobalDof( int nid, int localdof ) const { return fDofMap[nid][localdof]; }
00050         
00052         int NumNodes() const { return fDofMap.size(); }
00053         
00055         int NumDof() const { return fNumDof; }
00056 
00058         void Resize( int nn, int nldof=0 ); 
00059 
00065         const iArray &GlobalDofs( int nid ) const { return fDofMap[nid]; }
00066         
00074         void SetScatterVector( const iArray &conn, const Array<Dof> &ldofs, iArray &sctr ) const;
00075 
00076         
00085         void Gather( const iArray &conn, const Array<Dof> &ldofs, 
00086                 const nArray &d, nArray &de ) const;
00087         
00096         void Scatter( const iArray &conn, const Array<Dof> &ldofs, 
00097                 const nMatrix &ke, DynamicCSRMatrix &K ) const;
00098         
00107         void Scatter( const iArray &conn, const Dof &ldofs, 
00108                 const nMatrix &ke, DynamicCSRMatrix &K ) const; 
00109         
00118         void Scatter( const iArray &conn, const Array<Dof> &ldofs, const nArray &fe, nArray &f ) const;
00119 
00121         bool ActiveDof( int nid, int localdof ) const 
00122         { 
00123 #ifdef DOFMAP_EXPLICIT_BOUNDS_CHECK
00124                 if ( nid>NumNodes()-1 )
00125                         return false;
00126                 if ( localdof>fDofMap[nid].size()-1 )
00127                         return false;
00128 #endif
00129                 if ( fDofMap[nid][localdof]<0 )
00130                         return false;
00131                 return true;    
00132         }
00133         
00134                 
00140         void AddNodalDof( int nid, int localdof ); 
00141         
00145         void RenumberGlobalDofs( ); 
00146         
00147         
00148 private:
00149         Array< iArray > fDofMap;
00150         int fNumDof;
00151         
00152 };
00153 
00154 void DofMap::Resize( int nn, int nldof )
00155 { 
00156         int nnOld=vect_size(fDofMap);
00157         resize( fDofMap, nn );
00158         if ( nldof>0 )
00159                 for ( int n=nnOld; n<nn; ++n )
00160                         resize( fDofMap[n], nldof );
00161 }
00162 
00163 void DofMap::Gather( const iArray &conn, const Array<Dof> &ldofs, 
00164         const nArray &d, nArray &de ) const
00165 {
00166 #ifdef DOFMAP_ALLOW_DYNAMIC_RESIZE
00167         if ( de.size()!=conn.size()*ldofs.size() )
00168                 resize( de, conn.size()*ldofs.size() );
00169 #elif DOFMAP_EXPLICIT_BOUNDS_CHECK
00170         if ( de.size()!=conn.size()*ldofs.size()  )
00171                 ErrorMessage("DofMap::Gather","incompatible dimension size of de");
00172 #endif  
00173         iArray::const_iterator nrItr;
00174         Array<Dof>::const_iterator lrItr;
00175         int grdof, lrdof=0;
00176         for ( nrItr=conn.begin(); nrItr!=conn.end(); ++nrItr ) 
00177                 for ( lrItr=ldofs.begin(); lrItr!=ldofs.end(); ++lrItr ) 
00178                 {
00179                         grdof=fDofMap[*nrItr][*lrItr];
00180                         de[ lrdof++ ] = d[ grdof ];
00181                 }       
00182 }
00183 
00184 void DofMap::Scatter( const iArray &conn, const Array<Dof> &ldofs, 
00185         const nArray &fe, nArray &f ) const
00186 {
00187 #ifdef DOFMAP_EXPLICIT_BOUNDS_CHECK
00188         if ( fe.size()!=conn.size()*ldofs.size()  )
00189                 ErrorMessage("DofMap::Scatter","incompatible dimension size of fe");
00190 #endif  
00191         iArray::const_iterator nrItr;
00192         Array<Dof>::const_iterator lrItr;
00193         int grdof, lrdof=0;
00194         for ( nrItr=conn.begin(); nrItr!=conn.end(); ++nrItr ) 
00195                 for ( lrItr=ldofs.begin(); lrItr!=ldofs.end(); ++lrItr ) 
00196                 {
00197                         grdof=fDofMap[*nrItr][*lrItr];
00198                         f[ grdof ] += fe[ lrdof++ ];
00199                 }       
00200 }
00201 
00202 
00203 void DofMap::Scatter( const iArray &conn, const Array<Dof> &ldofs, 
00204                 const nMatrix &ke, DynamicCSRMatrix &K ) const
00205 {
00206 #ifdef DOFMAP_EXPLICIT_BOUNDS_CHECK
00207         if ( mat_nrows(ke)!=conn.size()*ldofs.size() || mat_ncols(ke)!=conn.size()*ldofs.size() )
00208                 ErrorMessage("DofMap::Scatter","incompatible dimension size of ke");
00209 #endif  
00210         iArray::const_iterator nrItr, ncItr;
00211         Array<Dof>::const_iterator lrItr, lcItr;
00212         int grdof, gcdof, lrdof=0, lcdof=0;
00213         for ( nrItr=conn.begin(); nrItr!=conn.end(); ++nrItr ) 
00214                 for ( lrItr=ldofs.begin(); lrItr!=ldofs.end(); ++lrItr ) 
00215                 {
00216                         grdof=fDofMap[*nrItr][*lrItr];
00217                         for ( ncItr=conn.begin(); ncItr!=conn.end(); ++ncItr ) 
00218                                 for ( lcItr=ldofs.begin(); lcItr!=ldofs.end(); ++lcItr )
00219                                 {
00220                                         gcdof=fDofMap[*ncItr][*lcItr];
00221                                         K( grdof, gcdof ) += ke( lrdof, lcdof++ );
00222                                 }
00223                         ++lrdof;
00224                         lcdof=0;
00225                 }
00226 }
00227 
00228 void DofMap::Scatter( const iArray &conn, const Dof &ldof, 
00229                 const nMatrix &ke, DynamicCSRMatrix &K ) const
00230 {
00231 #ifdef DOFMAP_EXPLICIT_BOUNDS_CHECK
00232         if ( mat_nrows(ke)!=conn.size() || mat_ncols(ke)!=conn.size() )
00233                 ErrorMessage("DofMap::Scatter","incompatible dimension size of ke");
00234 #endif  
00235         iArray::const_iterator nrItr, ncItr;
00236         int grdof, gcdof, lrdof=0, lcdof=0;
00237         for ( nrItr=conn.begin(); nrItr!=conn.end(); ++nrItr ) 
00238         {
00239                 grdof=fDofMap[*nrItr][ldof];
00240                 for ( ncItr=conn.begin(); ncItr!=conn.end(); ++ncItr ) 
00241                 {
00242                         gcdof=fDofMap[*ncItr][ldof];
00243                         K( grdof, gcdof ) += ke( lrdof, lcdof++ );
00244                 }
00245                 ++lrdof;
00246                 lcdof=0;
00247         }
00248 }
00249 
00250 void DofMap::SetScatterVector( const iArray &conn, const Array<Dof> &ldofs, iArray &sctr ) const
00251 {
00252 #ifdef DOFMAP_ALLOW_DYNAMIC_RESIZE
00253         if ( sctr.size()!=conn.size()*ldofs.size() )
00254                 resize( sctr, conn.size()*ldofs.size() );
00255 #elif DOFMAP_EXPLICIT_BOUNDS_CHECK
00256         if ( sctr.size()!=conn.size()*ldofs.size() )
00257                 ErrorMessage("DofMap::SetScatterVector","incompatible dimension size of sctr");
00258 #endif
00259         iArray::const_iterator nItr;
00260         Array<Dof>::const_iterator ldofItr;
00261         int n=0;
00262         for ( nItr=conn.begin(); nItr!=conn.end(); ++nItr ) 
00263                 for ( ldofItr=ldofs.begin(); ldofItr!=ldofs.end(); ++ldofItr )
00264                         sctr[n++]=fDofMap[*nItr][*ldofItr];
00265 }
00266 
00267 DofMap::DofMap( int neq, int maxnl ) : fDofMap(neq)
00268 {
00269         fNumDof=0;
00270         for ( int i=0; i<NumNodes(); ++i ) {
00271                 resize(fDofMap[i],maxnl);
00272                 for ( int j=0; j<fDofMap[i].size(); ++j )
00273                         fDofMap[i][j]=-1;
00274         }
00275 }
00276 
00277 void DofMap::RenumberGlobalDofs( )
00278 {
00279         fNumDof=0;
00280         for ( int i=0; i<fDofMap.size(); ++i ) 
00281                 for ( int j=0; j<fDofMap[i].size(); ++j ) 
00282                         if ( ActiveDof(i,j) ) 
00283                                 fDofMap[i][j] = fNumDof++;
00284 }
00285 
00286 void DofMap::AddNodalDof( int nid, int localdof ) 
00287 { 
00288         if ( fDofMap.size()<nid )
00289                 resize( fDofMap, nid );
00290         if ( fDofMap[nid].size()<localdof )
00291                 resize( fDofMap[nid], localdof+1 );
00292         if ( !ActiveDof(nid,localdof) )
00293                 fDofMap[nid][localdof] = fNumDof++;
00294 }
00295 
00296 std::ostream &operator << ( std::ostream &out, const DofMap &dmap )
00297 {
00298         out << "DofMap: " << dmap.NumNodes()  << " nodes " << dmap.NumDof() << " dofs";
00299  
00300         for ( int i=0; i<dmap.NumNodes(); ++i ) 
00301         {
00302                 cout << "\n" << i << " { ";
00303                 for ( int s=0; s<dmap.GlobalDofs(i).size(); ++s )
00304                         if ( dmap.ActiveDof(i,s) )
00305                                 cout << dmap.GlobalDof(i,s) << " ";
00306                 cout << "}";
00307         }
00308         
00309         return out;
00310 }
00311 
00312 } // end of namespace
00313 
00314 #endif

Generated on Sat Jan 19 09:03:57 2008 for Basso by  doxygen 1.5.2