9 #include "fei_sstream.hpp"
15 #include "fei_utils.hpp"
16 #include <fei_impl_utils.hpp>
20 #include <fei_ostream_ops.hpp>
21 #include "fei_CommUtils.hpp"
22 #include "fei_TemplateUtils.hpp"
23 #include "snl_fei_Constraint.hpp"
26 #include "fei_DirichletBCManager.hpp"
27 #include "fei_FillableMat.hpp"
28 #include "fei_CSVec.hpp"
29 #include "FEI_Implementation.hpp"
30 #include "fei_EqnCommMgr.hpp"
31 #include "fei_ConnectivityTable.hpp"
32 #include "fei_NodeDescriptor.hpp"
33 #include "fei_NodeDatabase.hpp"
34 #include "fei_BlockDescriptor.hpp"
35 #include "SNL_FEI_Structure.hpp"
36 #include "snl_fei_Utils.hpp"
37 #include "fei_Data.hpp"
38 #include "fei_LinearSystemCore.hpp"
39 #include "fei_LinSysCore_flexible.hpp"
41 #include "fei_LinSysCoreFilter.hpp"
44 #define fei_file "fei_LinSysCoreFilter.cpp"
45 #include "fei_ErrMacros.hpp"
47 #define ASSEMBLE_PUT 0
48 #define ASSEMBLE_SUM 1
58 timesInitializeCalled_(0),
61 newMatrixData_(false),
62 newVectorData_(false),
63 newConstraintData_(false),
65 connectivitiesInitialized_(false),
66 firstRemEqnExchange_(true),
67 needToCallMatrixLoadComplete_(false),
68 resolveConflictRequested_(false),
73 numLocallyOwnedNodes_(0),
75 firstLocalNodeNumber_(-1),
77 tooLateToChooseBlock_(false),
79 localReducedBlkOffset_(0),
80 numLocalReducedEqnBlks_(0),
86 masterRank_(masterRank),
87 problemStructure_(probStruct),
88 matrixAllocated_(false),
94 eqnCommMgr_put_(NULL),
112 rhsIDs_.resize(numRHSs_);
115 bcManager_ =
new fei::DirichletBCManager(probStruct);
116 eqnCommMgr_ = problemStructure_->getEqnCommMgr().deepCopy();
117 int err = createEqnCommMgr_put();
121 char** paramStrings = NULL;
125 err = parameters(numParams, paramStrings);
127 fei::console_out() <<
"LinSysCoreFilter::LinSysCoreFilter ERROR, parameters failed." << FEI_ENDL;
128 MPI_Abort(comm_, -1);
131 Kid_ =
new fei::FillableMat;
132 Kdi_ =
new fei::FillableMat;
133 Kdd_ =
new fei::FillableMat;
134 reducedEqnCounter_ = 0;
135 reducedRHSCounter_ = 0;
141 LinSysCoreFilter::~LinSysCoreFilter() {
149 delete eqnCommMgr_put_;
161 int LinSysCoreFilter::initialize()
166 debugOutput(
"#LinSysCoreFilter::initialize");
168 numLocalEqns_ = problemStructure_->getNumLocalEqns();
169 numLocalEqnBlks_ = problemStructure_->getNumLocalEqnBlks();
170 numLocalReducedEqnBlks_ = problemStructure_->getNumLocalReducedEqnBlks();
182 std::vector<int>& eqnOffsets = problemStructure_->getGlobalEqnOffsets();
183 localStartRow_ = eqnOffsets[localRank_];
184 localEndRow_ = eqnOffsets[localRank_+1]-1;
185 numGlobalEqns_ = eqnOffsets[numProcs_];
187 std::vector<int>& nodeOffsets = problemStructure_->getGlobalNodeOffsets();
188 firstLocalNodeNumber_ = nodeOffsets[localRank_];
189 numGlobalNodes_ = nodeOffsets[numProcs_];
194 if (eqnCommMgr_ != NULL)
delete eqnCommMgr_;
196 if (eqnCommMgr_put_ != NULL)
delete eqnCommMgr_put_;
197 eqnCommMgr_put_ = NULL;
199 eqnCommMgr_ = problemStructure_->getEqnCommMgr().
deepCopy();
200 if (eqnCommMgr_ == NULL) ERReturn(-1);
202 int err = createEqnCommMgr_put();
203 if (err != 0) ERReturn(err);
206 eqnCommMgr_->setNumRHSs(numRHSs_);
211 CHK_ERR( initLinSysCore() );
213 setLinSysCoreCREqns();
215 if (timesInitializeCalled_ == 0) {
220 std::vector<int> rowLengths;
221 CHK_ERR( problemStructure_->getMatrixRowLengths(rowLengths) );
223 int numReducedEqns = problemStructure_->getNumLocalReducedEqns();
224 int maxBlkSize = problemStructure_->getGlobalMaxBlkSize();
225 std::vector<int> blkSizes(numLocalReducedEqnBlks_, 1);
228 for(
size_t ii=0; ii<rowLengths.size(); ++ii) {
229 numNonzeros += rowLengths[ii];
232 std::vector<int> indices_1D(numNonzeros);
233 std::vector<int*> indices(numReducedEqns);
236 for(
size_t ii=0; ii<rowLengths.size(); ++ii) {
237 indices[ii] = &(indices_1D[offset]);
238 offset += rowLengths[ii];
241 if (maxBlkSize == 0) ERReturn(-1);
243 if (maxBlkSize == 1) {
244 CHK_ERR( problemStructure_->getMatrixStructure(&indices[0], rowLengths) );
246 debugOutput(
"#LinSysCoreFilter calling point lsc_->setMatrixStructure");
248 &indices[0], &rowLengths[0], &blkSizes[0]) );
251 std::vector<int> blkRowLengths;
252 int* blkIndices_1D = numNonzeros > 0 ?
new int[numNonzeros] : NULL;
253 int** blkIndices = numLocalReducedEqnBlks_ ?
254 new int*[numLocalReducedEqnBlks_] : NULL;
255 if (blkIndices == NULL && numLocalReducedEqnBlks_ != 0) ERReturn(-1);
257 CHK_ERR( problemStructure_->getMatrixStructure(&indices[0], rowLengths,
258 blkIndices, blkIndices_1D,
259 blkRowLengths, blkSizes) );
262 for(
int ii=0; ii<numLocalReducedEqnBlks_; ++ii) {
263 blkIndices[ii] = &(blkIndices_1D[offset]);
264 offset += blkRowLengths[ii];
267 debugOutput(
"#LinSysCoreFilter calling block lsc_->setMatrixStructure");
269 blkIndices, &blkRowLengths[0], &blkSizes[0]) );
271 if (numLocalReducedEqnBlks_ != 0)
delete [] blkIndices;
272 if (numNonzeros > 0)
delete [] blkIndices_1D;
276 matrixAllocated_ =
true;
278 debugOutput(
"#leaving LinSysCoreFilter::initialize");
279 ++timesInitializeCalled_;
284 int LinSysCoreFilter::createEqnCommMgr_put()
286 if (eqnCommMgr_put_ != NULL)
return(0);
288 eqnCommMgr_put_ = eqnCommMgr_->
deepCopy();
289 if (eqnCommMgr_put_ == NULL) ERReturn(-1);
291 eqnCommMgr_put_->resetCoefs();
292 eqnCommMgr_put_->accumulate_ =
false;
297 int LinSysCoreFilter::initLinSysCore()
299 debugOutput(
"#LinSysCoreFilter calling lsc_->setLookup");
300 int err = lsc_->
setLookup(*problemStructure_);
306 std::vector<int>& globalNodeOffsets = problemStructure_->getGlobalNodeOffsets();
307 std::vector<int>& globalEqnOffsets = problemStructure_->getGlobalEqnOffsets();
308 std::vector<int>& globalBlkEqnOffsets =
309 problemStructure_->getGlobalBlkEqnOffsets();
311 int startRow = localStartRow_;
312 while(problemStructure_->
isSlaveEqn(startRow)) startRow++;
313 int endRow = localEndRow_;
314 while(problemStructure_->
isSlaveEqn(endRow)) endRow--;
318 numReducedRows_ = reducedEndRow_ - reducedStartRow_ + 1;
320 std::vector<int> reducedEqnOffsets(globalEqnOffsets.size());
321 std::vector<int> reducedBlkEqnOffsets(globalBlkEqnOffsets.size());
322 std::vector<int> reducedNodeOffsets(globalNodeOffsets.size());
324 int numSlaveEqns = problemStructure_->numSlaveEquations();
329 std::vector<int> tmpSend(2), tmpRecv, tmpRecvLengths;
330 tmpSend[0] = reducedStartRow_;
331 tmpSend[1] = reducedNodeNum;
334 for(
size_t ii=0; ii<globalEqnOffsets.size()-1; ++ii) {
335 reducedEqnOffsets[ii] = tmpRecv[ii*2];
336 reducedNodeOffsets[ii] = tmpRecv[ii*2+1];
341 if (numSlaveEqns > 0) {
342 reducedBlkEqnOffsets[ii] = reducedNodeOffsets[ii];
345 reducedBlkEqnOffsets[ii] = globalBlkEqnOffsets[ii];
349 if (localRank_ == numProcs_-1) {
350 reducedNodeNum = problemStructure_->
351 translateToReducedNodeNumber(globalNodeOffsets[numProcs_]-1, localRank_);
352 int blkEqn = globalBlkEqnOffsets[numProcs_]-1;
353 if (numSlaveEqns > 0) {
354 blkEqn = reducedNodeNum;
358 tmpSend[0] = reducedEndRow_;
359 tmpSend[1] = reducedNodeNum;
366 CHK_ERR( fei::Bcast(comm_, tmpSend, numProcs_-1) );
367 reducedEqnOffsets[numProcs_] = tmpSend[0]+1;
368 reducedNodeOffsets[numProcs_] = tmpSend[1]+1;
369 reducedBlkEqnOffsets[numProcs_] = tmpSend[2]+1;
371 debugOutput(
"#LinSysCoreFilter calling lsc_->setGlobalOffsets");
373 &reducedNodeOffsets[0],
374 &reducedEqnOffsets[0],
375 &reducedBlkEqnOffsets[0]) );
377 if (connectivitiesInitialized_)
return(0);
380 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
381 NodeCommMgr& nodeCommMgr = problemStructure_->getNodeCommMgr();
384 int numRemoteNodes = nodeCommMgr.getSharedNodeIDs().size() -
385 nodeCommMgr.getLocalNodeIDs().size();
386 numNodes -= numRemoteNodes;
388 std::vector<int> numElemsPerBlock(numBlocks);
389 std::vector<int> numNodesPerElem(numBlocks);
390 std::vector<int> numDofPerNode(0,1);
392 for(
int blk=0; blk<numBlocks; blk++) {
396 numElemsPerBlock[blk] = block->getNumElements();
397 numNodesPerElem[blk] = block->getNumNodesPerElement();
399 int* fieldsPerNode = block->fieldsPerNodePtr();
402 for(
int nn=0; nn<numNodesPerElem[blk]; nn++) {
403 if (fieldsPerNode[nn] <= 0) ERReturn(-1);
404 numDofPerNode.push_back(0);
405 int indx = numDofPerNode.size()-1;
407 for(
int nf=0; nf<fieldsPerNode[nn]; nf++) {
408 numDofPerNode[indx] += problemStructure_->
getFieldSize(fieldIDsTable[nn][nf]);
413 for(
int i=0; i<numBlocks; i++) {
417 if (block->getNumElements() == 0)
continue;
420 problemStructure_->getBlockConnectivity(block->getGlobalBlockID());
422 std::vector<int> cNodeList(block->getNumNodesPerElement());
424 int* fieldsPerNode = block->fieldsPerNodePtr();
427 numDofPerNode.resize(0);
428 for(
int nn=0; nn<numNodesPerElem[i]; nn++) {
429 if (fieldsPerNode[nn] <= 0) ERReturn(-1);
430 numDofPerNode.push_back(0);
431 int indx = numDofPerNode.size()-1;
433 for(
int nf=0; nf<fieldsPerNode[nn]; nf++) {
434 numDofPerNode[indx] += problemStructure_->
getFieldSize(fieldIDsTable[nn][nf]);
438 int nodesPerElement = block->getNumNodesPerElement();
441 for(
int j=0; j<block->getNumElements(); j++) {
443 for(
int k=0; k<nodesPerElement; k++) {
445 cNodeList[k] = node->getNodeNumber();
448 int elemID = ctbl.elemNumbers[j];
449 int* nodeNumbers = &cNodeList[0];
450 debugOutput(
"#LinSysCoreFilter calling lsc->setConnectivities");
452 &elemID, &nodeNumbers) );
456 connectivitiesInitialized_ =
true;
462 void LinSysCoreFilter::setLinSysCoreCREqns()
466 std::vector<int> iwork;
468 std::map<GlobalID,ConstraintType*>::const_iterator
469 cr_iter = problemStructure_->getMultConstRecords().begin(),
470 cr_end = problemStructure_->getMultConstRecords().end();
472 while(cr_iter != cr_end) {
474 int numNodesPerCR = constraint.
getMasters().size();
477 std::vector<GlobalID>& nodeID_vec = constraint.
getMasters();
478 GlobalID* nodeIDPtr = &nodeID_vec[0];
480 if ((
int)iwork.size() < 2*numNodesPerCR) {
481 iwork.resize(2*numNodesPerCR);
484 int* nodeList = &(iwork[0]);
486 int* eqnList = nodeList+numNodesPerCR;
489 int* fieldIDs = &fieldIDs_vec[0];
491 for(
int k=0; k<numNodesPerCR; k++) {
499 nodeList[k] = node->getNodeNumber();
510 if (Filter::logStream() != NULL) {
511 FEI_OSTREAM& os = *logStream();
512 os <<
"#LinSysCoreFilter calling lsc_->setMultCREqns"<<FEI_ENDL;
513 os <<
"# multiplier eqn: " << meqn <<
", columns: ";
514 for(
int j=0; j<numNodesPerCR; ++j) os << eqnList[j] <<
" ";
521 if (err) voidERReturn;
527 debugOutput(
"LinSysCoreFilter calling lscf->setMultCRComplete");
530 fei::console_out() <<
"LinSysCoreFilter::setLinSysCoreCREqns ERROR returned from "
531 <<
"lscf->setMultCRComplete()" << FEI_ENDL;
538 cr_iter = problemStructure_->getPenConstRecords().begin();
539 cr_end = problemStructure_->getPenConstRecords().end();
541 while(cr_iter != cr_end) {
543 int numNodesPerCR = crset.
getMasters().size();
545 std::vector<GlobalID>& nodeIDs_vec = crset.
getMasters();
546 GlobalID* nodeIDsPtr = &nodeIDs_vec[0];
548 if ((
int)iwork.size() < 2*numNodesPerCR) {
549 iwork.resize(2*numNodesPerCR);
552 int* nodeList = &(iwork[0]);
554 int* eqnList = nodeList+numNodesPerCR;
557 int* fieldIDs = &fieldIDs_vec[0];
559 for(
int k=0; k<numNodesPerCR; k++) {
560 const NodeDescriptor& node = Filter::findNodeDescriptor(nodeIDsPtr[k]);
561 nodeList[k] = node.getNodeNumber();
573 if (err) voidERReturn;
579 int LinSysCoreFilter::storeNodalColumnCoefs(
int eqn,
const NodeDescriptor& node,
580 int fieldID,
int fieldSize,
587 if ((localStartRow_ > eqn) || (eqn > localEndRow_))
return(0);
592 int numParams = fieldSize;
597 if ((
int)iworkSpace2_.size() < numParams) {
598 iworkSpace2_.resize(numParams);
601 int* cols = &iworkSpace2_[0];
603 for(
int j=0; j<numParams; j++) {
604 cols[j] = eqnNumber + j;
607 CHK_ERR( giveToMatrix(1, &eqn, numParams, cols, &coefs, ASSEMBLE_SUM) );
613 int LinSysCoreFilter::storeNodalRowCoefs(
const NodeDescriptor& node,
614 int fieldID,
int fieldSize,
615 double* coefs,
int eqn)
624 if ((localStartRow_ > eqnNumber) || (eqnNumber > localEndRow_))
return(0);
626 int numParams = fieldSize;
632 if ((
int)iworkSpace2_.size() < numParams) {
633 iworkSpace2_.resize(numParams);
636 int* ptRows = &iworkSpace2_[0];
638 if ((
int)dworkSpace2_.size() < numParams) {
639 dworkSpace2_.resize(numParams);
642 const double* * values = &dworkSpace2_[0];
644 for(
int j=0; j<numParams; j++) {
645 ptRows[j] = eqnNumber + j;
646 values[j] = &(coefs[j]);
649 CHK_ERR( giveToMatrix(numParams, ptRows, 1, &eqn, values, ASSEMBLE_SUM) );
655 void LinSysCoreFilter::storeNodalSendEqn(
const NodeDescriptor& node,
656 int fieldID,
int col,
667 int proc = node.getOwnerProc();
674 for(
int i=0; i<numEqns; i++) {
675 eqnCommMgr_->addRemoteEqn(eqnNumber+i, proc, &coefs[i], &col, 1);
680 void LinSysCoreFilter::storePenNodeSendData(
const NodeDescriptor& iNode,
681 int iField,
int iFieldSize,
684 int jField,
int jFieldSize,
686 double penValue,
double CRValue)
693 int proc = iNode.getOwnerProc();
695 int iEqn = -1, jEqn = -1;
699 int iNumParams = iFieldSize;
700 int jNumParams = jFieldSize;
701 if (iNumParams < 1 || jNumParams < 1) {
702 fei::console_out() <<
"FEI ERROR, attempt to store indices for field with non-positive size"
703 <<
" field "<<iField<<
", size "<<iNumParams<<
", field "<<jField<<
", size "
704 << jNumParams<<FEI_ENDL;
708 if ((
int)dworkSpace_.size() < jNumParams) {
709 dworkSpace_.resize(jNumParams);
712 double* coefs = &dworkSpace_[0];
714 if ((
int)iworkSpace2_.size() < jNumParams) {
715 iworkSpace2_.resize(jNumParams);
718 int* cols = &iworkSpace2_[0];
720 for(
int i=0; i<iNumParams; i++) {
721 for(
int j=0; j<jNumParams; j++) {
723 coefs[j] = penValue*iCoefs[i]*jCoefs[j];
727 eqnCommMgr_->addRemoteEqn(row, proc, coefs, cols, jNumParams);
729 double rhsValue = penValue*iCoefs[i]*CRValue;
730 eqnCommMgr_->addRemoteRHS(row, proc, currentRHS_, rhsValue);
735 int LinSysCoreFilter::storePenNodeData(
const NodeDescriptor& iNode,
736 int iField,
int iFieldSize,
739 int jField,
int jFieldSize,
741 double penValue,
double CRValue){
748 int iEqn = -1, jEqn = -1;
752 int iNumParams = iFieldSize;
753 int jNumParams = jFieldSize;
754 if (iNumParams < 1 || jNumParams < 1) {
755 fei::console_out() <<
"FEI ERROR, attempt to store indices for field with non-positive size"
756 <<
" field "<<iField<<
", size "<<iNumParams<<
", field "<<jField<<
", size "
757 << jNumParams<<FEI_ENDL;
761 if ((
int)dworkSpace2_.size() < iNumParams) {
762 dworkSpace2_.resize(iNumParams);
765 const double* * coefs = &dworkSpace2_[0];
767 if ((
int)dworkSpace_.size() < iNumParams * jNumParams) {
768 dworkSpace_.resize(iNumParams * jNumParams);
771 double* coefList = &dworkSpace_[0];
773 if ((
int)iworkSpace2_.size() < jNumParams+iNumParams) {
774 iworkSpace2_.resize(jNumParams+iNumParams);
777 int* cols = &iworkSpace2_[0];
778 int* rows = &iworkSpace2_[jNumParams];
781 for(
int i=0; i<iNumParams; i++) {
782 double* coefPtr = coefList + i*jNumParams;
787 for(
int j=0; j<jNumParams; j++) {
788 if (i==0) cols[j] = jEqn + j;
789 coefPtr[j] = penValue*iCoefs[i]*jCoefs[j];
792 double rhsValue = penValue*iCoefs[i]*CRValue;
793 CHK_ERR( giveToRHS(1, &rhsValue, &rows[i], ASSEMBLE_SUM) );
796 CHK_ERR( giveToMatrix(iNumParams, rows,
797 jNumParams, cols, coefs, ASSEMBLE_SUM) );
803 int LinSysCoreFilter::resetSystem(
double s)
808 if (Filter::logStream() != NULL) {
809 (*logStream()) <<
"FEI: resetSystem" << FEI_ENDL << s << FEI_ENDL;
812 CHK_ERR( resetTheMatrix(s) );
813 CHK_ERR( resetTheRHSVector(s) );
815 debugOutput(
"#LinSysCoreFilter leaving resetSystem");
821 int LinSysCoreFilter::deleteMultCRs()
823 debugOutput(
"#LinSysCoreFilter::deleteMultCRs");
834 debugOutput(
"#LinSysCoreFilter leaving deleteMultCRs");
840 int LinSysCoreFilter::resetTheMatrix(
double s)
848 int LinSysCoreFilter::resetTheRHSVector(
double s)
856 int LinSysCoreFilter::resetMatrix(
double s) {
861 debugOutput(
"FEI: resetMatrix");
863 CHK_ERR( resetTheMatrix(s) )
866 bcManager_->clearAllBCs();
868 eqnCommMgr_->resetCoefs();
870 debugOutput("
#LinSysCoreFilter leaving resetMatrix");
876 int LinSysCoreFilter::resetRHSVector(
double s) {
881 debugOutput(
"FEI: resetRHSVector");
883 CHK_ERR( resetTheRHSVector(s) )
886 bcManager_->clearAllBCs();
888 eqnCommMgr_->resetCoefs();
890 debugOutput("
# LinSysCoreFilter leaving resetRHSVector");
896 int LinSysCoreFilter::resetInitialGuess(
double s) {
900 if (Filter::logStream() != NULL) {
901 FEI_OSTREAM& os = *logStream();
902 os <<
"FEI: resetInitialGuess" << FEI_ENDL;
903 os <<
"#value to which initial guess is to be set" << FEI_ENDL;
907 int* eqns =
new int[numReducedRows_];
908 double* values =
new double[numReducedRows_];
909 if (eqns == NULL || values == NULL)
return(-1);
911 for(
int i=0; i<numReducedRows_; ++i) {
912 eqns[i] = reducedStartRow_ + i;
921 debugOutput(
"# LinSysCoreFilter leaving resetInitialGuess");
927 int LinSysCoreFilter::loadNodeBCs(
int numNodes,
928 const GlobalID *nodeIDs,
930 const int* offsetsIntoField,
931 const double* prescribedValues)
938 fei::console_out() <<
"FEI Warning: loadNodeBCs called for fieldID "<<fieldID
939 <<
", which was defined with size "<<size<<
" (should be positive)."<<FEI_ENDL;
943 if (Filter::logStream() != NULL) {
944 (*logStream())<<
"FEI: loadNodeBCs"<<FEI_ENDL
945 <<
"#num-nodes"<<FEI_ENDL<<numNodes<<FEI_ENDL
946 <<
"#fieldID"<<FEI_ENDL<<fieldID<<FEI_ENDL
947 <<
"#field-size"<<FEI_ENDL<<size<<FEI_ENDL;
948 (*logStream())<<
"#following lines: nodeID offsetIntoField value "<<FEI_ENDL;
950 for(
int j=0; j<numNodes; j++) {
951 GlobalID nodeID = nodeIDs[j];
952 (*logStream())<<static_cast<int>(nodeID)<<
" ";
953 (*logStream())<<offsetsIntoField[j]<<
" "<<prescribedValues[j];
954 (*logStream())<<FEI_ENDL;
958 if (numNodes > 0) newBCData_ =
true;
960 bcManager_->addBCRecords(numNodes, nodeIDType_, fieldID, nodeIDs,
961 offsetsIntoField, prescribedValues);
967 int LinSysCoreFilter::loadElemBCs(
int numElems,
968 const GlobalID *elemIDs,
970 const double *
const *alpha,
971 const double *
const *beta,
972 const double *
const *gamma)
978 void LinSysCoreFilter::allocElemStuff()
982 for(
int i=0; i<nb; i++) {
985 if (err) voidERReturn;
987 int numEqns = block->getNumEqnsPerElement();
988 if (maxElemRows_ < numEqns) maxElemRows_ = numEqns;
991 scatterIndices_.resize(maxElemRows_);
993 if (eStiff_ != NULL)
delete [] eStiff_;
994 if (eStiff1D_ != NULL)
delete [] eStiff1D_;
995 if (eLoad_ != NULL)
delete [] eLoad_;
997 eStiff_ =
new double*[maxElemRows_];
998 eStiff1D_ =
new double[maxElemRows_*maxElemRows_];
1000 if (eStiff_ == NULL || eStiff1D_ == NULL) voidERReturn
1002 for(
int r=0; r<maxElemRows_; r++) {
1003 eStiff_[r] = eStiff1D_ + r*maxElemRows_;
1006 eLoad_ =
new double[maxElemRows_];
1008 if (eLoad_ == NULL) voidERReturn
1012 int LinSysCoreFilter::sumInElem(GlobalID elemBlockID,
1014 const GlobalID* elemConn,
1015 const double*
const* elemStiffness,
1016 const double* elemLoad,
1019 if (Filter::logStream() != NULL && outputLevel_ > 2) {
1020 (*logStream()) <<
"FEI: sumInElem" << FEI_ENDL <<
"#blkID" << FEI_ENDL
1021 << static_cast<int>(elemBlockID) << FEI_ENDL
1022 <<
"#elID" << FEI_ENDL << static_cast<int>(elemID) << FEI_ENDL;
1024 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) );
1025 int numNodes = block->getNumNodesPerElement();
1026 (*logStream()) <<
"#n-nodes" << FEI_ENDL << numNodes << FEI_ENDL;
1027 (*logStream()) <<
"#nodes" << FEI_ENDL;
1028 for(
int i=0; i<numNodes; ++i) {
1029 GlobalID nodeID = elemConn[i];
1030 (*logStream())<<static_cast<int>(nodeID)<<
" ";
1032 (*logStream())<<FEI_ENDL;
1035 return(generalElemInput(elemBlockID, elemID, elemConn, elemStiffness,
1036 elemLoad, elemFormat));
1040 int LinSysCoreFilter::sumInElemMatrix(GlobalID elemBlockID,
1042 const GlobalID* elemConn,
1043 const double*
const* elemStiffness,
1046 if (Filter::logStream() != NULL && outputLevel_ > 2) {
1047 (*logStream()) <<
"FEI: sumInElemMatrix"<<FEI_ENDL
1048 <<
"#blkID" << FEI_ENDL << static_cast<int>(elemBlockID) << FEI_ENDL
1049 <<
"#elID" << FEI_ENDL << static_cast<int>(elemID) << FEI_ENDL;
1051 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) );
1052 int numNodes = block->getNumNodesPerElement();
1053 (*logStream()) <<
"#n-nodes" << FEI_ENDL << numNodes << FEI_ENDL;
1054 (*logStream()) <<
"#nodes" << FEI_ENDL;
1055 for(
int i=0; i<numNodes; ++i) {
1056 GlobalID nodeID = elemConn[i];
1057 (*logStream())<<static_cast<int>(nodeID)<<
" ";
1059 (*logStream())<<FEI_ENDL;
1062 return(generalElemInput(elemBlockID, elemID, elemConn, elemStiffness,
1067 int LinSysCoreFilter::sumInElemRHS(GlobalID elemBlockID,
1069 const GlobalID* elemConn,
1070 const double* elemLoad)
1072 if (Filter::logStream() != NULL && outputLevel_ > 2) {
1073 (*logStream()) <<
"FEI: sumInElemRHS"<<FEI_ENDL<<
"#blID" << FEI_ENDL
1074 <<(
int)elemBlockID << FEI_ENDL
1075 <<
"#elID" << FEI_ENDL << static_cast<int>(elemID) << FEI_ENDL;
1077 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) );
1078 int numNodes = block->getNumNodesPerElement();
1079 (*logStream()) <<
"#n-nodes" << FEI_ENDL << numNodes << FEI_ENDL;
1080 (*logStream()) <<
"#nodes" << FEI_ENDL;
1081 for(
int i=0; i<numNodes; ++i) {
1082 GlobalID nodeID = elemConn[i];
1083 (*logStream())<<static_cast<int>(nodeID)<<
" ";
1085 (*logStream())<<FEI_ENDL;
1088 return(generalElemInput(elemBlockID, elemID, elemConn, NULL,
1093 int LinSysCoreFilter::generalElemInput(GlobalID elemBlockID,
1095 const GlobalID* elemConn,
1096 const double*
const* elemStiffness,
1097 const double* elemLoad,
1101 return(generalElemInput(elemBlockID, elemID, elemStiffness, elemLoad,
1106 int LinSysCoreFilter::generalElemInput(GlobalID elemBlockID,
1108 const double*
const* elemStiffness,
1109 const double* elemLoad,
1115 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) );
1119 if (maxElemRows_ <= 0) allocElemStuff();
1121 int numElemRows = block->getNumEqnsPerElement();
1122 int numBlkElemRows = block->getNumBlkEqnsPerElement();
1123 int interleave = block->getInterleaveStrategy();
1128 scatterIndices_.resize(numElemRows);
1129 blkScatterIndices_.resize(numBlkElemRows*2);
1131 const double*
const* stiff = NULL;
1132 if (elemStiffness != NULL) stiff = elemStiffness;
1134 const double* load = NULL;
1135 if (elemLoad != NULL) load = elemLoad;
1142 if (elemFormat != FEI_DENSE_ROW && stiff != NULL) {
1143 if (elemFormat == FEI_BLOCK_DIAGONAL_ROW ||
1144 elemFormat == FEI_BLOCK_DIAGONAL_COL) {
1145 fei::console_out() <<
"LinSysCoreFilter::generalElemInput ERROR, elemFormat="
1146 << elemFormat <<
" not supported."<<FEI_ENDL;
1150 Filter::copyStiffness(stiff, numElemRows, elemFormat, eStiff_);
1154 if (stiff != NULL) newMatrixData_ =
true;
1155 if (load != NULL) newVectorData_ =
true;
1157 if (Filter::logStream() != NULL && outputLevel_ > 2) {
1158 FEI_OSTREAM& os = *logStream();
1160 if (stiff != NULL || load != NULL) {
1161 os <<
"#numRows"<< FEI_ENDL << numElemRows << FEI_ENDL;
1164 if (stiff != NULL) {
1165 os <<
"#elem-stiff (after copy into dense-row format)" << FEI_ENDL;
1166 for(
int i=0; i<numElemRows; i++) {
1167 const double* stiff_i = stiff[i];
1168 for(
int j=0; j<numElemRows; j++) {
1169 os << stiff_i[j] <<
" ";
1176 os <<
"#elem-load" << FEI_ENDL;
1177 for(
int i=0; i<numElemRows; i++) {
1178 os << load[i] <<
" ";
1183 if (stiff != NULL) {
1184 os <<
"#elemformat" << FEI_ENDL << elemFormat << FEI_ENDL;
1191 int* indPtr = &scatterIndices_[0];
1192 int* blkIndPtr = &blkScatterIndices_[0];
1193 int* blkSizesPtr = blkIndPtr + numBlkElemRows;
1195 bool useBlkEqns =
false;
1196 if (interleave == 0) {
1198 problemStructure_->getScatterIndices_ID(elemBlockID, elemID,
1200 blkIndPtr, blkSizesPtr);
1201 int sumBlkSizes = 0;
1202 for(
int ii=0; ii<numBlkElemRows; ++ii) {
1203 sumBlkSizes += blkSizesPtr[ii];
1205 if (sumBlkSizes == numElemRows) {
1211 problemStructure_->getScatterIndices_ID(elemBlockID, elemID,
1212 interleave, indPtr);
1215 if (stiff != NULL) {
1216 if (problemStructure_->numSlaveEquations() == 0) {
1221 &stiff, scatterIndices_.size(),
1225 int len = scatterIndices_.size();
1226 if (interleave == 0) {
1227 CHK_ERR( assembleEqns( len, len, indPtr, indPtr, stiff,
true,
1228 numBlkElemRows, blkIndPtr,
1229 blkSizesPtr, useBlkEqns, ASSEMBLE_SUM ) );
1232 CHK_ERR( assembleEqns( len, len, indPtr, indPtr, stiff,
true,
1233 numBlkElemRows, blkIndPtr,
1234 blkSizesPtr,
false, ASSEMBLE_SUM ) );
1239 if (problemStructure_->numSlaveEquations() == 0) {
1244 &load, scatterIndices_.size(),
1248 CHK_ERR( assembleRHS(scatterIndices_.size(), indPtr, load, ASSEMBLE_SUM) );
1251 return(FEI_SUCCESS);
1255 int LinSysCoreFilter::putIntoRHS(
int IDType,
1258 const GlobalID* IDs,
1259 const double* rhsEntries)
1261 int fieldSize = problemStructure_->
getFieldSize(fieldID);
1263 rowIndices_.resize(fieldSize*numIDs);
1266 CHK_ERR( problemStructure_->getEqnNumbers(numIDs, IDs, IDType, fieldID,
1269 if (checkNumEqns != numIDs*fieldSize) {
1273 CHK_ERR( exchangeRemoteEquations() );
1275 CHK_ERR(assembleRHS(rowIndices_.size(), &rowIndices_[0], rhsEntries, ASSEMBLE_PUT));
1281 int LinSysCoreFilter::sumIntoRHS(
int IDType,
1284 const GlobalID* IDs,
1285 const double* rhsEntries)
1287 int fieldSize = problemStructure_->
getFieldSize(fieldID);
1289 rowIndices_.resize(fieldSize*numIDs);
1292 CHK_ERR( problemStructure_->getEqnNumbers(numIDs, IDs, IDType, fieldID,
1295 if (checkNumEqns != numIDs*fieldSize) {
1299 CHK_ERR(assembleRHS(rowIndices_.size(), &rowIndices_[0], rhsEntries, ASSEMBLE_SUM));
1305 int LinSysCoreFilter::implementAllBCs() {
1310 debugOutput(
"# implementAllBCs");
1312 std::vector<int> essEqns;
1313 std::vector<double> essGamma;
1317 CHK_ERR( bcManager_->finalizeBCEqns(bcEqns) );
1319 if (resolveConflictRequested_) {
1320 CHK_ERR( resolveConflictingCRs(bcEqns) );
1323 CHK_ERR( eqnCommMgr_->gatherSharedBCs(bcEqns) );
1326 fei::FillableMat bcEqns_mat(bcEqns);
1327 fei::impl_utils::separate_BC_eqns(bcEqns_mat, essEqns, essGamma);
1329 std::vector<double> essAlpha(essEqns.size(), 1);
1331 exchangeRemoteBCs(essEqns, essAlpha, essGamma);
1333 if (essEqns.size() > 0) {
1334 CHK_ERR( enforceEssentialBCs(&essEqns[0],
1336 &essGamma[0], essEqns.size()) );
1339 debugOutput(
"#LinSysCoreFilter leaving implementAllBCs");
1340 return(FEI_SUCCESS);
1344 int LinSysCoreFilter::enforceEssentialBCs(
const int* eqns,
1345 const double* alpha,
1346 const double* gamma,
1349 int* cc_eqns =
const_cast<int*
>(eqns);
1350 double* cc_alpha =
const_cast<double*
>(alpha);
1351 double* cc_gamma =
const_cast<double*
>(gamma);
1353 if (problemStructure_->numSlaveEquations() == 0) {
1359 std::vector<int> reducedEqns(numEqns);
1360 for(
int i=0; i<numEqns; i++) {
1367 return(FEI_SUCCESS);
1371 int LinSysCoreFilter::enforceRemoteEssBCs(
int numEqns,
const int* eqns,
1372 const int*
const* colIndices,
const int* colIndLens,
1373 const double*
const* BCcoefs)
1380 int* cc_eqns =
const_cast<int*
>(eqns);
1381 int** cc_colIndices =
const_cast<int**
>(colIndices);
1382 int* cc_colIndLens =
const_cast<int*
>(colIndLens);
1383 double** cc_BCcoefs =
const_cast<double**
>(BCcoefs);
1386 cc_colIndLens, cc_BCcoefs) );
1388 return(FEI_SUCCESS);
1392 int LinSysCoreFilter::resolveConflictingCRs(
EqnBuffer& bcEqns)
1394 int numMultCRs = problemStructure_->getNumMultConstRecords();
1395 if (numMultCRs < 1) {
1399 std::map<GlobalID,ConstraintType*>::const_iterator
1400 cr_iter = problemStructure_->getMultConstRecords().begin(),
1401 cr_end = problemStructure_->getMultConstRecords().end();
1403 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
1405 std::vector<int>& bcEqnNumbers = bcEqns.
eqnNumbers();
1413 double fei_eps = 1.e-49;
1415 while(cr_iter != cr_end) {
1420 std::vector<GlobalID>& CRNode_vec = multCR.
getMasters();
1421 GlobalID *CRNodePtr = &CRNode_vec[0];
1423 int* CRFieldPtr = &CRField_vec[0];
1425 double* weights = &weights_vec[0];
1428 for(
int j=0; j<lenList; ++j) {
1429 int fieldSize = problemStructure_->
getFieldSize(CRFieldPtr[j]);
1430 for(
int k=0; k<fieldSize; ++k) {
1431 if (std::abs(weights[offset++] + 1.0) < fei_eps) {
1443 CHK_ERR( bcEqns.
addEqn(crEqn, coefs, indices, 3,
false) );
1455 int LinSysCoreFilter::exchangeRemoteEquations()
1462 debugOutput(
"#LinSysCoreFilter::exchangeRemoteEquations");
1464 if (reducedEqnCounter_ > 0) CHK_ERR( assembleReducedEqns() );
1466 if (reducedRHSCounter_ > 0) CHK_ERR( assembleReducedRHS() );
1469 std::vector<int> flags(len), globalFlags(len);
1470 flags[0] = newMatrixData_ ? 1 : 0;
1471 flags[1] = newVectorData_ ? 1 : 0;
1472 flags[2] = newConstraintData_ ? 1 : 0;
1473 flags[3] = newBCData_ ? 1 : 0;
1477 newMatrixData_ = globalFlags[0] > 0 ?
true :
false;
1478 newVectorData_ = globalFlags[1] > 0 ?
true :
false;
1479 newConstraintData_ = globalFlags[2] > 0 ?
true :
false;
1480 newBCData_ = globalFlags[3] > 0 ?
true :
false;
1482 if (newMatrixData_ || newVectorData_ || newConstraintData_) {
1484 CHK_ERR( eqnCommMgr_->exchangeEqns(logStream()) );
1486 needToCallMatrixLoadComplete_ =
true;
1491 debugOutput(
"# putting remote contributions into linear system...");
1493 CHK_ERR( unpackRemoteContributions(*eqnCommMgr_, ASSEMBLE_SUM) );
1495 eqnCommMgr_->resetCoefs();
1497 newMatrixData_ =
false;
1498 newVectorData_ =
false;
1499 newConstraintData_ =
false;
1502 firstRemEqnExchange_ =
false;
1504 debugOutput(
"#LinSysCoreFilter leaving exchangeRemoteEquations");
1506 return(FEI_SUCCESS);
1510 int LinSysCoreFilter::unpackRemoteContributions(
EqnCommMgr& eqnCommMgr,
1513 int numRecvEqns = eqnCommMgr.getNumLocalEqns();
1514 std::vector<int>& recvEqnNumbers = eqnCommMgr.localEqnNumbers();
1515 std::vector<fei::CSVec*>& recvEqns = eqnCommMgr.localEqns();
1516 std::vector<std::vector<double>*>& recvRHSs = *(eqnCommMgr.localRHSsPtr());
1518 bool newCoefs = eqnCommMgr.newCoefData();
1519 bool newRHSs = eqnCommMgr.newRHSData();
1522 double** coefs =
new double*[numRecvEqns];
1524 for(i=0; i<numRecvEqns; i++) {
1525 coefs[i] = &(recvEqns[i]->coefs()[0]);
1528 for(i=0; i<numRecvEqns; i++) {
1530 int eqn = recvEqnNumbers[i];
1531 if ((reducedStartRow_ > eqn) || (reducedEndRow_ < eqn)) {
1532 fei::console_out() <<
"LinSysCoreFilter::unpackRemoteContributions: ERROR, recvEqn "
1533 << eqn <<
" out of range. (localStartRow_: " << reducedStartRow_
1534 <<
", localEndRow_: " << reducedEndRow_ <<
", localRank_: "
1535 << localRank_ <<
")" << FEI_ENDL;
1536 MPI_Abort(comm_, -1);
1539 for(
size_t ii=0; ii<recvEqns[i]->size(); ii++) {
1540 if (coefs[i][ii] > 1.e+200) {
1541 fei::console_out() << localRank_ <<
": LinSysCoreFilter::unpackRemoteContributions: "
1542 <<
"WARNING, coefs["<<i<<
"]["<<ii<<
"]: " << coefs[i][ii]
1544 MPI_Abort(comm_, -1);
1548 if (recvEqns[i]->size() > 0 && newCoefs) {
1550 CHK_ERR( giveToLocalReducedMatrix(1, &(recvEqnNumbers[i]),
1551 recvEqns[i]->size(),
1552 &(recvEqns[i]->indices()[0]),
1553 &(coefs[i]), assemblyMode ) );
1558 for(
int j=0; j<numRHSs_; j++) {
1559 CHK_ERR( giveToLocalReducedRHS(1, &( (*(recvRHSs[i]))[j] ),
1560 &eqn, assemblyMode) );
1571 int LinSysCoreFilter::exchangeRemoteBCs(std::vector<int>& essEqns,
1572 std::vector<double>& essAlpha,
1573 std::vector<double>& essGamma)
1585 std::vector<int>* eqns = &essEqns;
1587 if (problemStructure_->numSlaveEquations() > 0) {
1588 int numEqns = essEqns.size();
1589 eqns =
new std::vector<int>(numEqns);
1590 int* eqnsPtr = &(*eqns)[0];
1592 for(
int ii=0; ii<numEqns; ++ii) {
1597 FEI_OSTREAM* dbgOut = NULL;
1598 if (Filter::logStream() != NULL) {
1599 dbgOut = logStream();
1602 eqnCommMgr_->exchangeRemEssBCs(&(*eqns)[0], eqns->size(),
1603 &essAlpha[0], &essGamma[0],
1606 int numRemoteEssBCEqns = eqnCommMgr_->getNumRemEssBCEqns();
1607 if (numRemoteEssBCEqns > 0) {
1608 std::vector<int>& remEssBCEqnNumbers = eqnCommMgr_->remEssBCEqnNumbersPtr();
1609 fei::CSVec** remEssBCEqns = &(eqnCommMgr_->remEssBCEqns()[0]);
1610 std::vector<int> remEssBCEqnLengths(remEssBCEqnNumbers.size());
1612 int** indices =
new int*[numRemoteEssBCEqns];
1613 double** coefs =
new double*[numRemoteEssBCEqns];
1615 for(
int i=0; i<numRemoteEssBCEqns; i++) {
1616 coefs[i] = &(remEssBCEqns[i]->coefs()[0]);
1617 indices[i] = &(remEssBCEqns[i]->indices()[0]);
1618 remEssBCEqnLengths[i] = remEssBCEqns[i]->size();
1621 CHK_ERR( enforceRemoteEssBCs(numRemoteEssBCEqns,
1622 &remEssBCEqnNumbers[0], indices,
1623 &remEssBCEqnLengths[0], coefs));
1629 if (problemStructure_->numSlaveEquations() > 0) {
1633 debugOutput(
"#LinSysCoreFilter exchangeRemoteBCs");
1635 return(FEI_SUCCESS);
1639 int LinSysCoreFilter::loadCRMult(
int CRID,
1641 const GlobalID* CRNodes,
1642 const int* CRFields,
1643 const double* CRWeights,
1654 if (Filter::logStream() != NULL) {
1655 FEI_OSTREAM& os = *logStream();
1656 os<<
"FEI: loadCRMult"<<FEI_ENDL;
1657 os<<
"#num-nodes"<<FEI_ENDL<<numCRNodes<<FEI_ENDL;
1658 os<<
"#CRNodes:"<<FEI_ENDL;
1660 for(i=0; i<numCRNodes; ++i) {
1661 GlobalID nodeID = CRNodes[i];
1662 os << static_cast<int>(nodeID) <<
" ";
1664 os << FEI_ENDL <<
"#fields:"<<FEI_ENDL;
1665 for(i=0; i<numCRNodes; ++i) os << CRFields[i] <<
" ";
1666 os << FEI_ENDL <<
"#field-sizes:"<<FEI_ENDL;
1667 for(i=0; i<numCRNodes; ++i) {
1668 int size = problemStructure_->
getFieldSize(CRFields[i]);
1671 os << FEI_ENDL<<
"#weights:"<<FEI_ENDL;
1673 for(i=0; i<numCRNodes; ++i) {
1674 int size = problemStructure_->
getFieldSize(CRFields[i]);
1675 for(
int j=0; j<size; ++j) {
1676 os << CRWeights[offset++] <<
" ";
1679 os << FEI_ENDL<<
"#CRValue:"<<FEI_ENDL<<CRValue<<FEI_ENDL;
1683 CHK_ERR( problemStructure_->getMultConstRecord(CRID, multCR) );
1689 fei::console_out() <<
"ERROR in FEI, constraint with ID="<<CRID<<
" appears to have"
1690 <<
" a constrained-node list of length "<<lenList<<
", should be > 0."<<FEI_ENDL;
1697 std::vector<GlobalID>& CRNode_vec = multCR->
getMasters();
1698 GlobalID *CRNodePtr = &CRNode_vec[0];
1700 for(i=0; i<lenList; i++) {
1701 if (CRNodePtr[i] != CRNodes[i]) {
1702 fei::console_out() <<
"ERROR in FEI, constraint with ID="<<CRID<<
" had different node-list"
1703 <<
" in initCRMult than it has in loadCRMult."<<FEI_ENDL;
1709 int *CRFieldPtr = &CRField_vec[0];
1711 for (i = 0; i < lenList; i++) {
1712 if (CRFieldPtr[i] != CRFields[i]) {
1713 fei::console_out() <<
"ERROR in FEI, constraint with CRID="<<CRID<<
" had different field-list"
1714 <<
" in initCRMult than it has in loadCRMult."<<FEI_ENDL;
1719 newConstraintData_ =
true;
1721 if ((
int)iworkSpace_.size() < lenList) {
1722 iworkSpace_.resize(lenList);
1725 int* fieldSizes = &iworkSpace_[0];
1727 for (i = 0; i < lenList; i++) {
1728 int numSolnParams = problemStructure_->
getFieldSize(CRFields[i]);
1729 assert(numSolnParams >= 0);
1730 fieldSizes[i] = numSolnParams;
1739 for(i = 0; i < lenList; i++) {
1740 for(
int j = 0; j < fieldSizes[i]; j++) {
1741 CRWeightArray.push_back(CRWeights[offset++]);
1746 catch(std::runtime_error& exc) {
1752 double* CRWeightsPtr = &CRWeightArray[0];
1759 double* zeroPtr = &zero;
1760 CHK_ERR( giveToMatrix(1, &irow, 1, &irow, &zeroPtr, ASSEMBLE_PUT) );
1762 CHK_ERR( giveToRHS(1, &(CRValue), &irow, ASSEMBLE_PUT));
1765 for(
int j = 0; j < lenList; j++) {
1766 int myFieldID = CRFields[j];
1768 const NodeDescriptor& node = Filter::findNodeDescriptor(CRNodePtr[j]);
1772 storeNodalColumnCoefs(irow, node, myFieldID, fieldSizes[j],
1773 &(CRWeightsPtr[offset]));
1779 if (node.getOwnerProc() == localRank_) {
1781 storeNodalRowCoefs(node, myFieldID, fieldSizes[j],
1782 &(CRWeightsPtr[offset]), irow);
1786 storeNodalSendEqn(node, myFieldID, irow, &(CRWeightsPtr[offset]));
1789 offset += fieldSizes[j];
1792 return(FEI_SUCCESS);
1796 int LinSysCoreFilter::loadCRPen(
int CRID,
1798 const GlobalID* CRNodes,
1799 const int* CRFields,
1800 const double* CRWeights,
1808 debugOutput(
"FEI: loadCRPen");
1811 CHK_ERR( problemStructure_->getPenConstRecord(CRID, penCR) );
1816 fei::console_out() <<
"ERROR in FEI, constraint with ID="<<CRID<<
" appears to have"
1817 <<
" a constrained-node list of length "<<lenList<<
", should be > 0."<<FEI_ENDL;
1824 std::vector<GlobalID>& CRNode_vec = penCR->
getMasters();
1825 GlobalID* CRNodePtr = &CRNode_vec[0];
1827 for(
int j = 0; j < lenList; j++) {
1828 if (CRNodePtr[j] != CRNodes[j]) {
1829 fei::console_out() <<
"ERROR in FEI, constraint with ID="<<CRID<<
" had different node-list"
1830 <<
" in initCRPen than it has in loadCRPen."<<FEI_ENDL;
1835 newConstraintData_ =
true;
1839 if ((
int)iworkSpace_.size() < lenList) {
1840 iworkSpace_.resize(lenList);
1843 int* fieldSizes = &iworkSpace_[0];
1845 for (i = 0; i < lenList; i++) {
1846 int numSolnParams = problemStructure_->
getFieldSize(CRFields[i]);
1847 assert(numSolnParams >= 0);
1848 fieldSizes[i] = numSolnParams;
1856 for (i = 0; i < lenList; i++) {
1857 for (
int j = 0; j < fieldSizes[i]; j++) {
1858 CRWeightArray.push_back(CRWeights[offset++]);
1863 catch(std::runtime_error& exc) {
1870 double* CRWeightPtr = &CRWeightArray[0];
1872 int ioffset = 0, joffset = 0;
1873 for(i = 0; i < lenList; i++) {
1874 GlobalID iNodeID = CRNodePtr[i];
1875 int iField = CRFields[i];
1877 const NodeDescriptor& iNode = Filter::findNodeDescriptor(iNodeID);
1878 double* iweights = &(CRWeightPtr[ioffset]);
1879 ioffset += fieldSizes[i];
1882 for (
int j = 0; j < lenList; j++) {
1883 GlobalID jNodeID = CRNodePtr[j];
1884 int jField = CRFields[j];
1886 const NodeDescriptor& jNode = Filter::findNodeDescriptor(jNodeID);
1887 double* jweights = &(CRWeightPtr[joffset]);
1888 joffset += fieldSizes[j];
1890 double rhsValue = CRValue;
1891 if (j < lenList-1) {
1895 if (iNode.getOwnerProc() == localRank_) {
1897 storePenNodeData(iNode, iField, fieldSizes[i], iweights,
1898 jNode, jField, fieldSizes[j], jweights,
1899 penValue, rhsValue);
1902 storePenNodeSendData(iNode, iField, fieldSizes[i], iweights,
1903 jNode, jField, fieldSizes[j], jweights,
1904 penValue, rhsValue);
1909 return(FEI_SUCCESS);
1913 int LinSysCoreFilter::parameters(
int numParams,
const char *
const* paramStrings) {
1918 if (numParams == 0 || paramStrings == NULL) {
1919 debugOutput(
"#LinSysCoreFilter::parameters--- no parameters.");
1922 const char* param1 = snl_fei::getParamValue(
"AZ_matrix_type",
1926 if (param1 != NULL) {
1927 if (!strcmp(param1,
"AZ_VBR_MATRIX") ||
1928 !strcmp(param1,
"blockMatrix")) {
1929 blockMatrix_ =
true;
1933 param1 = snl_fei::getParamValue(
"matrixType",
1934 numParams, paramStrings);
1935 if (param1 != NULL) {
1936 if (!strcmp(param1,
"AZ_VBR_MATRIX") ||
1937 !strcmp(param1,
"blockMatrix")) {
1938 blockMatrix_ =
true;
1943 param1 = snl_fei::getParamValue(
"outputLevel",
1944 numParams,paramStrings);
1945 if ( param1 != NULL){
1946 std::string str(param1);
1947 FEI_ISTRINGSTREAM isstr(str);
1948 isstr >> outputLevel_;
1951 param1 = snl_fei::getParam(
"resolveConflict",numParams,paramStrings);
1952 if ( param1 != NULL){
1953 resolveConflictRequested_ =
true;
1956 param1 = snl_fei::getParamValue(
"internalFei", numParams,paramStrings);
1957 if ( param1 != NULL ){
1958 std::string str(param1);
1959 FEI_ISTRINGSTREAM isstr(str);
1960 isstr >> internalFei_;
1963 if (Filter::logStream() != NULL) {
1965 (*logStream())<<
"#LinSysCoreFilter::parameters"<<FEI_ENDL
1966 <<
"# --- numParams: "<< numParams<<FEI_ENDL;
1967 for(
int i=0; i<numParams; i++){
1968 (*logStream())<<
"#------ paramStrings["<<i<<
"]: "
1970 if (paramStrings[i][strlen(paramStrings[i])-1] !=
'\n') {
1971 (*logStream())<<FEI_ENDL;
1977 CHK_ERR( Filter::parameters(numParams, paramStrings) );
1979 debugOutput(
"#LinSysCoreFilter leaving parameters function");
1981 return(FEI_SUCCESS);
1985 int LinSysCoreFilter::loadComplete()
1988 std::vector<int> flags(len), globalFlags(len);
1989 flags[0] = newMatrixData_ ? 1 : 0;
1990 flags[1] = newVectorData_ ? 1 : 0;
1991 flags[2] = newConstraintData_ ? 1 : 0;
1992 flags[3] = newBCData_ ? 1 : 0;
1996 newMatrixData_ = globalFlags[0] > 0 ?
true :
false;
1997 newVectorData_ = globalFlags[1] > 0 ?
true :
false;
1998 newConstraintData_ = globalFlags[2] > 0 ?
true :
false;
1999 newBCData_ = globalFlags[3] > 0 ?
true :
false;
2001 bool called_exchange =
false;
2002 if (newMatrixData_ || newVectorData_ || newConstraintData_) {
2003 CHK_ERR( exchangeRemoteEquations() );
2004 called_exchange =
true;
2007 bool called_implbcs =
false;
2009 CHK_ERR( implementAllBCs() );
2010 called_implbcs =
true;
2013 if (called_exchange || called_implbcs ||needToCallMatrixLoadComplete_) {
2014 debugOutput(
"#LinSysCoreFilter calling LinSysCore matrixLoadComplete");
2017 needToCallMatrixLoadComplete_ =
false;
2020 newMatrixData_ =
false;
2021 newVectorData_ =
false;
2022 newConstraintData_ =
false;
2029 int LinSysCoreFilter::residualNorm(
int whichNorm,
int numFields,
2030 int* fieldIDs,
double* norms,
double& residTime)
2036 debugOutput(
"FEI: residualNorm");
2038 if (whichNorm < 0 || whichNorm > 2)
return(-1);
2040 CHK_ERR( loadComplete() );
2042 std::vector<double> residValues(numReducedRows_, 0.0);
2046 CHK_ERR( formResidual(&(residValues[0]), numReducedRows_) );
2050 CHK_ERR( Filter::calculateResidualNorms(whichNorm, numFields,
2051 fieldIDs, norms, residValues) );
2053 return(FEI_SUCCESS);
2057 int LinSysCoreFilter::formResidual(
double* residValues,
int numLocalEqns)
2059 CHK_ERR( lsc_->
formResidual(residValues, numLocalEqns))
2061 return(FEI_SUCCESS);
2065 int LinSysCoreFilter::solve(
int& status,
double& sTime) {
2067 debugOutput(
"FEI: solve");
2069 CHK_ERR( loadComplete() );
2071 debugOutput(
"#LinSysCoreFilter in solve, calling launchSolver...");
2079 debugOutput(
"#LinSysCoreFilter... back from solver");
2083 CHK_ERR( unpackSolution() );
2085 debugOutput(
"#LinSysCoreFilter leaving solve");
2087 if (status != 0)
return(1);
2088 else return(FEI_SUCCESS);
2092 int LinSysCoreFilter::setNumRHSVectors(
int numRHSs,
int* rhsIDs){
2095 fei::console_out() <<
"LinSysCoreFilter::setNumRHSVectors: ERROR, numRHSs < 0." << FEI_ENDL;
2101 rhsIDs_.resize(numRHSs_);
2102 for(
int i=0; i<numRHSs_; i++) rhsIDs_[i] = rhsIDs[i];
2105 eqnCommMgr_->setNumRHSs(numRHSs_);
2107 return(FEI_SUCCESS);
2111 int LinSysCoreFilter::setCurrentRHS(
int rhsID)
2113 std::vector<int>::iterator iter =
2114 std::find( rhsIDs_.begin(), rhsIDs_.end(), rhsID);
2116 if (iter == rhsIDs_.end()) ERReturn(-1)
2118 int index = iter - rhsIDs_.begin();
2119 currentRHS_ = index;
2123 return(FEI_SUCCESS);
2127 int LinSysCoreFilter::giveToMatrix_symm_noSlaves(
int numPtRows,
2128 const int* ptRowNumbers,
2129 const double*
const* coefs,
2132 for(
int i=0; i<numPtRows; i++) {
2133 int row = ptRowNumbers[i];
2134 const double* valptr = coefs[i];
2135 if (row < localStartRow_ || row > localEndRow_) {
2136 eqnCommMgr_->addRemoteEqn(row, valptr, ptRowNumbers, numPtRows);
2140 if (mode == ASSEMBLE_SUM) {
2141 if (Filter::logStream() != NULL && 0) {
2142 FEI_OSTREAM& os = *logStream();
2143 os <<
"# calling sumIntoSystemMatrix, row: " << ptRowNumbers[i]
2145 for(
int j=0; j<numPtRows; ++j) os << ptRowNumbers[j] <<
" ";
2150 numPtRows, ptRowNumbers,
2155 numPtRows, ptRowNumbers,
2164 int LinSysCoreFilter::giveToBlkMatrix_symm_noSlaves(
int numPtRows,
2165 const int* ptRowNumbers,
2167 const int* blkRowNumbers,
2168 const int* blkRowSizes,
2169 const double*
const* coefs,
2173 if ((
int)dworkSpace2_.size() < numPtRows) {
2174 dworkSpace2_.resize(numPtRows);
2176 const double* * valptr = &dworkSpace2_[0];
2177 for(i=0; i<numPtRows; i++) {
2178 int row = ptRowNumbers[i];
2179 valptr[i] = coefs[i];
2180 if (row < localStartRow_ || row > localEndRow_) {
2181 eqnCommMgr_->addRemoteEqn(row, valptr[i], ptRowNumbers, numPtRows);
2185 if (mode == ASSEMBLE_PUT) {
2187 numPtRows, ptRowNumbers,
2193 for(i=0; i<numBlkRows; i++) {
2194 int row = ptRowNumbers[offset];
2195 if (row < localStartRow_ || row > localEndRow_) {
2196 offset += blkRowSizes[i];
2200 if (mode == ASSEMBLE_SUM) {
2201 if (Filter::logStream() != NULL && 0) {
2202 FEI_OSTREAM& os = *logStream();
2203 os <<
"# calling sumIntoSystemMatrix, row: " << ptRowNumbers[i]
2205 for(
int j=0; j<numPtRows; ++j) os << ptRowNumbers[j] <<
" ";
2210 numPtRows, ptRowNumbers,
2211 1, &(blkRowNumbers[i]),
2212 numBlkRows, blkRowNumbers,
2213 &(valptr[offset])) );
2216 offset += blkRowSizes[i];
2223 int LinSysCoreFilter::giveToMatrix(
int numPtRows,
const int* ptRows,
2224 int numPtCols,
const int* ptCols,
2225 const double*
const* values,
int mode)
2229 if (problemStructure_->numSlaveEquations() == 0) {
2230 for(
int i=0; i<numPtRows; i++) {
2231 if (ptRows[i] < localStartRow_ || ptRows[i] > localEndRow_) {
2232 eqnCommMgr_->addRemoteEqn(ptRows[i], values[i], ptCols, numPtCols);
2236 if (mode == ASSEMBLE_SUM) {
2237 if (Filter::logStream() != NULL && 0) {
2238 FEI_OSTREAM& os = *logStream();
2239 os <<
"# calling sumIntoSystemMatrix, row: " << ptRows[i]
2241 for(
int j=0; j<numPtCols; ++j) os << ptCols[j] <<
" ";
2257 iworkSpace_.resize(numPtCols);
2258 iworkSpace2_.resize(numPtCols);
2259 int* iworkPtr = &iworkSpace_[0];
2260 int* iworkPtr2= &iworkSpace2_[0];
2262 for(
int ii=0; ii<numPtCols; ii++) {
2263 int reducedEqn = -1;
2268 iworkPtr[ii] = reducedEqn;
2271 iworkPtr[ii] = reducedEqn;
2272 iworkPtr2[offset++] = reducedEqn;
2275 iworkSpace2_.resize(offset);
2277 for(
int i=0; i<numPtRows; i++) {
2278 int row = ptRows[i];
2282 if (isSlave)
continue;
2284 if (reducedStartRow_ > reducedRow || reducedRow > reducedEndRow_) {
2286 dworkSpace_.resize(0);
2287 for(
int j=0; j<numPtCols; j++) {
2288 if (iworkSpace_[j]>=0) {
2289 if (Filter::logStream() != NULL) {
2290 (*logStream())<<
"# giveToMatrix remote("<<reducedRow<<
","
2291 <<iworkSpace_[j]<<
","<<values[i][j]<<
")"<<FEI_ENDL;
2294 dworkSpace_.push_back(values[i][j]);
2298 if (mode == ASSEMBLE_SUM) {
2299 if (Filter::logStream() != NULL) {
2300 (*logStream())<<
"sum"<<FEI_ENDL;
2303 eqnCommMgr_->addRemoteEqn(reducedRow,
2306 iworkSpace2_.size());
2309 if (Filter::logStream() != NULL) {
2310 (*logStream())<<
"put"<<FEI_ENDL;
2313 eqnCommMgr_put_->addRemoteEqn(reducedRow,
2316 iworkSpace2_.size());
2322 for(
int j=0; j<numPtCols; j++) {
2324 int reducedCol = iworkPtr[j];
2325 if (reducedCol<0)
continue;
2327 double* tmpCoef =
const_cast<double*
>(&(values[i][j]));
2329 if (Filter::logStream() != NULL) {
2330 (*logStream())<<
"# giveToMatrix local("<<reducedRow
2331 <<
","<<reducedCol<<
","<<*tmpCoef<<
")"<<FEI_ENDL;
2334 if (mode == ASSEMBLE_SUM) {
2335 if (Filter::logStream() != NULL && 0) {
2336 FEI_OSTREAM& os = *logStream();
2337 os <<
"# calling sumIntoSystemMatrix, row: " << reducedRow
2338 <<
", columns: " << reducedCol << FEI_ENDL;
2353 catch(std::runtime_error& exc) {
2358 return(FEI_SUCCESS);
2362 int LinSysCoreFilter::giveToLocalReducedMatrix(
int numPtRows,
const int* ptRows,
2363 int numPtCols,
const int* ptCols,
2364 const double*
const* values,
int mode)
2366 bool specialCase = (!firstRemEqnExchange_ && newConstraintData_
2367 && !newMatrixData_) ?
true :
false;
2369 double fei_min = std::numeric_limits<double>::min();
2371 for(
int i=0; i<numPtRows; i++) {
2373 if (mode == ASSEMBLE_SUM) {
2374 const double* values_i = values[i];
2376 for(
int j=0; j<numPtCols; ++j) {
2377 if (specialCase && std::abs(values_i[j]) < fei_min)
continue;
2379 const double* valPtr = &(values_i[j]);
2390 return(FEI_SUCCESS);
2394 int LinSysCoreFilter::sumIntoMatrix(
fei::CSRMat& mat)
2396 const std::vector<int>& rowNumbers = mat.getGraph().
rowNumbers;
2397 const std::vector<int>& rowOffsets = mat.getGraph().
rowOffsets;
2399 const std::vector<double>& pckCoefs = mat.getPackedCoefs();
2401 for(
size_t i=0; i<rowNumbers.size(); ++i) {
2402 int row = rowNumbers[i];
2403 int offset = rowOffsets[i];
2404 int rowlen = rowOffsets[i+1]-offset;
2405 const int* indices = &pckColInds[offset];
2406 const double* coefs = &pckCoefs[offset];
2408 if (giveToMatrix(1, &row, rowlen, indices, &coefs, ASSEMBLE_SUM) != 0) {
2409 throw std::runtime_error(
"fei::impl_utils::add_to_matrix ERROR in matrix.sumIn.");
2413 return(FEI_SUCCESS);
2417 int LinSysCoreFilter::getFromMatrix(
int numPtRows,
const int* ptRows,
2418 const int* rowColOffsets,
const int* ptCols,
2419 int numColsPerRow,
double** values)
2431 for(
int re=0; re<numPtRows; re++) {
2432 int eqn = ptRows[re];
2434 if (owner == localRank_)
continue;
2436 remoteProcEqns.
addEqn(eqn, owner);
2444 CHK_ERR( eqnCommMgr_->
mirrorProcEqns(remoteProcEqns, localProcEqns) )
2449 CHK_ERR( getEqnsFromMatrix(localProcEqns, localEqns) )
2452 std::vector<
int>& eqnNumbers = localEqns.eqnNumbers();
2453 fei::CSVec** localEqnsPtr = (localEqns.eqns().size() ? &(localEqns.eqns()[0]) : 0);
2454 std::vector<
int> eqnLengths(eqnNumbers.size());
2455 for(
size_t i=0; i<eqnNumbers.size(); ++i) {
2456 eqnLengths[i] = localEqnsPtr[i]->size();
2468 CHK_ERR( EqnCommMgr::exchangeEqnBuffers(comm_, &localProcEqns, &localEqns,
2469 &remoteProcEqns, &remoteEqns,
false));
2471 std::vector<int>& remEqnNumbers = remoteEqns.eqnNumbers();
2472 fei::CSVec** remEqnsPtr = (remoteEqns.eqns().size() ? &(remoteEqns.eqns()[0]) : 0);
2473 std::vector<fei::CSVec*>& remEqns = remoteEqns.eqns();
2476 for(
int i=0; i<numPtRows; i++) {
2477 int row = ptRows[i];
2482 if (eqnIndex < 0)
continue;
2487 if (ptCols == NULL) {
2488 for(
size_t j=0; j<remEqnsPtr[eqnIndex]->size(); j++) {
2489 values[i][j] = remEqns[eqnIndex]->coefs()[j];
2494 for(
int j=0; j<numColsPerRow; j++) {
2495 int offset = rowColOffsets[i] + j;
2497 if (colIndex < 0) ERReturn(-1);
2499 values[i][j] = remEqns[eqnIndex]->coefs()[colIndex];
2504 for(
int i=0; i<numPtRows; i++) {
2505 int row = ptRows[i];
2506 if (row < localStartRow_ || localEndRow_ < row)
continue;
2508 int rowLen = 0, checkRowLen;
2510 if (rowLen <= 0) ERReturn(-1);
2515 std::vector<
double> coefs(rowLen);
2516 std::vector<
int> indices(rowLen);
2518 CHK_ERR( lsc_->getMatrixRow(row, &coefs[0], &indices[0], rowLen, checkRowLen) );
2519 if (rowLen != checkRowLen) ERReturn(-1);
2527 if (ptCols == NULL) {
2528 for(
int j=0; j<rowLen; j++) {
2529 values[i][j] = coefs[j];
2534 for(
int j=0; j<numColsPerRow; j++) {
2535 std::vector<int>::iterator iter =
2536 std::find(indices.begin(), indices.end(), ptCols[rowColOffsets[i]+j]);
2537 if (iter == indices.end()) {
2541 int index = iter - indices.begin();
2542 values[i][j] = coefs[index];
2546 return(FEI_SUCCESS);
2558 for(
unsigned p=0; p<eqnNumbers.size(); p++) {
2559 for(
unsigned i=0; i<eqnNumbers[p]->size(); i++) {
2560 int eqn = (*(eqnNumbers[p]))[i];
2562 if (localStartRow_ > eqn || localEndRow_ < eqn)
continue;
2565 std::vector<int>& eqnDataEqns = eqnData.
eqnNumbers();
2571 if (len <= 0)
continue;
2572 std::vector<double> coefs(len);
2573 std::vector<int> indices(len);
2576 CHK_ERR( lsc_->
getMatrixRow(eqn, &coefs[0], &indices[0],
2578 if (outputLen != len) ERReturn(-1);
2580 CHK_ERR( eqnData.
addEqn(eqn, &coefs[0], &indices[0], len,
false) );
2583 return(FEI_SUCCESS);
2602 for(
int p=0; p<numSendProcs; p++) {
2603 for(
int i=0; i<eqnsPerProc[p]; i++) {
2607 if (reducedStartRow_ > reducedEqn || reducedEndRow_ < reducedEqn)
continue;
2610 std::vector<int>& eqnDataEqns = eqnData.
eqnNumbers();
2617 int bogusIndex = 19;
2618 CHK_ERR( eqnData.
addIndices(reducedEqn, &bogusIndex, 1) );
2619 CHK_ERR( eqnData.
addRHS(reducedEqn, 0, rhsValue) );
2622 return(FEI_SUCCESS);
2626 int LinSysCoreFilter::giveToRHS(
int num,
const double* values,
2627 const int* indices,
int mode)
2629 if (problemStructure_->numSlaveEquations() == 0) {
2630 for(
int i=0; i<num; i++) {
2631 if (indices[i] < localStartRow_ || indices[i] > localEndRow_) {
2632 if (mode == ASSEMBLE_SUM) {
2633 eqnCommMgr_->addRemoteRHS(indices[i], currentRHS_, values[i]);
2636 eqnCommMgr_put_->addRemoteRHS(indices[i], currentRHS_, values[i]);
2642 if (mode == ASSEMBLE_SUM) {
2651 for(
int i=0; i<num; i++) {
2653 bool isSlave = problemStructure_->
2654 translateToReducedEqn(indices[i], reducedEqn);
2655 if (isSlave)
continue;
2657 if (reducedEqn < reducedStartRow_ || reducedEqn > reducedEndRow_) {
2658 if (mode == ASSEMBLE_SUM) {
2659 eqnCommMgr_->addRemoteRHS(reducedEqn, currentRHS_, values[i]);
2662 eqnCommMgr_put_->addRemoteRHS(reducedEqn, currentRHS_, values[i]);
2668 if (mode == ASSEMBLE_SUM) {
2677 return(FEI_SUCCESS);
2681 int LinSysCoreFilter::giveToLocalReducedRHS(
int num,
const double* values,
2682 const int* indices,
int mode)
2684 for(
int i=0; i<num; i++) {
2686 if (mode == ASSEMBLE_SUM) {
2694 return(FEI_SUCCESS);
2698 int LinSysCoreFilter::sumIntoRHS(
fei::CSVec& vec)
2700 std::vector<int>& indices = vec.indices();
2701 std::vector<double>& coefs = vec.coefs();
2703 CHK_ERR( giveToRHS(indices.size(), &coefs[0], &indices[0], ASSEMBLE_SUM) );
2705 return(FEI_SUCCESS);
2709 int LinSysCoreFilter::getFromRHS(
int num,
double* values,
const int* indices)
2718 for(
int re=0; re<num; re++) {
2719 int eqn = indices[re];
2721 if (owner==localRank_)
continue;
2723 remoteProcEqns.
addEqn(eqn, owner);
2731 CHK_ERR( eqnCommMgr_->
mirrorProcEqns(remoteProcEqns, localProcEqns) );
2736 CHK_ERR( getEqnsFromRHS(localProcEqns, localEqns) );
2739 std::vector<int>& eqnNumbers = localEqns.eqnNumbers();
2740 fei::CSVec** localEqnsPtr = &(localEqns.eqns()[0]);
2741 std::vector<int> eqnLengths(eqnNumbers.size());
2742 for(
size_t i=0; i<eqnNumbers.size(); ++i) {
2743 eqnLengths[i] = localEqnsPtr[i]->size();
2755 CHK_ERR( EqnCommMgr::exchangeEqnBuffers(comm_, &localProcEqns, &localEqns,
2756 &remoteProcEqns, &remoteEqns,
false))
2759 std::vector<
int>& remEqnNumbers = remoteEqns.eqnNumbers();
2760 std::vector<std::vector<
double>*>& remRhsCoefs = *(remoteEqns.rhsCoefsPtr());
2762 for(
int i=0; i<num; i++) {
2763 int row = indices[i];
2766 if (eqnIndex < 0)
continue;
2768 values[i] = (*(remRhsCoefs[eqnIndex]))[0];
2772 for(
int i=0; i<num; i++) {
2773 if (indices[i] < localStartRow_ || indices[i] > localEndRow_)
continue;
2778 return(FEI_SUCCESS);
2782 int LinSysCoreFilter::getEqnSolnEntry(
int eqnNumber,
double& solnValue)
2794 if (problemStructure_->numSlaveEquations() == 0) {
2795 if (localStartRow_ > eqnNumber || eqnNumber > localEndRow_) {
2797 CHK_ERR( getSharedRemoteSolnEntry(eqnNumber, solnValue) );
2801 CHK_ERR( getReducedSolnEntry( eqnNumber, solnValue ) );
2818 std::vector<int>* masterEqns = NULL;
2819 std::vector<double>* masterCoefs = NULL;
2823 int len = masterEqns->size();
2828 for(
int i=0; i<len; i++) {
2829 int mEqn = (*masterEqns)[i];
2833 if (reducedStartRow_ > mReducedeqn || mReducedeqn > reducedEndRow_) {
2834 CHK_ERR( getSharedRemoteSolnEntry(mReducedeqn, coef) );
2837 CHK_ERR( getReducedSolnEntry(mReducedeqn, coef) );
2839 solnValue += coef * (*masterCoefs)[i];
2846 if (reducedStartRow_ > reducedEqn || reducedEqn > reducedEndRow_) {
2847 CHK_ERR( getSharedRemoteSolnEntry(reducedEqn, solnValue) );
2850 CHK_ERR( getReducedSolnEntry(reducedEqn, solnValue) );
2858 int LinSysCoreFilter::getSharedRemoteSolnEntry(
int eqnNumber,
double& solnValue)
2860 std::vector<int>& remoteEqnNumbers = eqnCommMgr_->sendEqnNumbersPtr();
2861 double* remoteSoln = eqnCommMgr_->sendEqnSolnPtr();
2865 fei::console_out() <<
"LinSysCoreFilter::getSharedRemoteSolnEntry: ERROR, eqn "
2866 << eqnNumber <<
" not found." << FEI_ENDL;
2869 solnValue = remoteSoln[index];
2874 int LinSysCoreFilter::getReducedSolnEntry(
int eqnNumber,
double& solnValue)
2882 return(FEI_SUCCESS);
2886 int LinSysCoreFilter::unpackSolution()
2894 if (Filter::logStream() != NULL) {
2895 (*logStream())<<
"# entering unpackSolution, outputLevel: "
2896 <<outputLevel_<<FEI_ENDL;
2905 int numRecvEqns = eqnCommMgr_->getNumLocalEqns();
2906 std::vector<int>& recvEqnNumbers = eqnCommMgr_->localEqnNumbers();
2908 for(
int i=0; i<numRecvEqns; i++) {
2909 int eqn = recvEqnNumbers[i];
2911 if ((reducedStartRow_ > eqn) || (reducedEndRow_ < eqn)) {
2912 fei::console_out() <<
"LinSysCoreFilter::unpackSolution: ERROR, 'recv' eqn (" << eqn
2913 <<
") out of local range." << FEI_ENDL;
2914 MPI_Abort(comm_, -1);
2917 double solnValue = 0.0;
2919 CHK_ERR( getReducedSolnEntry(eqn, solnValue) );
2921 eqnCommMgr_->addSolnValues(&eqn, &solnValue, 1);
2924 eqnCommMgr_->exchangeSoln();
2926 debugOutput(
"#LinSysCoreFilter leaving unpackSolution");
2927 return(FEI_SUCCESS);
2931 void LinSysCoreFilter::setEqnCommMgr(
EqnCommMgr* eqnCommMgr)
2934 eqnCommMgr_ = eqnCommMgr;
2938 int LinSysCoreFilter::getBlockNodeSolution(GlobalID elemBlockID,
2940 const GlobalID *nodeIDs,
2944 debugOutput(
"FEI: getBlockNodeSolution");
2946 int numActiveNodes = problemStructure_->getNumActiveNodes();
2947 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
2949 if (numActiveNodes <= 0)
return(0);
2951 int numSolnParams = 0;
2954 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) );
2960 for(
int i=0; i<numActiveNodes; i++) {
2964 if (offset == numNodes)
break;
2966 GlobalID nodeID = nodeIDs[offset];
2969 offsets[offset++] = numSolnParams;
2976 if (node_i!=NULL && nodeID == node_i->getGlobalNodeID()) {
2990 int numFields = node->getNumFields();
2991 const int* fieldIDs = node->getFieldIDList();
2993 for(
int j=0; j<numFields; j++) {
2994 if (block->containsField(fieldIDs[j])) {
2995 int size = problemStructure_->
getFieldSize(fieldIDs[j]);
3002 for(
int k=0; k<size; k++) {
3003 CHK_ERR( getEqnSolnEntry(thisEqn+k, answer) )
3004 results[numSolnParams++] = answer;
3010 offsets[numNodes] = numSolnParams;
3012 return(FEI_SUCCESS);
3017 const GlobalID *nodeIDs,
3021 debugOutput(
"FEI: getNodalSolution");
3023 int numActiveNodes = problemStructure_->getNumActiveNodes();
3024 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
3026 if (numActiveNodes <= 0)
return(0);
3028 int numSolnParams = 0;
3034 for(
int i=0; i<numActiveNodes; i++) {
3038 if (offset == numNodes)
break;
3040 GlobalID nodeID = nodeIDs[offset];
3043 offsets[offset++] = numSolnParams;
3050 if (node_i!=NULL && nodeID == node_i->getGlobalNodeID()) {
3064 int numFields = node->getNumFields();
3065 const int* fieldIDs = node->getFieldIDList();
3067 for(
int j=0; j<numFields; j++) {
3068 int size = problemStructure_->
getFieldSize(fieldIDs[j]);
3075 for(
int k=0; k<size; k++) {
3076 CHK_ERR( getEqnSolnEntry(thisEqn+k, answer) )
3077 results[numSolnParams++] = answer;
3082 offsets[numNodes] = numSolnParams;
3084 return(FEI_SUCCESS);
3091 const GlobalID *nodeIDs,
3099 debugOutput(
"FEI: getBlockFieldNodeSolution");
3101 int numActiveNodes = problemStructure_->getNumActiveNodes();
3102 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
3104 if (numActiveNodes <= 0)
return(0);
3107 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) );
3109 int fieldSize = problemStructure_->
getFieldSize(fieldID);
3110 if (fieldSize <= 0) ERReturn(-1);
3112 if (!block->containsField(fieldID)) {
3113 fei::console_out() <<
"LinSysCoreFilter::getBlockFieldNodeSolution WARNING: fieldID " << fieldID
3114 <<
" not contained in element-block " << (int)elemBlockID << FEI_ENDL;
3121 for(
int i=0; i<numNodes; i++) {
3125 GlobalID nodeID = nodeIDs[i];
3135 if (node_i!=NULL && nodeID == node_i->getGlobalNodeID()) {
3151 if (!hasField)
continue;
3153 int offset = fieldSize*i;
3154 for(
int j=0; j<fieldSize; j++) {
3155 double answer = 0.0;
3156 CHK_ERR( getEqnSolnEntry(eqnNumber+j, answer) );
3157 results[offset+j] = answer;
3161 return(FEI_SUCCESS);
3165 int LinSysCoreFilter::getNodalFieldSolution(
int fieldID,
3167 const GlobalID *nodeIDs,
3170 debugOutput(
"FEI: getNodalFieldSolution");
3172 int numActiveNodes = problemStructure_->getNumActiveNodes();
3173 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
3175 if (numActiveNodes <= 0)
return(0);
3177 int fieldSize = problemStructure_->
getFieldSize(fieldID);
3178 if (fieldSize <= 0) ERReturn(-1);
3183 for(
int i=0; i<numNodes; i++) {
3187 GlobalID nodeID = nodeIDs[i];
3194 if (node_i!=NULL && nodeID == node_i->getGlobalNodeID()) {
3213 if (!hasField)
continue;
3215 int offset = fieldSize*i;
3216 for(
int j=0; j<fieldSize; j++) {
3217 double answer = 0.0;
3218 CHK_ERR( getEqnSolnEntry(eqnNumber+j, answer) );
3219 results[offset+j] = answer;
3223 return(FEI_SUCCESS);
3227 int LinSysCoreFilter::putBlockNodeSolution(GlobalID elemBlockID,
3229 const GlobalID *nodeIDs,
3231 const double *estimates) {
3233 debugOutput(
"FEI: putBlockNodeSolution");
3235 int numActiveNodes = problemStructure_->getNumActiveNodes();
3237 if (numActiveNodes <= 0)
return(0);
3240 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) );
3242 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
3249 for(
int i=0; i<numNodes; i++) {
3251 int err = nodeDB.getNodeWithID(nodeIDs[i], node);
3253 if (err != 0)
continue;
3255 if (!node->hasBlockIndex(blk_idx))
continue;
3257 if (node->getOwnerProc() != localRank_)
continue;
3259 int numFields = node->getNumFields();
3260 const int* fieldIDs = node->getFieldIDList();
3261 const int* fieldEqnNumbers = node->getFieldEqnNumbers();
3263 if (fieldEqnNumbers[0] < localStartRow_ ||
3264 fieldEqnNumbers[0] > localEndRow_)
continue;
3266 int offs = offsets[i];
3268 for(
int j=0; j<numFields; j++) {
3269 int size = problemStructure_->
getFieldSize(fieldIDs[j]);
3271 if (block->containsField(fieldIDs[j])) {
3272 for(
int k=0; k<size; k++) {
3275 translateToReducedEqn(fieldEqnNumbers[j]+k, reducedEqn);
3278 &estimates[offs+k], 1) );
3285 return(FEI_SUCCESS);
3289 int LinSysCoreFilter::putBlockFieldNodeSolution(GlobalID elemBlockID,
3292 const GlobalID *nodeIDs,
3293 const double *estimates)
3295 int fieldSize = problemStructure_->
getFieldSize(fieldID);
3297 if (Filter::logStream() != NULL) {
3298 FEI_OSTREAM& os = *logStream();
3299 os <<
"FEI: putBlockFieldNodeSolution" << FEI_ENDL;
3300 os <<
"#blkID" << FEI_ENDL << (int)elemBlockID << FEI_ENDL
3301 <<
"#fieldID"<<FEI_ENDL << fieldID << FEI_ENDL
3302 <<
"#fieldSize"<<FEI_ENDL << fieldSize << FEI_ENDL
3303 <<
"#numNodes"<<FEI_ENDL << numNodes << FEI_ENDL
3304 <<
"#nodeIDs" << FEI_ENDL;
3306 for(i=0; i<numNodes; ++i) os << (
int)nodeIDs[i] << FEI_ENDL;
3307 os <<
"#estimates" << FEI_ENDL;
3308 for(i=0; i<numNodes*fieldSize; ++i) os << estimates[i] << FEI_ENDL;
3312 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) );
3313 if (!block->containsField(fieldID))
return(1);
3315 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
3320 std::vector<int> numbers(numNodes);
3325 std::vector<double> data;
3328 assert(fieldSize >= 0);
3329 numbers.resize(numNodes*fieldSize);
3330 data.resize(numNodes*fieldSize);
3335 for(
int i=0; i<numNodes; i++) {
3339 if (fieldID < 0) numbers[count++] = node->getNodeNumber();
3343 if (eqn >= localStartRow_ && eqn <= localEndRow_) {
3344 for(
int j=0; j<fieldSize; j++) {
3345 data[count] = estimates[i*fieldSize + j];
3355 &numbers[0], numNodes, estimates));
3361 return(FEI_SUCCESS);
3365 int LinSysCoreFilter::getBlockElemSolution(GlobalID elemBlockID,
3367 const GlobalID *elemIDs,
3368 int& numElemDOFPerElement,
3375 debugOutput(
"FEI: getBlockElemSolution");
3378 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) )
3380 numElemDOFPerElement = block->getNumElemDOFPerElement();
3381 if (numElemDOFPerElement <= 0)
return(0);
3384 problemStructure_->getBlockConnectivity(elemBlockID);
3385 std::map<GlobalID,int>& elemIDList = ctable.elemIDs;
3387 std::vector<int>& elemDOFEqnNumbers = block->elemDOFEqnNumbers();
3390 for(
int i=0; i<numElems; i++) {
3391 std::map<GlobalID,int>::const_iterator
3392 iter = elemIDList.find(elemIDs[i]);
3393 if (iter == elemIDList.end())
continue;
3394 int index = iter->second;
3396 int offset = i*numElemDOFPerElement;
3398 for(
int j=0; j<numElemDOFPerElement; j++) {
3399 int eqn = elemDOFEqnNumbers[index] + j;
3401 CHK_ERR( getEqnSolnEntry(eqn, answer) )
3403 results[offset+j] = answer;
3407 return(FEI_SUCCESS);
3413 const GlobalID *elemIDs,
3415 const
double *estimates)
3417 debugOutput(
"FEI: putBlockElemSolution");
3420 CHK_ERR( problemStructure_->getBlockDescriptor(elemBlockID, block) )
3422 int DOFPerElement = block->getNumElemDOFPerElement();
3423 assert(DOFPerElement == dofPerElem);
3424 if (DOFPerElement <= 0)
return(0);
3427 problemStructure_->getBlockConnectivity(elemBlockID);
3428 std::map<GlobalID,int>& elemIDList = ctable.elemIDs;
3430 std::vector<int>& elemDOFEqnNumbers = block->elemDOFEqnNumbers();
3433 for(
int i=0; i<numElems; i++) {
3434 std::map<GlobalID,int>::const_iterator
3435 iter = elemIDList.find(elemIDs[i]);
3436 if (iter == elemIDList.end())
continue;
3438 int index = iter->second;
3440 for(
int j=0; j<DOFPerElement; j++) {
3443 translateToReducedEqn(elemDOFEqnNumbers[index] + j, reducedEqn);
3444 double soln = estimates[i*DOFPerElement + j];
3450 return(FEI_SUCCESS);
3454 int LinSysCoreFilter::getCRMultipliers(
int numCRs,
3456 double* multipliers)
3458 int multCRsLen = problemStructure_->getNumMultConstRecords();
3459 if (numCRs > multCRsLen) {
3463 std::map<GlobalID, ConstraintType*>::const_iterator
3464 cr_iter = problemStructure_->getMultConstRecords().begin(),
3465 cr_end = problemStructure_->getMultConstRecords().end();
3468 while(cr_iter != cr_end && i < numCRs) {
3469 GlobalID CRID = (*cr_iter).first;
3471 if (CRID != CRIDs[i]) {
3472 CHK_ERR( problemStructure_->getMultConstRecord(CRIDs[i], multCR) );
3477 CHK_ERR( getEqnSolnEntry(eqn, multipliers[i]) );
3482 return(FEI_SUCCESS);
3486 int LinSysCoreFilter::putCRMultipliers(
int numMultCRs,
3488 const double *multEstimates)
3490 debugOutput(
"FEI: putCRMultipliers");
3492 for(
int j = 0; j < numMultCRs; j++) {
3494 CHK_ERR( problemStructure_->getMultConstRecord(CRIDs[j], multCR) );
3497 if (eqnNumber < localStartRow_ || eqnNumber > localEndRow_)
continue;
3501 return(FEI_SUCCESS);
3505 int LinSysCoreFilter::putNodalFieldData(
int fieldID,
3507 const GlobalID* nodeIDs,
3508 const double* nodeData)
3510 debugOutput(
"FEI: putNodalFieldData");
3513 return(putNodalFieldSolution(fieldID, numNodes, nodeIDs, nodeData));
3516 int fieldSize = problemStructure_->
getFieldSize(fieldID);
3517 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
3519 std::vector<int> nodeNumbers(numNodes);
3521 for(
int i=0; i<numNodes; i++) {
3525 int nodeNumber = node->getNodeNumber();
3526 if (nodeNumber < 0) {
3527 fei::console_out() <<
"LinSysCoreFilter::putNodalFieldData ERROR, node with ID "
3528 << (int)nodeIDs[i] <<
" doesn't have an associated nodeNumber "
3529 <<
"assigned. putNodalFieldData shouldn't be called until after the "
3530 <<
"initComplete method has been called." << FEI_ENDL;
3534 nodeNumbers[i] = nodeNumber;
3538 &nodeNumbers[0], numNodes, nodeData) );
3544 int LinSysCoreFilter::putNodalFieldSolution(
int fieldID,
3546 const GlobalID* nodeIDs,
3547 const double* nodeData)
3549 debugOutput(
"FEI: putNodalFieldSolution");
3552 return(putNodalFieldData(fieldID, numNodes, nodeIDs, nodeData));
3555 int fieldSize = problemStructure_->
getFieldSize(fieldID);
3556 NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
3558 std::vector<int> eqnNumbers(fieldSize);
3560 for(
int i=0; i<numNodes; i++) {
3566 if (!hasField)
continue;
3568 int reducedEqn = -1;
3570 if (isSlave)
continue;
3572 if (reducedStartRow_ > reducedEqn || reducedEndRow_ < reducedEqn)
continue;
3574 int localLen = fieldSize;
3575 for(
int j=0; j<fieldSize; j++) {
3576 int thisEqn = reducedEqn+j;
3577 if (reducedStartRow_ > thisEqn || reducedEndRow_ <thisEqn) {
3581 eqnNumbers[j] = reducedEqn+j;
3584 int offset = i*fieldSize;
3586 &nodeData[offset], localLen) );
3593 int LinSysCoreFilter::assembleEqns(
int numPtRows,
3595 const int* rowNumbers,
3596 const int* colIndices,
3597 const double*
const* coefs,
3598 bool structurallySymmetric,
3599 int numBlkEqns,
int* blkEqns,
3600 int* blkSizes,
bool useBlkEqns,
3603 if (numPtRows == 0)
return(FEI_SUCCESS);
3605 bool anySlaves =
false;
3606 int numSlaveEqns = problemStructure_->numSlaveEquations();
3607 if (numSlaveEqns > 0) {
3608 rSlave_.resize(numPtRows);
3610 const int* indPtr = colIndices;
3611 for(
int r=0; r<numPtRows; r++) {
3612 rSlave_[r] = problemStructure_->
isSlaveEqn(rowNumbers[r]) ? 1 : 0;
3613 if (rSlave_[r] == 1) anySlaves =
true;
3615 for(
int j=0; j<numPtCols; j++) {
3616 int isSlave = problemStructure_->
isSlaveEqn(indPtr[j]) ? 1 : 0;
3617 cSlave_.push_back(isSlave);
3618 if (isSlave == 1) anySlaves =
true;
3621 if (!structurallySymmetric) indPtr += numPtCols;
3625 if (numSlaveEqns == 0 || !anySlaves) {
3626 if (numSlaveEqns == 0 && structurallySymmetric) {
3628 CHK_ERR( giveToBlkMatrix_symm_noSlaves(numPtRows, rowNumbers,
3629 numBlkEqns, blkEqns, blkSizes,
3633 CHK_ERR( giveToMatrix_symm_noSlaves(numPtRows, rowNumbers, coefs, mode) );
3637 if ((
int)dworkSpace2_.size() < numPtRows) {
3638 dworkSpace2_.resize(numPtRows);
3640 const double* * coefPtr = &dworkSpace2_[0];
3641 for(
int i=0; i<numPtRows; i++) {
3642 coefPtr[i] = coefs[i];
3645 if (structurallySymmetric) {
3646 CHK_ERR( giveToMatrix(numPtRows, rowNumbers, numPtRows, rowNumbers,
3650 const int* indPtr = colIndices;
3651 for(
int i=0; i<numPtRows; i++) {
3652 int row = rowNumbers[i];
3654 const double* coefPtr1 = coefs[i];
3656 CHK_ERR(giveToMatrix(1, &row, numPtCols, indPtr, &coefPtr1, mode));
3657 indPtr += numPtCols;
3664 const int* indicesPtr = colIndices;
3665 for(
int i=0; i<numPtRows; i++) {
3666 int row = rowNumbers[i];
3668 const double* coefPtr = coefs[i];
3669 int* colSlave = &cSlave_[offset];
3670 offset += numPtCols;
3672 if (rSlave_[i] == 1) {
3675 for(
int jj=0; jj<numPtCols; jj++) {
3676 int col = indicesPtr[jj];
3678 Kdd_->sumInCoef(row, col, coefPtr[jj]);
3681 Kdi_->sumInCoef(row, col, coefPtr[jj]);
3686 const int* ii_indicesPtr = colIndices;
3687 for(
int ii=0; ii<numPtRows; ii++) {
3688 int rowi = rowNumbers[ii];
3689 if (rSlave_[ii] == 1)
continue;
3692 if (index < 0)
continue;
3694 const double* coefs_ii = coefs[ii];
3696 Kid_->sumInCoef(rowi, row, coefs_ii[index]);
3698 if (!structurallySymmetric) ii_indicesPtr += numPtCols;
3701 reducedEqnCounter_++;
3709 CHK_ERR( giveToMatrix(1, &row, numPtCols, indicesPtr, &coefPtr, mode) );
3712 if (!structurallySymmetric) indicesPtr += numPtCols;
3715 if (reducedEqnCounter_ > 300) CHK_ERR( assembleReducedEqns() );
3718 return(FEI_SUCCESS);
3722 int LinSysCoreFilter::assembleReducedEqns()
3724 fei::FillableMat* D = problemStructure_->getSlaveDependencies();
3737 if (Filter::logStream() != NULL) {
3738 FEI_OSTREAM& os = *Filter::logStream();
3739 os <<
"# tmpMat1_"<<FEI_ENDL << tmpMat1_ << FEI_ENDL;
3740 os <<
"# tmpMat2_"<<FEI_ENDL << tmpMat2_ << FEI_ENDL;
3744 CHK_ERR( sumIntoMatrix(tmpMat1_) );
3745 CHK_ERR( sumIntoMatrix(tmpMat2_) );
3753 if (Filter::logStream() != NULL) {
3754 FEI_OSTREAM& os = *Filter::logStream();
3755 os <<
"# tmpMat2_"<<FEI_ENDL << tmpMat2_ << FEI_ENDL;
3759 CHK_ERR( sumIntoMatrix(tmpMat2_) );
3764 reducedEqnCounter_ = 0;
3770 int LinSysCoreFilter::assembleRHS(
int numValues,
3772 const double* coefs,
3779 if (problemStructure_->numSlaveEquations() == 0) {
3780 CHK_ERR( giveToRHS(numValues, coefs, indices, mode) );
3781 return(FEI_SUCCESS);
3784 for(
int i = 0; i < numValues; i++) {
3785 int eqn = indices[i];
3788 fei::add_entry( fd_, eqn, coefs[i]);
3789 reducedRHSCounter_++;
3793 CHK_ERR( giveToRHS(1, &(coefs[i]), &eqn, mode ) );
3796 if (reducedRHSCounter_ > 300) CHK_ERR( assembleReducedRHS() );
3798 return(FEI_SUCCESS);
3802 int LinSysCoreFilter::assembleReducedRHS()
3804 fei::FillableMat* D = problemStructure_->getSlaveDependencies();
3811 CHK_ERR( sumIntoRHS(tmpVec1_) );
3814 reducedRHSCounter_ = 0;
3820 void LinSysCoreFilter::debugOutput(
const char* mesg) {
3821 if (Filter::logStream() != NULL) {
3822 (*logStream())<<mesg<<FEI_ENDL;
virtual int sumIntoSystemMatrix(int numPtRows, const int *ptRows, int numPtCols, const int *ptCols, int numBlkRows, const int *blkRows, int numBlkCols, const int *blkCols, const double *const *values)=0
virtual int setRHSID(int rhsID)=0
virtual int setMultCREqns(int multCRSetID, int numCRs, int numNodesPerCR, int **nodeNumbers, int **eqnNumbers, int *fieldIDs, int *multiplierEqnNumbers)=0
int getParameters(int &numParams, char **¶mStrings)
int getFieldSize(int fieldID)
int Allgatherv(MPI_Comm comm, std::vector< T > &sendbuf, std::vector< int > &recvLengths, std::vector< T > &recvbuf)
std::vector< int > & getMasterFieldIDs()
int getBlockDescriptor_index(int index, BlockDescriptor *&block)
int addEqn(int eqnNumber, const double *coefs, const int *indices, int len, bool accumulate, bool create_indices_union=false)
std::vector< int > & eqnsPerProcPtr()
void multiply_CSRMat_CSRMat(const CSRMat &A, const CSRMat &B, CSRMat &C, bool storeResultZeros)
int getMasterEqnRHS(int slaveEqn, double &rhsValue)
virtual int sumIntoRHSVector(int num, const double *values, const int *indices)=0
virtual int setLookup(Lookup &lookup)=0
virtual int setLoadVectors(GlobalID elemBlock, int numElems, const GlobalID *elemIDs, const double *const *load, int numEqnsPerElem, const int *const *eqnIndices)=0
virtual int setConnectivities(GlobalID elemBlock, int numElements, int numNodesPerElem, const GlobalID *elemIDs, const int *const *connNodes)=0
int getMasterEqnCoefs(int slaveEqn, std::vector< double > *&masterCoefs)
virtual int setMultCRComplete()=0
virtual int resetMatrix(double s)=0
void setProcEqnLengths(int *eqnNumbers, int *eqnLengths, int len)
int mirrorProcEqns(ProcEqns &inProcEqns, ProcEqns &outProcEqns)
virtual int putNodalFieldData(int fieldID, int fieldSize, int *nodeNumbers, int numNodes, const double *data)=0
void addEqn(int eqnNumber, int proc)
std::vector< int > rowNumbers
std::vector< int > & eqnNumbers()
virtual int getFromRHSVector(int num, double *values, const int *indices)=0
void multiply_trans_CSRMat_CSVec(const CSRMat &A, const CSVec &x, CSVec &y)
int addRHS(int eqnNumber, int rhsIndex, double value, bool accumulate=true)
bool getFieldEqnNumber(int fieldID, int &eqnNumber) const
virtual int getMatrixRowLength(int row, int &length)=0
virtual int enforceEssentialBC(int *globalEqn, double *alpha, double *gamma, int len)=0
int getMasterEqnNumbers(int slaveEqn, std::vector< int > *&masterEqns)
std::vector< int > packedColumnIndices
std::vector< int > rowOffsets
virtual int setPenCREqns(int penCRSetID, int numCRs, int numNodesPerCR, int **nodeNumbers, int **eqnNumbers, int *fieldIDs)=0
virtual int setGlobalOffsets(int len, int *nodeOffsets, int *eqnOffsets, int *blkEqnOffsets)=0
int ** fieldIDsTablePtr()
int binarySearch(const T &item, const T *list, int len)
std::vector< double > & getMasterWeights()
virtual int putIntoRHSVector(int num, const double *values, const int *indices)=0
int getConstraintID() const
std::vector< std::vector< int > * > & procEqnNumbersPtr()
void getNodeAtIndex(int i, const NodeDescriptor *&node) const
virtual int putIntoSystemMatrix(int numPtRows, const int *ptRows, int numPtCols, const int *ptCols, const double *const *values)=0
void setRHSValue(double rhs)
virtual int setMatrixStructure(int **ptColIndices, int *ptRrowLengths, int **blkColIndices, int *blkRowLengths, int *ptRowsPerBlkRow)=0
virtual int setStiffnessMatrices(GlobalID elemBlock, int numElems, const GlobalID *elemIDs, const double *const *const *stiff, int numEqnsPerElem, const int *const *eqnIndices)=0
virtual int resetRHSVector(double s)=0
bool translateToReducedEqn(int eqn, int &reducedEqn)
int addIndices(int eqnNumber, const int *indices, int len)
std::ostream & console_out()
int GlobalMax(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
virtual int matrixLoadComplete()=0
int getOwnerProcForEqn(int eqn)
int getAssociatedNodeNumber(int eqnNumber)
void multiply_trans_CSRMat_CSRMat(const CSRMat &A, const CSRMat &B, CSRMat &C, bool storeResultZeros)
int localProc(MPI_Comm comm)
int mirrorProcEqnLengths(ProcEqns &inProcEqns, ProcEqns &outProcEqns)
virtual int resetConstraints(double s)=0
virtual int putInitialGuess(const int *eqnNumbers, const double *values, int len)=0
virtual int getSolnEntry(int eqnNumber, double &answer)=0
virtual int enforceRemoteEssBCs(int numEqns, int *globalEqns, int **colIndices, int *colIndLen, double **coefs)=0
std::vector< int > & getMasters()
int getNumNodeDescriptors() const
virtual int formResidual(double *values, int len)=0
virtual int getMatrixRow(int row, double *coefs, int *indices, int len, int &rowLength)=0
int getNodeWithID(GlobalID nodeID, const NodeDescriptor *&node) const
virtual int launchSolver(int &solveStatus, int &iterations)=0
int numProcs(MPI_Comm comm)
int getIndexOfBlock(GlobalID blockID) const