9 #include "fei_sstream.hpp"
10 #include "fei_fstream.hpp"
18 #include "fei_TemplateUtils.hpp"
19 #include <fei_CommUtils.hpp>
20 #include "snl_fei_Constraint.hpp"
23 #include "fei_NodeDescriptor.hpp"
24 #include "fei_NodeCommMgr.hpp"
25 #include "fei_NodeDatabase.hpp"
27 #include "fei_SlaveVariable.hpp"
29 #include "fei_BlockDescriptor.hpp"
31 #include "snl_fei_PointBlockMap.hpp"
32 #include "fei_ProcEqns.hpp"
33 #include "fei_EqnBuffer.hpp"
34 #include <fei_FillableMat.hpp>
35 #include <fei_CSRMat.hpp>
36 #include <fei_CSVec.hpp>
37 #include "fei_EqnCommMgr.hpp"
39 #include "fei_Lookup.hpp"
40 #include "fei_ConnectivityTable.hpp"
41 #include "snl_fei_Utils.hpp"
42 #include "SNL_FEI_Structure.hpp"
45 #define fei_file "SNL_FEI_Structure.cpp"
46 #include "fei_ErrMacros.hpp"
56 fieldDatabase_(new std::map<int,int>),
63 activeNodesInitialized_(false),
66 globalBlkEqnOffsets_(),
74 globalNumNodesVanished_(),
75 localVanishedNodeNumbers_(),
83 numLocalNodalEqns_(0),
88 numLocalReducedRows_(0),
94 reducedEqnCounter_(0),
95 reducedRHSCounter_(0),
99 structureFinalized_(false),
100 generateGraph_(true),
101 sysMatIndices_(NULL),
103 numGlobalEqnBlks_(0),
105 numLocalReducedEqnBlks_(0),
107 localReducedBlkOffset_(0),
108 globalMaxBlkSize_(0),
109 firstLocalNodeNumber_(-1),
111 sysBlkMatIndices_(NULL),
112 matIndicesDestroyed_(false),
114 blkEqnMapper_(new snl_fei::PointBlockMap()),
117 checkSharedNodes_(false),
122 dbgOStreamPtr_(NULL),
123 setDbgOutCalled_(true)
125 numProcs_ = 1, localProc_ = 0, masterProc_ = 0;
131 slaveVars_ =
new std::vector<SlaveVariable*>;
137 eqnCommMgr_->setNumRHSs(1);
139 nodeDatabase_ =
new NodeDatabase(fieldDatabase_, nodeCommMgr_);
141 Kid_ =
new fei::FillableMat;
142 Kdi_ =
new fei::FillableMat;
143 Kdd_ =
new fei::FillableMat;
149 const char* param = NULL;
151 param = snl_fei::getParamValue(
"outputLevel",numParams,paramStrings);
153 std::string str(param);
154 FEI_ISTRINGSTREAM isstr(str);
155 isstr >> outputLevel_;
158 param = snl_fei::getParam(
"debugOutput",numParams,paramStrings);
163 param = snl_fei::getParam(
"debugOutputOff",numParams,paramStrings);
165 debugOutput_ =
false;
168 param = snl_fei::getParam(
"FEI_CHECK_SHARED_IDS", numParams,paramStrings);
170 checkSharedNodes_ =
true;
173 param = snl_fei::getParamValue(
"sharedNodeOwnership",
174 numParams,paramStrings);
176 if (!strcmp(param,
"LowNumberedProc")) {
177 nodeCommMgr_->setSharedOwnershipRule(NodeCommMgr::STRICTLY_LOW_PROC);
179 if (!strcmp(param,
"ProcWithLocalElem")) {
180 nodeCommMgr_->setSharedOwnershipRule(NodeCommMgr::PROC_WITH_LOCAL_ELEM);
182 if (!strcmp(param,
"SierraSpecifies")) {
183 nodeCommMgr_->setSharedOwnershipRule(NodeCommMgr::CALLER_SPECIFIES);
193 for(
size_t j=0; j<slaveVars_->size(); j++) {
194 delete (*slaveVars_)[j];
201 destroyBlockRoster();
202 destroyConnectivityTables();
206 delete blkEqnMapper_;
212 int numPCRs = penCRs_.size();
218 delete nodeDatabase_;
219 delete fieldDatabase_;
227 int SNL_FEI_Structure::setDbgOut(FEI_OSTREAM& ostr,
228 const char* path,
const char* feiName)
230 dbgOStreamPtr_ = &ostr;
231 setDbgOutCalled_ =
true;
238 if (feiName != NULL) {
247 void SNL_FEI_Structure::destroyBlockRoster()
249 for(
size_t i=0; i<blockIDs_.size(); i++)
delete blocks_[i];
254 void SNL_FEI_Structure::destroyConnectivityTables()
256 for(
size_t i=0; i<blockIDs_.size(); i++) {
257 delete connTables_[i];
259 connTables_.resize(0);
263 void SNL_FEI_Structure::destroyMatIndices()
265 if (matIndicesDestroyed_ ==
true)
return;
267 delete [] sysMatIndices_;
268 sysMatIndices_ = NULL;
270 delete [] sysBlkMatIndices_;
271 sysBlkMatIndices_ = NULL;
273 matIndicesDestroyed_ =
true;
280 int err = getBlockDescriptor(blockID, block);
281 if (err)
return(NULL);
283 return(block->fieldsPerNodePtr());
290 int err = getBlockDescriptor(blockID, block);
291 if (err)
return(NULL);
298 int& interleaveStrategy,
int& lumpingStrategy,
299 int& numElemDOF,
int& numElements,
300 int& numNodesPerElem,
int& numEqnsPerElem)
303 int err = getBlockDescriptor(blockID, block);
305 interleaveStrategy = -1;
306 lumpingStrategy = -1;
309 numNodesPerElem = -1;
313 interleaveStrategy = block->getInterleaveStrategy();
314 lumpingStrategy = block->getLumpingStrategy();
315 numElemDOF = block->getNumElemDOFPerElement();
316 numElements = block->getNumElements();
317 numNodesPerElem = block->getNumNodesPerElement();
318 numEqnsPerElem = block->getNumEqnsPerElement();
334 fei::console_out() <<
"SNL_FEI_Structure::getEqnNumber: ERROR, node with nodeNumber "
335 << nodeNumber <<
" doesn't have fieldID " << fieldID << FEI_ENDL;
341 if (isSlave)
return(-1);
349 if (eqn < 0)
return(-1);
351 int len = globalEqnOffsets_.size();
353 for(
int i=0; i<len-1; i++) {
354 if (eqn >= globalEqnOffsets_[i] && eqn < globalEqnOffsets_[i+1])
return(i);
361 int SNL_FEI_Structure::initFields(
int numFields,
362 const int *fieldSizes,
364 const int *fieldTypes)
369 FEI_OSTREAM& ostr = dbgOut();
370 ostr <<
"FEI: initFields" << FEI_ENDL
371 <<
"#num-fields" << FEI_ENDL << numFields << FEI_ENDL;
373 ostr <<
"#field-sizes" << FEI_ENDL;
374 for(nf=0; nf<numFields; nf++) {
375 ostr <<fieldSizes[nf] <<
" ";
377 ostr << FEI_ENDL <<
"#field-ids" << FEI_ENDL;
378 for(nf=0; nf<numFields; nf++) {
379 ostr << fieldIDs[nf] <<
" ";
381 if (fieldTypes != NULL) {
382 ostr << FEI_ENDL <<
"#field-types" << FEI_ENDL;
383 for(nf=0; nf<numFields; nf++) {
384 ostr << fieldTypes[nf] <<
" ";
390 for (
int i=0; i<numFields; i++) {
391 fieldDatabase_->insert(std::pair<int,int>(fieldIDs[i], fieldSizes[i]));
393 if (offs >= 0) fieldSizes_.insert(fieldSizes_.begin()+offs, fieldSizes[i]);
395 if (fieldIDs[i] >= 0) {
396 if (fieldTypes != NULL) {
397 fieldDofMap_.add_field(fieldIDs[i], fieldSizes[i], fieldTypes[i]);
400 fieldDofMap_.add_field(fieldIDs[i], fieldSizes[i]);
409 int SNL_FEI_Structure::initElemBlock(GlobalID elemBlockID,
411 int numNodesPerElement,
412 const int* numFieldsPerNode,
413 const int*
const* nodalFieldIDs,
414 int numElemDofFieldsPerElement,
415 const int* elemDofFieldIDs,
416 int interleaveStrategy)
420 FEI_OSTREAM& os = dbgOut();
421 os <<
"FEI: initElemBlock" << FEI_ENDL <<
"#elemBlockID" << FEI_ENDL
422 << (int)elemBlockID << FEI_ENDL;
423 os <<
"#numElements"<< FEI_ENDL << numElements << FEI_ENDL;
424 os <<
"#numNodesPerElement"<< FEI_ENDL <<numNodesPerElement << FEI_ENDL;
425 os <<
"#numFieldsPerNode -- one entry per node " << FEI_ENDL;
426 for(nn=0; nn<numNodesPerElement; nn++) os << numFieldsPerNode[nn]<<
" ";
427 os << FEI_ENDL <<
"#nodalFieldIDs -- one row per node" << FEI_ENDL;
428 for(nn=0; nn<numNodesPerElement; ++nn) {
429 for(nf=0; nf<numFieldsPerNode[nn]; ++nf) os << nodalFieldIDs[nn][nf] <<
" ";
432 os <<
"#numElemDofFieldsPerElement" << FEI_ENDL
433 << numElemDofFieldsPerElement<<FEI_ENDL;
434 os <<
"#elemDofFieldIDs -- 'numElemDofFieldsPerElement' entries" << FEI_ENDL;
435 for(nn=0; nn<numElemDofFieldsPerElement; ++nn) {
436 os << elemDofFieldIDs[nn] <<
" ";
438 if (numElemDofFieldsPerElement > 0) os << FEI_ENDL;
439 os <<
"#interleaveStrategy" << FEI_ENDL << interleaveStrategy << FEI_ENDL;
443 CHK_ERR( addBlock(elemBlockID) );
445 CHK_ERR( getBlockDescriptor(elemBlockID, block) );
448 block->setNumElements(numElements);
449 block->setElemDofFieldIDs(numElemDofFieldsPerElement, elemDofFieldIDs);
450 block->setInterleaveStrategy(interleaveStrategy);
452 int *fieldsPerNodePtr = block->fieldsPerNodePtr();
456 int numNodalEqns = 0;
458 std::vector<int> distinctFields(0);
460 for(j=0; j<numNodesPerElement; j++) {
463 for(
int k = 0; k < numFieldsPerNode[j]; k++) {
469 nodalFieldIDs[j][k] <<
" has negative size. " << FEI_ENDL;
472 countDOF += fieldSize;
475 fieldsPerNodePtr[j] = numFieldsPerNode[j];
476 numNodalEqns += countDOF;
479 block->setNumDistinctFields(distinctFields.size());
481 int numElemDOFPerElement = 0;
482 for(j=0; j<numElemDofFieldsPerElement; j++) {
485 fei::console_out() <<
"SNL_FEI_Structure::initElemBlock ERROR: elemDoffieldID " <<
486 elemDofFieldIDs[j] <<
" has negative size. " << FEI_ENDL;
489 numElemDOFPerElement += fieldSize;
492 block->setNumElemDOFPerElement(numElemDOFPerElement);
493 block->setNumEqnsPerElement(numNodalEqns + numElemDOFPerElement);
494 block->setNumBlkEqnsPerElement(numNodesPerElement + numElemDOFPerElement);
498 CHK_ERR( block->allocateFieldIDsTable() );
501 for (j = 0; j < numNodesPerElement; j++) {
502 for(
int k = 0; k < numFieldsPerNode[j]; k++) {
503 fieldIDsTablePtr[j][k] = nodalFieldIDs[j][k];
509 if (numElements > 0) {
510 CHK_ERR( allocateBlockConnectivity(elemBlockID) );
517 int SNL_FEI_Structure::initElem(GlobalID elemBlockID,
519 const GlobalID* elemConn)
521 if (debugOutput_ && outputLevel_ > 2) {
522 FEI_OSTREAM& os = dbgOut();
523 os <<
"FEI: initElem"<<FEI_ENDL;
524 os <<
"#blkID"<<FEI_ENDL<<(int)elemBlockID<<FEI_ENDL<<
"#elmID"<<FEI_ENDL
525 <<(
int)elemID<< FEI_ENDL;
531 CHK_ERR( getBlockDescriptor(elemBlockID, block) );
535 std::map<GlobalID,
int>& elemIDList = connTable.elemIDs;
536 GlobalID* conn = &((*connTable.elem_conn_ids)[0]);
538 int elemIndex = elemIDList.size();
539 std::map<GlobalID,
int>::iterator
540 iter = elemIDList.find(elemID);
542 bool redundantElem = false;
544 if (iter != elemIDList.end()) {
545 elemIndex = iter->second;
546 redundantElem =
true;
549 elemIDList.insert(std::make_pair(elemID,elemIndex));
552 int numNodes = block->getNumNodesPerElement();
554 if (debugOutput_ && outputLevel_ > 2) {
555 FEI_OSTREAM& os = dbgOut();
556 os <<
"#n-nodes"<<FEI_ENDL<<numNodes<<FEI_ENDL<<
"#nodeIDs"<<FEI_ENDL;
557 for(
int nn=0; nn<numNodes; nn++) os << (
int)elemConn[nn] <<
" ";
566 int offset = elemIndex*numNodes;
567 for(
int j=0; j<numNodes; j++) {
568 if ( conn[offset+j] != elemConn[j]) {
569 fei::console_out() <<
"SNL_FEI_Structure::initElem ERROR, elemID " << (int)elemID
570 <<
" registered more than once, with differing connectivity."
577 int offset = elemIndex*numNodes;
578 for(
int j = 0; j < numNodes; j++) {
579 conn[offset+j] = elemConn[j];
582 CHK_ERR( nodeDatabase_->
initNodeIDs(&(conn[offset]), numNodes) );
589 int SNL_FEI_Structure::initSlaveVariable(GlobalID slaveNodeID,
591 int offsetIntoSlaveField,
593 const GlobalID* masterNodeIDs,
594 const int* masterFieldIDs,
595 const double* weights,
599 FEI_OSTREAM& os = dbgOut();
600 os <<
"FEI: initSlaveVariable" << FEI_ENDL;
601 os <<
"#slvNodeID" << FEI_ENDL << (int)slaveNodeID << FEI_ENDL
602 <<
"#slvFieldID"<< FEI_ENDL << slaveFieldID << FEI_ENDL
603 <<
"#offsetIntoSlvField" << FEI_ENDL << offsetIntoSlaveField << FEI_ENDL
604 <<
"#numMasterNodes" << FEI_ENDL << numMasterNodes << FEI_ENDL
605 <<
"#masterNodeIDs" << FEI_ENDL;
607 for(nn=0; nn<numMasterNodes; ++nn) {
608 os <<(int)masterNodeIDs[nn]<<
" ";
610 os << FEI_ENDL <<
"#masterFieldIDs" << FEI_ENDL;
611 for(nn=0; nn<numMasterNodes; ++nn) {
612 os <<masterFieldIDs[nn] <<
" ";
614 os << FEI_ENDL <<
"#field-sizes" << FEI_ENDL;
615 for(nn=0; nn<numMasterNodes; ++nn) {
619 os << FEI_ENDL <<
"#weights" << FEI_ENDL;
621 for(nn=0; nn<numMasterNodes; ++nn) {
623 for(
int j=0; j<size; ++j) {
624 os << weights[offset++] <<
" ";
627 os << FEI_ENDL <<
"#rhsValue" << FEI_ENDL << rhsValue << FEI_ENDL;
634 svar->setNodeID(slaveNodeID);
635 svar->setFieldID(slaveFieldID);
636 svar->setFieldOffset(offsetIntoSlaveField);
640 for(
int i=0; i<numMasterNodes; i++) {
641 svar->addMasterNodeID(masterNodeIDs[i]);
642 svar->addMasterField(masterFieldIDs[i]);
644 if (fieldSize < 0) ERReturn(-1);
646 for(
int j=0; j<fieldSize; j++) {
647 svar->addWeight(weights[woffset++]);
651 addSlaveVariable(svar);
657 int SNL_FEI_Structure::deleteMultCRs()
659 int numMCRs = multCRs_.size();
668 int SNL_FEI_Structure::initSharedNodes(
int numSharedNodes,
669 const GlobalID *sharedNodeIDs,
670 const int* numProcsPerNode,
671 const int *
const *sharingProcIDs)
674 FEI_OSTREAM& os = dbgOut();
675 os <<
"FEI: initSharedNodes"<<FEI_ENDL;
676 os <<
"#n-nodes"<<FEI_ENDL<<numSharedNodes<<FEI_ENDL;
677 os <<
"#num-procs-per-node"<<FEI_ENDL;
679 for(nn=0; nn<numSharedNodes; ++nn) {
680 os << numProcsPerNode[nn] <<
" ";
682 os << FEI_ENDL <<
"#following lines: nodeID sharing-procs" << FEI_ENDL;
683 for(nn=0; nn<numSharedNodes; nn++) {
684 os << (int)sharedNodeIDs[nn]<<
" ";
685 for(
int np=0; np<numProcsPerNode[nn]; np++) os<<sharingProcIDs[nn][np]<<
" ";
688 os <<
"#end shared nodes"<<FEI_ENDL;
694 CHK_ERR( nodeCommMgr_->addSharedNodes(sharedNodeIDs, numSharedNodes,
695 sharingProcIDs, numProcsPerNode) );
697 if (activeNodesInitialized_) {
708 for(
int i=0; i<numSharedNodes; ++i) {
709 for(
size_t nc=0; nc<connTables_.size(); ++nc) {
710 if (connTables_[nc]->elem_conn_ids == NULL)
continue;
711 int len = connTables_[nc]->elem_conn_ids->size();
712 if (len < 1)
continue;
713 GlobalID* conn_ids = &((*connTables_[nc]->elem_conn_ids)[0]);
714 NodeDescriptor** nodes = &((*connTables_[nc]->elem_conn_ptrs)[0]);
716 for(
int j=0; j<len; ++j) {
717 if (conn_ids[j] == sharedNodeIDs[i]) {
718 CHK_ERR( nodeCommMgr_->informLocal(*(nodes[j])));
730 int SNL_FEI_Structure::initCRMult(
int numCRNodes,
731 const GlobalID* CRNodes,
736 FEI_OSTREAM& os = dbgOut();
737 os <<
"FEI: initCRMult" << FEI_ENDL <<
"# numCRNodes: "<<FEI_ENDL<<numCRNodes<<FEI_ENDL;
738 os <<
"#CRNodes:"<<FEI_ENDL;
740 for(nn=0; nn<numCRNodes; nn++) {
741 os << (int)CRNodes[nn]<<
" ";
743 os << FEI_ENDL<<
"#fields:"<<FEI_ENDL;
744 for(nn=0; nn<numCRNodes; nn++) {
745 os << CRFields[nn]<<
" ";
753 CRID = localProc_*100000 + multCRs_.size();
755 addCR(CRID, multCRPtr, multCRs_);
761 std::vector<GlobalID>& CRNodeArray = multCR.
getMasters();
764 for(
int j = 0; j < numCRNodes; j++) {
765 CRNodeArray.push_back(CRNodes[j]);
766 CRFieldArray.push_back(CRFields[j]);
769 if (debugOutput_) dbgOut() <<
"#(output) CRID:"<<FEI_ENDL << CRID << FEI_ENDL;
775 int SNL_FEI_Structure::initCRPen(
int numCRNodes,
776 const GlobalID* CRNodes,
781 FEI_OSTREAM& os = dbgOut();
782 os <<
"initCRPen, numCRNodes: "<<numCRNodes<<FEI_ENDL;
783 for(
int nn=0; nn<numCRNodes; nn++) {
784 os <<
" crNodeID: "<<(int)CRNodes[nn]<<
", field: "<<CRFields[nn]<<FEI_ENDL;
788 CRID = localProc_*100000 + penCRs_.size();
791 addCR(CRID, penCRPtr, penCRs_);
798 std::vector<GlobalID>& CRNodesArray = penCR.
getMasters();
802 for(
int i = 0; i < numCRNodes; i++) {
803 CRNodesArray.push_back(CRNodes[i]);
804 CRFieldArray.push_back(CRFields[i]);
816 if (numProcs_ < 2)
return(
true);
820 if (err != 0)
return(
false);
822 GlobalID nodeID = node->getGlobalNodeID();
825 int shIndx = nodeCommMgr_->getSharedNodeIndex(nodeID);
834 std::vector<GlobalID>& localNodes = nodeCommMgr_->getLocalNodeIDs();
836 if (index >= 0)
return(
true);
845 int SNL_FEI_Structure::initComplete(
bool generateGraph)
942 FEI_OSTREAM& os = dbgOut();
943 os <<
"FEI: initComplete" << FEI_ENDL;
952 CHK_ERR( finalizeActiveNodes() );
954 CHK_ERR( finalizeNodeCommMgr() );
956 numLocalElemDOF_ = calcTotalNumElemDOF();
957 numLocalMultCRs_ = calcNumMultCREqns();
966 numLocalEqns_ = numLocalNodalEqns_ + numLocalElemDOF_ + numLocalMultCRs_;
967 numLocalEqnBlks_ = numLocalNodes + numLocalElemDOF_ + numLocalMultCRs_;
970 FEI_OSTREAM& os = dbgOut();
971 os <<
"# numMultCRs: " << numLocalMultCRs_ <<
", numElemDOF: "
972 << numLocalElemDOF_ <<
", numLocalNodalEqns: " <<numLocalNodalEqns_
974 os <<
"# numLocalEqns_: " << numLocalEqns_ << FEI_ENDL;
977 calcGlobalEqnInfo(numLocalNodes, numLocalEqns_, numLocalEqnBlks_);
979 CHK_ERR( setNodalEqnInfo() );
989 CHK_ERR( setMultCREqnInfo() );
994 CHK_ERR( nodeDatabase_->
synchronize(firstLocalNodeNumber_, localStartRow_,
995 localProc_, comm_) );
1003 setNumNodesAndEqnsPerBlock();
1010 slvCommMgr_->setNumRHSs(1);
1012 CHK_ERR( calculateSlaveEqns(comm_) );
1019 initializeEqnCommMgr();
1022 int startRow = localStartRow_;
1025 numLocalReducedRows_ = reducedEndRow_ - reducedStartRow_ + 1;
1027 generateGraph_ = generateGraph;
1029 if (generateGraph_) {
1036 CHK_ERR( formMatrixStructure() );
1038 CHK_ERR( initializeBlkEqnMapper() );
1040 if (globalMaxBlkSize_ > 1) {
1041 CHK_ERR( eqnCommMgr_->exchangePtToBlkInfo(*blkEqnMapper_) );
1044 CHK_ERR( slvCommMgr_->exchangeIndices() );
1046 catch (std::runtime_error& exc) {
1051 CHK_ERR( slvCommMgr_->exchangePtToBlkInfo(*blkEqnMapper_) );
1057 numLocalReducedEqnBlks_ = lastLocalReducedBlkEqn - localReducedBlkOffset_ + 1;
1059 if (globalMaxBlkSize_ > 1 && generateGraph_) {
1060 sysBlkMatIndices_ = numLocalReducedEqnBlks_>0 ?
1066 blockMatrix_ =
true;
1068 structureFinalized_ =
true;
1069 matIndicesDestroyed_ =
false;
1074 if (debugOutput_) writeEqn2NodeMap();
1076 if (debugOutput_) dbgOut() <<
"#leaving initComplete" << FEI_ENDL;
1077 return(FEI_SUCCESS);
1081 int SNL_FEI_Structure::formMatrixStructure()
1083 FEI_OSTREAM& os = dbgOut();
1084 if (debugOutput_) os <<
"# formMatrixStructure" << FEI_ENDL;
1090 CHK_ERR( initElemBlockStructure() );
1095 CHK_ERR( initMultCRStructure() );
1100 CHK_ERR( initPenCRStructure() );
1107 CHK_ERR( eqnCommMgr_->exchangeIndices(&os) );
1109 catch(std::runtime_error& exc) {
1117 int numRecvEqns = eqnCommMgr_->getNumLocalEqns();
1118 std::vector<int>& recvEqnNumbers = eqnCommMgr_->localEqnNumbers();
1119 std::vector<fei::CSVec*>& recvEqns = eqnCommMgr_->localEqns();
1122 os <<
"# after eqnCommMgr_->exchangeIndices, numRecvEqns: "
1123 << numRecvEqns << FEI_ENDL;
1126 for(i=0; i<numRecvEqns; i++) {
1127 int eqn = recvEqnNumbers[i];
1128 if ((reducedStartRow_ > eqn) || (reducedEndRow_ < eqn)) {
1129 fei::console_out() <<
"SNL_FEI_Structure::initComplete: ERROR, recvEqn " << eqn
1130 <<
" out of range. (reducedStartRow_: " << reducedStartRow_
1131 <<
", reducedEndRow_: " << reducedEndRow_ <<
", localProc_: "
1132 << localProc_ <<
")" << FEI_ENDL;
1136 for(
size_t j=0; j<recvEqns[i]->size(); j++) {
1137 CHK_ERR( createMatrixPosition(eqn, recvEqns[i]->indices()[j],
1143 os <<
"# leaving formMatrixStructure" << FEI_ENDL;
1150 int SNL_FEI_Structure::initElemBlockStructure()
1154 FEI_OSTREAM& os = dbgOut();
1156 os <<
"# initElemBlockStructure" << FEI_ENDL;
1157 os <<
"# numElemBlocks: " << numBlocks << FEI_ENDL;
1160 for (
int bIndex = 0; bIndex < numBlocks; bIndex++) {
1164 int numEqns = block->getNumEqnsPerElement();
1165 int interleave = block->getInterleaveStrategy();
1166 std::vector<int> scatterIndices(numEqns);
1168 GlobalID elemBlockID = block->getGlobalBlockID();
1171 std::map<GlobalID,int>& elemIDList = connTable.elemIDs;
1172 block->setNumElements(elemIDList.size());
1173 int numBlockElems = block->getNumElements();
1178 os <<
"# block " << bIndex <<
", numElems: " << numBlockElems<<FEI_ENDL;
1180 for(
int elemIndex = 0; elemIndex < numBlockElems; elemIndex++) {
1182 getScatterIndices_index(bIndex, elemIndex, interleave,
1183 &scatterIndices[0]);
1189 CHK_ERR( createSymmEqnStructure(scatterIndices) );
1193 if (reducedEqnCounter_ > 0) CHK_ERR( assembleReducedStructure() );
1195 if (debugOutput_) os <<
"# leaving initElemBlockStructure" << FEI_ENDL;
1196 return(FEI_SUCCESS);
1200 int SNL_FEI_Structure::getMatrixRowLengths(std::vector<int>& rowLengths)
1202 if (!structureFinalized_)
return(-1);
1204 rowLengths.resize(numLocalReducedRows_);
1206 for(
int i=0; i<numLocalReducedRows_; i++) {
1207 rowLengths[i] = sysMatIndices_[i].
size();
1213 int SNL_FEI_Structure::getMatrixStructure(
int** indices,
1214 std::vector<int>& rowLengths)
1216 if (!structureFinalized_)
return(-1);
1218 rowLengths.resize(numLocalReducedRows_);
1220 for(
int i=0; i<numLocalReducedRows_; i++) {
1221 rowLengths[i] = sysMatIndices_[i].
size();
1229 int SNL_FEI_Structure::getMatrixStructure(
int** ptColIndices,
1230 std::vector<int>& ptRowLengths,
1231 int** blkColIndices,
1233 std::vector<int>& blkRowLengths,
1234 std::vector<int>& numPtRowsPerBlkRow)
1236 int err = getMatrixStructure(ptColIndices, ptRowLengths);
1237 if (err != 0)
return(-1);
1239 if (globalMaxBlkSize_ == 1) {
1242 int numRows = ptRowLengths.size();
1243 blkRowLengths.resize(numRows);
1244 numPtRowsPerBlkRow.assign(numRows, 1);
1246 blkRowLengths.resize(ptRowLengths.size());
1247 for(
size_t ii=0; ii<ptRowLengths.size(); ++ii) {
1248 blkRowLengths[ii] = ptRowLengths[ii];
1251 for(
int i=0; i<numRows; i++) {
1252 blkColIndices[i] = ptColIndices[i];
1259 std::map<int,int>* ptEqns = blkEqnMapper_->
getPtEqns();
1260 int numPtEqns = ptEqns->size();
1262 std::map<int,int>::const_iterator
1263 pteq = ptEqns->begin(),
1264 pteq_end = ptEqns->end();
1266 int lastBlkRow = -1;
1268 for(
int jj=0; jj<numPtEqns; ++jj, ++pteq) {
1269 int ptEqn = (*pteq).first;
1270 int localPtEqn = ptEqn - reducedStartRow_;
1271 if (localPtEqn < 0 || localPtEqn >= numLocalReducedRows_)
continue;
1273 int rowLength = sysMatIndices_[localPtEqn].
size();
1280 if (blkRow == lastBlkRow)
continue;
1282 int localBlkRow = blkRow - localReducedBlkOffset_;
1283 if (localBlkRow < 0 || localBlkRow >= numLocalReducedEqnBlks_) {
1289 int* theseColIndices = ptColIndices[localPtEqn];
1291 for(
int colj=0; colj<rowLength; colj++) {
1292 int blkCol = blkEqnMapper_->
eqnToBlkEqn(theseColIndices[colj]);
1295 <<
"SNL_FEI_Structure::getMatrixStructure ERROR pt row "
1296 << ptEqn <<
", pt col "
1297 << ptColIndices[localPtEqn][colj]
1298 <<
" doesn't have a corresponding block" << FEI_ENDL;
1299 blkCol = blkEqnMapper_->
eqnToBlkEqn(theseColIndices[colj]);
1303 sysBlkIndices.
insert2(blkCol);
1306 lastBlkRow = blkRow;
1311 numPtRowsPerBlkRow.resize(numLocalReducedEqnBlks_);
1312 blkRowLengths.resize(numLocalReducedEqnBlks_);
1314 for(
int i=0; i<numLocalReducedEqnBlks_; i++) {
1315 blkRowLengths[i] = sysBlkMatIndices_[i].
size();
1317 &(blkIndices_1D[offset]));
1318 offset += blkRowLengths[i];
1320 int blkEqn = localReducedBlkOffset_ + i;
1321 numPtRowsPerBlkRow[i] = blkEqnMapper_->
getBlkEqnSize(blkEqn);
1329 bool SNL_FEI_Structure::nodalEqnsAllSlaves(
const NodeDescriptor* node,
1330 std::vector<int>& slaveEqns)
1332 int numFields = node->getNumFields();
1333 const int* fieldIDs = node->getFieldIDList();
1334 const int* fieldEqns= node->getFieldEqnNumbers();
1336 for(
int i=0; i<numFields; ++i) {
1338 for(
int eqn=0; eqn<fieldSize; ++eqn) {
1339 int thisEqn = fieldEqns[i] + eqn;
1351 NodeDescriptor& SNL_FEI_Structure::findNodeDescriptor(GlobalID nodeID)
1360 fei::console_out() <<
"ERROR, findNodeDescriptor unable to find node " << (int)nodeID
1377 int SNL_FEI_Structure::initMultCRStructure()
1379 FEI_OSTREAM& os = dbgOut();
1380 if (debugOutput_) os <<
"# initMultCRStructure" << FEI_ENDL;
1393 std::map<GlobalID,ConstraintType*>::const_iterator
1394 cr_iter = multCRs_.begin(),
1395 cr_end = multCRs_.end();
1397 while(cr_iter != cr_end) {
1402 std::vector<GlobalID>& CRNode_vec = multCR.
getMasters();
1403 GlobalID *CRNodePtr = &CRNode_vec[0];
1405 int* CRFieldPtr = &CRField_vec[0];
1408 int reducedCrEqn = 0;
1411 createMatrixPosition(reducedCrEqn, reducedCrEqn,
"initMCRStr");
1413 for(
int j=0; j<lenList; j++) {
1414 GlobalID nodeID = CRNodePtr[j];
1415 int fieldID = CRFieldPtr[j];
1418 if(nodePtr==NULL)
continue;
1424 storeNodalColumnIndices(crEqn, node, fieldID);
1429 if (node.getOwnerProc() == localProc_) {
1433 storeNodalRowIndices(node, fieldID, crEqn);
1441 storeNodalSendIndex(node, fieldID, crEqn);
1446 return(FEI_SUCCESS);
1450 int SNL_FEI_Structure::initPenCRStructure()
1452 FEI_OSTREAM& os = dbgOut();
1453 if (debugOutput_) os <<
"# initPenCRStructure" << FEI_ENDL;
1477 std::map<GlobalID,ConstraintType*>::const_iterator
1478 cr_iter = penCRs_.begin(),
1479 cr_end = penCRs_.end();
1481 while(cr_iter != cr_end) {
1485 std::vector<GlobalID>& CRNode_vec = penCR.
getMasters();
1486 GlobalID* CRNodesPtr = &CRNode_vec[0];
1489 int* CRFieldPtr = &CRField_vec[0];
1494 for(
int i = 0; i < lenList; i++) {
1495 GlobalID iNodeID = CRNodesPtr[i];
1496 int iField = CRFieldPtr[i];
1499 if(!iNodePtr)
continue;
1502 for(
int j = 0; j < lenList; j++) {
1503 GlobalID jNodeID = CRNodesPtr[j];
1504 int jField = CRFieldPtr[j];
1507 if(!jNodePtr)
continue;
1510 if (iNode.getOwnerProc() == localProc_) {
1514 storeLocalNodeIndices(iNode, iField, jNode, jField);
1520 storeNodalSendIndices(iNode, iField, jNode, jField);
1526 return(FEI_SUCCESS);
1530 void SNL_FEI_Structure::storeNodalSendIndex(
NodeDescriptor& node,
int fieldID,
1541 int proc = node.getOwnerProc();
1548 fei::console_out() <<
"FEI error, attempt to store indices for field ("<<fieldID
1549 <<
") with size "<<numEqns<<FEI_ENDL;
1553 for(
int i=0; i<numEqns; i++) {
1554 eqnCommMgr_->addRemoteIndices(eqnNumber+i, proc, &col, 1);
1559 void SNL_FEI_Structure::storeNodalSendIndices(
NodeDescriptor& iNode,
int iField,
1566 int proc = iNode.getOwnerProc();
1568 int iEqn = -1, jEqn = -1;
1574 if (iNumParams < 1 || jNumParams < 1) {
1575 fei::console_out() <<
"FEI ERROR, attempt to store indices for field with non-positive size"
1576 <<
" field "<<iField<<
", size "<<iNumParams<<
", field "<<jField<<
", size "
1577 << jNumParams<<FEI_ENDL;
1581 for(
int i=0; i<iNumParams; i++) {
1584 for(
int j=0; j<jNumParams; j++) {
1586 eqnCommMgr_->addRemoteIndices(eqn, proc, &col, 1);
1592 void SNL_FEI_Structure::storeLocalNodeIndices(
NodeDescriptor& iNode,
int iField,
1600 int iEqn = -1, jEqn = -1;
1606 if (iNumParams < 1 || jNumParams < 1) {
1607 fei::console_out() <<
"FEI ERROR, attempt to store indices for field with non-positive size"
1608 <<
" field "<<iField<<
", size "<<iNumParams<<
", field "<<jField<<
", size "
1609 << jNumParams<<FEI_ENDL;
1613 for(
int i=0; i<iNumParams; i++) {
1615 int reducedRow = -1;
1617 if (isSlave)
continue;
1619 for(
int j=0; j<jNumParams; j++) {
1621 int reducedCol = -1;
1623 if (isSlave)
continue;
1625 createMatrixPosition(reducedRow, reducedCol,
1632 void SNL_FEI_Structure::storeNodalColumnIndices(
int eqn,
NodeDescriptor& node,
1639 if ((localStartRow_ > eqn) || (eqn > localEndRow_)) {
1647 if (numParams < 1) {
1648 fei::console_out() <<
"FEI error, attempt to store indices for field ("<<fieldID
1649 <<
") with size "<<numParams<<FEI_ENDL;
1653 int reducedEqn = -1;
1655 if (isSlave)
return;
1657 for(
int j=0; j<numParams; j++) {
1658 int reducedCol = -1;
1660 if (isSlave)
continue;
1662 createMatrixPosition(reducedEqn, reducedCol,
1668 void SNL_FEI_Structure::storeNodalRowIndices(
NodeDescriptor& node,
1669 int fieldID,
int eqn)
1679 if (numParams < 1) {
1680 fei::console_out() <<
"FEI error, attempt to store indices for field ("<<fieldID
1681 <<
") with size "<<numParams<<FEI_ENDL;
1685 int reducedEqn = -1;
1687 if (isSlave)
return;
1689 for(
int j=0; j<numParams; j++) {
1690 int reducedRow = -1;
1692 if (isSlave)
continue;
1694 createMatrixPosition(reducedRow, reducedEqn,
"storeNdRowInd");
1699 int SNL_FEI_Structure::createSymmEqnStructure(std::vector<int>& scatterIndices)
1707 if (numSlaveEquations() == 0) {
1708 CHK_ERR( storeElementScatterIndices_noSlaves(scatterIndices) );
1709 return(FEI_SUCCESS);
1714 int len = scatterIndices.size();
1715 bool anySlaves =
false;
1716 rSlave_.resize(len);
1717 for(
int is=0; is<len; is++) {
1718 rSlave_[is] =
isSlaveEqn(scatterIndices[is]) ? 1 : 0;
1719 if (rSlave_[is] == 1) anySlaves =
true;
1725 CHK_ERR( storeElementScatterIndices(scatterIndices) );
1726 return(FEI_SUCCESS);
1729 int* scatterPtr = &scatterIndices[0];
1731 workSpace_.resize(len);
1732 for(
int j=0; j<len; j++) {
1736 for(
int i=0; i<len; i++) {
1737 int row = scatterPtr[i];
1738 if (rSlave_[i] == 1) {
1739 reducedEqnCounter_++;
1744 for(
int jj=0; jj<len; jj++) {
1745 int col = scatterPtr[jj];
1747 if (rSlave_[jj] == 1) {
1749 for(
int ii=0; ii<len; ii++) {
1750 int rowi = scatterPtr[ii];
1753 if (rSlave_[ii] == 1)
continue;
1755 Kid_->createPosition(rowi, col);
1761 Kdi_->createPosition(row, col);
1765 for(
int kk=0; kk<len; kk++) {
1766 int colk = scatterPtr[kk];
1768 if (rSlave_[kk] != 1)
continue;
1770 Kdd_->createPosition(row, colk);
1776 int reducedRow = -1;
1779 bool rowIsLocal =
true;
1780 int owner = localProc_;
1781 if (reducedStartRow_ > reducedRow || reducedEndRow_ < reducedRow) {
1786 for(
int j=0; j<len; j++) {
1787 if (rSlave_[j] == 1)
continue;
1789 int reducedCol = workSpace_[j];
1792 CHK_ERR( createMatrixPosition(reducedRow, reducedCol,
1796 eqnCommMgr_->addRemoteIndices(reducedRow, owner, &reducedCol, 1);
1802 if (reducedEqnCounter_ > 300) CHK_ERR( assembleReducedStructure() );
1805 catch(std::runtime_error& exc) {
1810 return(FEI_SUCCESS);
1814 int SNL_FEI_Structure::createBlkSymmEqnStructure(std::vector<int>& scatterIndices)
1822 if (numSlaveEquations() == 0) {
1823 return( storeElementScatterBlkIndices_noSlaves(scatterIndices) );
1828 int len = scatterIndices.size();
1829 bool anySlaves =
false;
1830 rSlave_.resize(len);
1831 for(
int is=0; is<len; is++) {
1832 rSlave_[is] =
isSlaveEqn(scatterIndices[is]) ? 1 : 0;
1833 if (rSlave_[is] == 1) anySlaves =
true;
1839 CHK_ERR( storeElementScatterIndices(scatterIndices) );
1840 return(FEI_SUCCESS);
1843 int* scatterPtr = &scatterIndices[0];
1845 workSpace_.resize(len);
1846 for(
int j=0; j<len; j++) {
1850 for(
int i=0; i<len; i++) {
1851 int row = scatterPtr[i];
1852 if (rSlave_[i] == 1) {
1853 reducedEqnCounter_++;
1858 for(
int jj=0; jj<len; jj++) {
1859 int col = scatterPtr[jj];
1861 if (rSlave_[jj] == 1) {
1863 for(
int ii=0; ii<len; ii++) {
1864 int rowi = scatterPtr[ii];
1867 if (rSlave_[ii] == 1)
continue;
1869 Kid_->createPosition(rowi, col);
1875 Kdi_->createPosition(row, col);
1879 for(
int kk=0; kk<len; kk++) {
1880 int colk = scatterPtr[kk];
1882 if (rSlave_[kk] != 1)
continue;
1884 Kdd_->createPosition(row, colk);
1890 int reducedRow = -1;
1893 bool rowIsLocal =
true;
1894 int owner = localProc_;
1895 if (reducedStartRow_ > reducedRow || reducedEndRow_ < reducedRow) {
1900 for(
int j=0; j<len; j++) {
1901 if (rSlave_[j] == 1)
continue;
1903 int reducedCol = workSpace_[j];
1906 CHK_ERR( createMatrixPosition(reducedRow, reducedCol,
1910 eqnCommMgr_->addRemoteIndices(reducedRow, owner, &reducedCol, 1);
1916 if (reducedEqnCounter_ > 300) CHK_ERR( assembleReducedStructure() );
1919 catch(std::runtime_error& exc) {
1924 return(FEI_SUCCESS);
1928 int SNL_FEI_Structure::storeElementScatterIndices(std::vector<int>& indices)
1936 int numIndices = indices.size();
1937 int* indPtr = &indices[0];
1939 workSpace_.resize(numIndices);
1940 int* workPtr = &workSpace_[0];
1941 int reducedEqn = -1;
1942 for(
size_t j=0; j<indices.size(); j++) {
1944 if (isSlave) ERReturn(-1);
1945 workPtr[j] = reducedEqn;
1948 for(
int i=0; i<numIndices; i++) {
1949 int row = indPtr[i];
1950 int rrow = workPtr[i];
1952 if ((localStartRow_ > row) || (row > localEndRow_)) {
1955 eqnCommMgr_->addRemoteIndices(rrow, owner, workPtr, numIndices);
1959 CHK_ERR( createMatrixPositions(rrow, numIndices, workPtr,
1960 "storeElemScttrInd") );
1963 return(FEI_SUCCESS);
1967 int SNL_FEI_Structure::storeElementScatterIndices_noSlaves(std::vector<int>& indices)
1975 int i, numIndices = indices.size();
1976 int* indPtr = &indices[0];
1978 for(i=0; i<numIndices; i++) {
1979 int row = indPtr[i];
1980 if (row < localStartRow_ || row > localEndRow_) {
1982 eqnCommMgr_->addRemoteIndices(row, owner, indPtr, numIndices);
1986 if (generateGraph_) {
1988 sysMatIndices_[row - reducedStartRow_];
1990 for(
int j=0; j<numIndices; ++j) {
1991 if (debugOutput_ && outputLevel_ > 2) {
1992 dbgOut() <<
"# storeElemScttrInds_ns crtMatPoss("
1993 << row <<
"," << indPtr[j] <<
")"<<FEI_ENDL;
2001 return(FEI_SUCCESS);
2005 int SNL_FEI_Structure::storeElementScatterBlkIndices_noSlaves(std::vector<int>& indices)
2013 int i, numIndices = indices.size();
2014 int* indPtr = &indices[0];
2016 for(i=0; i<numIndices; i++) {
2017 int row = indPtr[i];
2018 if (row < localStartRow_ || row > localEndRow_) {
2020 eqnCommMgr_->addRemoteIndices(row, owner, indPtr, numIndices);
2024 if (generateGraph_) {
2026 sysMatIndices_[row - reducedStartRow_];
2028 for(
int j=0; j<numIndices; ++j) {
2029 if (debugOutput_ && outputLevel_ > 2) {
2030 dbgOut() <<
"# storeElemScttrInds_ns crtMatPoss("
2031 << row <<
"," << indPtr[j] <<
")"<<FEI_ENDL;
2039 return(FEI_SUCCESS);
2043 int SNL_FEI_Structure::assembleReducedStructure()
2051 fei::FillableMat* D = getSlaveDependencies();
2066 if (numProcs_ > 1) {
2067 CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat1_,
true) );
2068 CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat2_,
true) );
2071 CHK_ERR( createMatrixPositions(tmpMat1_) );
2072 CHK_ERR( createMatrixPositions(tmpMat2_) );
2082 if (numProcs_ > 1) {
2083 CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat2_,
true) );
2085 CHK_ERR( createMatrixPositions(tmpMat2_) );
2090 reducedEqnCounter_ = 0;
2092 return(FEI_SUCCESS);
2098 if (numSlvs_ < 1)
return(0);
2113 std::vector<fei::CSVec*>& eqnArray = eqnBuf.
eqns();
2114 for(
int i=0; i<numEqns; ++i) {
2117 eqnNumbers[i] = reducedEqn;
2119 int* indicesPtr = &(eqnArray[i]->indices()[0]);
2120 int numIndices = eqnArray[i]->size();
2121 for(
int j=0; j<numIndices; ++j) {
2123 indicesPtr[j] = reducedEqn;
2134 int dim1 = eqnTable.size();
2135 for(
int i=0; i<dim1; ++i) {
2136 int dim2 = eqnTable[i]->size();
2137 int* indicesPtr = &(*(eqnTable[i]))[0];
2138 for(
int j=0; j<dim2; ++j) {
2141 indicesPtr[j] = reducedEqn;
2156 int reducedEqn = -1;
2161 std::vector<int>& rowNumbers = srg.
rowNumbers;
2162 for(
size_t i=0; i<rowNumbers.size(); ++i) {
2164 if (isSlave) foundSlave = 1;
2165 else rowNumbers[i] = reducedEqn;
2169 for(
size_t i=0; i<colIndices.size(); ++i) {
2171 if (isSlave) foundSlave = 1;
2172 else colIndices[i] = reducedEqn;
2179 int SNL_FEI_Structure::createMatrixPositions(
fei::CSRMat& mat)
2181 if (!generateGraph_) {
2192 const std::vector<int>& rowNumbers = mat.getGraph().
rowNumbers;
2193 const std::vector<int>& rowOffsets = mat.getGraph().
rowOffsets;
2196 for(
size_t i=0; i<rowNumbers.size(); ++i) {
2197 int row = rowNumbers[i];
2198 int offset = rowOffsets[i];
2199 int rowlen = rowOffsets[i+1]-offset;
2200 const int* indices = &pckColInds[offset];
2202 for(
int j=0; j<rowlen; j++) {
2203 CHK_ERR( createMatrixPosition(row, indices[j],
"crtMatPos(CSRMat)") );
2211 int SNL_FEI_Structure::createMatrixPosition(
int row,
int col,
2212 const char* callingFunction)
2214 if (!generateGraph_) {
2228 if (row < reducedStartRow_ || row > reducedEndRow_) {
2230 dbgOut() <<
" " << callingFunction <<
" passed " <<row<<
","<<col
2231 <<
", not local." << FEI_ENDL;
2237 if (debugOutput_ && outputLevel_ > 2) {
2238 dbgOut() <<
"# " << callingFunction <<
" crtMatPos("
2239 << row <<
"," << col <<
")"<<FEI_ENDL;
2250 int SNL_FEI_Structure::createMatrixPositions(
int row,
int numCols,
int* cols,
2251 const char* callingFunction)
2253 if (!generateGraph_) {
2267 if (row < reducedStartRow_ || row > reducedEndRow_) {
2269 dbgOut() <<
" " << callingFunction <<
" passed " <<row
2270 <<
", not local." << FEI_ENDL;
2278 for(
int i=0; i<numCols; i++) {
2279 if (debugOutput_ && outputLevel_ > 2) {
2280 dbgOut() <<
"# " << callingFunction <<
" crtMatPoss("
2281 << row <<
"," << cols[i] <<
")"<<FEI_ENDL;
2291 int SNL_FEI_Structure::initializeBlkEqnMapper()
2299 if (blkEqnMapper_ != NULL)
delete blkEqnMapper_;
2305 int numFields = fieldDatabase_->size();
2307 const int* fieldSizes = fieldIDs+numFields;
2308 int numNonNegativeFields = 0;
2309 int maxFieldSize = 0;
2310 for(
int f=0; f<numFields; f++) {
2311 if (fieldIDs[f] >= 0) {
2312 numNonNegativeFields++;
2313 if (fieldSizes[f] > maxFieldSize) maxFieldSize = fieldSizes[f];
2317 if (numNonNegativeFields == 1 && maxFieldSize == 1) {
2318 globalMaxBlkSize_ = 1;
2323 int localVanishedNodeAdjustment = 0;
2324 for(
int i=0; i<localProc_; ++i) {
2325 localVanishedNodeAdjustment += globalNumNodesVanished_[i];
2328 int eqnNumber, blkEqnNumber;
2330 std::map<GlobalID,int>& nodeIDmap = nodeDatabase_->
getNodeIDs();
2331 std::map<GlobalID,int>::iterator
2332 iter = nodeIDmap.begin(), iter_end = nodeIDmap.end();
2334 for(; iter!=iter_end; ++iter) {
2339 if (node==NULL)
continue;
2342 int numFields = node->getNumFields();
2343 if(numFields == 0)
continue;
2345 int firstPtEqn = node->getFieldEqnNumbers()[0];
2346 int numNodalDOF = node->getNumNodalDOF();
2347 blkEqnNumber = node->getBlkEqnNumber() - localVanishedNodeAdjustment;
2349 int blkSize = numNodalDOF;
2351 for(
int j=0; j<numNodalDOF; ++j) {
2357 CHK_ERR( blkEqnMapper.
setEqn(eqnNumber, blkEqnNumber) );
2362 CHK_ERR( blkEqnMapper.
setBlkEqnSize(blkEqnNumber, blkSize) );
2365 ++localVanishedNodeAdjustment;
2373 int numLocalNodes = globalNodeOffsets_[localProc_+1]-globalNodeOffsets_[localProc_];
2374 eqnNumber = localStartRow_ + numLocalNodalEqns_;
2375 blkEqnNumber = localBlkOffset_ + numLocalNodes;
2377 for(
int i = 0; i < numBlocks; i++) {
2381 int numElemDOF = block->getNumElemDOFPerElement();
2383 if (numElemDOF > 0) {
2384 int numElems = block->getNumElements();
2386 for(
int j=0; j<numElems; j++) {
2388 for(
int ede=0; ede<numElemDOF; ede++) {
2389 blkEqnMapper.
setEqn(eqnNumber+ede, blkEqnNumber+ede);
2393 eqnNumber += numElemDOF;
2394 blkEqnNumber += numElemDOF;
2403 std::map<GlobalID,ConstraintType*>::const_iterator
2404 cr_iter = multCRs_.begin(),
2405 cr_end = multCRs_.end();
2407 std::vector<int> localMultEqns;
2408 localMultEqns.reserve(multCRs_.size()*2);
2409 while(cr_iter != cr_end) {
2414 CHK_ERR( blkEqnMapper_->
setEqn(eqnNumber, blkEqnNumber) );
2417 localMultEqns.push_back(eqnNumber);
2418 localMultEqns.push_back(blkEqnNumber);
2428 globalMaxBlkSize_ = 0;
2429 CHK_ERR(
fei::GlobalMax(comm_, localMaxBlkEqnSize, globalMaxBlkSize_) );
2433 if (globalMaxBlkSize_ == 1) {
2440 if (numProcs_ > 1) {
2441 std::vector<int> recvLengths, globalMultEqns;
2442 CHK_ERR(
fei::Allgatherv(comm_, localMultEqns, recvLengths, globalMultEqns));
2445 for(
int p=0; p<numProcs_; p++) {
2446 if (p == localProc_) { offset += recvLengths[p];
continue; }
2448 for(
int j=0; j<recvLengths[p]/2; j++) {
2449 blkEqnMapper_->
setEqn(globalMultEqns[offset], globalMultEqns[offset+1]);
2460 int SNL_FEI_Structure::setMultCREqnInfo()
2466 std::map<GlobalID,ConstraintType*>::const_iterator
2467 cr_iter = multCRs_.begin(),
2468 cr_end = multCRs_.end();
2470 int eqnNumber = localStartRow_ + numLocalNodalEqns_ + numLocalElemDOF_;
2471 int blkEqnNum = localBlkOffset_ + numLocalEqnBlks_ - numLocalMultCRs_;
2473 while(cr_iter != cr_end) {
2489 int SNL_FEI_Structure::writeEqn2NodeMap()
2491 FEI_OSTRINGSTREAM osstr;
2492 osstr << dbgPath_ <<
"/FEI" << name_ <<
"_nID_nNum_blkEq_ptEq."
2493 << numProcs_ <<
"." << localProc_;
2495 FEI_OFSTREAM e2nFile(osstr.str().c_str());
2498 fei::console_out() <<
"SNL_FEI_Structure::writeEqn2NodeMap: ERROR, couldn't open file "
2499 << osstr.str() << FEI_ENDL;
2503 std::map<GlobalID,ConstraintType*>::const_iterator
2504 cr_iter = multCRs_.begin(),
2505 cr_end = multCRs_.end();
2507 while(cr_iter != cr_end) {
2512 e2nFile <<
"-999 -999 " << blkEqnNumber <<
" " << eqnNumber << FEI_ENDL;
2516 std::map<GlobalID,int>& nodeIDmap = nodeDatabase_->
getNodeIDs();
2517 std::map<GlobalID,int>::iterator
2518 iter = nodeIDmap.begin(), iter_end = nodeIDmap.end();
2520 for(; iter!=iter_end; ++iter) {
2524 if (node==NULL || node->getOwnerProc() != localProc_) {
2528 const int* fieldIDList = node->getFieldIDList();
2529 const int* eqnNumbers = node->getFieldEqnNumbers();
2530 int nodeNum = node->getNodeNumber();
2531 int blkEqnNumber = node->getBlkEqnNumber();
2532 int numFields = node->getNumFields();
2534 for(
int j=0; j<numFields; j++) {
2536 assert( numFieldParams > 0 );
2538 for(
int k=0; k<numFieldParams; k++) {
2539 e2nFile << (int)node->getGlobalNodeID() <<
" " << nodeNum
2540 <<
" " << blkEqnNumber <<
" " << eqnNumbers[j]+k<<FEI_ENDL;
2545 return(FEI_SUCCESS);
2549 int SNL_FEI_Structure::calcTotalNumElemDOF()
2552 int totalNumElemDOF = 0;
2554 for(
int i = 0; i < numBlocks; i++) {
2557 int numElemDOF = block->getNumElemDOFPerElement();
2558 if (numElemDOF > 0) {
2559 int numElems = block->getNumElements();
2561 totalNumElemDOF += numElems*numElemDOF;
2565 return(totalNumElemDOF);
2569 int SNL_FEI_Structure::calcNumMultCREqns()
2571 int totalNumMultCRs = 0;
2572 int numMCRecords = getNumMultConstRecords();
2574 totalNumMultCRs = numMCRecords;
2576 return( totalNumMultCRs );
2580 void SNL_FEI_Structure::calcGlobalEqnInfo(
int numLocallyOwnedNodes,
2582 int numLocalEqnBlks)
2584 FEI_OSTREAM& os = dbgOut();
2585 if (debugOutput_) os <<
"# entering calcGlobalEqnInfo" << FEI_ENDL;
2596 std::vector<int> numProcNodes(numProcs_);
2597 std::vector<int> numProcEqns(numProcs_);
2598 std::vector<int> numProcEqnBlks(numProcs_);
2600 if (numProcs_ > 1) {
2603 std::vector<int> recvList(3*numProcs_);
2605 glist[0] = numLocallyOwnedNodes;
2606 glist[1] = numLocalEqns;
2607 glist[2] = numLocalEqnBlks;
2608 if (MPI_Gather(&glist[0], 3, MPI_INT, &recvList[0], 3,
2609 MPI_INT, masterProc_, comm_) != MPI_SUCCESS) {
2610 fei::console_out() <<
"SNL_FEI_Structure::calcGlobalEqnInfo: ERROR in MPI_Gather" << FEI_ENDL;
2611 MPI_Abort(comm_, -1);
2614 for(
int p=0; p<numProcs_; p++) {
2615 numProcNodes[p] = recvList[p*3];
2616 numProcEqns[p] = recvList[p*3+1];
2617 numProcEqnBlks[p] = recvList[p*3+2];
2622 numProcNodes[0] = numLocallyOwnedNodes;
2623 numProcEqns[0] = numLocalEqns;
2624 numProcEqnBlks[0] = numLocalEqnBlks;
2629 globalNodeOffsets_.resize(numProcs_+1);
2630 globalEqnOffsets_.resize(numProcs_+1);
2631 globalBlkEqnOffsets_.resize(numProcs_+1);
2633 globalNodeOffsets_[0] = 0;
2634 globalEqnOffsets_[0] = 0;
2635 globalBlkEqnOffsets_[0] = 0;
2637 if (localProc_ == masterProc_) {
2638 for(
int i=1;i<numProcs_;i++) {
2639 globalNodeOffsets_[i] = globalNodeOffsets_[i-1] +numProcNodes[i-1];
2640 globalEqnOffsets_[i] = globalEqnOffsets_[i-1] + numProcEqns[i-1];
2641 globalBlkEqnOffsets_[i] = globalBlkEqnOffsets_[i-1] +
2642 numProcEqnBlks[i-1];
2645 globalNodeOffsets_[numProcs_] = globalNodeOffsets_[numProcs_-1] +
2646 numProcNodes[numProcs_-1];
2647 globalEqnOffsets_[numProcs_] = globalEqnOffsets_[numProcs_-1] +
2648 numProcEqns[numProcs_-1];
2649 globalBlkEqnOffsets_[numProcs_] = globalBlkEqnOffsets_[numProcs_-1] +
2650 numProcEqnBlks[numProcs_-1];
2655 if (numProcs_ > 1) {
2657 std::vector<int> blist(3*(numProcs_+1));
2659 if (localProc_ == masterProc_) {
2661 for(
int i=0; i<numProcs_+1; i++) {
2662 blist[offset++] = globalNodeOffsets_[i];
2663 blist[offset++] = globalEqnOffsets_[i];
2664 blist[offset++] = globalBlkEqnOffsets_[i];
2668 if (MPI_Bcast(&blist[0], 3*(numProcs_+1), MPI_INT,
2669 masterProc_, comm_) != MPI_SUCCESS) {
2670 fei::console_out() <<
"SNL_FEI_Structure::calcGlobalEqnInfo: ERROR in MPI_Bcast" << FEI_ENDL;
2671 MPI_Abort(comm_, -1);
2674 if (localProc_ != masterProc_) {
2676 for(
int i=0; i<numProcs_+1; i++) {
2677 globalNodeOffsets_[i] = blist[offset++];
2678 globalEqnOffsets_[i] = blist[offset++];
2679 globalBlkEqnOffsets_[i] = blist[offset++];
2685 localStartRow_ = globalEqnOffsets_[localProc_];
2686 localEndRow_ = globalEqnOffsets_[localProc_+1]-1;
2687 numGlobalEqns_ = globalEqnOffsets_[numProcs_];
2689 firstLocalNodeNumber_ = globalNodeOffsets_[localProc_];
2690 numGlobalNodes_ = globalNodeOffsets_[numProcs_];
2692 localBlkOffset_ = globalBlkEqnOffsets_[localProc_];
2693 numGlobalEqnBlks_ = globalBlkEqnOffsets_[numProcs_];
2696 os <<
"# localStartRow_: " << localStartRow_ << FEI_ENDL;
2697 os <<
"# localEndRow_: " << localEndRow_ << FEI_ENDL;
2698 os <<
"# numGlobalEqns_: " << numGlobalEqns_ << FEI_ENDL;
2699 os <<
"# numGlobalEqnBlks_: " << numGlobalEqnBlks_ << FEI_ENDL;
2700 os <<
"# localBlkOffset_: " << localBlkOffset_ << FEI_ENDL;
2701 os <<
"# firstLocalNodeNumber_: " << firstLocalNodeNumber_ << FEI_ENDL;
2703 os <<
"# numGlobalNodes_: " << numGlobalNodes_ << FEI_ENDL;
2704 os <<
"# " << globalNodeOffsets_.size() <<
" globalNodeOffsets_: ";
2705 for(
size_t nn=0; nn<globalNodeOffsets_.size(); nn++)
2706 os << globalNodeOffsets_[nn] <<
" ";
2708 os <<
"# " << globalEqnOffsets_.size() <<
" globalEqnOffsets_: ";
2709 for(n=0; n<globalEqnOffsets_.size(); n++)
2710 os << globalEqnOffsets_[n] <<
" ";
2712 os <<
"# " << globalBlkEqnOffsets_.size() <<
" globalBlkEqnOffsets_: ";
2713 for(n=0; n<globalBlkEqnOffsets_.size(); n++)
2714 os << globalBlkEqnOffsets_[n] <<
" ";
2716 os <<
"# leaving calcGlobalEqnInfo" << FEI_ENDL;
2721 int SNL_FEI_Structure::setNodalEqnInfo()
2731 int eqn = localStartRow_;
2734 int blkEqnNumber = localBlkOffset_;
2736 std::map<GlobalID,int>& nodeIDmap = nodeDatabase_->
getNodeIDs();
2737 std::map<GlobalID,int>::iterator
2738 iter = nodeIDmap.begin(), iter_end = nodeIDmap.end();
2740 for(; iter!=iter_end; ++iter) {
2744 if (node==NULL)
continue;
2746 int numFields = node->getNumFields();
2747 const int* fieldIDs = node->getFieldIDList();
2749 if (node->getOwnerProc() == localProc_) {
2750 int numNodalDOF = 0;
2752 for(
int j=0; j<numFields; j++) {
2753 node->setFieldEqnNumber(fieldIDs[j], eqn);
2756 numNodalDOF += fieldSize;
2759 node->setNumNodalDOF(numNodalDOF);
2760 node->setBlkEqnNumber(blkEqnNumber++);
2768 void SNL_FEI_Structure::setElemDOFEqnInfo()
2778 int eqnNumber = localStartRow_ + numLocalNodalEqns_;
2780 for(
int i = 0; i < numBlocks; i++) {
2783 if (err) voidERReturn;
2785 int numElemDOF = block->getNumElemDOFPerElement();
2787 if (numElemDOF > 0) {
2788 std::vector<int>& elemDOFEqns = block->elemDOFEqnNumbers();
2789 std::map<GlobalID,int>& elemIDs = connTables_[i]->elemIDs;
2791 std::map<GlobalID,int>::const_iterator
2792 iter = elemIDs.begin(),
2793 iter_end = elemIDs.end();
2795 for(; iter != iter_end; ++iter) {
2796 elemDOFEqns[iter->second] = eqnNumber;
2798 eqnNumber += numElemDOF;
2805 int SNL_FEI_Structure::addBlock(GlobalID blockID) {
2811 int insertPoint = -1;
2815 blockIDs_.insert(blockIDs_.begin()+insertPoint, blockID);
2818 block->setGlobalBlockID(blockID);
2820 blocks_.insert(blocks_.begin()+insertPoint, block);
2823 connTables_.insert(connTables_.begin()+insertPoint, newConnTable);
2826 return(FEI_SUCCESS);
2830 int SNL_FEI_Structure::getBlockDescriptor(GlobalID blockID,
2836 fei::console_out() <<
"SNL_FEI_Structure::getBlockDescriptor: ERROR, blockID "
2837 << (int)blockID <<
" not found." << FEI_ENDL;
2841 block = blocks_[index];
2843 return(FEI_SUCCESS);
2857 if (index < 0 || index >= (
int)blockIDs_.size()) ERReturn(FEI_FATAL_ERROR);
2859 block = blocks_[index];
2861 return(FEI_SUCCESS);
2865 int SNL_FEI_Structure::allocateBlockConnectivity(GlobalID blockID) {
2870 fei::console_out() <<
"SNL_FEI_Structure::allocateConnectivityTable: ERROR, blockID "
2871 << (int)blockID <<
" not found. Aborting." << FEI_ENDL;
2872 MPI_Abort(comm_, -1);
2875 connTables_[index]->numNodesPerElem =
2876 blocks_[index]->getNumNodesPerElement();
2878 int numRows = blocks_[index]->getNumElements();
2879 int numCols = connTables_[index]->numNodesPerElem;
2881 if ((numRows <= 0) || (numCols <= 0)) {
2882 fei::console_out() <<
"SNL_FEI_Structure::allocateConnectivityTable: ERROR, either "
2883 <<
"numElems or numNodesPerElem not yet set for blockID "
2884 << (int)blockID <<
". Aborting." << FEI_ENDL;
2885 MPI_Abort(comm_, -1);
2888 connTables_[index]->elemNumbers.resize(numRows);
2890 connTables_[index]->elem_conn_ids =
new std::vector<GlobalID>(numRows*numCols);
2892 return(FEI_SUCCESS);
2901 fei::console_out() <<
"SNL_FEI_Structure::getBlockConnectivity: ERROR, blockID "
2902 << (int)blockID <<
" not found. Aborting." << FEI_ENDL;
2903 MPI_Abort(comm_, -1);
2906 return(*(connTables_[index]));
2910 int SNL_FEI_Structure::finalizeActiveNodes()
2912 FEI_OSTREAM& os = dbgOut();
2914 os <<
"# finalizeActiveNodes" << FEI_ENDL;
2919 std::vector<GlobalID>& shNodeIDs = nodeCommMgr_->getSharedNodeIDs();
2920 for(
unsigned i=0; i<shNodeIDs.size(); i++) {
2921 CHK_ERR( nodeDatabase_->
initNodeID(shNodeIDs[i]) );
2924 if (activeNodesInitialized_)
return(0);
2936 int numBlocks = blockIDs_.size();
2937 for(
int bIndex=0; bIndex<numBlocks; bIndex++) {
2939 GlobalID blockID = blocks_[bIndex]->getGlobalBlockID();
2942 GlobalID* elemConn = NULL;
2945 int numElems = conn.elemIDs.size();
2947 elemConn = &((*conn.elem_conn_ids)[0]);
2948 if (!activeNodesInitialized_) {
2949 int elemConnLen = conn.elem_conn_ids->size();
2950 conn.elem_conn_ptrs =
new std::vector<NodeDescriptor*>(elemConnLen);
2952 elemNodeDescPtrs = &((*conn.elem_conn_ptrs)[0]);
2954 int nodesPerElem = conn.numNodesPerElem;
2956 int* fieldsPerNodePtr = blocks_[bIndex]->fieldsPerNodePtr();
2957 int** fieldIDsTablePtr = blocks_[bIndex]->fieldIDsTablePtr();
2970 conn.elemNumbers.resize(numElems);
2972 int numDistinctFields = blocks_[bIndex]->getNumDistinctFields();
2973 int fieldID = fieldIDsTablePtr[0][0];
2976 for(elem=0; elem<numElems; elem++) {
2977 conn.elemNumbers[elem] = elemNumber++;
2978 GlobalID* elemNodes = &(elemConn[elem*nodesPerElem]);
2979 NodeDescriptor** elemNodePtrs = &(elemNodeDescPtrs[elem*nodesPerElem]);
2981 for(
int n=0; n<nodesPerElem; n++) {
2983 int index = nodeDatabase_->
getNodeWithID( elemNodes[n], node );
2985 fei::console_out() <<
"ERROR in SNL_FEI_Structure::initializeActiveNodes, "
2986 << FEI_ENDL <<
"failed to find node "
2987 << (int)(elemNodes[n]) << FEI_ENDL;
2990 if (numDistinctFields == 1) {
2991 node->addField(fieldID);
2994 for(
int i=0; i<fieldsPerNodePtr[n]; i++) {
2995 node->addField(fieldIDsTablePtr[n][i]);
3001 node->addBlockIndex(blk_idx);
3005 elemNodePtrs[n] = node;
3007 node->setOwnerProc(localProc_);
3008 if (numProcs_ > 1) nodeCommMgr_->informLocal(*node);
3018 if (numProcs_ > 1) {
3019 std::map<GlobalID,ConstraintType*>::const_iterator
3020 cr_iter = getPenConstRecords().begin(),
3021 cr_end = getPenConstRecords().end();
3023 while(cr_iter != cr_end) {
3025 std::vector<GlobalID>& nodeID_vec = cr.
getMasters();
3026 GlobalID* nodeIDs = &nodeID_vec[0];
3030 for(
int k=0; k<numNodes; ++k) {
3033 nodeCommMgr_->informLocal(*node);
3042 activeNodesInitialized_ =
true;
3044 if (debugOutput_) os <<
"# leaving finalizeActiveNodes" << FEI_ENDL;
3045 return(FEI_SUCCESS);
3049 int SNL_FEI_Structure::finalizeNodeCommMgr()
3056 bool safetyCheck = checkSharedNodes_;
3058 if (safetyCheck && localProc_==0 && numProcs_>1 && outputLevel_>0) {
3059 FEI_COUT <<
"FEI Info: A consistency-check of shared-node data will be "
3060 <<
"performed, which involves all-to-all communication. This check is "
3061 <<
"done only if explicitly requested by parameter "
3062 <<
"'FEI_CHECK_SHARED_IDS'."<<FEI_ENDL;
3065 CHK_ERR( nodeCommMgr_->initComplete(*nodeDatabase_, safetyCheck) );
3068 FEI_OSTREAM& os = dbgOut();
3069 int numSharedNodes = nodeCommMgr_->getNumSharedNodes();
3070 os <<
"# numSharedNodes: " << numSharedNodes << FEI_ENDL;
3071 for(
int ns=0; ns<numSharedNodes; ns++) {
3073 GlobalID nodeID = node.getGlobalNodeID();
3074 int proc = node.getOwnerProc();
3075 os <<
"# shNodeID " << (int)nodeID <<
", owned by proc "<<proc<<FEI_ENDL;
3083 int SNL_FEI_Structure::setNumNodesAndEqnsPerBlock()
3088 int numBlocks = blockIDs_.size();
3089 std::vector<int> nodesPerBlock(numBlocks);
3090 std::vector<int> eqnsPerBlock(numBlocks);
3093 for(j=0; j<numBlocks; j++) {
3094 nodesPerBlock[j] = 0;
3095 eqnsPerBlock[j] = 0;
3100 for(j=0; j<numNodes; j++) {
3103 if (node==NULL)
continue;
3105 const int* fieldIDList = node->getFieldIDList();
3107 int numFields = node->getNumFields();
3109 const std::vector<unsigned>& blkIndices = node->getBlockIndexList();
3110 for(std::vector<unsigned>::const_iterator b=blkIndices.begin(), bend=blkIndices.end();
3112 nodesPerBlock[*b]++;
3114 for(
int fld=0; fld<numFields; fld++) {
3115 if (blocks_[*b]->containsField(fieldIDList[fld])) {
3118 eqnsPerBlock[*b] += fSize;
3124 for(j=0; j<numBlocks; j++) {
3125 blocks_[j]->setNumActiveNodes(nodesPerBlock[j]);
3131 for(j=0; j<numBlocks; j++) {
3132 eqnsPerBlock[j] += blocks_[j]->getNumElemDOFPerElement() *
3133 blocks_[j]->getNumElements();
3135 blocks_[j]->setTotalNumEqns(eqnsPerBlock[j]);
3141 void SNL_FEI_Structure::initializeEqnCommMgr()
3143 FEI_OSTREAM& os = dbgOut();
3144 if (debugOutput_) os <<
"# initializeEqnCommMgr" << FEI_ENDL;
3154 int numSharedNodes = nodeCommMgr_->getNumSharedNodes();
3156 for(
int i=0; i<numSharedNodes; i++) {
3159 int numFields = node.getNumFields();
3160 const int* nodeFieldIDList = node.getFieldIDList();
3161 const int* nodeEqnNums = node.getFieldEqnNumbers();
3163 int owner = node.getOwnerProc();
3164 if (owner == localProc_) {
3165 std::vector<int>& proc = nodeCommMgr_->getSharedNodeProcs(i);
3168 for(
int p=0; p<numProcs; p++) {
3170 if (proc[p] == localProc_)
continue;
3172 for(
int j=0; j<numFields; j++) {
3174 assert(numEqns >= 0);
3177 for(eqn=0; eqn<numEqns; eqn++) {
3178 int reducedEqn = -1;
3181 if (isSlave)
continue;
3189 for(
int j=0; j<numFields; j++) {
3191 assert(numEqns >= 0);
3192 for(
int eqn=0; eqn<numEqns; eqn++) {
3193 int reducedEqn = -1;
3195 if (isSlave)
continue;
3197 eqnCommMgr_->addRemoteIndices(reducedEqn, owner, NULL, 0);
3203 if (debugOutput_) os <<
"# leaving initializeEqnCommMgr" << FEI_ENDL;
3207 void SNL_FEI_Structure::getEqnInfo(
int& numGlobalEqns,
int& numLocalEqns,
3208 int& localStartRow,
int& localEndRow){
3210 numGlobalEqns = numGlobalEqns_;
3211 numLocalEqns = numLocalEqns_;
3212 localStartRow = localStartRow_;
3213 localEndRow = localEndRow_;
3217 int SNL_FEI_Structure::getEqnNumbers(GlobalID ID,
3218 int idType,
int fieldID,
3219 int& numEqns,
int* eqnNumbers)
3222 if (idType != FEI_NODE) ERReturn(-1);
3228 if (numEqns < 0) ERReturn(-1);
3230 int nodeFieldEqnNumber = -1;
3235 for(
int i=0; i<numEqns; i++) eqnNumbers[i] = nodeFieldEqnNumber + i;
3237 return(FEI_SUCCESS);
3241 int SNL_FEI_Structure::getEqnNumbers(
int numIDs,
3242 const GlobalID* IDs,
3243 int idType,
int fieldID,
3244 int& numEqns,
int* eqnNumbers)
3247 if (idType != FEI_NODE) ERReturn(-1);
3250 if (fieldSize < 0) {
3255 for(
int i=0; i<numIDs; ++i) {
3260 for(
int ii=0; ii<fieldSize; ii++) {
3261 eqnNumbers[offset++] = -1;
3267 int nodeFieldEqnNumber = -1;
3273 for(
int ii=0; ii<fieldSize; ii++) {
3274 eqnNumbers[offset++] = -1;
3279 for(
int ii=0; ii<fieldSize; ii++) {
3280 eqnNumbers[offset++] = nodeFieldEqnNumber + ii;
3285 numEqns = fieldSize*numIDs;
3287 return(FEI_SUCCESS);
3291 int SNL_FEI_Structure::translateToReducedNodeNumber(
int nodeNumber,
int proc)
3293 if (proc != localProc_) {
3294 return(nodeNumber - globalNumNodesVanished_[proc]);
3297 int insertPoint = -1;
3301 int localAdjustment = index < 0 ? insertPoint : index + 1;
3303 return(nodeNumber - localAdjustment - globalNumNodesVanished_[proc]);
3307 void SNL_FEI_Structure::getEqnBlkInfo(
int& numGlobalEqnBlks,
3308 int& numLocalEqnBlks,
3309 int& localBlkOffset) {
3311 numGlobalEqnBlks = numGlobalEqnBlks_;
3312 numLocalEqnBlks = numLocalEqnBlks_;
3313 localBlkOffset = localBlkOffset_;
3317 int SNL_FEI_Structure::calculateSlaveEqns(MPI_Comm comm)
3319 FEI_OSTREAM& os = dbgOut();
3320 if (debugOutput_) os <<
"# calculateSlaveEqns" << FEI_ENDL;
3322 if (eqnCommMgr_ != NULL)
delete eqnCommMgr_;
3324 eqnCommMgr_->setNumRHSs(1);
3326 std::vector<int> eqns;
3327 std::vector<int> mEqns;
3328 std::vector<double> mCoefs;
3330 for(
size_t i=0; i<slaveVars_->size(); i++) {
3335 CHK_ERR( getEqnNumbers(svar->getNodeID(), FEI_NODE, svar->getFieldID(),
3336 numEqns, &eqns[0]));
3338 int slaveEqn = eqns[svar->getFieldOffset()];
3340 const std::vector<GlobalID>* mNodes = svar->getMasterNodeIDs();
3341 const std::vector<int>* mFields = svar->getMasterFields();
3342 const std::vector<double>* mWeights = svar->getWeights();
3343 const std::vector<double>& mWeightsRef = *mWeights;
3346 for(
size_t j=0; j<mNodes->size(); j++) {
3349 eqns.resize(mfSize);
3350 GlobalID mNodeID = (*mNodes)[j];
3351 int mFieldID = (*mFields)[j];
3352 CHK_ERR( getEqnNumbers( mNodeID, FEI_NODE, mFieldID,
3355 double fei_eps = 1.e-49;
3357 for(
int k=0; k<mfSize; k++) {
3358 if (std::abs(mWeightsRef[mwOffset++]) > fei_eps) {
3359 mEqns.push_back(eqns[k]);
3360 mCoefs.push_back(mWeightsRef[mwOffset-1]);
3365 CHK_ERR( slaveEqns_->
addEqn(slaveEqn, &mCoefs[0], &mEqns[0],
3366 mEqns.size(),
false) );
3372 int numLocalSlaves = slaveVars_->size();
3373 int globalMaxSlaves = 0;
3374 CHK_ERR(
fei::GlobalMax(comm_, numLocalSlaves, globalMaxSlaves) );
3376 if (globalMaxSlaves > 0) {
3377 CHK_ERR( gatherSlaveEqns(comm, eqnCommMgr_, slaveEqns_) );
3381 globalNumNodesVanished_.resize(numProcs_+1, 0);
3383 slvEqnNumbers_ = &(slaveEqns_->
eqnNumbers());
3384 numSlvs_ = slvEqnNumbers_->size();
3391 os <<
"# slave-equations:" << FEI_ENDL;
3393 os <<
"# leaving calculateSlaveEqns" << FEI_ENDL;
3396 int levelsOfCoupling;
3397 CHK_ERR( removeCouplings(*slaveEqns_, levelsOfCoupling) );
3400 os <<
"# SNL_FEI_Structure: " << levelsOfCoupling
3401 <<
" level(s) of coupling removed: " << FEI_ENDL;
3404 lowestSlv_ = (*slvEqnNumbers_)[0];
3405 highestSlv_ = (*slvEqnNumbers_)[numSlvs_-1];
3420 std::vector<int>& slvEqns = *slvEqnNumbers_;
3421 std::vector<fei::CSVec*>& mstrEqns = slaveEqns_->
eqns();
3425 int numLocalNodesVanished = 0;
3427 GlobalID lastNodeID = -1;
3429 for(
int i=0; i<numSlvs_; i++) {
3431 int reducedSlaveEqn;
3433 int numMasters = mstrEqns[i]->size();
3438 os <<
"# no local node for slave eqn " << slvEqns[i] << FEI_ENDL;
3444 if (node->getGlobalNodeID() != lastNodeID &&
3445 node->getOwnerProc() == localProc_) {
3446 if (nodalEqnsAllSlaves(node, slvEqns)) {
3447 numLocalNodesVanished++;
3453 lastNodeID = node->getGlobalNodeID();
3456 GlobalID slvNodeID = node->getGlobalNodeID();
3457 int shIndex = nodeCommMgr_->getSharedNodeIndex(slvNodeID);
3462 std::vector<int>& sharingProcs = nodeCommMgr_->getSharedNodeProcs(shIndex);
3464 for(
int j=0; j<numMasters; j++) {
3465 int masterEquation = mstrEqns[i]->indices()[j];
3468 int reducedMasterEqn;
3471 if (owner == localProc_) {
3472 int numSharing = sharingProcs.size();
3473 for(
int sp=0; sp<numSharing; sp++) {
3474 if (sharingProcs[sp] == localProc_)
continue;
3477 os <<
"# slave node " << (int)slvNodeID <<
",eqn "<<slvEqns[i]
3478 <<
", master eqn " << masterEquation <<
" eqnCommMgr_->addLocal "
3479 << reducedMasterEqn <<
", proc " << sharingProcs[sp] << FEI_ENDL;
3481 eqnCommMgr_->
addLocalEqn(reducedMasterEqn, sharingProcs[sp]);
3482 slvCommMgr_->addRemoteIndices(reducedSlaveEqn, sharingProcs[sp],
3483 &reducedMasterEqn, 1);
3488 os <<
"# slave node " << (int)slvNodeID <<
",eqn "<<slvEqns[i]
3489 <<
", master eqn " << masterEquation <<
" eqnCommMgr_->addRemote "
3490 << reducedMasterEqn <<
", proc " << owner << FEI_ENDL;
3492 eqnCommMgr_->addRemoteIndices(reducedMasterEqn, owner,
3493 &reducedMasterEqn, 1);
3499 std::vector<int> tmp(1), tmp2(numProcs_);
3500 tmp[0] = numLocalNodesVanished;
3501 CHK_ERR(
fei::Allgatherv(comm_, tmp, tmp2, globalNumNodesVanished_) );
3503 if ((
int)globalNumNodesVanished_.size() != numProcs_) {
3507 globalNumNodesVanished_.resize(numProcs_+1);
3508 int tmpNumVanished = 0;
3509 for(
int proc=0; proc<numProcs_; ++proc) {
3510 int temporary = tmpNumVanished;
3511 tmpNumVanished += globalNumNodesVanished_[proc];
3512 globalNumNodesVanished_[proc] = temporary;
3514 globalNumNodesVanished_[numProcs_] = tmpNumVanished;
3517 if (slaveMatrix_ != NULL)
delete slaveMatrix_;
3518 slaveMatrix_ =
new fei::FillableMat(*slaveEqns_);
3521 os <<
"# slave-equations:" << FEI_ENDL;
3523 os <<
"# leaving calculateSlaveEqns" << FEI_ENDL;
3530 int SNL_FEI_Structure::removeCouplings(
EqnBuffer& eqnbuf,
int& levelsOfCoupling)
3532 std::vector<int>& eqnNumbers = eqnbuf.
eqnNumbers();
3533 std::vector<fei::CSVec*>& eqns = eqnbuf.
eqns();
3535 std::vector<double> tempCoefs;
3536 std::vector<int> tempIndices;
3538 levelsOfCoupling = 0;
3539 bool finished =
false;
3541 bool foundCoupling =
false;
3542 for(
size_t i=0; i<eqnNumbers.size(); i++) {
3545 if (rowIndex == (
int)i) {
3547 <<
" illegal master-slave constraint coupling. Eqn "
3548 << eqnNumbers[i] <<
" is both master and slave. " << FEI_ENDL;
3552 while(rowIndex >= 0) {
3553 foundCoupling =
true;
3556 eqnNumbers[i], coef) );
3558 std::vector<int>& indicesRef = eqns[i]->indices();
3559 std::vector<double>& coefsRef = eqns[i]->coefs();
3561 int len = indicesRef.size();
3562 tempCoefs.resize(len);
3563 tempIndices.resize(len);
3565 double* tempCoefsPtr = &tempCoefs[0];
3566 int* tempIndicesPtr = &tempIndices[0];
3567 double* coefsPtr = &coefsRef[0];
3568 int* indicesPtr = &indicesRef[0];
3570 for(
int j=0; j<len; ++j) {
3571 tempIndicesPtr[j] = indicesPtr[j];
3572 tempCoefsPtr[j] = coef*coefsPtr[j];
3575 CHK_ERR( eqnbuf.
addEqn(eqnNumbers[rowIndex], tempCoefsPtr,
3576 tempIndicesPtr, len,
true) );
3581 if (foundCoupling) ++levelsOfCoupling;
3582 else finished =
true;
3584 if (levelsOfCoupling>1 && !finished) {
3586 <<
" too many (>1) levels of master-slave constraint coupling. "
3587 <<
"Hint: coupling is considered infinite if two slaves depend on "
3588 <<
"each other. This may or may not be the case here." << FEI_ENDL;
3598 int SNL_FEI_Structure::gatherSlaveEqns(MPI_Comm comm,
3603 if (MPI_Comm_size(comm, &numProcs) != MPI_SUCCESS)
return(-1);
3604 if (numProcs == 1)
return(0);
3606 if (MPI_Comm_rank(comm, &localProc) != MPI_SUCCESS)
return(-1);
3612 ProcEqns localProcEqns, remoteProcEqns;
3613 std::vector<int>& slvEqnNums = slaveEqns->
eqnNumbers();
3615 if (slaveEqns->
eqns().size() > 0) slvEqnsPtr = &(slaveEqns->
eqns()[0]);
3617 for(
size_t i=0; i<slvEqnNums.size(); i++) {
3618 for(
int p=0; p<numProcs; p++) {
3619 if (p == localProc)
continue;
3621 localProcEqns.
addEqn(slvEqnNums[i], slvEqnsPtr[i]->size(), p);
3625 CHK_ERR( eqnCommMgr->
mirrorProcEqns(localProcEqns, remoteProcEqns) );
3631 CHK_ERR( EqnCommMgr::exchangeEqnBuffers(comm, &localProcEqns, slaveEqns,
3632 &remoteProcEqns, &remoteEqns,
3637 CHK_ERR( slaveEqns->
addEqns(remoteEqns,
false) );
3646 if (numSlvs_ == 0)
return(
false);
3648 std::vector<int>& slvEqns = slaveEqns_->
eqnNumbers();
3649 int insertPoint = -1;
3652 if (foundOffset >= 0)
return(
true);
3659 if (numSlvs_ == 0) { reducedEqn = eqn;
return(
false); }
3661 if (eqn < lowestSlv_) {reducedEqn = eqn;
return(
false); }
3662 if (eqn > highestSlv_) {reducedEqn = eqn - numSlvs_;
return(
false); }
3667 bool isSlave =
false;
3669 if (foundOffset < 0) {
3670 reducedEqn = eqn - index;
3673 isSlave =
true; reducedEqn = eqn - (foundOffset+1);
3684 if (numSlvs == 0)
return(reducedEqn);
3686 const int* slvEqns = &(slaveEqns_->
eqnNumbers()[0]);
3688 if (reducedEqn < slvEqns[0])
return(reducedEqn);
3690 int eqn = reducedEqn;
3692 for(
int i=0; i<numSlvs; i++) {
3693 if (eqn < slvEqns[i])
return(eqn);
3702 std::vector<int>*& masterEqns)
3709 std::vector<int>& slvEqns = slaveEqns_->
eqnNumbers();
3713 if (foundOffset >= 0) {
3714 masterEqns = &(slaveEqns_->
eqns()[foundOffset]->indices());
3725 std::vector<double>*& masterCoefs)
3732 std::vector<int>& slvEqns = slaveEqns_->
eqnNumbers();
3736 if (foundOffset >= 0) {
3737 masterCoefs = &(slaveEqns_->
eqns()[foundOffset]->coefs());
3754 std::vector<int>& slvEqns = slaveEqns_->
eqnNumbers();
3758 if (foundOffset >= 0) {
3759 std::vector<double>* rhsCoefsPtr = (*(slaveEqns_->
rhsCoefsPtr()))[foundOffset];
3760 rhsValue = (*rhsCoefsPtr)[0];
3767 void SNL_FEI_Structure::getScatterIndices_ID(GlobalID blockID, GlobalID elemID,
3768 int interleaveStrategy,
3769 int* scatterIndices)
3774 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_ID: ERROR, blockID "
3775 << (int)blockID <<
" not found. Aborting." << FEI_ENDL;
3779 std::map<GlobalID,int>& elemIDs = connTables_[index]->elemIDs;
3781 std::map<GlobalID,int>::const_iterator
3782 iter = elemIDs.find(elemID);
3784 if (iter == elemIDs.end()) {
3785 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_ID: ERROR, blockID: "
3786 << (int)blockID <<
", elemID "
3787 << (
int)elemID <<
" not found. Aborting." << FEI_ENDL;
3791 int elemIndex = iter->second;
3793 getScatterIndices_index(index, elemIndex,
3794 interleaveStrategy, scatterIndices);
3798 void SNL_FEI_Structure::getScatterIndices_ID(GlobalID blockID, GlobalID elemID,
3799 int interleaveStrategy,
3800 int* scatterIndices,
3801 int* blkScatterIndices,
3807 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_ID: ERROR, blockID "
3808 << (int)blockID <<
" not found. Aborting." << FEI_ENDL;
3812 std::map<GlobalID,int>& elemIDs = connTables_[index]->elemIDs;
3814 std::map<GlobalID,int>::const_iterator
3815 iter = elemIDs.find(elemID);
3817 if (iter == elemIDs.end()) {
3818 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_ID: ERROR, blockID: "
3819 << (int)blockID <<
", elemID "
3820 << (
int)elemID <<
" not found. Aborting." << FEI_ENDL;
3824 int elemIndex = iter->second;
3826 getScatterIndices_index(index, elemIndex,
3827 interleaveStrategy, scatterIndices,
3828 blkScatterIndices, blkSizes);
3832 int SNL_FEI_Structure::getBlkScatterIndices_index(
int blockIndex,
3834 int* scatterIndices)
3837 int numNodes = block.getNumNodesPerElement();
3838 work_nodePtrs_.resize(numNodes);
3840 int err = getElemNodeDescriptors(blockIndex, elemIndex, nodes);
3842 fei::console_out() <<
"SNL_FEI_Structure::getBlkScatterIndices_index: ERROR getting"
3843 <<
" node descriptors." << FEI_ENDL;
3848 return( getNodeBlkIndices(nodes, numNodes, scatterIndices, offset) );
3852 void SNL_FEI_Structure::getScatterIndices_index(
int blockIndex,
int elemIndex,
3853 int interleaveStrategy,
3854 int* scatterIndices)
3860 int numNodes = block.getNumNodesPerElement();
3861 int* fieldsPerNode = block.fieldsPerNodePtr();
3864 work_nodePtrs_.resize(numNodes);
3867 int err = getElemNodeDescriptors(blockIndex, elemIndex, nodes);
3869 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_index: ERROR getting"
3870 <<
" node descriptors." << FEI_ENDL;
3875 if (fieldDatabase_->size() == 1) {
3876 err = getNodeIndices_simple(nodes, numNodes, fieldIDs[0][0],
3877 scatterIndices, offset);
3878 if (err)
fei::console_out() <<
"ERROR in getNodeIndices_simple." << FEI_ENDL;
3881 switch (interleaveStrategy) {
3883 err = getNodeMajorIndices(nodes, numNodes, fieldIDs, fieldsPerNode,
3884 scatterIndices, offset);
3885 if (err)
fei::console_out() <<
"ERROR in getNodeMajorIndices." << FEI_ENDL;
3889 err = getFieldMajorIndices(nodes, numNodes, fieldIDs, fieldsPerNode,
3890 scatterIndices, offset);
3891 if (err)
fei::console_out() <<
"ERROR in getFieldMajorIndices." << FEI_ENDL;
3895 fei::console_out() <<
"ERROR, unrecognized interleaveStrategy." << FEI_ENDL;
3901 int numElemDOF = blocks_[blockIndex]->getNumElemDOFPerElement();
3902 std::vector<int>& elemDOFEqns = blocks_[blockIndex]->elemDOFEqnNumbers();
3904 for(
int i=0; i<numElemDOF; i++) {
3905 scatterIndices[offset++] = elemDOFEqns[elemIndex] + i;
3910 void SNL_FEI_Structure::getScatterIndices_index(
int blockIndex,
int elemIndex,
3911 int interleaveStrategy,
3912 int* scatterIndices,
3913 int* blkScatterIndices,
3920 int numNodes = block.getNumNodesPerElement();
3921 int* fieldsPerNode = block.fieldsPerNodePtr();
3924 work_nodePtrs_.resize(numNodes);
3927 int err = getElemNodeDescriptors(blockIndex, elemIndex, nodes);
3929 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_index: ERROR getting"
3930 <<
" node descriptors." << FEI_ENDL;
3934 int offset = 0, blkOffset = 0;
3935 if (fieldDatabase_->size() == 1) {
3936 err = getNodeIndices_simple(nodes, numNodes, fieldIDs[0][0],
3937 scatterIndices, offset,
3938 blkScatterIndices, blkSizes, blkOffset);
3939 if (err)
fei::console_out() <<
"ERROR in getNodeIndices_simple." << FEI_ENDL;
3942 switch (interleaveStrategy) {
3944 err = getNodeMajorIndices(nodes, numNodes, fieldIDs, fieldsPerNode,
3945 scatterIndices, offset,
3946 blkScatterIndices, blkSizes, blkOffset);
3947 if (err)
fei::console_out() <<
"ERROR in getNodeMajorIndices." << FEI_ENDL;
3951 err = getFieldMajorIndices(nodes, numNodes, fieldIDs, fieldsPerNode,
3952 scatterIndices, offset);
3953 if (err)
fei::console_out() <<
"ERROR in getFieldMajorIndices." << FEI_ENDL;
3957 fei::console_out() <<
"ERROR, unrecognized interleaveStrategy." << FEI_ENDL;
3963 int numElemDOF = blocks_[blockIndex]->getNumElemDOFPerElement();
3964 std::vector<int>& elemDOFEqns = blocks_[blockIndex]->elemDOFEqnNumbers();
3966 for(
int i=0; i<numElemDOF; i++) {
3967 scatterIndices[offset++] = elemDOFEqns[elemIndex] + i;
3968 if (interleaveStrategy == 0) {
3969 blkSizes[blkOffset] = 1;
3970 blkScatterIndices[blkOffset++] = elemDOFEqns[elemIndex] + i;
3976 int SNL_FEI_Structure::getElemNodeDescriptors(
int blockIndex,
int elemIndex,
3985 int numNodes = connTables_[blockIndex]->numNodesPerElem;
3987 if (activeNodesInitialized_) {
3989 &((*connTables_[blockIndex]->elem_conn_ptrs)[elemIndex*numNodes]);
3990 for(
int i=0; i<numNodes; ++i) nodes[i] = elemNodePtrs[i];
3993 const GlobalID* elemConn =
3994 &((*connTables_[blockIndex]->elem_conn_ids)[elemIndex*numNodes]);
3995 for(
int i=0; i<numNodes; ++i) {
3996 CHK_ERR( nodeDatabase_->
getNodeWithID(elemConn[i], nodes[i]));
4000 return(FEI_SUCCESS);
4004 int SNL_FEI_Structure::getNodeIndices_simple(
NodeDescriptor** nodes,
4007 int* scatterIndices,
4012 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4014 const int* eqnNumbers = node.getFieldEqnNumbers();
4015 int eqn = eqnNumbers[0];
4016 scatterIndices[offset++] = eqn;
4017 if (fieldSize > 1) {
4018 for(
int i=1; i<fieldSize; i++) {
4019 scatterIndices[offset++] = eqn+i;
4027 int SNL_FEI_Structure::getNodeIndices_simple(
NodeDescriptor** nodes,
4030 int* scatterIndices,
4032 int* blkScatterIndices,
4038 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4040 const int* eqnNumbers = node.getFieldEqnNumbers();
4041 int eqn = eqnNumbers[0];
4042 scatterIndices[offset++] = eqn;
4043 if (fieldSize > 1) {
4044 for(
int i=1; i<fieldSize; i++) {
4045 scatterIndices[offset++] = eqn+i;
4048 blkSizes[blkOffset] = node.getNumNodalDOF();
4049 blkScatterIndices[blkOffset++] = node.getBlkEqnNumber();
4055 int SNL_FEI_Structure::getNodeMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4056 int** fieldIDs,
int* fieldsPerNode,
4057 int* scatterIndices,
int& offset)
4059 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4063 const int* nodeFieldIDList = node.getFieldIDList();
4064 const int* nodeEqnNums = node.getFieldEqnNumbers();
4065 int numFields = node.getNumFields();
4067 int* fieldID_ind = fieldIDs[nodeIndex];
4069 for(
int j=0; j<fieldsPerNode[nodeIndex]; j++) {
4071 assert(numEqns >= 0);
4078 int eqn = nodeEqnNums[nind];
4081 FEI_COUT <<
"SNL_FEI_Structure::getNodeMajorIndices: ERROR, node "
4082 << (int)node.getGlobalNodeID()
4083 <<
", field " << nodeFieldIDList[nind]
4084 <<
" has equation number " << eqn << FEI_ENDL;
4088 for(
int jj=0; jj<numEqns; jj++) {
4089 scatterIndices[offset++] = eqn+jj;
4093 if (outputLevel_ > 2) {
4095 <<
" not found for node "
4096 << (int)(node.getGlobalNodeID()) << FEI_ENDL;
4102 return(FEI_SUCCESS);
4108 int* scatterIndices,
4111 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4113 scatterIndices[offset++] = node->getBlkEqnNumber();
4119 int SNL_FEI_Structure::getNodeMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4120 int** fieldIDs,
int* fieldsPerNode,
4121 int* scatterIndices,
int& offset,
4122 int* blkScatterIndices,
4126 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4130 const int* nodeFieldIDList = node.getFieldIDList();
4131 const int* nodeEqnNums = node.getFieldEqnNumbers();
4132 int numFields = node.getNumFields();
4134 blkSizes[blkOffset] = node.getNumNodalDOF();
4135 blkScatterIndices[blkOffset++] = node.getBlkEqnNumber();
4137 int* fieldID_ind = fieldIDs[nodeIndex];
4139 for(
int j=0; j<fieldsPerNode[nodeIndex]; j++) {
4141 assert(numEqns >= 0);
4148 int eqn = nodeEqnNums[nind];
4150 FEI_COUT <<
"SNL_FEI_Structure::getNodeMajorIndices: ERROR, node "
4151 << (int)node.getGlobalNodeID()
4152 <<
", field " << nodeFieldIDList[nind]
4153 <<
" has equation number " << eqn << FEI_ENDL;
4157 for(
int jj=0; jj<numEqns; jj++) {
4158 scatterIndices[offset++] = eqn+jj;
4162 if (outputLevel_ > 2) {
4164 <<
" not found for node "
4165 << (int)(node.getGlobalNodeID()) << FEI_ENDL;
4171 return(FEI_SUCCESS);
4175 int SNL_FEI_Structure::getNodeMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4176 std::vector<int>* fieldIDs,
4177 std::vector<int>& fieldsPerNode,
4178 std::vector<int>& scatterIndices)
4181 scatterIndices.resize(0);
4183 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4187 const int* nodeFieldIDList = node.getFieldIDList();
4188 const int* nodeEqnNums = node.getFieldEqnNumbers();
4189 int numFields = node.getNumFields();
4191 int* fieldID_ind = &(fieldIDs[nodeIndex][0]);
4193 for(
int j=0; j<fieldsPerNode[nodeIndex]; j++) {
4195 assert(numEqns >= 0);
4202 int eqn = nodeEqnNums[nind];
4205 FEI_COUT <<
"SNL_FEI_Structure::getNodeMajorIndices: ERROR, node "
4206 << (int)node.getGlobalNodeID()
4207 <<
", field " << nodeFieldIDList[nind]
4208 <<
" has equation number " << eqn << FEI_ENDL;
4209 MPI_Abort(comm_, -1);
4212 scatterIndices.resize(offset+numEqns);
4213 int* inds = &scatterIndices[0];
4215 for(
int jj=0; jj<numEqns; jj++) {
4216 inds[offset+jj] = eqn+jj;
4221 if (outputLevel_ > 2) {
4223 <<
" not found for node "
4224 << (int)node.getGlobalNodeID() << FEI_ENDL;
4230 return(FEI_SUCCESS);
4234 int SNL_FEI_Structure::getFieldMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4235 int** fieldIDs,
int* fieldsPerNode,
4236 int* scatterIndices,
int& offset)
4244 std::vector<int> fields;
4245 for(
int ii=0; ii<numNodes; ii++) {
4246 for(
int j=0; j<fieldsPerNode[ii]; j++) {
4247 if (std::find(fields.begin(), fields.end(), fieldIDs[ii][j]) == fields.end()) {
4248 fields.push_back(fieldIDs[ii][j]);
4253 int* fieldsPtr = fields.size()>0 ? &fields[0] : NULL;
4258 for(
size_t i=0; i<fields.size(); i++) {
4259 int field = fieldsPtr[i];
4261 for(
int nodeIndex = 0; nodeIndex < numNodes; ++nodeIndex) {
4263 fieldsPerNode[nodeIndex]);
4270 const int* nodeFieldIDList = node->getFieldIDList();
4271 const int* nodeEqnNums = node->getFieldEqnNumbers();
4272 int numFields = node->getNumFields();
4275 assert(numEqns >= 0);
4282 for(
int jj=0; jj<numEqns; ++jj) {
4283 scatterIndices[offset++] = nodeEqnNums[nind]+jj;
4292 return(FEI_SUCCESS);
4296 int SNL_FEI_Structure::getFieldMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4297 std::vector<int>* fieldIDs,
4298 std::vector<int>& fieldsPerNode,
4299 std::vector<int>& scatterIndices)
4307 std::vector<int> fields;
4308 for(
int ii=0; ii<numNodes; ii++) {
4309 for(
int j=0; j<fieldsPerNode[ii]; j++) {
4310 std::vector<int>& fldIDs = fieldIDs[ii];
4311 if (std::find(fields.begin(), fields.end(), fldIDs[j]) == fields.end()) {
4312 fields.push_back(fldIDs[j]);
4321 scatterIndices.resize(0);
4323 for(
size_t i=0; i<fields.size(); i++) {
4324 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4326 const int* nodeFieldIDList = nodes[nodeIndex]->getFieldIDList();
4327 const int* nodeEqnNums = nodes[nodeIndex]->getFieldEqnNumbers();
4328 int numFields = nodes[nodeIndex]->getNumFields();
4331 assert(numEqns >= 0);
4338 for(
int jj=0; jj<numEqns; jj++) {
4339 scatterIndices.push_back(nodeEqnNums[nind]+jj);
4344 if (outputLevel_ > 2) {
4346 <<
" not found for node "
4347 << (int)nodes[nodeIndex]->getGlobalNodeID() << FEI_ENDL;
4353 return(FEI_SUCCESS);
4357 void SNL_FEI_Structure::addCR(
int CRID,
4361 std::map<GlobalID,snl_fei::Constraint<GlobalID>* >::iterator
4362 cr_iter = crDB.find(CRID);
4364 if (cr_iter == crDB.end()) {
int sortedListInsert(const T &item, std::vector< T > &list)
int translateMatToReducedEqns(fei::CSRMat &mat)
int getFieldSize(int fieldID)
const int * getFieldIDsPtr()
int Allgatherv(MPI_Comm comm, std::vector< T > &sendbuf, std::vector< int > &recvLengths, std::vector< T > &recvbuf)
int countLocalNodeDescriptors(int localRank)
std::vector< int > & getMasterFieldIDs()
int getBlockDescriptor_index(int index, BlockDescriptor *&block)
std::map< GlobalID, int > & getNodeIDs()
int getNodeWithNumber(int nodeNumber, const NodeDescriptor *&node) const
int addEqn(int eqnNumber, const double *coefs, const int *indices, int len, bool accumulate, bool create_indices_union=false)
SNL_FEI_Structure(MPI_Comm comm)
void multiply_CSRMat_CSRMat(const CSRMat &A, const CSRMat &B, CSRMat &C, bool storeResultZeros)
int getMasterEqnRHS(int slaveEqn, double &rhsValue)
int initNodeID(GlobalID nodeID)
int ptEqnToBlkEqn(int ptEqn)
std::vector< fei::CSVec * > & eqns()
int getMasterEqnCoefs(int slaveEqn, std::vector< double > *&masterCoefs)
int mirrorProcEqns(ProcEqns &inProcEqns, ProcEqns &outProcEqns)
void addEqn(int eqnNumber, int proc)
std::vector< int > rowNumbers
std::vector< int > & eqnNumbers()
void copySetToArray(const SET_TYPE &set_obj, int lenList, int *list)
bool getFieldEqnNumber(int fieldID, int &eqnNumber) const
void setEqnNumber(int eqn)
void setConstraintID(int id)
int getMasterEqnNumbers(int slaveEqn, std::vector< int > *&masterEqns)
std::vector< int > packedColumnIndices
std::vector< std::vector< double > * > * rhsCoefsPtr()
std::vector< int > rowOffsets
void setBlkEqnNumber(int blkEqn)
void addLocalEqn(int eqnNumber, int srcProc)
int ** fieldIDsTablePtr()
int binarySearch(const T &item, const T *list, int len)
int getNodeWithEqn(int eqnNumber, const NodeDescriptor *&node) const
int synchronize(int firstLocalNodeNumber, int firstLocalEqn, int localRank, MPI_Comm comm)
virtual ~SNL_FEI_Structure()
std::vector< std::vector< int > * > & procEqnNumbersPtr()
void getNodeAtIndex(int i, const NodeDescriptor *&node) const
int setBlkEqnSize(int blkEqn, int size)
void insert2(const T &item)
int translateToReducedEqns(EqnCommMgr &eqnCommMgr)
int getCoefAndRemoveIndex(int eqnNumber, int colIndex, double &coef)
bool isInLocalElement(int nodeNumber)
int setEqn(int ptEqn, int blkEqn)
const int * getNumFieldsPerNode(GlobalID blockID)
int eqnToBlkEqn(int eqn) const
int countLocalNodalEqns(int localRank)
int addEqns(EqnBuffer &inputEqns, bool accumulate)
bool translateToReducedEqn(int eqn, int &reducedEqn)
std::ostream & console_out()
int GlobalMax(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
int getOwnerProcForEqn(int eqn)
void setMaxBlkEqnSize(int sz)
void setIsPenalty(bool isPenaltyConstr)
void multiply_trans_CSRMat_CSRMat(const CSRMat &A, const CSRMat &B, CSRMat &C, bool storeResultZeros)
int getBlkEqnSize(int blkEqn)
int localProc(MPI_Comm comm)
int mirrorProcEqnLengths(ProcEqns &inProcEqns, ProcEqns &outProcEqns)
std::map< int, int > * getPtEqns()
int getBlkEqnNumber() const
std::vector< int > & getMasters()
void destroyValues(MAP_TYPE &map_obj)
int getNumNodeDescriptors() const
int translateFromReducedEqn(int reducedEqn)
int getNodeWithID(GlobalID nodeID, const NodeDescriptor *&node) const
int parameters(int numParams, const char *const *paramStrings)
void getElemBlockInfo(GlobalID blockID, int &interleaveStrategy, int &lumpingStrategy, int &numElemDOF, int &numElements, int &numNodesPerElem, int &numEqnsPerElem)
int searchList(const T &item, const T *list, int len)
int setNumNodesPerElement(int numNodes)
int numProcs(MPI_Comm comm)
int getIndexOfBlock(GlobalID blockID) const
const int *const * getFieldIDsTable(GlobalID blockID)
int getEqnNumber(int nodeNumber, int fieldID)
int initNodeIDs(GlobalID *nodeIDs, int numNodes)