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 = getRow(row, true);
00123 
00124   rowvec->addEntry(col, coef);
00125 }
00126 
00127 //-----------------------------------------------------------------
00128 void
00129 FillableMat::putCoef(int row, int col, double coef)
00130 {
00131   FillableVec* rowvec = getRow(row, true);
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 = getRow(row, true);
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 = getRow(row, true);
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 FillableVec*
00177 FillableMat::getRow(int row, bool create_if_not_already_present)
00178 {
00179   feipoolmat::iterator iter = matdata_.lower_bound(row);
00180 
00181   if (iter == matdata_.end() || iter->first != row) {
00182     if (create_if_not_already_present == false) {
00183       throw std::runtime_error("fei::FillableMat: row not found.");
00184     }
00185     else {
00186       iter = insert_row(matdata_, iter, row, vecpool_);
00187     }
00188   }
00189 
00190   return iter->second;
00191 }
00192 
00193 //-----------------------------------------------------------------
00194 void
00195 FillableMat::clear()
00196 {
00197   feipoolmat::iterator
00198     iter = matdata_.begin(), iter_end = matdata_.end();
00199   for(; iter!=iter_end; ++iter) {
00200     vecpool_.destroy(iter->second);
00201     vecpool_.deallocate(iter->second, 1);
00202   }
00203 
00204   matdata_.clear();
00205 }
00206 
00207 //-----------------------------------------------------------------
00208 bool
00209 FillableMat::operator==(const FillableMat& rhs) const
00210 {
00211   if (getNumRows() != rhs.getNumRows()) return false;
00212 
00213   FillableMat::const_iterator
00214     this_it = begin(),
00215     this_end = end();
00216 
00217   FillableMat::const_iterator
00218     rhs_it = rhs.begin(),
00219     rhs_end = rhs.end();
00220 
00221   for(; this_it != this_end; ++this_it, ++rhs_it) {
00222     int this_row = this_it->first;
00223     int rhs_row = rhs_it->first;
00224     if (this_row != rhs_row) return false;
00225 
00226     const FillableVec* this_row_vec = this_it->second;
00227     const FillableVec* rhs_row_vec = rhs_it->second;
00228 
00229     if (*this_row_vec != *rhs_row_vec) return false;
00230   }
00231 
00232   return true;
00233 }
00234 
00235 //-----------------------------------------------------------------
00236 bool
00237 FillableMat::operator!=(const FillableMat& rhs) const
00238 {
00239   return !(*this == rhs);
00240 }
00241 
00242 //-----------------------------------------------------------------
00243 int count_nnz(const FillableMat& mat)
00244 {
00245   int nnz = 0;
00246 
00247   FillableMat::const_iterator
00248     r_iter = mat.begin(),
00249     r_end = mat.end();
00250 
00251   for(; r_iter != r_end; ++r_iter) {
00252     FillableVec* row = r_iter->second;
00253     nnz += row->size();
00254   }
00255 
00256   return nnz;
00257 }
00258 
00259 //-----------------------------------------------------------------
00260 void get_row_numbers(const FillableMat& mat, std::vector<int>& rows)
00261 {
00262   rows.resize(mat.getNumRows());
00263 
00264   FillableMat::const_iterator
00265     m_iter = mat.begin(),
00266     m_end = mat.end();
00267 
00268   size_t offset = 0;
00269   for(; m_iter!=m_end; ++m_iter) {
00270     rows[offset++] = m_iter->first;
00271   }
00272 }
00273 
00274 }//namespace fei
00275 

Generated on Wed May 12 21:30:41 2010 for FEI by  doxygen 1.4.7