FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_FillableMat.cpp
1 /*--------------------------------------------------------------------*/
2 /* Copyright 2005 Sandia Corporation. */
3 /* Under the terms of Contract DE-AC04-94AL85000, there is a */
4 /* non-exclusive license for use of this work by or on behalf */
5 /* of the U.S. Government. Export of this program may require */
6 /* a license from the United States Government. */
7 /*--------------------------------------------------------------------*/
8 
9 #include <fei_FillableMat.hpp>
10 #include <fei_EqnBuffer.hpp>
11 #include <fei_CSVec.hpp>
12 
13 namespace fei {
14 
15 //-----------------------------------------------------------------
16 FillableMat::FillableMat()
17  : matdata_(),
18  vecpool_()
19 {
20 }
21 
22 //-----------------------------------------------------------------
23 FillableMat::FillableMat(EqnBuffer& eqnbuf)
24  : matdata_(),
25  vecpool_()
26 {
27  std::vector<int>& eqnNums = eqnbuf.eqnNumbers();
28  int numEqns = eqnNums.size();
29  std::vector<fei::CSVec*>& eqns = eqnbuf.eqns();
30 
31  for(int i=0; i<numEqns; ++i) {
32  int row = eqnNums[i];
33  fei::CSVec* row_vec = eqns[i];
34  int rowlen = row_vec->size();
35  int* indices = &(row_vec->indices()[0]);
36  double* coefs = &(row_vec->coefs()[0]);
37 
38  for(int j=0; j<rowlen; ++j) {
39  putCoef(row, indices[j], coefs[j]);
40  }
41  }
42 }
43 
44 //-----------------------------------------------------------------
45 FillableMat::~FillableMat()
46 {
47  feipoolmat::iterator
48  iter = matdata_.begin(), iter_end = matdata_.end();
49  for(; iter!=iter_end; ++iter) {
50  vecpool_.destroy(iter->second);
51  vecpool_.deallocate(iter->second, 1);
52  }
53 }
54 
55 //-----------------------------------------------------------------
56 FillableMat&
57 FillableMat::operator=(const FillableMat& src)
58 {
59  clear();
60 
61  FillableMat::const_iterator
62  s_iter = src.begin(),
63  s_end = src.end();
64 
65  for(; s_iter != s_end; ++s_iter) {
66  int row = s_iter->first;
67  const CSVec* srow = s_iter->second;
68  const std::vector<int>& s_ind = srow->indices();
69  const std::vector<double>& s_coef = srow->coefs();
70 
71  for(size_t i=0; i<s_ind.size(); ++i) {
72  int col = s_ind[i];
73  double coef = s_coef[i];
74 
75  putCoef(row, col, coef);
76  }
77  }
78 
79  return *this;
80 }
81 
82 //-----------------------------------------------------------------
83 void
84 FillableMat::setValues(double value)
85 {
86  feipoolmat::iterator
87  iter = matdata_.begin(), iter_end = matdata_.end();
88 
89  for(; iter != iter_end; ++iter) {
90  set_values(*(iter->second), value);
91  }
92 }
93 
94 //-----------------------------------------------------------------
95 void
96 FillableMat::createPosition(int row, int col)
97 {
98  sumInCoef(row, col, 0.0);
99 }
100 
101 //-----------------------------------------------------------------
102 FillableMat::feipoolmat::iterator
103 insert_row(FillableMat::feipoolmat& matdata,
104  FillableMat::feipoolmat::iterator iter,
105  int row,
106  fei_Pool_alloc<CSVec>& vecpool)
107 {
108  static CSVec dummy;
109 
110  CSVec* vptr = vecpool.allocate(1);
111  vecpool.construct(vptr, dummy);
112 
113  if (vptr->indices().capacity() == 0) {
114  vptr->indices().reserve(16);
115  vptr->coefs().reserve(16);
116  }
117 
118  return matdata.insert(iter, std::make_pair(row, vptr));
119 }
120 
121 //-----------------------------------------------------------------
122 void
123 FillableMat::sumInCoef(int row, int col, double coef)
124 {
125  CSVec* rowvec = create_or_getRow(row);
126 
127  add_entry(*rowvec, col, coef);
128 }
129 
130 //-----------------------------------------------------------------
131 void
132 FillableMat::putCoef(int row, int col, double coef)
133 {
134  CSVec* rowvec = create_or_getRow(row);
135 
136  put_entry(*rowvec, col, coef);
137 }
138 
139 //-----------------------------------------------------------------
140 void
141 FillableMat::sumInRow(int row, const int* cols, const double* coefs,
142  unsigned len)
143 {
144  CSVec* rowvec = create_or_getRow(row);
145 
146  for(unsigned i=0; i<len; ++i) {
147  add_entry(*rowvec, cols[i], coefs[i]);
148  }
149 }
150 
151 //-----------------------------------------------------------------
152 void
153 FillableMat::putRow(int row, const int* cols, const double* coefs,
154  unsigned len)
155 {
156  CSVec* rowvec = create_or_getRow(row);
157 
158  for(unsigned i=0; i<len; ++i) {
159  put_entry(*rowvec, cols[i], coefs[i]);
160  }
161 }
162 
163 //-----------------------------------------------------------------
164 unsigned
165 FillableMat::getNumRows() const
166 {
167  return matdata_.size();
168 }
169 
170 //-----------------------------------------------------------------
171 bool
172 FillableMat::hasRow(int row) const
173 {
174  feipoolmat::const_iterator iter = matdata_.find(row);
175  return iter != matdata_.end();
176 }
177 
178 //-----------------------------------------------------------------
179 const CSVec*
180 FillableMat::getRow(int row) const
181 {
182  feipoolmat::const_iterator iter = matdata_.lower_bound(row);
183 
184  if (iter == matdata_.end() || iter->first != row) {
185  throw std::runtime_error("fei::FillableMat: row not found.");
186  }
187 
188  return iter->second;
189 }
190 
191 //-----------------------------------------------------------------
192 CSVec*
193 FillableMat::create_or_getRow(int row)
194 {
195  feipoolmat::iterator iter = matdata_.lower_bound(row);
196 
197  if (iter == matdata_.end() || iter->first != row) {
198  iter = insert_row(matdata_, iter, row, vecpool_);
199  }
200 
201  return iter->second;
202 }
203 
204 //-----------------------------------------------------------------
205 void
206 FillableMat::clear()
207 {
208  feipoolmat::iterator
209  iter = matdata_.begin(), iter_end = matdata_.end();
210  for(; iter!=iter_end; ++iter) {
211  vecpool_.destroy(iter->second);
212  vecpool_.deallocate(iter->second, 1);
213  }
214 
215  matdata_.clear();
216 }
217 
218 //-----------------------------------------------------------------
219 bool
220 FillableMat::operator==(const FillableMat& rhs) const
221 {
222  if (getNumRows() != rhs.getNumRows()) return false;
223 
224  FillableMat::const_iterator
225  this_it = begin(),
226  this_end = end();
227 
228  FillableMat::const_iterator rhs_it = rhs.begin();
229 
230  for(; this_it != this_end; ++this_it, ++rhs_it) {
231  int this_row = this_it->first;
232  int rhs_row = rhs_it->first;
233  if (this_row != rhs_row) return false;
234 
235  const CSVec* this_row_vec = this_it->second;
236  const CSVec* rhs_row_vec = rhs_it->second;
237 
238  if (*this_row_vec != *rhs_row_vec) return false;
239  }
240 
241  return true;
242 }
243 
244 //-----------------------------------------------------------------
245 bool
246 FillableMat::operator!=(const FillableMat& rhs) const
247 {
248  return !(*this == rhs);
249 }
250 
251 //-----------------------------------------------------------------
252 void print(std::ostream& os, const FillableMat& mat)
253 {
254  FillableMat::const_iterator
255  irow = mat.begin(), irowend = mat.end();
256  for(; irow!=irowend; ++irow) {
257  int row = irow->first;
258  const CSVec* vec = irow->second;
259  const std::vector<int>& v_ind = vec->indices();
260  const std::vector<double>& v_coef = vec->coefs();
261  os << "row " << row << ": ";
262  for(size_t i=0; i<v_ind.size(); ++i) {
263  os << "("<<v_ind[i]<<","<<v_coef[i]<<") ";
264  }
265  os << std::endl;
266  }
267 }
268 
269 //-----------------------------------------------------------------
270 int count_nnz(const FillableMat& mat)
271 {
272  int nnz = 0;
273 
274  FillableMat::const_iterator
275  r_iter = mat.begin(),
276  r_end = mat.end();
277 
278  for(; r_iter != r_end; ++r_iter) {
279  CSVec* row = r_iter->second;
280  nnz += row->size();
281  }
282 
283  return nnz;
284 }
285 
286 //-----------------------------------------------------------------
287 void get_row_numbers(const FillableMat& mat, std::vector<int>& rows)
288 {
289  rows.resize(mat.getNumRows());
290 
291  FillableMat::const_iterator
292  m_iter = mat.begin(),
293  m_end = mat.end();
294 
295  size_t offset = 0;
296  for(; m_iter!=m_end; ++m_iter) {
297  rows[offset++] = m_iter->first;
298  }
299 }
300 
301 }//namespace fei
302 
std::vector< fei::CSVec * > & eqns()
std::vector< int > & eqnNumbers()
void get_row_numbers(const FillableMat &mat, std::vector< int > &rows)
int count_nnz(const FillableMat &mat)
void print(std::ostream &os, const FillableMat &mat)