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 FillableVec* srow = s_iter->second;
00103 
00104     FillableVec::const_iterator
00105       r_iter = srow->begin(),
00106       r_end = srow->end();
00107 
00108     for(; r_iter != r_end; ++r_iter) {
00109       int col = r_iter->first;
00110       double coef = r_iter->second;
00111 
00112       putCoef(row, col, coef);
00113     }
00114   }
00115 
00116   return *this;
00117 }
00118 
00119 //-----------------------------------------------------------------
00120 void
00121 FillableMat::setValues(double value)
00122 {
00123   feipoolmat::iterator
00124     iter = matdata_.begin(), iter_end = matdata_.end();
00125 
00126   for(; iter != iter_end; ++iter) {
00127     iter->second->setValues(value);
00128   }
00129 }
00130 
00131 //-----------------------------------------------------------------
00132 void
00133 FillableMat::createPosition(int row, int col)
00134 {
00135   sumInCoef(row, col, 0.0);
00136 }
00137 
00138 //-----------------------------------------------------------------
00139 FillableMat::feipoolmat::iterator
00140 insert_row(FillableMat::feipoolmat& matdata,
00141            FillableMat::feipoolmat::iterator iter,
00142            int row,
00143            fei_Pool_alloc<FillableVec>& vecpool)
00144 {
00145   static FillableVec dummy;
00146 
00147   FillableVec* vptr = vecpool.allocate(1);
00148   vecpool.construct(vptr, dummy);
00149 
00150   return matdata.insert(iter, std::make_pair(row, vptr));
00151 }
00152 
00153 //-----------------------------------------------------------------
00154 void
00155 FillableMat::sumInCoef(int row, int col, double coef)
00156 {
00157   FillableVec* rowvec = create_or_getRow(row);
00158 
00159   rowvec->addEntry(col, coef);
00160 }
00161 
00162 //-----------------------------------------------------------------
00163 void
00164 FillableMat::putCoef(int row, int col, double coef)
00165 {
00166   FillableVec* rowvec = create_or_getRow(row);
00167 
00168   rowvec->putEntry(col, coef);
00169 }
00170 
00171 //-----------------------------------------------------------------
00172 void
00173 FillableMat::sumInRow(int row, const int* cols, const double* coefs,
00174                       unsigned len)
00175 {
00176   FillableVec* rowvec = create_or_getRow(row);
00177 
00178   for(unsigned i=0; i<len; ++i) {
00179     rowvec->addEntry(cols[i], coefs[i]);
00180   }
00181 }
00182 
00183 //-----------------------------------------------------------------
00184 void
00185 FillableMat::putRow(int row, const int* cols, const double* coefs,
00186                     unsigned len)
00187 {
00188   FillableVec* rowvec = create_or_getRow(row);
00189 
00190   for(unsigned i=0; i<len; ++i) {
00191     rowvec->putEntry(cols[i], coefs[i]);
00192   }
00193 }
00194 
00195 //-----------------------------------------------------------------
00196 unsigned
00197 FillableMat::getNumRows() const
00198 {
00199   return matdata_.size();
00200 }
00201 
00202 //-----------------------------------------------------------------
00203 bool
00204 FillableMat::hasRow(int row) const
00205 {
00206   feipoolmat::const_iterator iter = matdata_.find(row);
00207   return iter != matdata_.end();
00208 }
00209 
00210 //-----------------------------------------------------------------
00211 const FillableVec*
00212 FillableMat::getRow(int row) const
00213 {
00214   feipoolmat::const_iterator iter = matdata_.lower_bound(row);
00215 
00216   if (iter == matdata_.end() || iter->first != row) {
00217     throw std::runtime_error("fei::FillableMat: row not found.");
00218   }
00219 
00220   return iter->second;
00221 }
00222 
00223 //-----------------------------------------------------------------
00224 FillableVec*
00225 FillableMat::create_or_getRow(int row)
00226 {
00227   feipoolmat::iterator iter = matdata_.lower_bound(row);
00228 
00229   if (iter == matdata_.end() || iter->first != row) {
00230     iter = insert_row(matdata_, iter, row, vecpool_);
00231   }
00232 
00233   return iter->second;
00234 }
00235 
00236 //-----------------------------------------------------------------
00237 void
00238 FillableMat::clear()
00239 {
00240   feipoolmat::iterator
00241     iter = matdata_.begin(), iter_end = matdata_.end();
00242   for(; iter!=iter_end; ++iter) {
00243     vecpool_.destroy(iter->second);
00244     vecpool_.deallocate(iter->second, 1);
00245   }
00246 
00247   matdata_.clear();
00248 }
00249 
00250 //-----------------------------------------------------------------
00251 bool
00252 FillableMat::operator==(const FillableMat& rhs) const
00253 {
00254   if (getNumRows() != rhs.getNumRows()) return false;
00255 
00256   FillableMat::const_iterator
00257     this_it = begin(),
00258     this_end = end();
00259 
00260   FillableMat::const_iterator
00261     rhs_it = rhs.begin(),
00262     rhs_end = rhs.end();
00263 
00264   for(; this_it != this_end; ++this_it, ++rhs_it) {
00265     int this_row = this_it->first;
00266     int rhs_row = rhs_it->first;
00267     if (this_row != rhs_row) return false;
00268 
00269     const FillableVec* this_row_vec = this_it->second;
00270     const FillableVec* rhs_row_vec = rhs_it->second;
00271 
00272     if (*this_row_vec != *rhs_row_vec) return false;
00273   }
00274 
00275   return true;
00276 }
00277 
00278 //-----------------------------------------------------------------
00279 bool
00280 FillableMat::operator!=(const FillableMat& rhs) const
00281 {
00282   return !(*this == rhs);
00283 }
00284 
00285 //-----------------------------------------------------------------
00286 void print(std::ostream& os, const FillableMat& mat)
00287 {
00288   FillableMat::const_iterator
00289     irow = mat.begin(), irowend = mat.end();
00290   for(; irow!=irowend; ++irow) {
00291     int row = irow->first;
00292     const FillableVec* vec = irow->second;
00293     os << "row " << row << ": ";
00294     FillableVec::const_iterator
00295       ivec = vec->begin(), ivecend = vec->end();
00296     for(; ivec!=ivecend; ++ivec) {
00297       os << "("<<ivec->first<<","<<ivec->second<<") ";
00298     }
00299     os << std::endl;
00300   }
00301 }
00302 
00303 //-----------------------------------------------------------------
00304 int count_nnz(const FillableMat& mat)
00305 {
00306   int nnz = 0;
00307 
00308   FillableMat::const_iterator
00309     r_iter = mat.begin(),
00310     r_end = mat.end();
00311 
00312   for(; r_iter != r_end; ++r_iter) {
00313     FillableVec* row = r_iter->second;
00314     nnz += row->size();
00315   }
00316 
00317   return nnz;
00318 }
00319 
00320 //-----------------------------------------------------------------
00321 void get_row_numbers(const FillableMat& mat, std::vector<int>& rows)
00322 {
00323   rows.resize(mat.getNumRows());
00324 
00325   FillableMat::const_iterator
00326     m_iter = mat.begin(),
00327     m_end = mat.end();
00328 
00329   size_t offset = 0;
00330   for(; m_iter!=m_end; ++m_iter) {
00331     rows[offset++] = m_iter->first;
00332   }
00333 }
00334 
00335 }//namespace fei
00336 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends