FEI Version of the Day
fei_FillableMat.cpp
00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #include <fei_FillableMat.hpp>
00010 #include <fei_EqnBuffer.hpp>
00011 #include <fei_CSVec.hpp>
00012 
00013 namespace fei {
00014 
00015 //-----------------------------------------------------------------
00016 FillableMat::FillableMat()
00017  : matdata_(),
00018    vecpool_()
00019 {
00020 }
00021 
00022 //-----------------------------------------------------------------
00023 FillableMat::FillableMat(EqnBuffer& eqnbuf)
00024  : matdata_(),
00025    vecpool_()
00026 {
00027   std::vector<int>& eqnNums = eqnbuf.eqnNumbers();
00028   int numEqns = eqnNums.size();
00029   std::vector<fei::CSVec*>& eqns = eqnbuf.eqns();
00030 
00031   for(int i=0; i<numEqns; ++i) {
00032     int row = eqnNums[i];
00033     fei::CSVec* row_vec = eqns[i];
00034     int rowlen = row_vec->size();
00035     int* indices = &(row_vec->indices()[0]);
00036     double* coefs = &(row_vec->coefs()[0]);
00037 
00038     for(int j=0; j<rowlen; ++j) {
00039       putCoef(row, indices[j], coefs[j]);
00040     }
00041   }
00042 }
00043 
00044 //-----------------------------------------------------------------
00045 FillableMat::~FillableMat()
00046 {
00047   feipoolmat::iterator
00048     iter = matdata_.begin(), iter_end = matdata_.end();
00049   for(; iter!=iter_end; ++iter) {
00050     vecpool_.destroy(iter->second);
00051     vecpool_.deallocate(iter->second, 1);
00052   }
00053 }
00054 
00055 //-----------------------------------------------------------------
00056 FillableMat&
00057 FillableMat::operator=(const FillableMat& src)
00058 {
00059   clear();
00060 
00061   FillableMat::const_iterator
00062     s_iter = src.begin(),
00063     s_end = src.end();
00064 
00065   for(; s_iter != s_end; ++s_iter) {
00066     int row = s_iter->first;
00067     const FillableVec* srow = s_iter->second;
00068 
00069     FillableVec::const_iterator
00070       r_iter = srow->begin(),
00071       r_end = srow->end();
00072 
00073     for(; r_iter != r_end; ++r_iter) {
00074       int col = r_iter->first;
00075       double coef = r_iter->second;
00076 
00077       putCoef(row, col, coef);
00078     }
00079   }
00080 
00081   return *this;
00082 }
00083 
00084 //-----------------------------------------------------------------
00085 void
00086 FillableMat::setValues(double value)
00087 {
00088   feipoolmat::iterator
00089     iter = matdata_.begin(), iter_end = matdata_.end();
00090 
00091   for(; iter != iter_end; ++iter) {
00092     iter->second->setValues(value);
00093   }
00094 }
00095 
00096 //-----------------------------------------------------------------
00097 void
00098 FillableMat::createPosition(int row, int col)
00099 {
00100   sumInCoef(row, col, 0.0);
00101 }
00102 
00103 //-----------------------------------------------------------------
00104 FillableMat::feipoolmat::iterator
00105 insert_row(FillableMat::feipoolmat& matdata,
00106            FillableMat::feipoolmat::iterator iter,
00107            int row,
00108            fei_Pool_alloc<FillableVec>& vecpool)
00109 {
00110   static FillableVec dummy;
00111 
00112   FillableVec* vptr = vecpool.allocate(1);
00113   vecpool.construct(vptr, dummy);
00114 
00115   return matdata.insert(iter, std::make_pair(row, vptr));
00116 }
00117 
00118 //-----------------------------------------------------------------
00119 void
00120 FillableMat::sumInCoef(int row, int col, double coef)
00121 {
00122   FillableVec* rowvec = create_or_getRow(row);
00123 
00124   rowvec->addEntry(col, coef);
00125 }
00126 
00127 //-----------------------------------------------------------------
00128 void
00129 FillableMat::putCoef(int row, int col, double coef)
00130 {
00131   FillableVec* rowvec = create_or_getRow(row);
00132 
00133   rowvec->putEntry(col, coef);
00134 }
00135 
00136 //-----------------------------------------------------------------
00137 void
00138 FillableMat::sumInRow(int row, const int* cols, const double* coefs,
00139                       unsigned len)
00140 {
00141   FillableVec* rowvec = create_or_getRow(row);
00142 
00143   for(unsigned i=0; i<len; ++i) {
00144     rowvec->addEntry(cols[i], coefs[i]);
00145   }
00146 }
00147 
00148 //-----------------------------------------------------------------
00149 void
00150 FillableMat::putRow(int row, const int* cols, const double* coefs,
00151                     unsigned len)
00152 {
00153   FillableVec* rowvec = create_or_getRow(row);
00154 
00155   for(unsigned i=0; i<len; ++i) {
00156     rowvec->putEntry(cols[i], coefs[i]);
00157   }
00158 }
00159 
00160 //-----------------------------------------------------------------
00161 unsigned
00162 FillableMat::getNumRows() const
00163 {
00164   return matdata_.size();
00165 }
00166 
00167 //-----------------------------------------------------------------
00168 bool
00169 FillableMat::hasRow(int row) const
00170 {
00171   feipoolmat::const_iterator iter = matdata_.find(row);
00172   return iter != matdata_.end();
00173 }
00174 
00175 //-----------------------------------------------------------------
00176 const FillableVec*
00177 FillableMat::getRow(int row) const
00178 {
00179   feipoolmat::const_iterator iter = matdata_.lower_bound(row);
00180 
00181   if (iter == matdata_.end() || iter->first != row) {
00182     throw std::runtime_error("fei::FillableMat: row not found.");
00183   }
00184 
00185   return iter->second;
00186 }
00187 
00188 //-----------------------------------------------------------------
00189 FillableVec*
00190 FillableMat::create_or_getRow(int row)
00191 {
00192   feipoolmat::iterator iter = matdata_.lower_bound(row);
00193 
00194   if (iter == matdata_.end() || iter->first != row) {
00195     iter = insert_row(matdata_, iter, row, vecpool_);
00196   }
00197 
00198   return iter->second;
00199 }
00200 
00201 //-----------------------------------------------------------------
00202 void
00203 FillableMat::clear()
00204 {
00205   feipoolmat::iterator
00206     iter = matdata_.begin(), iter_end = matdata_.end();
00207   for(; iter!=iter_end; ++iter) {
00208     vecpool_.destroy(iter->second);
00209     vecpool_.deallocate(iter->second, 1);
00210   }
00211 
00212   matdata_.clear();
00213 }
00214 
00215 //-----------------------------------------------------------------
00216 bool
00217 FillableMat::operator==(const FillableMat& rhs) const
00218 {
00219   if (getNumRows() != rhs.getNumRows()) return false;
00220 
00221   FillableMat::const_iterator
00222     this_it = begin(),
00223     this_end = end();
00224 
00225   FillableMat::const_iterator
00226     rhs_it = rhs.begin(),
00227     rhs_end = rhs.end();
00228 
00229   for(; this_it != this_end; ++this_it, ++rhs_it) {
00230     int this_row = this_it->first;
00231     int rhs_row = rhs_it->first;
00232     if (this_row != rhs_row) return false;
00233 
00234     const FillableVec* this_row_vec = this_it->second;
00235     const FillableVec* rhs_row_vec = rhs_it->second;
00236 
00237     if (*this_row_vec != *rhs_row_vec) return false;
00238   }
00239 
00240   return true;
00241 }
00242 
00243 //-----------------------------------------------------------------
00244 bool
00245 FillableMat::operator!=(const FillableMat& rhs) const
00246 {
00247   return !(*this == rhs);
00248 }
00249 
00250 //-----------------------------------------------------------------
00251 void print(std::ostream& os, const FillableMat& mat)
00252 {
00253   FillableMat::const_iterator
00254     irow = mat.begin(), irowend = mat.end();
00255   for(; irow!=irowend; ++irow) {
00256     int row = irow->first;
00257     const FillableVec* vec = irow->second;
00258     os << "row " << row << ": ";
00259     FillableVec::const_iterator
00260       ivec = vec->begin(), ivecend = vec->end();
00261     for(; ivec!=ivecend; ++ivec) {
00262       os << "("<<ivec->first<<","<<ivec->second<<") ";
00263     }
00264     os << std::endl;
00265   }
00266 }
00267 
00268 //-----------------------------------------------------------------
00269 int count_nnz(const FillableMat& mat)
00270 {
00271   int nnz = 0;
00272 
00273   FillableMat::const_iterator
00274     r_iter = mat.begin(),
00275     r_end = mat.end();
00276 
00277   for(; r_iter != r_end; ++r_iter) {
00278     FillableVec* row = r_iter->second;
00279     nnz += row->size();
00280   }
00281 
00282   return nnz;
00283 }
00284 
00285 //-----------------------------------------------------------------
00286 void get_row_numbers(const FillableMat& mat, std::vector<int>& rows)
00287 {
00288   rows.resize(mat.getNumRows());
00289 
00290   FillableMat::const_iterator
00291     m_iter = mat.begin(),
00292     m_end = mat.end();
00293 
00294   size_t offset = 0;
00295   for(; m_iter!=m_end; ++m_iter) {
00296     rows[offset++] = m_iter->first;
00297   }
00298 }
00299 
00300 }//namespace fei
00301 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends