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.");