20 namespace impl_utils {
24 const std::vector<int>& targets,
25 std::vector<int>& offsets)
27 offsets.assign(sources.size(), -1);
29 size_t ssize = sources.size(), tsize = targets.size();
30 size_t si = 0, ti = 0;
32 const int* sourcesptr = &sources[0];
33 const int* targetsptr = &targets[0];
35 while(si<ssize && ti<tsize) {
36 if (sourcesptr[si] == targetsptr[ti]) {
41 while(sourcesptr[si] < targetsptr[ti] && si<ssize) {
45 while(sourcesptr[si] > targetsptr[ti] && ti<tsize) {
57 int num_chars_int = (2 + nrows*2 + nnz)*
sizeof(
int);
58 int num_chars_double = nnz*
sizeof(double);
60 return num_chars_int + num_chars_double;
70 int num_chars_int = (2 + nrows*2 + nnz)*
sizeof(
int);
72 int* intdata =
reinterpret_cast<int*
>(buffer);
73 double* doubledata =
reinterpret_cast<double*
>(buffer+num_chars_int);
78 intdata[ioffset++] = nrows;
79 intdata[ioffset++] = nnz;
81 int ioffsetcols = 2+nrows*2;
87 for(; r_iter!=r_end; ++r_iter) {
88 int rowNumber = r_iter->first;
91 intdata[ioffset++] = rowNumber;
92 const int rowlen = row->
size();
93 intdata[ioffset++] = rowlen;
95 const std::vector<int>& rowindices = row->
indices();
96 const std::vector<double>& rowcoefs = row->
coefs();
97 for(
int i=0; i<rowlen; ++i) {
98 intdata[ioffsetcols++] = rowindices[i];
99 doubledata[doffset++] = rowcoefs[i];
107 bool clear_mat_on_entry,
108 bool overwrite_entries)
110 if (clear_mat_on_entry) {
114 if (buffer_end == buffer_begin) {
118 const int* intdata =
reinterpret_cast<const int*
>(buffer_begin);
120 int nrows = intdata[ioffset++];
121 int nnz = intdata[ioffset++];
123 int ioffsetcols = 2+nrows*2;
125 int num_chars_int = (2+nrows*2 + nnz)*
sizeof(
int);
126 const double* doubledata =
reinterpret_cast<const double*
>(buffer_begin+num_chars_int);
130 for(
int i=0; i<nrows; ++i) {
131 int row = intdata[ioffset++];
132 int rowlen = intdata[ioffset++];
134 for(
int j=0; j<rowlen; ++j) {
135 int col = intdata[ioffsetcols++];
136 double coef = doubledata[doffset++];
138 if (overwrite_entries) {
147 if (doffset != nnz) {
148 throw std::runtime_error(
"fei::impl_utils::unpack_FillableMat: failed, sizes don't agree.");
155 bool all_zeros =
true;
156 if (buffer_end == buffer_begin) {
160 const int* intdata =
reinterpret_cast<const int*
>(buffer_begin);
162 int nrows = intdata[ioffset++];
163 int nnz = intdata[ioffset++];
170 packed_coefs.resize(nnz);
172 int ioffsetcols = 2+nrows*2;
174 int num_chars_int = (2+nrows*2 + nnz)*
sizeof(
int);
175 const double* doubledata =
reinterpret_cast<const double*
>(buffer_begin+num_chars_int);
179 for(
int i=0; i<nrows; ++i) {
180 int row = intdata[ioffset++];
181 int rowlen = intdata[ioffset++];
186 for(
int j=0; j<rowlen; ++j) {
187 int col = intdata[ioffsetcols++];
188 double coef = doubledata[doffset];
189 if (coef != 0.0) all_zeros =
false;
191 packed_coefs[doffset++] = coef;
199 const std::vector<double>& coefs)
201 int num = indices.size();
202 int num_chars_int = (1+num)*
sizeof(
int);
203 int num_chars = num_chars_int + num*
sizeof(double);
208 const std::vector<double>& coefs,
209 std::vector<char>& buffer,
212 if (indices.size() != coefs.size()) {
213 throw std::runtime_error(
"fei::impl_utils::pack_indices_coefs failed, sizes don't match.");
216 int num = indices.size();
217 int num_chars_int = (1+num)*
sizeof(
int);
218 int num_chars = num_chars_int + num*
sizeof(double);
220 buffer.resize(num_chars);
223 int* intdata =
reinterpret_cast<int*
>(&buffer[0]);
224 double* doubledata =
reinterpret_cast<double*
>(&buffer[0]+num_chars_int);
228 intdata[ioffset++] = num;
229 for(
int i=0; i<num; ++i) {
230 intdata[ioffset++] = indices[i];
231 doubledata[doffset++] = coefs[i];
236 std::vector<int>& indices,
237 std::vector<double>& coefs)
239 if (buffer.size() == 0)
return;
241 const int* intdata =
reinterpret_cast<const int*
>(&buffer[0]);
243 int num = intdata[ioffset++];
244 int num_chars_int = (1+num)*
sizeof(
int);
245 const double* doubledata =
reinterpret_cast<const double*
>(&buffer[0]+num_chars_int);
251 for(
int i=0; i<num; ++i) {
252 indices[i] = intdata[ioffset++];
253 coefs[i] = doubledata[doffset++];
259 std::vector<int>& bcEqns,
260 std::vector<double>& bcVals)
263 m_iter = mat.
begin(),
266 for(; m_iter != m_end; ++m_iter) {
267 int eqn = m_iter->first;
270 std::vector<int>::iterator
271 iter = std::lower_bound(bcEqns.begin(), bcEqns.end(), eqn);
272 if (iter == bcEqns.end() || *iter != eqn) {
273 size_t offset = iter - bcEqns.begin();
274 bcEqns.insert(iter, eqn);
275 std::vector<double>::iterator viter = bcVals.begin();
279 bcVals.insert(viter, val);
282 fei::console_out() <<
"separate_BC_eqns ERROR, failed to find coef for eqn " << eqn;
291 std::multimap<int,int>& crmap)
297 std::vector<int> rowNumbers;
301 m_iter = mat.
begin(),
304 for(; m_iter != m_end; ++m_iter) {
305 int rowNum = m_iter->first;
308 const std::vector<int>& rowindices = rowvec->
indices();
310 for(
size_t i=0; i<rowindices.size(); ++i) {
311 int colNum = rowindices[i];
313 crmap.insert(std::make_pair(colNum, rowNum));
321 int levelsOfCoupling = 0;
323 std::vector<int> rowNumbers;
326 bool finished =
false;
328 std::multimap<int,int> crmap;
331 typedef std::multimap<int,int>::iterator MM_Iter;
334 m_iter = mat.
begin(),
337 bool foundCoupling =
false;
338 for(; m_iter != m_end; ++m_iter) {
339 int rownum = m_iter->first;
343 std::pair<MM_Iter,MM_Iter> mmi = crmap.equal_range(rownum);
346 for(MM_Iter cri = mmi.first; cri != mmi.second; ++cri) {
347 int cri_row = cri->second;
355 std::vector<int>& indices = mrow->
indices();
356 std::vector<double>& coefs = mrow->
coefs();
358 size_t rowlen = mrow->
size();
359 for(
size_t ii=0; ii<rowlen; ++ii) {
363 int* indPtr = indices.empty() ? NULL : &indices[0];
364 double* coefPtr = coefs.empty() ? NULL : &coefs[0];
366 foundCoupling =
true;
370 if (foundCoupling ==
true) ++levelsOfCoupling;
371 else finished =
true;
374 if (levelsOfCoupling > 1) {
376 << levelsOfCoupling <<
" (Each level of coupling means that a slave DOF "
377 <<
"depends on a master which is itself a slave.) Behavior is not well "
378 <<
"understood for levelsOfCoupling greater than 1..."<<
FEI_ENDL;
381 return levelsOfCoupling;
389 globalUnionMatrix = localMatrix;
401 std::vector<char> localchardata(num_bytes);
408 std::vector<int> recvdatalengths;
409 std::vector<char> recvdata;
410 int err =
fei::Allgatherv(comm, localchardata, recvdatalengths, recvdata);
412 throw std::runtime_error(
"fei::impl_utils::global_union: Allgatherv-int failed.");
417 bool clearMatOnEntry =
false;
418 bool overwriteEntries =
true;
421 for(
size_t p=0; p<recvdatalengths.size(); ++p) {
422 int len = recvdatalengths[p];
426 globalUnionMatrix, clearMatOnEntry, overwriteEntries);
437 globalUnionVec.
indices().clear();
438 globalUnionVec.
coefs().clear();
440 const std::vector<int>& localindices = localVec.
indices();
441 const std::vector<double>& localcoefs = localVec.
coefs();
443 std::vector<int> localintdata;
444 if (localindices.size() > 0) {
445 localintdata.assign(&localindices[0], &localindices[0]+localindices.size());
448 std::vector<double> localdoubledata;
449 if (localcoefs.size() > 0) {
450 localdoubledata.assign(&localcoefs[0], &localcoefs[0]+localcoefs.size());
456 std::vector<int> recvintdatalengths;
457 std::vector<int> recvintdata;
458 int err =
fei::Allgatherv(comm, localintdata, recvintdatalengths, recvintdata);
460 throw std::runtime_error(
"snl_fei::globalUnion csvec: Allgatherv-int failed.");
463 std::vector<int> recvdoubledatalengths;
464 std::vector<double> recvdoubledata;
465 err =
fei::Allgatherv(comm, localdoubledata, recvdoubledatalengths, recvdoubledata);
467 throw std::runtime_error(
"snl_fei::globalUnion csvec: Allgatherv-double failed.");
470 if (recvintdatalengths.size() != recvdoubledatalengths.size()) {
471 throw std::runtime_error(
"snl_fei::globalUnion csvec: inconsistent lengths from Allgatherv");
476 unsigned len = recvintdata.size();
478 int* recvintPtr = &recvintdata[0];
479 double* recvdoublePtr = &recvdoubledata[0];
481 for(
unsigned i=0; i<len; ++i) {
492 std::vector<int>& rowNumbers = srg.
rowNumbers;
493 for(
size_t i=0; i<rowNumbers.size(); ++i) {
498 for(
size_t i=0; i<colIndices.size(); ++i) {
506 std::vector<int>& indices = vec.
indices();
507 for(
size_t i=0; i<indices.size(); ++i) {
519 for(
size_t i=0; i<rowNumbers.size(); ++i) {
520 int row = rowNumbers[i];
521 int offset = rowOffsets[i];
522 int rowlen = rowOffsets[i+1]-offset;
523 const int* indices = pckColInds.empty() ? NULL : &pckColInds[offset];
525 if (graph.
addIndices(row, rowlen, indices) != 0) {
526 throw std::runtime_error(
"fei::impl_utils::add_to_graph ERROR in graph.addIndices.");
539 for(
size_t i=0; i<rowNumbers.size(); ++i) {
540 int row = rowNumbers[i];
541 int offset = rowOffsets[i];
542 int rowlen = rowOffsets[i+1]-offset;
543 const int* indices = &pckColInds[offset];
544 const double* coefs = &pckCoefs[offset];
548 throw std::runtime_error(
"fei::impl_utils::add_to_matrix ERROR in matrix.sumIn.");
553 throw std::runtime_error(
"fei::impl_utils::add_to_matrix ERROR in matrix.copyIn.");
void unpack_indices_coefs(const std::vector< char > &buffer, std::vector< int > &indices, std::vector< double > &coefs)
void remove_entry(CSVec &vec, int eqn)
int Allgatherv(MPI_Comm comm, std::vector< T > &sendbuf, std::vector< int > &recvLengths, std::vector< T > &recvbuf)
feipoolmat::iterator iterator
void translate_to_reduced_eqns(const fei::Reducer &reducer, fei::CSRMat &mat)
void add_entries(CSVec &vec, int num, const int *eqns, const double *coefs)
CSVec * create_or_getRow(int row)
bool unpack_CSRMat(const char *buffer_begin, const char *buffer_end, fei::CSRMat &mat)
std::vector< int > & indices()
int translateToReducedEqn(int unreducedEqn) const
std::vector< int > rowNumbers
void add_to_matrix(const fei::CSRMat &inmat, bool sum_into, fei::Matrix &matrix)
void get_row_numbers(const FillableMat &mat, std::vector< int > &rows)
std::vector< int > packedColumnIndices
void pack_indices_coefs(const std::vector< int > &indices, const std::vector< double > &coefs, std::vector< char > &buffer, bool resize_buffer)
std::vector< int > rowOffsets
void put_entry(CSVec &vec, int eqn, double coef)
void find_offsets(const std::vector< int > &sources, const std::vector< int > &targets, std::vector< int > &offsets)
virtual int addIndices(int row, int len, const int *indices)=0
void global_union(MPI_Comm comm, const fei::FillableMat &localMatrix, fei::FillableMat &globalUnionMatrix)
void unpack_FillableMat(const char *buffer_begin, const char *buffer_end, fei::FillableMat &mat, bool clear_mat_on_entry, bool overwrite_entries)
virtual int sumIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)=0
void pack_FillableMat(const fei::FillableMat &mat, char *buffer)
void putCoef(int row, int col, double coef)
size_t num_bytes_indices_coefs(const std::vector< int > &indices, const std::vector< double > &coefs)
void add_to_graph(const fei::CSRMat &inmat, fei::Graph &graph)
feipoolmat::const_iterator const_iterator
double get_entry(const CSVec &vec, int eqn)
SparseRowGraph & getGraph()
std::ostream & console_out()
size_t num_bytes_FillableMat(const fei::FillableMat &mat)
void separate_BC_eqns(const fei::FillableMat &mat, std::vector< int > &bcEqns, std::vector< double > &bcVals)
int localProc(MPI_Comm comm)
void sumInCoef(int row, int col, double coef)
virtual int copyIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)=0
unsigned getNumRows() const
std::vector< double > & getPackedCoefs()
void create_col_to_row_map(const fei::FillableMat &mat, std::multimap< int, int > &crmap)
int count_nnz(const FillableMat &mat)
int numProcs(MPI_Comm comm)
std::vector< double > & coefs()
int remove_couplings(fei::FillableMat &mat)