FEI Version of the Day
fei_FillableMat.cpp
00001 /*
00002 // @HEADER
00003 // ************************************************************************
00004 //             FEI: Finite Element Interface to Linear Solvers
00005 //                  Copyright (2005) Sandia Corporation.
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the
00008 // U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Alan Williams (william@sandia.gov) 
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 */
00042 
00043 
00044 #include <fei_FillableMat.hpp>
00045 #include <fei_EqnBuffer.hpp>
00046 #include <fei_CSVec.hpp>
00047 
00048 namespace fei {
00049 
00050 //-----------------------------------------------------------------
00051 FillableMat::FillableMat()
00052  : matdata_(),
00053    vecpool_()
00054 {
00055 }
00056 
00057 //-----------------------------------------------------------------
00058 FillableMat::FillableMat(EqnBuffer& eqnbuf)
00059  : matdata_(),
00060    vecpool_()
00061 {
00062   std::vector<int>& eqnNums = eqnbuf.eqnNumbers();
00063   int numEqns = eqnNums.size();
00064   std::vector<fei::CSVec*>& eqns = eqnbuf.eqns();
00065 
00066   for(int i=0; i<numEqns; ++i) {
00067     int row = eqnNums[i];
00068     fei::CSVec* row_vec = eqns[i];
00069     int rowlen = row_vec->size();
00070     int* indices = &(row_vec->indices()[0]);
00071     double* coefs = &(row_vec->coefs()[0]);
00072 
00073     for(int j=0; j<rowlen; ++j) {
00074       putCoef(row, indices[j], coefs[j]);
00075     }
00076   }
00077 }
00078 
00079 //-----------------------------------------------------------------
00080 FillableMat::~FillableMat()
00081 {
00082   feipoolmat::iterator
00083     iter = matdata_.begin(), iter_end = matdata_.end();
00084   for(; iter!=iter_end; ++iter) {
00085     vecpool_.destroy(iter->second);
00086     vecpool_.deallocate(iter->second, 1);
00087   }
00088 }
00089 
00090 //-----------------------------------------------------------------
00091 FillableMat&
00092 FillableMat::operator=(const FillableMat& src)
00093 {
00094   clear();
00095 
00096   FillableMat::const_iterator
00097     s_iter = src.begin(),
00098     s_end = src.end();
00099 
00100   for(; s_iter != s_end; ++s_iter) {
00101     int row = s_iter->first;
00102     const CSVec* srow = s_iter->second;
00103     const std::vector<int>& s_ind = srow->indices();
00104     const std::vector<double>& s_coef = srow->coefs();
00105 
00106     for(size_t i=0; i<s_ind.size(); ++i) {
00107       int col = s_ind[i];
00108       double coef = s_coef[i];
00109 
00110       putCoef(row, col, coef);
00111     }
00112   }
00113 
00114   return *this;
00115 }
00116 
00117 //-----------------------------------------------------------------
00118 void
00119 FillableMat::setValues(double value)
00120 {
00121   feipoolmat::iterator
00122     iter = matdata_.begin(), iter_end = matdata_.end();
00123 
00124   for(; iter != iter_end; ++iter) {
00125     set_values(*(iter->second), value);
00126   }
00127 }
00128 
00129 //-----------------------------------------------------------------
00130 void
00131 FillableMat::createPosition(int row, int col)
00132 {
00133   sumInCoef(row, col, 0.0);
00134 }
00135 
00136 //-----------------------------------------------------------------
00137 FillableMat::feipoolmat::iterator
00138 insert_row(FillableMat::feipoolmat& matdata,
00139            FillableMat::feipoolmat::iterator iter,
00140            int row,
00141            fei_Pool_alloc<CSVec>& vecpool)
00142 {
00143   static CSVec dummy;
00144 
00145   CSVec* vptr = vecpool.allocate(1);
00146   vecpool.construct(vptr, dummy);
00147 
00148   if (vptr->indices().capacity() == 0) {
00149     vptr->indices().reserve(16);
00150     vptr->coefs().reserve(16);
00151   }
00152 
00153   return matdata.insert(iter, std::make_pair(row, vptr));
00154 }
00155 
00156 //-----------------------------------------------------------------
00157 void
00158 FillableMat::sumInCoef(int row, int col, double coef)
00159 {
00160   CSVec* rowvec = create_or_getRow(row);
00161 
00162   add_entry(*rowvec, col, coef);
00163 }
00164 
00165 //-----------------------------------------------------------------
00166 void
00167 FillableMat::putCoef(int row, int col, double coef)
00168 {
00169   CSVec* rowvec = create_or_getRow(row);
00170 
00171   put_entry(*rowvec, col, coef);
00172 }
00173 
00174 //-----------------------------------------------------------------
00175 void
00176 FillableMat::sumInRow(int row, const int* cols, const double* coefs,
00177                       unsigned len)
00178 {
00179   CSVec* rowvec = create_or_getRow(row);
00180 
00181   for(unsigned i=0; i<len; ++i) {
00182     add_entry(*rowvec, cols[i], coefs[i]);
00183   }
00184 }
00185 
00186 //-----------------------------------------------------------------
00187 void
00188 FillableMat::putRow(int row, const int* cols, const double* coefs,
00189                     unsigned len)
00190 {
00191   CSVec* rowvec = create_or_getRow(row);
00192 
00193   for(unsigned i=0; i<len; ++i) {
00194     put_entry(*rowvec, cols[i], coefs[i]);
00195   }
00196 }
00197 
00198 //-----------------------------------------------------------------
00199 unsigned
00200 FillableMat::getNumRows() const
00201 {
00202   return matdata_.size();
00203 }
00204 
00205 //-----------------------------------------------------------------
00206 bool
00207 FillableMat::hasRow(int row) const
00208 {
00209   feipoolmat::const_iterator iter = matdata_.find(row);
00210   return iter != matdata_.end();
00211 }
00212 
00213 //-----------------------------------------------------------------
00214 const CSVec*
00215 FillableMat::getRow(int row) const
00216 {
00217   feipoolmat::const_iterator iter = matdata_.lower_bound(row);
00218 
00219   if (iter == matdata_.end() || iter->first != row) {
00220     throw std::runtime_error("fei::FillableMat: row not found.");
00221   }
00222 
00223   return iter->second;
00224 }
00225 
00226 //-----------------------------------------------------------------
00227 CSVec*
00228 FillableMat::create_or_getRow(int row)
00229 {
00230   feipoolmat::iterator iter = matdata_.lower_bound(row);
00231 
00232   if (iter == matdata_.end() || iter->first != row) {
00233     iter = insert_row(matdata_, iter, row, vecpool_);
00234   }
00235 
00236   return iter->second;
00237 }
00238 
00239 //-----------------------------------------------------------------
00240 void
00241 FillableMat::clear()
00242 {
00243   feipoolmat::iterator
00244     iter = matdata_.begin(), iter_end = matdata_.end();
00245   for(; iter!=iter_end; ++iter) {
00246     vecpool_.destroy(iter->second);
00247     vecpool_.deallocate(iter->second, 1);
00248   }
00249 
00250   matdata_.clear();
00251 }
00252 
00253 //-----------------------------------------------------------------
00254 bool
00255 FillableMat::operator==(const FillableMat& rhs) const
00256 {
00257   if (getNumRows() != rhs.getNumRows()) return false;
00258 
00259   FillableMat::const_iterator
00260     this_it = begin(),
00261     this_end = end();
00262 
00263   FillableMat::const_iterator
00264     rhs_it = rhs.begin(),
00265     rhs_end = rhs.end();
00266 
00267   for(; this_it != this_end; ++this_it, ++rhs_it) {
00268     int this_row = this_it->first;
00269     int rhs_row = rhs_it->first;
00270     if (this_row != rhs_row) return false;
00271 
00272     const CSVec* this_row_vec = this_it->second;
00273     const CSVec* rhs_row_vec = rhs_it->second;
00274 
00275     if (*this_row_vec != *rhs_row_vec) return false;
00276   }
00277 
00278   return true;
00279 }
00280 
00281 //-----------------------------------------------------------------
00282 bool
00283 FillableMat::operator!=(const FillableMat& rhs) const
00284 {
00285   return !(*this == rhs);
00286 }
00287 
00288 //-----------------------------------------------------------------
00289 void print(std::ostream& os, const FillableMat& mat)
00290 {
00291   FillableMat::const_iterator
00292     irow = mat.begin(), irowend = mat.end();
00293   for(; irow!=irowend; ++irow) {
00294     int row = irow->first;
00295     const CSVec* vec = irow->second;
00296     const std::vector<int>& v_ind = vec->indices();
00297     const std::vector<double>& v_coef = vec->coefs();
00298     os << "row " << row << ": ";
00299     for(size_t i=0; i<v_ind.size(); ++i) {
00300       os << "("<<v_ind[i]<<","<<v_coef[i]<<") ";
00301     }
00302     os << std::endl;
00303   }
00304 }
00305 
00306 //-----------------------------------------------------------------
00307 int count_nnz(const FillableMat& mat)
00308 {
00309   int nnz = 0;
00310 
00311   FillableMat::const_iterator
00312     r_iter = mat.begin(),
00313     r_end = mat.end();
00314 
00315   for(; r_iter != r_end; ++r_iter) {
00316     CSVec* row = r_iter->second;
00317     nnz += row->size();
00318   }
00319 
00320   return nnz;
00321 }
00322 
00323 //-----------------------------------------------------------------
00324 void get_row_numbers(const FillableMat& mat, std::vector<int>& rows)
00325 {
00326   rows.resize(mat.getNumRows());
00327 
00328   FillableMat::const_iterator
00329     m_iter = mat.begin(),
00330     m_end = mat.end();
00331 
00332   size_t offset = 0;
00333   for(; m_iter!=m_end; ++m_iter) {
00334     rows[offset++] = m_iter->first;
00335   }
00336 }
00337 
00338 }//namespace fei
00339 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends