9 #include <fei_macros.hpp>
13 #include <fei_EqnCommMgr.hpp>
15 #include <fei_CommUtils.hpp>
17 #include <fei_ProcEqns.hpp>
18 #include <fei_EqnBuffer.hpp>
19 #include <fei_TemplateUtils.hpp>
24 #define fei_file "EqnCommMgr.cpp"
25 #include <fei_ErrMacros.hpp>
29 : accumulate_(accumulate),
32 exchangeIndicesCalled_(false),
52 : accumulate_(src.accumulate_),
55 exchangeIndicesCalled_(false),
82 recvProcEqns_ = src.recvProcEqns_->
deepCopy();
84 exchangeIndicesCalled_ = src.exchangeIndicesCalled_;
85 accumulate_ = src.accumulate_;
88 recvEqns_ = src.recvEqns_->
deepCopy();
90 int len = src.solnValues_.size();
92 solnValues_.resize(len);
94 for(
int i=0; i<len; i++) {
95 solnValues_[i] = src.solnValues_[i];
99 sendProcEqns_ = src.sendProcEqns_->
deepCopy();
102 sendEqns_ = src.sendEqns_->
deepCopy();
104 len = src.sendEqnSoln_.size();
105 sendEqnSoln_.resize(len);
107 for(
int i=0; i<len; i++) {
108 sendEqnSoln_[i] = src.sendEqnSoln_[i];
112 essBCEqns_ = src.essBCEqns_->
deepCopy();
137 if (srcProc == localProc_) {
138 fei::console_out() <<
"EqnCommMgr::addRecvEqn: ERROR, srcProc == localProc_, "
139 <<
"which is a recipe for a deadlock." << FEI_ENDL;
143 recvProcEqns_->
addEqn(eqnNumber, srcProc);
147 void EqnCommMgr::addSolnValues(
int* eqnNumbers,
double* values,
int num)
149 if (!exchangeIndicesCalled_) {
150 fei::console_out() <<
"EqnCommMgr::addSolnValues: ERROR, you may not call this until"
151 " after exchangeIndices has been called." << FEI_ENDL;
155 std::vector<int>& recvEqnNumbers = recvEqns_->
eqnNumbers();
157 double* solnValuesPtr = &solnValues_[0];
158 for(
int i=0; i<num; i++) {
161 if (index < 0)
continue;
163 solnValuesPtr[index] = values[i];
168 int EqnCommMgr::exchangeIndices(FEI_OSTREAM* dbgOut) {
180 fei::CSVec** sendEqnsPtr = numSendEqns>0 ?&(sendEqns_->
eqns()[0]) : NULL;
181 std::vector<int>& sendEqnNumbers = sendEqns_->
eqnNumbers();
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) {
199 size_t numRecvProcs = recvProcEqns_->
getNumProcs();
200 size_t numSendProcs = sendProcEqns_->
getNumProcs();
201 std::vector<int>& sendProcs = sendProcEqns_->
procsPtr();
205 sendEqnSoln_.resize(numSendEqns);
210 std::vector<int> recvProcTotalLengths(numRecvProcs);
211 std::vector<int> sendProcTotalLengths(numSendProcs);
213 std::vector<int>& recvProcs = recvProcEqns_->
procsPtr();
214 std::vector<int>& eqnsPerRecvProc = recvProcEqns_->
eqnsPerProcPtr();
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;
230 std::vector<int>& eqnsPerSendProc = sendProcEqns_->
eqnsPerProcPtr();
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;
250 CHK_ERR( consistencyCheck(
"exchangeIndices", recvProcs, recvProcTotalLengths,
251 sendProcs, sendProcTotalLengths) );
253 int** recvProcEqnIndices = NULL;
255 if (numRecvProcs > 0) {
256 recvProcEqnIndices =
new int*[numRecvProcs];
259 MPI_Request* indRequests = NULL;
261 if (numRecvProcs > 0) {
262 indRequests =
new MPI_Request[numRecvProcs];
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,
277 recvProcs[i], indTag, comm_, &indRequests[i]) != MPI_SUCCESS) {
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++) {
297 int eqnLoc = sendEqns_->
getEqnIndex((*(sendProcEqnNumbers[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],
307 indTag, comm_) != MPI_SUCCESS) ERReturn(-1)
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: "
339 << numCompleted << FEI_ENDL;
345 solnValues_.resize(numRecvEqns);
347 exchangeIndicesCalled_ =
true;
349 if (dbgOut != NULL) {
350 FEI_OSTREAM& os = *dbgOut;
351 os <<
"#ereb exchangeIndices, sendEqns_:"<<FEI_ENDL;
357 #endif // #ifndef FEI_SER
363 int EqnCommMgr::consistencyCheck(
const char* caller,
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 "
403 << i <<
" is expecting to send to proc " << localProc_ << FEI_ENDL;
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 "
422 << sendLength <<
" indices to proc " << localProc_ << FEI_ENDL;
438 int EqnCommMgr::exchangeEqns(FEI_OSTREAM* dbgOut)
447 if (dbgOut != NULL) {
448 FEI_OSTREAM& os = *dbgOut;
449 os <<
"#ereb exchangeEqns begin, sendEqns_:"<<FEI_ENDL;
453 CHK_ERR( exchangeEqnBuffers(comm_, sendProcEqns_,
454 sendEqns_, recvProcEqns_, recvEqns_, accumulate_));
456 if (dbgOut != NULL) {
457 FEI_OSTREAM& os = *dbgOut;
458 os <<
"#ereb exchangeEqns end, sendEqns_:"<<FEI_ENDL;
466 int EqnCommMgr::exchangeEqnBuffers(MPI_Comm comm,
ProcEqns* sendProcEqns,
484 int indTag = 9113, coefTag = 9114;
488 if ((numRecvProcs == 0) && (numSendProcs == 0))
return(0);
494 MPI_Request* indRequests = NULL;
495 MPI_Request* coefRequests = NULL;
496 int** recvProcEqnIndices = NULL;
497 double** recvProcEqnCoefs = NULL;
499 if (numRecvProcs > 0) {
500 indRequests =
new MPI_Request[numRecvProcs];
501 coefRequests =
new MPI_Request[numRecvProcs];
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];
587 indicesPtr[offset] = sendEqns->newCoefData_;
588 indicesPtr[offset+1] = sendEqns->newRHSData_;
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
663 void EqnCommMgr::exchangeSoln()
671 MPI_Request* solnRequests = NULL;
672 double** solnBuffer = NULL;
674 size_t numSendProcs = sendProcEqns_->
getNumProcs();
675 std::vector<int>& sendProcs = sendProcEqns_->
procsPtr();
676 std::vector<int>& eqnsPerSendProc = sendProcEqns_->
eqnsPerProcPtr();
678 if (numSendProcs > 0) {
679 solnRequests =
new MPI_Request[numSendProcs];
680 solnBuffer =
new double*[numSendProcs];
683 MPI_Comm comm = comm_;
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]);
693 size_t numRecvProcs = recvProcEqns_->
getNumProcs();
694 std::vector<int>& recvProcs = recvProcEqns_->
procsPtr();
695 std::vector<int>& eqnsPerRecvProc = recvProcEqns_->
eqnsPerProcPtr();
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];
707 solnBuff[j] = solnValues_[index];
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];
732 sendEqnSoln_[ind] = solnBuffer[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);
793 MPI_Request* requests =
new MPI_Request[numOutProcs];
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,
799 comm_, &requests[offset++]) != MPI_SUCCESS) ERReturn(-1);
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,
805 comm_) != MPI_SUCCESS) ERReturn(-1);
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]);
835 CHK_ERR( fei::exchangeData(comm_, inProcs,
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
877 CHK_ERR( fei::exchangeData( comm_, inProcEqns.
procsPtr(),
882 #endif //#ifndef FEI_SER
888 int EqnCommMgr::addRemoteEqn(
int eqnNumber,
int destProc,
889 const double* coefs,
const int* indices,
int num) {
891 sendEqns_->newCoefData_ = 1;
893 return(sendEqns_->
addEqn(eqnNumber, coefs, indices, num, accumulate_));
897 int EqnCommMgr::addRemoteEqn(
int eqnNumber,
const double* coefs,
898 const int* indices,
int num)
900 sendEqns_->newCoefData_ = 1;
902 return(sendEqns_->
addEqn(eqnNumber, coefs, indices, num, accumulate_));
906 void EqnCommMgr::setNumRHSs(
int numRHSs) {
912 int EqnCommMgr::addRemoteRHS(
int eqnNumber,
int destProc,
int rhsIndex,
916 sendEqns_->newRHSData_ = 1;
917 return(sendEqns_->
addRHS(eqnNumber, rhsIndex, value));
921 int EqnCommMgr::addRemoteRHS(
int eqnNumber,
int rhsIndex,
double value)
923 sendEqns_->newRHSData_ = 1;
924 return(sendEqns_->
addRHS(eqnNumber, rhsIndex, value));
928 void EqnCommMgr::addRemoteIndices(
int eqnNumber,
int destProc,
929 int* indices,
int num)
932 fei::console_out() <<
"fei: EqnCommMgr::addRemoteIndices ERROR, destProc < 0" << FEI_ENDL;
936 sendEqns_->
addIndices(eqnNumber, indices, num);
938 sendProcEqns_->
addEqn(eqnNumber, destProc);
942 void EqnCommMgr::resetCoefs() {
947 sendEqns_->newCoefData_ = 0;
948 sendEqns_->newRHSData_ = 0;
949 recvEqns_->newCoefData_ = 0;
950 recvEqns_->newRHSData_ = 0;
953 for(
int i=0; i<numRecvEqns; i++) {
954 solnValues_[i] = 0.0;
959 int EqnCommMgr::gatherSharedBCs(
EqnBuffer& bcEqns)
981 ProcEqns sendBCProcEqns, recvBCProcEqns;
985 std::vector<int>& bcEqnNumbers = bcEqns.
eqnNumbers();
986 int numBCeqns = bcEqnNumbers.size();
988 std::vector<int>& sendEqnNumbers = sendEqns_->
eqnNumbers();
989 std::vector<int>& sendProcs = sendProcEqns_->
procsPtr();
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();
1002 CHK_ERR( sendBCs.
addEqn(eqn, &coefs[0], &indices[0],
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]);
1017 CHK_ERR( exchangeEqnBuffers(comm_, &sendBCProcEqns,
1018 &sendBCs, &recvBCProcEqns, &recvBCs,
false) );
1021 CHK_ERR( bcEqns.
addEqns(recvBCs,
false) );
1027 int EqnCommMgr::exchangeRemEssBCs(
int* essEqns,
int numEssEqns,
double* essAlpha,
1028 double* essGamma, MPI_Comm comm,
1029 FEI_OSTREAM* dbgOut)
1037 std::vector<fei::CSVec*>& _sendEqns = sendEqns_->
eqns();
1038 std::vector<int>& _sendEqnNumbers = sendEqns_->
eqnNumbers();
1044 if (dbgOut != NULL) {
1045 FEI_OSTREAM& os = *dbgOut;
1046 os <<
"#ereb: num-remote-rows: " << _numSendEqns
1047 <<
", numEssEqns: " << numEssEqns << FEI_ENDL;
1051 os <<
"#ereb sendEqns_:"<<FEI_ENDL;
1052 os << *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];
1069 int proc = getSendProcNumber(sendEqn_j);
1071 const int* sendEqnsPtr_j = &indices[0];
1073 if (dbgOut != NULL) {
1074 FEI_OSTREAM& os = *dbgOut;
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];
1099 essBCEqns_->
addEqn(row, &coef, essEqns_i_ptr, 1, accumulate);
1104 if (dbgOut != NULL) {
1105 FEI_OSTREAM& os = *dbgOut;
1106 os <<
"#ereb sendEssEqns:"<<FEI_ENDL;
1107 os << *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) {
1129 CHK_ERR( exchangeEqnBuffers(comm, essSendProcEqns, sendEssEqns,
1130 essRecvProcEqns, essBCEqns_, accumulate) );
1132 if (dbgOut != NULL) {
1133 FEI_OSTREAM& os = *dbgOut;
1134 os <<
"essBCEqns:"<<FEI_ENDL;
1135 os << *essBCEqns_ << FEI_ENDL;
1139 delete essSendProcEqns;
1140 delete essRecvProcEqns;
1148 std::set<int> sendIndices;
1149 std::vector<fei::CSVec*>& sendeqns = sendEqns_->
eqns();
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;
1161 std::vector<fei::CSVec*>& recveqns = recvEqns_->
eqns();
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);
1197 size_t numRecvProcs = recvProcEqns_->
getNumProcs();
1198 std::vector<int>& recvProcs = recvProcEqns_->
procsPtr();
1199 size_t numSendProcs = sendProcEqns_->
getNumProcs();
1200 std::vector<int>& sendProcs = sendProcEqns_->
procsPtr();
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;
1212 CHK_ERR( fei::exchangeData(comm_, sendProcs, sendData,
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);
1239 int EqnCommMgr::addRemoteEqns(
fei::CSRMat& mat,
bool onlyIndices)
1241 std::vector<int>& rowNumbers = mat.getGraph().
rowNumbers;
1242 std::vector<int>& rowOffsets = mat.getGraph().
rowOffsets;
1244 std::vector<double>& pckCoefs = mat.getPackedCoefs();
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];
1253 int proc = getSendProcNumber(row);
1254 if (proc == localProc_ || proc < 0)
continue;
1257 addRemoteIndices(row, proc, indices, rowlen);
1260 CHK_ERR( addRemoteEqn(row, proc, coefs, indices, rowlen) );
1268 int EqnCommMgr::addRemoteRHS(
fei::CSVec& vec,
int rhsIndex)
1270 std::vector<int>& indices = vec.indices();
1271 std::vector<double>& coefs = vec.coefs();
1273 for(
size_t i=0; i<indices.size(); i++) {
1274 int proc = getSendProcNumber(indices[i]);
1276 if (proc == localProc_ || proc < 0)
continue;
1278 CHK_ERR( addRemoteRHS(indices[i], proc, rhsIndex, coefs[i]) );
1285 int EqnCommMgr::getSendProcNumber(
int eqn)
1287 size_t numSendProcs = sendProcEqns_->
getNumProcs();
1288 std::vector<int>& sendProcs = sendProcEqns_->
procsPtr();
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)
int Allgatherv(MPI_Comm comm, std::vector< T > &sendbuf, std::vector< int > &recvLengths, std::vector< T > &recvbuf)
int addEqn(int eqnNumber, const double *coefs, const int *indices, int len, bool accumulate, bool create_indices_union=false)
std::vector< int > & eqnsPerProcPtr()
std::vector< fei::CSVec * > & eqns()
EqnCommMgr(MPI_Comm comm, bool accumulate=true)
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)
EqnCommMgr & operator=(const EqnCommMgr &src)
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()
std::vector< std::vector< int > * > & procEqnNumbersPtr()
int mirrorProcs(MPI_Comm comm, std::vector< int > &toProcs, std::vector< int > &fromProcs)
int setEqn(int ptEqn, int blkEqn)
int eqnToBlkEqn(int eqn) const
int addEqns(EqnBuffer &inputEqns, bool accumulate)
std::vector< std::vector< int > * > & procEqnLengthsPtr()
int addIndices(int eqnNumber, const int *indices, int len)
std::ostream & console_out()
int getBlkEqnSize(int blkEqn)
int localProc(MPI_Comm comm)
int mirrorProcEqnLengths(ProcEqns &inProcEqns, ProcEqns &outProcEqns)
std::map< int, int > * getPtEqns()
int numProcs(MPI_Comm comm)