00001
00012 #ifndef _DOF_MAP_BASSO_H_
00013 #define _DOF_MAP_BASSO_H_
00014
00015
00016
00017
00018
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 }
00313
00314 #endif