24 #define fei_file "EqnCommMgr.cpp"
29 : accumulate_(accumulate),
32 exchangeIndicesCalled_(false),
52 : accumulate_(src.accumulate_),
55 exchangeIndicesCalled_(false),
94 for(
int i=0; i<len; i++) {
107 for(
int i=0; i<len; i++) {
138 fei::console_out() <<
"EqnCommMgr::addRecvEqn: ERROR, srcProc == localProc_, "
139 <<
"which is a recipe for a deadlock." <<
FEI_ENDL;
150 fei::console_out() <<
"EqnCommMgr::addSolnValues: ERROR, you may not call this until"
151 " after exchangeIndices has been called." <<
FEI_ENDL;
158 for(
int i=0; i<num; i++) {
161 if (index < 0)
continue;
163 solnValuesPtr[index] = values[i];
182 std::vector<int> sendEqnLengths(numSendEqns);
183 for(
int i=0; i<numSendEqns; ++i) {
184 sendEqnLengths[i] = sendEqnsPtr[i]->
size();
187 if (sendEqnNumbers.size() > 0) {
210 std::vector<int> recvProcTotalLengths(numRecvProcs);
211 std::vector<int> sendProcTotalLengths(numSendProcs);
215 std::vector<std::vector<int>*>& recvProcEqnLengths =
217 std::vector<std::vector<int>*>& recvProcEqnNumbers =
220 for(
unsigned i=0; i<numRecvProcs; i++) {
224 for(
int j=0; j<eqnsPerRecvProc[i]; j++) {
225 totalLength += (*(recvProcEqnLengths[i]))[j];
227 recvProcTotalLengths[i] = totalLength;
231 std::vector<std::vector<int>*>& sendProcEqnNumbers =
233 std::vector<std::vector<int>*>& sendProcLengths =
236 for(
unsigned i=0; i<numSendProcs; i++) {
238 for(
int j=0; j<eqnsPerSendProc[i]; j++) {
239 totalLength += (*(sendProcLengths[i]))[j];
241 sendProcTotalLengths[i] = totalLength;
251 sendProcs, sendProcTotalLengths) );
253 int** recvProcEqnIndices = NULL;
255 if (numRecvProcs > 0) {
256 recvProcEqnIndices =
new int*[numRecvProcs];
261 if (numRecvProcs > 0) {
265 int numRecvsStarted = 0;
269 for(
unsigned i=0; i<numRecvProcs; i++) {
271 int totalLength = recvProcTotalLengths[i];
273 recvProcEqnIndices[i] =
new int[totalLength];
276 if (MPI_Irecv(recvProcEqnIndices[i], totalLength, MPI_INT,
285 std::vector<int> indices;
287 for(
unsigned i=0; i<numSendProcs; i++) {
288 int totalLength = sendProcTotalLengths[i];
291 indices.resize(totalLength);
292 int* indicesPtr = &indices[0];
296 for(j=0; j<eqnsPerSendProc[i]; j++) {
298 std::vector<int>& sendIndices =
sendEqns_->
eqns()[eqnLoc]->indices();
299 int* sendIndicesPtr = &sendIndices[0];
301 for(
int k=0; k<(*(sendProcLengths[i]))[j]; k++) {
302 indicesPtr[offset++] = sendIndicesPtr[k];
306 if (MPI_Send(indicesPtr, totalLength, MPI_INT, sendProcs[i],
312 int numCompleted = 0;
313 for(
unsigned i=0; i<numRecvProcs; i++) {
316 MPI_Wait(&indRequests[i], &status);
320 for(
int j=0; j<eqnsPerRecvProc[index]; j++) {
321 int eqn = (*(recvProcEqnNumbers[index]))[j];
322 int* indxs = &(recvProcEqnIndices[index][offset]);
323 int len = (*(recvProcEqnLengths[index]))[j];
330 delete [] recvProcEqnIndices[index];
333 delete [] recvProcEqnIndices;
334 delete [] indRequests;
336 if (numRecvsStarted != numCompleted) {
338 <<
"numRecvsStarted: " << numRecvsStarted <<
", numCompleted: "
349 if (dbgOut != NULL) {
351 os <<
"#ereb exchangeIndices, sendEqns_:"<<
FEI_ENDL;
357 #endif // #ifndef FEI_SER
364 std::vector<int>& recvProcs,
365 std::vector<int>& recvProcTotalLengths,
366 std::vector<int>& sendProcs,
367 std::vector<int>& sendProcTotalLengths)
371 std::vector<int> globalProcSendLengths, globalSendProcs;
372 std::vector<int> gatherSizes;
375 gatherSizes, globalProcSendLengths) );
378 gatherSizes, globalSendProcs) );
383 for(
unsigned i=0; i<gatherSizes.size(); i++) {
384 int size = gatherSizes[i];
385 if ((
int)i==
localProc_) {offset += size;
continue; }
389 std::vector<int>::iterator rp_iter =
390 std::lower_bound(recvProcs.begin(), recvProcs.end(), (int)i);
392 if (rp_iter != recvProcs.end() && (int)i == *rp_iter) {
393 rpIndex = (int)(rp_iter - recvProcs.begin());
399 for(
int j=0; j<size; j++) {
400 if (globalSendProcs[offset+j] ==
localProc_) {
402 <<
" is not expecting to receive from proc " << i <<
" but proc "
407 if (err == -1)
break;
414 for(
int j=0; j<size; j++) {
415 if (globalSendProcs[offset+j] ==
localProc_) {
416 int sendLength = globalProcSendLengths[offset+j];
417 int recvLength = recvProcTotalLengths[rpIndex];
418 if (sendLength != recvLength) {
420 <<
" is expecting to receive " << recvLength <<
" indices from "
421 <<
"proc " << i <<
" but proc " << i <<
" is expecting to send "
447 if (dbgOut != NULL) {
449 os <<
"#ereb exchangeEqns begin, sendEqns_:"<<
FEI_ENDL;
456 if (dbgOut != NULL) {
458 os <<
"#ereb exchangeEqns end, sendEqns_:"<<
FEI_ENDL;
484 int indTag = 9113, coefTag = 9114;
488 if ((numRecvProcs == 0) && (numSendProcs == 0))
return(0);
496 int** recvProcEqnIndices = NULL;
497 double** recvProcEqnCoefs = NULL;
499 if (numRecvProcs > 0) {
502 recvProcEqnIndices =
new int*[numRecvProcs];
503 recvProcEqnCoefs =
new double*[numRecvProcs];
513 std::vector<int>& recvProcs = recvProcEqns->
procsPtr();
514 std::vector<int>& eqnsPerRecvProc = recvProcEqns->
eqnsPerProcPtr();
515 std::vector<std::vector<int>*>& recvProcEqnNumbers =
517 std::vector<std::vector<int>*>& recvProcEqnLengths =
521 for(
unsigned i=0; i<numRecvProcs; i++) {
524 for(
int j=0; j<eqnsPerRecvProc[i]; j++) {
525 totalLength += (*(recvProcEqnLengths[i]))[j];
531 recvProcEqnIndices[i] =
new int[totalLength+padding];
533 int coefLength = totalLength + numRHSs*eqnsPerRecvProc[i];
535 recvProcEqnCoefs[i] =
new double[coefLength];
537 MPI_Irecv(recvProcEqnIndices[i], totalLength+padding, MPI_INT,
538 recvProcs[i], indTag, comm, &indRequests[i]);
540 MPI_Irecv(recvProcEqnCoefs[i], coefLength, MPI_DOUBLE,
541 recvProcs[i], coefTag, comm, &coefRequests[i]);
546 std::vector<int>& sendProcs = sendProcEqns->
procsPtr();
547 std::vector<int>& eqnsPerSendProc = sendProcEqns->
eqnsPerProcPtr();
548 std::vector<std::vector<int>*>& sendProcEqnNumbers =
550 std::vector<std::vector<int>*>& sendProcEqnLengths =
553 std::vector<std::vector<double>*>& sendRHS = *(sendEqns->
rhsCoefsPtr());
555 for(
unsigned i=0; i<numSendProcs; i++) {
557 int* sendProcEqnNumbers_i = &(*(sendProcEqnNumbers[i]))[0];
558 int* sendProcEqnLengths_i = &(*(sendProcEqnLengths[i]))[0];
560 for(j=0; j<eqnsPerSendProc[i]; j++)
561 totalLength += sendProcEqnLengths_i[j];
565 std::vector<int> indices(totalLength+padding);
566 int* indicesPtr = &indices[0];
567 int coefLength = totalLength + numRHSs*eqnsPerSendProc[i];
569 std::vector<double> coefs(coefLength);
570 double* coefsPtr = &coefs[0];
575 for(j=0; j<eqnsPerSendProc[i]; j++) {
576 int eqnLoc = sendEqns->
getEqnIndex(sendProcEqnNumbers_i[j]);
577 int* sendIndices = &(sendEqns->
eqns()[eqnLoc]->indices())[0];
578 double* sendCoefs= &(sendEqns->
eqns()[eqnLoc]->coefs())[0];
580 for(
int k=0; k<sendProcEqnLengths_i[j]; k++) {
581 indicesPtr[offset] = sendIndices[k];
582 coefsPtr[offset++] = sendCoefs[k];
591 for(j=0; j<eqnsPerSendProc[i]; j++) {
592 int eqnLoc = sendEqns->
getEqnIndex(sendProcEqnNumbers_i[j]);
594 for(
int k=0; k<numRHSs; k++) {
595 coefsPtr[offset++] = (*(sendRHS[eqnLoc]))[k];
599 MPI_Send(&indices[0], (
int)indices.size(), MPI_INT, sendProcs[i],
601 MPI_Send(&coefs[0], coefLength, MPI_DOUBLE, sendProcs[i],
607 for(
unsigned i=0; i<numRecvProcs; i++) {
610 MPI_Wait(&indRequests[index], &status);
611 MPI_Wait(&coefRequests[index], &status);
614 for(j=0; j<eqnsPerRecvProc[index]; j++) {
615 int eqn = (*(recvProcEqnNumbers[index]))[j];
616 int* indices = &(recvProcEqnIndices[index][offset]);
617 double* coefs = &(recvProcEqnCoefs[index][offset]);
618 int len = (*(recvProcEqnLengths[index]))[j];
620 recvEqns->
addEqn(eqn, coefs, indices, len, accumulate);
625 recvEqns->
newCoefData_ += recvProcEqnIndices[index][offset];
626 recvEqns->
newRHSData_ += recvProcEqnIndices[index][offset+1];
627 delete [] recvProcEqnIndices[index];
634 for(
unsigned i=0; i<numRecvProcs; i++) {
636 for(j=0; j<eqnsPerRecvProc[i]; j++) {
637 offset += (*(recvProcEqnLengths[i]))[j];
640 for(j=0; j<eqnsPerRecvProc[i]; j++) {
641 int eqn = (*(recvProcEqnNumbers[i]))[j];
643 for(
int k=0; k<numRHSs; k++) {
644 CHK_ERR( recvEqns->
addRHS(eqn, k, recvProcEqnCoefs[i][offset++],
649 delete [] recvProcEqnCoefs[i];
652 delete [] recvProcEqnIndices;
653 delete [] recvProcEqnCoefs;
654 delete [] indRequests;
655 delete [] coefRequests;
657 #endif //#ifndef FEI_SER
672 double** solnBuffer = NULL;
678 if (numSendProcs > 0) {
680 solnBuffer =
new double*[numSendProcs];
686 for(
unsigned i=0; i<numSendProcs; i++) {
687 solnBuffer[i] =
new double[eqnsPerSendProc[i]];
689 MPI_Irecv(solnBuffer[i], eqnsPerSendProc[i], MPI_DOUBLE, sendProcs[i],
690 solnTag, comm, &solnRequests[i]);
696 std::vector<std::vector<int>*>& recvProcEqnNumbers =
700 for(
unsigned i=0; i<numRecvProcs; i++) {
701 double* solnBuff =
new double[eqnsPerRecvProc[i]];
703 for(
int j=0; j<eqnsPerRecvProc[i]; j++) {
704 int eqnNumber = (*(recvProcEqnNumbers[i]))[j];
710 MPI_Send(solnBuff, eqnsPerRecvProc[i], MPI_DOUBLE, recvProcs[i],
716 std::vector<std::vector<int>*>& sendProcEqnNumbers =
723 for(
unsigned i=0; i<numSendProcs; i++) {
726 MPI_Waitany((
int)numSendProcs, solnRequests, &index, &status);
728 for(
int j=0; j<eqnsPerSendProc[index]; j++) {
729 int eqnNumber = (*(sendProcEqnNumbers[index]))[j];
735 delete [] solnBuffer[index];
738 delete [] solnRequests;
739 delete [] solnBuffer;
740 #endif //#ifndef FEI_SER
746 #if defined (__clang__) && ! defined(__INTEL_CLANG_COMPILER)
747 __attribute__((optnone))
777 if (numProcs < 2)
return(0);
779 std::vector<int> buf(numProcs*2, 0);
781 std::vector<int>& inProcs = inProcEqns.
procsPtr();
782 std::vector<int> outProcs;
787 size_t numOutProcs = outProcs.size();
789 std::vector<int> recvbuf(numOutProcs, 0);
794 MPI_Status* statuses =
new MPI_Status[numOutProcs];
797 for(
size_t i=0; i<numOutProcs; ++i) {
798 if (MPI_Irecv(&(recvbuf[i]), 1, MPI_INT, outProcs[i], firsttag,
802 size_t numInProcs = inProcs.size();
803 for(
size_t i=0; i<numInProcs; ++i) {
804 if (MPI_Send(&(eqnsPerInProc[i]), 1, MPI_INT, inProcs[i], firsttag,
808 MPI_Waitall((
int)numOutProcs, requests, statuses);
813 std::vector<int> lengths(numOutProcs);
816 for(
unsigned i=0; i<numOutProcs; ++i) {
817 if (recvbuf[i] > 0) {
818 lengths[offset++] = recvbuf[i];
824 std::vector<std::vector<int>*>* outEqns = NULL;
825 if (numOutProcs > 0) {
826 outEqns =
new std::vector<std::vector<int>*>(numOutProcs);
829 for(
unsigned i=0; i<numOutProcs; i++) {
830 (*outEqns)[i] =
new std::vector<int>(lengths[i]);
837 outProcs,
true, *outEqns) );
841 for(
unsigned i=0; i<numOutProcs; i++) {
842 std::vector<int>* eqnArray = (*outEqns)[i];
843 int* eqns = &(*eqnArray)[0];
844 size_t len = eqnArray->size();
845 for(
unsigned j=0; j<len; j++) {
846 outProcEqns.
addEqn(eqns[j], outProcs[i]);
853 #endif //#ifndef FEI_SER
882 #endif //#ifndef FEI_SER
889 const double* coefs,
const int* indices,
int num) {
898 const int* indices,
int num)
929 int* indices,
int num)
953 for(
int i=0; i<numRecvEqns; i++) {
981 ProcEqns sendBCProcEqns, recvBCProcEqns;
985 std::vector<int>& bcEqnNumbers = bcEqns.
eqnNumbers();
986 int numBCeqns = bcEqnNumbers.size();
990 std::vector<std::vector<int>*>& sendProcEqnNumbers =
992 size_t numSendProcs = sendProcs.size();
994 for(i=0; i<numBCeqns; i++) {
995 int eqn = bcEqnNumbers[i];
998 if (index<0)
continue;
1000 std::vector<double>& coefs = bcEqns.
eqns()[i]->coefs();
1001 std::vector<int>& indices = bcEqns.
eqns()[i]->indices();
1003 indices.size(),
false) );
1005 for(
unsigned p=0; p<numSendProcs; p++) {
1006 if (std::binary_search(sendProcEqnNumbers[p]->begin(),
1007 sendProcEqnNumbers[p]->end(), eqn)) {
1009 sendBCProcEqns.
addEqn(eqn, indices.size(), sendProcs[p]);
1018 &sendBCs, &recvBCProcEqns, &recvBCs,
false) );
1044 if (dbgOut != NULL) {
1046 os <<
"#ereb: num-remote-rows: " << _numSendEqns
1047 <<
", numEssEqns: " << numEssEqns <<
FEI_ENDL;
1051 os <<
"#ereb sendEqns_:"<<
FEI_ENDL;
1055 bool accumulate =
false;
1057 std::vector<int> offsets(numEssEqns);
1058 int* offsetsPtr = numEssEqns>0 ? &offsets[0] : NULL;
1060 for(
int j=0; j<_numSendEqns; j++) {
1062 std::vector<int>& indices = _sendEqns[j]->indices();
1065 &indices[0], indices.size());
1067 int sendEqn_j = _sendEqnNumbers[j];
1071 const int* sendEqnsPtr_j = &indices[0];
1073 if (dbgOut != NULL) {
1075 os <<
"#ereb sendeqns["<<j<<
"].length: "
1076 <<_sendEqns[j]->size()<<
", numEssEqns: " << numEssEqns<<
FEI_ENDL;
1079 for(
int i=0; i<numEssEqns; i++) {
1081 int index = offsetsPtr[i];
1083 if (index < 0)
continue;
1085 essSendProcEqns->
addEqn(sendEqn_j, proc);
1087 double coef = essGamma[i]/essAlpha[i];
1088 int essEqns_i = essEqns[i];
1090 int* essEqns_i_ptr = &essEqns_i;
1092 sendEssEqns->
addEqn(sendEqn_j, &coef,
1093 essEqns_i_ptr, 1, accumulate);
1095 for(
size_t k=0; k<_sendEqns[j]->size(); k++) {
1097 int row = sendEqnsPtr_j[k];
1104 if (dbgOut != NULL) {
1106 os <<
"#ereb sendEssEqns:"<<
FEI_ENDL;
1114 std::vector<int>& eqnNumbers = sendEssEqns->
eqnNumbers();
1115 std::vector<fei::CSVec*>& sendEssEqnsVec = sendEssEqns->
eqns();
1116 std::vector<int> eqnLengths(eqnNumbers.size());
1117 for(
size_t i=0; i<eqnNumbers.size(); ++i) {
1118 eqnLengths[i] = sendEssEqnsVec[i]->size();
1121 if (eqnNumbers.size() > 0) {
1132 if (dbgOut != NULL) {
1139 delete essSendProcEqns;
1140 delete essRecvProcEqns;
1148 std::set<int> sendIndices;
1150 for(
size_t i=0; i<sendeqns.size(); ++i) {
1151 std::vector<int>& indices = sendeqns[i]->indices();
1152 int len = indices.size();
1153 if (len < 1)
continue;
1154 int* indicesPtr = &indices[0];
1155 for(
int j=0; j<len; ++j) {
1156 sendIndices.insert(indicesPtr[j]);
1160 std::set<int> recvIndices;
1162 for(
size_t i=0; i<recveqns.size(); ++i) {
1163 std::vector<int>& indices = recveqns[i]->indices();
1164 int len = indices.size();
1165 if (len < 1)
continue;
1166 int* indicesPtr = &indices[0];
1167 for(
int j=0; j<len; ++j) {
1168 recvIndices.insert(indicesPtr[j]);
1172 std::map<int,int>* ptEqns = blkEqnMapper.
getPtEqns();
1173 size_t numPtEqns = ptEqns->size();
1175 std::map<int,int>::const_iterator
1176 pteq = ptEqns->begin(),
1177 pteq_end = ptEqns->end();
1179 std::vector<int> ptBlkInfo(numPtEqns*3);
1180 int* ptBlkInfoPtr = &ptBlkInfo[0];
1183 for(; pteq!=pteq_end; ++pteq) {
1184 int ptEqn = (*pteq).first;
1185 if (sendIndices.find(ptEqn) == sendIndices.end())
continue;
1190 ptBlkInfoPtr[offset++] = ptEqn;
1191 ptBlkInfoPtr[offset++] = blkEqn;
1192 ptBlkInfoPtr[offset++] = blkSize;
1195 ptBlkInfo.resize(offset);
1202 std::vector<std::vector<int>* > recvData(numRecvProcs);
1203 for(
unsigned i=0; i<numRecvProcs; ++i) {
1204 recvData[i] =
new std::vector<int>;
1207 std::vector<std::vector<int>* > sendData(numSendProcs);
1208 for(
unsigned i=0; i<numSendProcs; ++i) {
1209 sendData[i] = &ptBlkInfo;
1213 recvProcs,
false, recvData) );
1215 for(
unsigned i=0; i<numRecvProcs; ++i) {
1216 size_t len = recvData[i]->size()/3;
1217 int* dataPtr = &(*(recvData[i]))[0];
1220 for(
unsigned eq=0; eq<len; ++eq) {
1221 int ptEqn = dataPtr[offset++];
1223 if (recvIndices.find(ptEqn) == recvIndices.end()) {
1224 offset += 2;
continue;
1227 int blkEqn = dataPtr[offset++];
1228 int blkSize = dataPtr[offset++];
1230 blkEqnMapper.
setEqn(ptEqn, blkEqn, blkSize);
1246 for(
size_t i=0; i<rowNumbers.size(); ++i) {
1247 int row = rowNumbers[i];
1248 int offset = rowOffsets[i];
1249 int rowlen = rowOffsets[i+1]-offset;
1250 int* indices = &pckColInds[offset];
1251 double* coefs = &pckCoefs[offset];
1254 if (proc ==
localProc_ || proc < 0)
continue;
1270 std::vector<int>& indices = vec.
indices();
1271 std::vector<double>& coefs = vec.
coefs();
1273 for(
size_t i=0; i<indices.size(); i++) {
1276 if (proc ==
localProc_ || proc < 0)
continue;
1289 std::vector<std::vector<int>*>& sendProcEqnNumbers =
1292 for(
unsigned i=0; i<numSendProcs; i++) {
1293 if (std::binary_search(sendProcEqnNumbers[i]->begin(),
1294 sendProcEqnNumbers[i]->end(), eqn)) {
1296 return(sendProcs[i]);
int GlobalSum(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
static int exchangeEqnBuffers(MPI_Comm comm, ProcEqns *sendProcEqns, EqnBuffer *sendEqns, ProcEqns *recvProcEqns, EqnBuffer *recvEqns, bool accumulate)
int exchangeEqns(std::ostream *dbgOut=NULL)
int Allgatherv(MPI_Comm comm, std::vector< T > &sendbuf, std::vector< int > &recvLengths, std::vector< T > &recvbuf)
int exchangeRemEssBCs(int *essEqns, int numEssEqns, double *essAlpha, double *essGamma, MPI_Comm comm, std::ostream *dbgOut=NULL)
int addEqn(int eqnNumber, const double *coefs, const int *indices, int len, bool accumulate, bool create_indices_union=false)
std::vector< int > & eqnsPerProcPtr()
bool exchangeIndicesCalled_
std::vector< fei::CSVec * > & eqns()
int addRemoteEqns(fei::CSRMat &mat, bool onlyIndices)
EqnCommMgr(MPI_Comm comm, bool accumulate=true)
std::vector< int > & indices()
void setProcEqnLengths(int *eqnNumbers, int *eqnLengths, int len)
int mirrorProcEqns(ProcEqns &inProcEqns, ProcEqns &outProcEqns)
void addEqn(int eqnNumber, int proc)
std::vector< int > rowNumbers
std::vector< int > & eqnNumbers()
int addRHS(int eqnNumber, int rhsIndex, double value, bool accumulate=true)
int exchangeData(MPI_Comm comm, std::vector< int > &sendProcs, std::vector< std::vector< T > > &sendData, std::vector< int > &recvProcs, bool recvDataLengthsKnownOnEntry, std::vector< std::vector< T > > &recvData)
int exchangePtToBlkInfo(snl_fei::PointBlockMap &blkEqnMapper)
EqnCommMgr & operator=(const EqnCommMgr &src)
std::vector< double > solnValues_
int getSendProcNumber(int eqn)
std::vector< int > packedColumnIndices
std::vector< std::vector< double > * > * rhsCoefsPtr()
std::vector< int > rowOffsets
void addLocalEqn(int eqnNumber, int srcProc)
int binarySearch(const T &item, const T *list, int len)
std::vector< int > & procsPtr()
int exchangeIndices(std::ostream *dbgOut=NULL)
std::vector< std::vector< int > * > & procEqnNumbersPtr()
int mirrorProcs(MPI_Comm comm, std::vector< int > &toProcs, std::vector< int > &fromProcs)
int addRemoteEqn(int eqnNumber, int destProc, const double *coefs, const int *indices, int num)
void addRemoteIndices(int eqnNumber, int destProc, int *indices, int num)
int setEqn(int ptEqn, int blkEqn)
int eqnToBlkEqn(int eqn) const
int addEqns(EqnBuffer &inputEqns, bool accumulate)
SparseRowGraph & getGraph()
std::vector< std::vector< int > * > & procEqnLengthsPtr()
int addIndices(int eqnNumber, const int *indices, int len)
std::ostream & console_out()
int consistencyCheck(const char *caller, std::vector< int > &recvProcs, std::vector< int > &recvProcTotalLengths, std::vector< int > &sendProcs, std::vector< int > &sendProcTotalLengths)
std::vector< double > sendEqnSoln_
int getBlkEqnSize(int blkEqn)
int localProc(MPI_Comm comm)
int mirrorProcEqnLengths(ProcEqns &inProcEqns, ProcEqns &outProcEqns)
void setNumRHSs(int numRHSs)
std::map< int, int > * getPtEqns()
int addRemoteRHS(fei::CSVec &vec, int rhsIndex)
std::vector< double > & getPackedCoefs()
void addSolnValues(int *eqnNumbers, double *values, int num)
int numProcs(MPI_Comm comm)
std::vector< double > & coefs()
int gatherSharedBCs(EqnBuffer &bcEqns)