FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_Vector_Local.cpp
1 /*--------------------------------------------------------------------*/
2 /* Copyright 2007 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_Vector_Local.hpp"
10 #include "fei_sstream.hpp"
11 #include "fei_fstream.hpp"
12 #include <fei_ErrMacros.hpp>
13 
14 #include <algorithm>
15 
16 #undef fei_file
17 #define fei_file "fei_Vector_Local.cpp"
18 
19 namespace fei {
20 
21 Vector_Local::Vector_Local(fei::SharedPtr<fei::VectorSpace> vecSpace)
22  : vecSpace_(vecSpace),
23  coefs_(),
24  global_to_local_(),
25  work_indices_()
26 {
27  int numCoefs = vecSpace_->getNumIndices_SharedAndOwned();
28  coefs_.resize(numCoefs);
29 
30  std::vector<int> indices;
31  vecSpace_->getIndices_SharedAndOwned(indices);
32 
33  std::sort(indices.begin(), indices.end());
34 
35  for(int i=0; i<numCoefs; ++i) {
36  global_to_local_.insert(std::make_pair(indices[i], i));
37  }
38 }
39 
40 Vector_Local::~Vector_Local()
41 {
42 }
43 
44 int
45 Vector_Local::update(double a,
46  const fei::Vector* x,
47  double b)
48 {
49  fei::console_out() << "Vector_Local::update NOT IMPLEMENTED."<<FEI_ENDL;
50  return(-1);
51 }
52 
53 int
54 Vector_Local::scatterToOverlap()
55 { return(0); }
56 
57 void
58 Vector_Local::setCommSizes()
59 {
60 }
61 
62 int
63 Vector_Local::gatherFromOverlap(bool accumulate)
64 { (void)accumulate; return(0); }
65 
66 int
67 Vector_Local::putScalar(double scalar)
68 {
69  for(size_t i=0; i<coefs_.size(); ++i) coefs_[i] = scalar;
70  return(0);
71 }
72 
73 int
74 Vector_Local::giveToVector(int numValues, const int* indices,
75  const double* values,
76  bool sumInto, int vectorIndex)
77 {
78  if (vectorIndex != 0) {
79  fei::console_out() << "fei::Vector_Local ERROR, vectorIndex!=0. Report to Alan Williams."<<FEI_ENDL;
80  return(-1);
81  }
82 
83  for(int i=0; i<numValues; ++i) {
84  std::map<int,int>::iterator
85  iter = global_to_local_.find(indices[i]);
86  if (iter == global_to_local_.end()) {
87  fei::console_out() << "fei::Vector_Local ERROR, eqn "<<indices[i]<<" not found "
88  << "locally."<<FEI_ENDL;
89  return(-1);
90  }
91 
92  if (sumInto) {
93  coefs_[iter->second] += values[i];
94  }
95  else {
96  coefs_[iter->second] = values[i];
97  }
98  }
99 
100  return(0);
101 }
102 
103 int
104 Vector_Local::sumIn(int numValues, const int* indices, const double* values,
105  int vectorIndex)
106 {
107  return( giveToVector(numValues, indices, values, true, vectorIndex) );
108 }
109 
110 int
111 Vector_Local::copyIn(int numValues, const int* indices, const double* values,
112  int vectorIndex)
113 {
114  return( giveToVector(numValues, indices, values, false, vectorIndex) );
115 }
116 
118 Vector_Local::getVectorSpace() const
119 { return( vecSpace_ ); }
120 
121 void
122 Vector_Local::setVectorSpace(fei::SharedPtr<fei::VectorSpace> vecSpace)
123 { vecSpace_ = vecSpace; }
124 
125 int
126 Vector_Local::assembleFieldData(int fieldID,
127  int idType,
128  int numIDs,
129  const int* IDs,
130  const double* data,
131  bool sumInto,
132  int vectorIndex)
133 {
134  int fieldSize = vecSpace_->getFieldSize(fieldID);
135 
136  work_indices_.resize(numIDs*fieldSize);
137  int* indicesPtr = &work_indices_[0];
138 
139  CHK_ERR( vecSpace_->getGlobalIndices(numIDs, IDs, idType, fieldID,
140  indicesPtr) );
141 
142  CHK_ERR( giveToVector(numIDs*fieldSize, indicesPtr, data, sumInto, vectorIndex) );
143 
144  return(0);
145 }
146 
147 int
148 Vector_Local::assembleFieldDataLocalIDs(int fieldID,
149  int idType,
150  int numIDs,
151  const int* localIDs,
152  const double* data,
153  bool sumInto,
154  int vectorIndex)
155 {
156  int fieldSize = vecSpace_->getFieldSize(fieldID);
157 
158  work_indices_.resize(numIDs*fieldSize);
159  int* indicesPtr = &work_indices_[0];
160 
161  CHK_ERR( vecSpace_->getGlobalIndicesLocalIDs(numIDs, localIDs, idType, fieldID,
162  indicesPtr) );
163 
164  CHK_ERR( giveToVector(numIDs*fieldSize, indicesPtr, data, sumInto, vectorIndex) );
165 
166  return(0);
167 }
168 
169 int
170 Vector_Local::sumInFieldData(int fieldID,
171  int idType,
172  int numIDs,
173  const int* IDs,
174  const double* data,
175  int vectorIndex)
176 {
177  return(assembleFieldData(fieldID, idType, numIDs, IDs,
178  data, true, vectorIndex));
179 }
180 
181 int
182 Vector_Local::copyInFieldData(int fieldID,
183  int idType,
184  int numIDs,
185  const int* IDs,
186  const double* data,
187  int vectorIndex)
188 {
189  return(assembleFieldData(fieldID, idType, numIDs, IDs,
190  data, false, vectorIndex));
191 }
192 
193 int
194 Vector_Local::copyInFieldDataLocalIDs(int fieldID,
195  int idType,
196  int numIDs,
197  const int* localIDs,
198  const double* data,
199  int vectorIndex)
200 {
201  return(assembleFieldDataLocalIDs(fieldID, idType, numIDs, localIDs,
202  data, false, vectorIndex));
203 }
204 
205 int
206 Vector_Local::copyOutFieldData(int fieldID,
207  int idType,
208  int numIDs,
209  const int* IDs,
210  double* data,
211  int vectorIndex)
212 {
213  int fieldSize = vecSpace_->getFieldSize(fieldID);
214 
215  work_indices_.resize(numIDs*fieldSize);
216  int* indicesPtr = &work_indices_[0];
217 
218  CHK_ERR( vecSpace_->getGlobalIndices(numIDs, IDs, idType, fieldID,
219  indicesPtr) );
220 
221  for(int i=0; i<(int)work_indices_.size(); ++i) {
222  std::map<int,int>::iterator
223  iter = global_to_local_.find(work_indices_[i]);
224  if (iter == global_to_local_.end()) {
225  fei::console_out() << "fei::Vector_Local::copyOut ERROR, eqn "<<work_indices_[i]<<" not found "
226  << "locally."<<FEI_ENDL;
227  return(-1);
228  }
229 
230  data[i] = coefs_[iter->second];
231  }
232 
233  return(0);
234 }
235 
236 int
237 Vector_Local::copyOut(int numValues, const int* indices,
238  double* values, int vectorIndex) const
239 {
240  if (vectorIndex != 0) {
241  fei::console_out() << "fei::Vector_Local ERROR, vectorIndex!=0. Report to Alan Williams."<<FEI_ENDL;
242  return(-1);
243  }
244 
245  for(int i=0; i<numValues; ++i) {
246  std::map<int,int>::const_iterator
247  iter = global_to_local_.find(indices[i]);
248  if (iter == global_to_local_.end()) {
249  fei::console_out() << "fei::Vector_Local::copyOut ERROR, eqn "<<indices[i]<<" not found "
250  << "locally."<<FEI_ENDL;
251  return(-1);
252  }
253 
254  values[i] = coefs_[iter->second];
255  }
256 
257  return(0);
258 }
259 
260 std::vector<double>&
261 Vector_Local::getCoefs()
262 {
263  return(coefs_);
264 }
265 
266 int
267 Vector_Local::writeToFile(const char* filename,
268  bool matrixMarketFormat)
269 {
270  int local_proc = fei::localProc(vecSpace_->getCommunicator());
271  FEI_OSTRINGSTREAM osstr;
272  osstr << filename << "." << local_proc;
273  std::string fullname = osstr.str();
274  FEI_OFSTREAM ofstr(fullname.c_str(), IOS_OUT);
275 
276  return( writeToStream(ofstr, matrixMarketFormat) );
277 }
278 
279 int
280 Vector_Local::writeToStream(FEI_OSTREAM& ostrm,
281  bool matrixMarketFormat)
282 {
283  static char mmbanner[] = "%%MatrixMarket matrix array real general";
284 
285  if (matrixMarketFormat) {
286  ostrm << mmbanner << FEI_ENDL;
287  ostrm << coefs_.size() << " 1" << FEI_ENDL;
288  }
289  else {
290  ostrm << coefs_.size() << FEI_ENDL;
291  }
292 
293  ostrm.setf(IOS_SCIENTIFIC, IOS_FLOATFIELD);
294  ostrm.precision(13);
295 
296  std::map<int,int>::iterator
297  iter = global_to_local_.begin();
298 
299  for(unsigned i=0; i<coefs_.size(); ++i) {
300  if (matrixMarketFormat) {
301  ostrm << coefs_[i] << FEI_ENDL;
302  }
303  else {
304  ostrm << iter->first << " " << coefs_[i] << FEI_ENDL;
305  ++iter;
306  }
307  }
308 
309  return(0);
310 }
311 
312 }//namespace fei
313 
void writeToStream(snl_fei::RaggedTable< MAP_TYPE, SET_TYPE > &table, FEI_OSTREAM &os, const char *lineprefix=NULL)
std::ostream & console_out()
int localProc(MPI_Comm comm)
unsigned getFieldSize(int fieldID)