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
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);
788 MPI_Request* requests =
new MPI_Request[numOutProcs];
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,
794 comm_, &requests[offset++]) != MPI_SUCCESS) ERReturn(-1);
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,
800 comm_) != MPI_SUCCESS) ERReturn(-1);
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]);
830 CHK_ERR( fei::exchangeData(comm_, inProcs,
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
872 CHK_ERR( fei::exchangeData( comm_, inProcEqns.
procsPtr(),
877 #endif //#ifndef FEI_SER
883 int EqnCommMgr::addRemoteEqn(
int eqnNumber,
int destProc,
884 const double* coefs,
const int* indices,
int num) {
886 sendEqns_->newCoefData_ = 1;
888 return(sendEqns_->
addEqn(eqnNumber, coefs, indices, num, accumulate_));
892 int EqnCommMgr::addRemoteEqn(
int eqnNumber,
const double* coefs,
893 const int* indices,
int num)
895 sendEqns_->newCoefData_ = 1;
897 return(sendEqns_->
addEqn(eqnNumber, coefs, indices, num, accumulate_));
901 void EqnCommMgr::setNumRHSs(
int numRHSs) {
907 int EqnCommMgr::addRemoteRHS(
int eqnNumber,
int destProc,
int rhsIndex,
911 sendEqns_->newRHSData_ = 1;
912 return(sendEqns_->
addRHS(eqnNumber, rhsIndex, value));
916 int EqnCommMgr::addRemoteRHS(
int eqnNumber,
int rhsIndex,
double value)
918 sendEqns_->newRHSData_ = 1;
919 return(sendEqns_->
addRHS(eqnNumber, rhsIndex, value));
923 void EqnCommMgr::addRemoteIndices(
int eqnNumber,
int destProc,
924 int* indices,
int num)
927 fei::console_out() <<
"fei: EqnCommMgr::addRemoteIndices ERROR, destProc < 0" << FEI_ENDL;
931 sendEqns_->
addIndices(eqnNumber, indices, num);
933 sendProcEqns_->
addEqn(eqnNumber, destProc);
937 void EqnCommMgr::resetCoefs() {
942 sendEqns_->newCoefData_ = 0;
943 sendEqns_->newRHSData_ = 0;
944 recvEqns_->newCoefData_ = 0;
945 recvEqns_->newRHSData_ = 0;
948 for(
int i=0; i<numRecvEqns; i++) {
949 solnValues_[i] = 0.0;
954 int EqnCommMgr::gatherSharedBCs(
EqnBuffer& bcEqns)
976 ProcEqns sendBCProcEqns, recvBCProcEqns;
980 std::vector<int>& bcEqnNumbers = bcEqns.
eqnNumbers();
981 int numBCeqns = bcEqnNumbers.size();
983 std::vector<int>& sendEqnNumbers = sendEqns_->
eqnNumbers();
984 std::vector<int>& sendProcs = sendProcEqns_->
procsPtr();
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();
997 CHK_ERR( sendBCs.
addEqn(eqn, &coefs[0], &indices[0],
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]);
1012 CHK_ERR( exchangeEqnBuffers(comm_, &sendBCProcEqns,
1013 &sendBCs, &recvBCProcEqns, &recvBCs,
false) );
1016 CHK_ERR( bcEqns.
addEqns(recvBCs,
false) );
1022 int EqnCommMgr::exchangeRemEssBCs(
int* essEqns,
int numEssEqns,
double* essAlpha,
1023 double* essGamma, MPI_Comm comm,
1024 FEI_OSTREAM* dbgOut)
1032 std::vector<fei::CSVec*>& _sendEqns = sendEqns_->
eqns();
1033 std::vector<int>& _sendEqnNumbers = sendEqns_->
eqnNumbers();
1039 if (dbgOut != NULL) {
1040 FEI_OSTREAM& os = *dbgOut;
1041 os <<
"#ereb: num-remote-rows: " << _numSendEqns
1042 <<
", numEssEqns: " << numEssEqns << FEI_ENDL;
1046 os <<
"#ereb sendEqns_:"<<FEI_ENDL;
1047 os << *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];
1064 int proc = getSendProcNumber(sendEqn_j);
1066 const int* sendEqnsPtr_j = &indices[0];
1068 if (dbgOut != NULL) {
1069 FEI_OSTREAM& os = *dbgOut;
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];
1094 essBCEqns_->
addEqn(row, &coef, essEqns_i_ptr, 1, accumulate);
1099 if (dbgOut != NULL) {
1100 FEI_OSTREAM& os = *dbgOut;
1101 os <<
"#ereb sendEssEqns:"<<FEI_ENDL;
1102 os << *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) {
1124 CHK_ERR( exchangeEqnBuffers(comm, essSendProcEqns, sendEssEqns,
1125 essRecvProcEqns, essBCEqns_, accumulate) );
1127 if (dbgOut != NULL) {
1128 FEI_OSTREAM& os = *dbgOut;
1129 os <<
"essBCEqns:"<<FEI_ENDL;
1130 os << *essBCEqns_ << FEI_ENDL;
1134 delete essSendProcEqns;
1135 delete essRecvProcEqns;
1143 std::set<int> sendIndices;
1144 std::vector<fei::CSVec*>& sendeqns = sendEqns_->
eqns();
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;
1156 std::vector<fei::CSVec*>& recveqns = recvEqns_->
eqns();
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);
1192 size_t numRecvProcs = recvProcEqns_->
getNumProcs();
1193 std::vector<int>& recvProcs = recvProcEqns_->
procsPtr();
1194 size_t numSendProcs = sendProcEqns_->
getNumProcs();
1195 std::vector<int>& sendProcs = sendProcEqns_->
procsPtr();
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;
1207 CHK_ERR( fei::exchangeData(comm_, sendProcs, sendData,
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);
1234 int EqnCommMgr::addRemoteEqns(
fei::CSRMat& mat,
bool onlyIndices)
1236 std::vector<int>& rowNumbers = mat.getGraph().
rowNumbers;
1237 std::vector<int>& rowOffsets = mat.getGraph().
rowOffsets;
1239 std::vector<double>& pckCoefs = mat.getPackedCoefs();
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];
1248 int proc = getSendProcNumber(row);
1249 if (proc == localProc_ || proc < 0)
continue;
1252 addRemoteIndices(row, proc, indices, rowlen);
1255 CHK_ERR( addRemoteEqn(row, proc, coefs, indices, rowlen) );
1263 int EqnCommMgr::addRemoteRHS(
fei::CSVec& vec,
int rhsIndex)
1265 std::vector<int>& indices = vec.indices();
1266 std::vector<double>& coefs = vec.coefs();
1268 for(
size_t i=0; i<indices.size(); i++) {
1269 int proc = getSendProcNumber(indices[i]);
1271 if (proc == localProc_ || proc < 0)
continue;
1273 CHK_ERR( addRemoteRHS(indices[i], proc, rhsIndex, coefs[i]) );
1280 int EqnCommMgr::getSendProcNumber(
int eqn)
1282 size_t numSendProcs = sendProcEqns_->
getNumProcs();
1283 std::vector<int>& sendProcs = sendProcEqns_->
procsPtr();
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)
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)