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
772 if (numProcs < 2)
return(0);
774 std::vector<int> buf(numProcs*2, 0);
776 std::vector<int>& inProcs = inProcEqns.
procsPtr();
777 std::vector<int> outProcs;
782 size_t numOutProcs = outProcs.size();
784 std::vector<int> recvbuf(numOutProcs, 0);
789 MPI_Status* statuses =
new MPI_Status[numOutProcs];
792 for(
size_t i=0; i<numOutProcs; ++i) {
793 if (MPI_Irecv(&(recvbuf[i]), 1, MPI_INT, outProcs[i], firsttag,
797 size_t numInProcs = inProcs.size();
798 for(
size_t i=0; i<numInProcs; ++i) {
799 if (MPI_Send(&(eqnsPerInProc[i]), 1, MPI_INT, inProcs[i], firsttag,
803 MPI_Waitall((
int)numOutProcs, requests, statuses);
808 std::vector<int> lengths(numOutProcs);
811 for(
unsigned i=0; i<numOutProcs; ++i) {
812 if (recvbuf[i] > 0) {
813 lengths[offset++] = recvbuf[i];
819 std::vector<std::vector<int>*>* outEqns = NULL;
820 if (numOutProcs > 0) {
821 outEqns =
new std::vector<std::vector<int>*>(numOutProcs);
824 for(
unsigned i=0; i<numOutProcs; i++) {
825 (*outEqns)[i] =
new std::vector<int>(lengths[i]);
832 outProcs,
true, *outEqns) );
836 for(
unsigned i=0; i<numOutProcs; i++) {
837 std::vector<int>* eqnArray = (*outEqns)[i];
838 int* eqns = &(*eqnArray)[0];
839 size_t len = eqnArray->size();
840 for(
unsigned j=0; j<len; j++) {
841 outProcEqns.
addEqn(eqns[j], outProcs[i]);
848 #endif //#ifndef FEI_SER
877 #endif //#ifndef FEI_SER
884 const double* coefs,
const int* indices,
int num) {
893 const int* indices,
int num)
924 int* indices,
int num)
948 for(
int i=0; i<numRecvEqns; i++) {
976 ProcEqns sendBCProcEqns, recvBCProcEqns;
980 std::vector<int>& bcEqnNumbers = bcEqns.
eqnNumbers();
981 int numBCeqns = bcEqnNumbers.size();
985 std::vector<std::vector<int>*>& sendProcEqnNumbers =
987 size_t numSendProcs = sendProcs.size();
989 for(i=0; i<numBCeqns; i++) {
990 int eqn = bcEqnNumbers[i];
993 if (index<0)
continue;
995 std::vector<double>& coefs = bcEqns.
eqns()[i]->coefs();
996 std::vector<int>& indices = bcEqns.
eqns()[i]->indices();
998 indices.size(),
false) );
1000 for(
unsigned p=0; p<numSendProcs; p++) {
1001 if (std::binary_search(sendProcEqnNumbers[p]->begin(),
1002 sendProcEqnNumbers[p]->end(), eqn)) {
1004 sendBCProcEqns.
addEqn(eqn, indices.size(), sendProcs[p]);
1013 &sendBCs, &recvBCProcEqns, &recvBCs,
false) );
1039 if (dbgOut != NULL) {
1041 os <<
"#ereb: num-remote-rows: " << _numSendEqns
1042 <<
", numEssEqns: " << numEssEqns <<
FEI_ENDL;
1046 os <<
"#ereb sendEqns_:"<<
FEI_ENDL;
1050 bool accumulate =
false;
1052 std::vector<int> offsets(numEssEqns);
1053 int* offsetsPtr = numEssEqns>0 ? &offsets[0] : NULL;
1055 for(
int j=0; j<_numSendEqns; j++) {
1057 std::vector<int>& indices = _sendEqns[j]->indices();
1060 &indices[0], indices.size());
1062 int sendEqn_j = _sendEqnNumbers[j];
1066 const int* sendEqnsPtr_j = &indices[0];
1068 if (dbgOut != NULL) {
1070 os <<
"#ereb sendeqns["<<j<<
"].length: "
1071 <<_sendEqns[j]->size()<<
", numEssEqns: " << numEssEqns<<
FEI_ENDL;
1074 for(
int i=0; i<numEssEqns; i++) {
1076 int index = offsetsPtr[i];
1078 if (index < 0)
continue;
1080 essSendProcEqns->
addEqn(sendEqn_j, proc);
1082 double coef = essGamma[i]/essAlpha[i];
1083 int essEqns_i = essEqns[i];
1085 int* essEqns_i_ptr = &essEqns_i;
1087 sendEssEqns->
addEqn(sendEqn_j, &coef,
1088 essEqns_i_ptr, 1, accumulate);
1090 for(
size_t k=0; k<_sendEqns[j]->size(); k++) {
1092 int row = sendEqnsPtr_j[k];
1099 if (dbgOut != NULL) {
1101 os <<
"#ereb sendEssEqns:"<<
FEI_ENDL;
1109 std::vector<int>& eqnNumbers = sendEssEqns->
eqnNumbers();
1110 std::vector<fei::CSVec*>& sendEssEqnsVec = sendEssEqns->
eqns();
1111 std::vector<int> eqnLengths(eqnNumbers.size());
1112 for(
size_t i=0; i<eqnNumbers.size(); ++i) {
1113 eqnLengths[i] = sendEssEqnsVec[i]->size();
1116 if (eqnNumbers.size() > 0) {
1127 if (dbgOut != NULL) {
1134 delete essSendProcEqns;
1135 delete essRecvProcEqns;
1143 std::set<int> sendIndices;
1145 for(
size_t i=0; i<sendeqns.size(); ++i) {
1146 std::vector<int>& indices = sendeqns[i]->indices();
1147 int len = indices.size();
1148 if (len < 1)
continue;
1149 int* indicesPtr = &indices[0];
1150 for(
int j=0; j<len; ++j) {
1151 sendIndices.insert(indicesPtr[j]);
1155 std::set<int> recvIndices;
1157 for(
size_t i=0; i<recveqns.size(); ++i) {
1158 std::vector<int>& indices = recveqns[i]->indices();
1159 int len = indices.size();
1160 if (len < 1)
continue;
1161 int* indicesPtr = &indices[0];
1162 for(
int j=0; j<len; ++j) {
1163 recvIndices.insert(indicesPtr[j]);
1167 std::map<int,int>* ptEqns = blkEqnMapper.
getPtEqns();
1168 size_t numPtEqns = ptEqns->size();
1170 std::map<int,int>::const_iterator
1171 pteq = ptEqns->begin(),
1172 pteq_end = ptEqns->end();
1174 std::vector<int> ptBlkInfo(numPtEqns*3);
1175 int* ptBlkInfoPtr = &ptBlkInfo[0];
1178 for(; pteq!=pteq_end; ++pteq) {
1179 int ptEqn = (*pteq).first;
1180 if (sendIndices.find(ptEqn) == sendIndices.end())
continue;
1185 ptBlkInfoPtr[offset++] = ptEqn;
1186 ptBlkInfoPtr[offset++] = blkEqn;
1187 ptBlkInfoPtr[offset++] = blkSize;
1190 ptBlkInfo.resize(offset);
1197 std::vector<std::vector<int>* > recvData(numRecvProcs);
1198 for(
unsigned i=0; i<numRecvProcs; ++i) {
1199 recvData[i] =
new std::vector<int>;
1202 std::vector<std::vector<int>* > sendData(numSendProcs);
1203 for(
unsigned i=0; i<numSendProcs; ++i) {
1204 sendData[i] = &ptBlkInfo;
1208 recvProcs,
false, recvData) );
1210 for(
unsigned i=0; i<numRecvProcs; ++i) {
1211 size_t len = recvData[i]->size()/3;
1212 int* dataPtr = &(*(recvData[i]))[0];
1215 for(
unsigned eq=0; eq<len; ++eq) {
1216 int ptEqn = dataPtr[offset++];
1218 if (recvIndices.find(ptEqn) == recvIndices.end()) {
1219 offset += 2;
continue;
1222 int blkEqn = dataPtr[offset++];
1223 int blkSize = dataPtr[offset++];
1225 blkEqnMapper.
setEqn(ptEqn, blkEqn, blkSize);
1241 for(
size_t i=0; i<rowNumbers.size(); ++i) {
1242 int row = rowNumbers[i];
1243 int offset = rowOffsets[i];
1244 int rowlen = rowOffsets[i+1]-offset;
1245 int* indices = &pckColInds[offset];
1246 double* coefs = &pckCoefs[offset];
1249 if (proc ==
localProc_ || proc < 0)
continue;
1265 std::vector<int>& indices = vec.
indices();
1266 std::vector<double>& coefs = vec.
coefs();
1268 for(
size_t i=0; i<indices.size(); i++) {
1271 if (proc ==
localProc_ || proc < 0)
continue;
1284 std::vector<std::vector<int>*>& sendProcEqnNumbers =
1287 for(
unsigned i=0; i<numSendProcs; i++) {
1288 if (std::binary_search(sendProcEqnNumbers[i]->begin(),
1289 sendProcEqnNumbers[i]->end(), eqn)) {
1291 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)