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();
1265 int lastBlkRow = -1;
1267 for(
int jj=0; jj<numPtEqns; ++jj, ++pteq) {
1268 int ptEqn = (*pteq).first;
1269 int localPtEqn = ptEqn - reducedStartRow_;
1270 if (localPtEqn < 0 || localPtEqn >= numLocalReducedRows_)
continue;
1272 int rowLength = sysMatIndices_[localPtEqn].
size();
1279 if (blkRow == lastBlkRow)
continue;
1281 int localBlkRow = blkRow - localReducedBlkOffset_;
1282 if (localBlkRow < 0 || localBlkRow >= numLocalReducedEqnBlks_) {
1288 int* theseColIndices = ptColIndices[localPtEqn];
1290 for(
int colj=0; colj<rowLength; colj++) {
1291 int blkCol = blkEqnMapper_->
eqnToBlkEqn(theseColIndices[colj]);
1294 <<
"SNL_FEI_Structure::getMatrixStructure ERROR pt row "
1295 << ptEqn <<
", pt col "
1296 << ptColIndices[localPtEqn][colj]
1297 <<
" doesn't have a corresponding block" << FEI_ENDL;
1298 blkCol = blkEqnMapper_->
eqnToBlkEqn(theseColIndices[colj]);
1302 sysBlkIndices.
insert2(blkCol);
1305 lastBlkRow = blkRow;
1310 numPtRowsPerBlkRow.resize(numLocalReducedEqnBlks_);
1311 blkRowLengths.resize(numLocalReducedEqnBlks_);
1313 for(
int i=0; i<numLocalReducedEqnBlks_; i++) {
1314 blkRowLengths[i] = sysBlkMatIndices_[i].
size();
1316 &(blkIndices_1D[offset]));
1317 offset += blkRowLengths[i];
1319 int blkEqn = localReducedBlkOffset_ + i;
1320 numPtRowsPerBlkRow[i] = blkEqnMapper_->
getBlkEqnSize(blkEqn);
1328 bool SNL_FEI_Structure::nodalEqnsAllSlaves(
const NodeDescriptor* node,
1329 std::vector<int>& slaveEqns)
1331 int numFields = node->getNumFields();
1332 const int* fieldIDs = node->getFieldIDList();
1333 const int* fieldEqns= node->getFieldEqnNumbers();
1335 for(
int i=0; i<numFields; ++i) {
1337 for(
int eqn=0; eqn<fieldSize; ++eqn) {
1338 int thisEqn = fieldEqns[i] + eqn;
1350 NodeDescriptor& SNL_FEI_Structure::findNodeDescriptor(GlobalID nodeID)
1359 fei::console_out() <<
"ERROR, findNodeDescriptor unable to find node " << (int)nodeID
1376 int SNL_FEI_Structure::initMultCRStructure()
1378 FEI_OSTREAM& os = dbgOut();
1379 if (debugOutput_) os <<
"# initMultCRStructure" << FEI_ENDL;
1392 std::map<GlobalID,ConstraintType*>::const_iterator
1393 cr_iter = multCRs_.begin(),
1394 cr_end = multCRs_.end();
1396 while(cr_iter != cr_end) {
1401 std::vector<GlobalID>& CRNode_vec = multCR.
getMasters();
1402 GlobalID *CRNodePtr = &CRNode_vec[0];
1404 int* CRFieldPtr = &CRField_vec[0];
1407 int reducedCrEqn = 0;
1410 createMatrixPosition(reducedCrEqn, reducedCrEqn,
"initMCRStr");
1412 for(
int j=0; j<lenList; j++) {
1413 GlobalID nodeID = CRNodePtr[j];
1414 int fieldID = CRFieldPtr[j];
1417 if(nodePtr==NULL)
continue;
1423 storeNodalColumnIndices(crEqn, node, fieldID);
1428 if (node.getOwnerProc() == localProc_) {
1432 storeNodalRowIndices(node, fieldID, crEqn);
1440 storeNodalSendIndex(node, fieldID, crEqn);
1445 return(FEI_SUCCESS);
1449 int SNL_FEI_Structure::initPenCRStructure()
1451 FEI_OSTREAM& os = dbgOut();
1452 if (debugOutput_) os <<
"# initPenCRStructure" << FEI_ENDL;
1476 std::map<GlobalID,ConstraintType*>::const_iterator
1477 cr_iter = penCRs_.begin(),
1478 cr_end = penCRs_.end();
1480 while(cr_iter != cr_end) {
1484 std::vector<GlobalID>& CRNode_vec = penCR.
getMasters();
1485 GlobalID* CRNodesPtr = &CRNode_vec[0];
1488 int* CRFieldPtr = &CRField_vec[0];
1493 for(
int i = 0; i < lenList; i++) {
1494 GlobalID iNodeID = CRNodesPtr[i];
1495 int iField = CRFieldPtr[i];
1498 if(!iNodePtr)
continue;
1501 for(
int j = 0; j < lenList; j++) {
1502 GlobalID jNodeID = CRNodesPtr[j];
1503 int jField = CRFieldPtr[j];
1506 if(!jNodePtr)
continue;
1509 if (iNode.getOwnerProc() == localProc_) {
1513 storeLocalNodeIndices(iNode, iField, jNode, jField);
1519 storeNodalSendIndices(iNode, iField, jNode, jField);
1525 return(FEI_SUCCESS);
1529 void SNL_FEI_Structure::storeNodalSendIndex(
NodeDescriptor& node,
int fieldID,
1540 int proc = node.getOwnerProc();
1547 fei::console_out() <<
"FEI error, attempt to store indices for field ("<<fieldID
1548 <<
") with size "<<numEqns<<FEI_ENDL;
1552 for(
int i=0; i<numEqns; i++) {
1553 eqnCommMgr_->addRemoteIndices(eqnNumber+i, proc, &col, 1);
1558 void SNL_FEI_Structure::storeNodalSendIndices(
NodeDescriptor& iNode,
int iField,
1565 int proc = iNode.getOwnerProc();
1567 int iEqn = -1, jEqn = -1;
1573 if (iNumParams < 1 || jNumParams < 1) {
1574 fei::console_out() <<
"FEI ERROR, attempt to store indices for field with non-positive size"
1575 <<
" field "<<iField<<
", size "<<iNumParams<<
", field "<<jField<<
", size "
1576 << jNumParams<<FEI_ENDL;
1580 for(
int i=0; i<iNumParams; i++) {
1583 for(
int j=0; j<jNumParams; j++) {
1585 eqnCommMgr_->addRemoteIndices(eqn, proc, &col, 1);
1591 void SNL_FEI_Structure::storeLocalNodeIndices(
NodeDescriptor& iNode,
int iField,
1599 int iEqn = -1, jEqn = -1;
1605 if (iNumParams < 1 || jNumParams < 1) {
1606 fei::console_out() <<
"FEI ERROR, attempt to store indices for field with non-positive size"
1607 <<
" field "<<iField<<
", size "<<iNumParams<<
", field "<<jField<<
", size "
1608 << jNumParams<<FEI_ENDL;
1612 for(
int i=0; i<iNumParams; i++) {
1614 int reducedRow = -1;
1616 if (isSlave)
continue;
1618 for(
int j=0; j<jNumParams; j++) {
1620 int reducedCol = -1;
1622 if (isSlave)
continue;
1624 createMatrixPosition(reducedRow, reducedCol,
1631 void SNL_FEI_Structure::storeNodalColumnIndices(
int eqn,
NodeDescriptor& node,
1638 if ((localStartRow_ > eqn) || (eqn > localEndRow_)) {
1646 if (numParams < 1) {
1647 fei::console_out() <<
"FEI error, attempt to store indices for field ("<<fieldID
1648 <<
") with size "<<numParams<<FEI_ENDL;
1652 int reducedEqn = -1;
1654 if (isSlave)
return;
1656 for(
int j=0; j<numParams; j++) {
1657 int reducedCol = -1;
1659 if (isSlave)
continue;
1661 createMatrixPosition(reducedEqn, reducedCol,
1667 void SNL_FEI_Structure::storeNodalRowIndices(
NodeDescriptor& node,
1668 int fieldID,
int eqn)
1678 if (numParams < 1) {
1679 fei::console_out() <<
"FEI error, attempt to store indices for field ("<<fieldID
1680 <<
") with size "<<numParams<<FEI_ENDL;
1684 int reducedEqn = -1;
1686 if (isSlave)
return;
1688 for(
int j=0; j<numParams; j++) {
1689 int reducedRow = -1;
1691 if (isSlave)
continue;
1693 createMatrixPosition(reducedRow, reducedEqn,
"storeNdRowInd");
1698 int SNL_FEI_Structure::createSymmEqnStructure(std::vector<int>& scatterIndices)
1706 if (numSlaveEquations() == 0) {
1707 CHK_ERR( storeElementScatterIndices_noSlaves(scatterIndices) );
1708 return(FEI_SUCCESS);
1713 int len = scatterIndices.size();
1714 bool anySlaves =
false;
1715 rSlave_.resize(len);
1716 for(
int is=0; is<len; is++) {
1717 rSlave_[is] =
isSlaveEqn(scatterIndices[is]) ? 1 : 0;
1718 if (rSlave_[is] == 1) anySlaves =
true;
1724 CHK_ERR( storeElementScatterIndices(scatterIndices) );
1725 return(FEI_SUCCESS);
1728 int* scatterPtr = &scatterIndices[0];
1730 workSpace_.resize(len);
1731 for(
int j=0; j<len; j++) {
1735 for(
int i=0; i<len; i++) {
1736 int row = scatterPtr[i];
1737 if (rSlave_[i] == 1) {
1738 reducedEqnCounter_++;
1743 for(
int jj=0; jj<len; jj++) {
1744 int col = scatterPtr[jj];
1746 if (rSlave_[jj] == 1) {
1748 for(
int ii=0; ii<len; ii++) {
1749 int rowi = scatterPtr[ii];
1752 if (rSlave_[ii] == 1)
continue;
1754 Kid_->createPosition(rowi, col);
1760 Kdi_->createPosition(row, col);
1764 for(
int kk=0; kk<len; kk++) {
1765 int colk = scatterPtr[kk];
1767 if (rSlave_[kk] != 1)
continue;
1769 Kdd_->createPosition(row, colk);
1775 int reducedRow = -1;
1778 bool rowIsLocal =
true;
1779 int owner = localProc_;
1780 if (reducedStartRow_ > reducedRow || reducedEndRow_ < reducedRow) {
1785 for(
int j=0; j<len; j++) {
1786 if (rSlave_[j] == 1)
continue;
1788 int reducedCol = workSpace_[j];
1791 CHK_ERR( createMatrixPosition(reducedRow, reducedCol,
1795 eqnCommMgr_->addRemoteIndices(reducedRow, owner, &reducedCol, 1);
1801 if (reducedEqnCounter_ > 300) CHK_ERR( assembleReducedStructure() );
1804 catch(std::runtime_error& exc) {
1809 return(FEI_SUCCESS);
1813 int SNL_FEI_Structure::createBlkSymmEqnStructure(std::vector<int>& scatterIndices)
1821 if (numSlaveEquations() == 0) {
1822 return( storeElementScatterBlkIndices_noSlaves(scatterIndices) );
1827 int len = scatterIndices.size();
1828 bool anySlaves =
false;
1829 rSlave_.resize(len);
1830 for(
int is=0; is<len; is++) {
1831 rSlave_[is] =
isSlaveEqn(scatterIndices[is]) ? 1 : 0;
1832 if (rSlave_[is] == 1) anySlaves =
true;
1838 CHK_ERR( storeElementScatterIndices(scatterIndices) );
1839 return(FEI_SUCCESS);
1842 int* scatterPtr = &scatterIndices[0];
1844 workSpace_.resize(len);
1845 for(
int j=0; j<len; j++) {
1849 for(
int i=0; i<len; i++) {
1850 int row = scatterPtr[i];
1851 if (rSlave_[i] == 1) {
1852 reducedEqnCounter_++;
1857 for(
int jj=0; jj<len; jj++) {
1858 int col = scatterPtr[jj];
1860 if (rSlave_[jj] == 1) {
1862 for(
int ii=0; ii<len; ii++) {
1863 int rowi = scatterPtr[ii];
1866 if (rSlave_[ii] == 1)
continue;
1868 Kid_->createPosition(rowi, col);
1874 Kdi_->createPosition(row, col);
1878 for(
int kk=0; kk<len; kk++) {
1879 int colk = scatterPtr[kk];
1881 if (rSlave_[kk] != 1)
continue;
1883 Kdd_->createPosition(row, colk);
1889 int reducedRow = -1;
1892 bool rowIsLocal =
true;
1893 int owner = localProc_;
1894 if (reducedStartRow_ > reducedRow || reducedEndRow_ < reducedRow) {
1899 for(
int j=0; j<len; j++) {
1900 if (rSlave_[j] == 1)
continue;
1902 int reducedCol = workSpace_[j];
1905 CHK_ERR( createMatrixPosition(reducedRow, reducedCol,
1909 eqnCommMgr_->addRemoteIndices(reducedRow, owner, &reducedCol, 1);
1915 if (reducedEqnCounter_ > 300) CHK_ERR( assembleReducedStructure() );
1918 catch(std::runtime_error& exc) {
1923 return(FEI_SUCCESS);
1927 int SNL_FEI_Structure::storeElementScatterIndices(std::vector<int>& indices)
1935 int numIndices = indices.size();
1936 int* indPtr = &indices[0];
1938 workSpace_.resize(numIndices);
1939 int* workPtr = &workSpace_[0];
1940 int reducedEqn = -1;
1941 for(
size_t j=0; j<indices.size(); j++) {
1943 if (isSlave) ERReturn(-1);
1944 workPtr[j] = reducedEqn;
1947 for(
int i=0; i<numIndices; i++) {
1948 int row = indPtr[i];
1949 int rrow = workPtr[i];
1951 if ((localStartRow_ > row) || (row > localEndRow_)) {
1954 eqnCommMgr_->addRemoteIndices(rrow, owner, workPtr, numIndices);
1958 CHK_ERR( createMatrixPositions(rrow, numIndices, workPtr,
1959 "storeElemScttrInd") );
1962 return(FEI_SUCCESS);
1966 int SNL_FEI_Structure::storeElementScatterIndices_noSlaves(std::vector<int>& indices)
1974 int i, numIndices = indices.size();
1975 int* indPtr = &indices[0];
1977 for(i=0; i<numIndices; i++) {
1978 int row = indPtr[i];
1979 if (row < localStartRow_ || row > localEndRow_) {
1981 eqnCommMgr_->addRemoteIndices(row, owner, indPtr, numIndices);
1985 if (generateGraph_) {
1987 sysMatIndices_[row - reducedStartRow_];
1989 for(
int j=0; j<numIndices; ++j) {
1990 if (debugOutput_ && outputLevel_ > 2) {
1991 dbgOut() <<
"# storeElemScttrInds_ns crtMatPoss("
1992 << row <<
"," << indPtr[j] <<
")"<<FEI_ENDL;
2000 return(FEI_SUCCESS);
2004 int SNL_FEI_Structure::storeElementScatterBlkIndices_noSlaves(std::vector<int>& indices)
2012 int i, numIndices = indices.size();
2013 int* indPtr = &indices[0];
2015 for(i=0; i<numIndices; i++) {
2016 int row = indPtr[i];
2017 if (row < localStartRow_ || row > localEndRow_) {
2019 eqnCommMgr_->addRemoteIndices(row, owner, indPtr, numIndices);
2023 if (generateGraph_) {
2025 sysMatIndices_[row - reducedStartRow_];
2027 for(
int j=0; j<numIndices; ++j) {
2028 if (debugOutput_ && outputLevel_ > 2) {
2029 dbgOut() <<
"# storeElemScttrInds_ns crtMatPoss("
2030 << row <<
"," << indPtr[j] <<
")"<<FEI_ENDL;
2038 return(FEI_SUCCESS);
2042 int SNL_FEI_Structure::assembleReducedStructure()
2050 fei::FillableMat* D = getSlaveDependencies();
2065 if (numProcs_ > 1) {
2066 CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat1_,
true) );
2067 CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat2_,
true) );
2070 CHK_ERR( createMatrixPositions(tmpMat1_) );
2071 CHK_ERR( createMatrixPositions(tmpMat2_) );
2081 if (numProcs_ > 1) {
2082 CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat2_,
true) );
2084 CHK_ERR( createMatrixPositions(tmpMat2_) );
2089 reducedEqnCounter_ = 0;
2091 return(FEI_SUCCESS);
2097 if (numSlvs_ < 1)
return(0);
2112 std::vector<fei::CSVec*>& eqnArray = eqnBuf.
eqns();
2113 for(
int i=0; i<numEqns; ++i) {
2116 eqnNumbers[i] = reducedEqn;
2118 int* indicesPtr = &(eqnArray[i]->indices()[0]);
2119 int numIndices = eqnArray[i]->size();
2120 for(
int j=0; j<numIndices; ++j) {
2122 indicesPtr[j] = reducedEqn;
2133 int dim1 = eqnTable.size();
2134 for(
int i=0; i<dim1; ++i) {
2135 int dim2 = eqnTable[i]->size();
2136 int* indicesPtr = &(*(eqnTable[i]))[0];
2137 for(
int j=0; j<dim2; ++j) {
2140 indicesPtr[j] = reducedEqn;
2155 int reducedEqn = -1;
2160 std::vector<int>& rowNumbers = srg.
rowNumbers;
2161 for(
size_t i=0; i<rowNumbers.size(); ++i) {
2163 if (isSlave) foundSlave = 1;
2164 else rowNumbers[i] = reducedEqn;
2168 for(
size_t i=0; i<colIndices.size(); ++i) {
2170 if (isSlave) foundSlave = 1;
2171 else colIndices[i] = reducedEqn;
2178 int SNL_FEI_Structure::createMatrixPositions(
fei::CSRMat& mat)
2180 if (!generateGraph_) {
2191 const std::vector<int>& rowNumbers = mat.getGraph().
rowNumbers;
2192 const std::vector<int>& rowOffsets = mat.getGraph().
rowOffsets;
2195 for(
size_t i=0; i<rowNumbers.size(); ++i) {
2196 int row = rowNumbers[i];
2197 int offset = rowOffsets[i];
2198 int rowlen = rowOffsets[i+1]-offset;
2199 const int* indices = &pckColInds[offset];
2201 for(
int j=0; j<rowlen; j++) {
2202 CHK_ERR( createMatrixPosition(row, indices[j],
"crtMatPos(CSRMat)") );
2210 int SNL_FEI_Structure::createMatrixPosition(
int row,
int col,
2211 const char* callingFunction)
2213 if (!generateGraph_) {
2227 if (row < reducedStartRow_ || row > reducedEndRow_) {
2229 dbgOut() <<
" " << callingFunction <<
" passed " <<row<<
","<<col
2230 <<
", not local." << FEI_ENDL;
2236 if (debugOutput_ && outputLevel_ > 2) {
2237 dbgOut() <<
"# " << callingFunction <<
" crtMatPos("
2238 << row <<
"," << col <<
")"<<FEI_ENDL;
2249 int SNL_FEI_Structure::createMatrixPositions(
int row,
int numCols,
int* cols,
2250 const char* callingFunction)
2252 if (!generateGraph_) {
2266 if (row < reducedStartRow_ || row > reducedEndRow_) {
2268 dbgOut() <<
" " << callingFunction <<
" passed " <<row
2269 <<
", not local." << FEI_ENDL;
2277 for(
int i=0; i<numCols; i++) {
2278 if (debugOutput_ && outputLevel_ > 2) {
2279 dbgOut() <<
"# " << callingFunction <<
" crtMatPoss("
2280 << row <<
"," << cols[i] <<
")"<<FEI_ENDL;
2290 int SNL_FEI_Structure::initializeBlkEqnMapper()
2298 if (blkEqnMapper_ != NULL)
delete blkEqnMapper_;
2304 int numFields = fieldDatabase_->size();
2306 const int* fieldSizes = fieldIDs+numFields;
2307 int numNonNegativeFields = 0;
2308 int maxFieldSize = 0;
2309 for(
int f=0; f<numFields; f++) {
2310 if (fieldIDs[f] >= 0) {
2311 numNonNegativeFields++;
2312 if (fieldSizes[f] > maxFieldSize) maxFieldSize = fieldSizes[f];
2316 if (numNonNegativeFields == 1 && maxFieldSize == 1) {
2317 globalMaxBlkSize_ = 1;
2322 int localVanishedNodeAdjustment = 0;
2323 for(
int i=0; i<localProc_; ++i) {
2324 localVanishedNodeAdjustment += globalNumNodesVanished_[i];
2327 int eqnNumber, blkEqnNumber;
2329 std::map<GlobalID,int>& nodeIDmap = nodeDatabase_->
getNodeIDs();
2330 std::map<GlobalID,int>::iterator
2331 iter = nodeIDmap.begin(), iter_end = nodeIDmap.end();
2333 for(; iter!=iter_end; ++iter) {
2338 if (node==NULL)
continue;
2341 int numFields = node->getNumFields();
2342 if(numFields == 0)
continue;
2344 int firstPtEqn = node->getFieldEqnNumbers()[0];
2345 int numNodalDOF = node->getNumNodalDOF();
2346 blkEqnNumber = node->getBlkEqnNumber() - localVanishedNodeAdjustment;
2348 int blkSize = numNodalDOF;
2350 for(
int j=0; j<numNodalDOF; ++j) {
2356 CHK_ERR( blkEqnMapper.
setEqn(eqnNumber, blkEqnNumber) );
2361 CHK_ERR( blkEqnMapper.
setBlkEqnSize(blkEqnNumber, blkSize) );
2364 ++localVanishedNodeAdjustment;
2372 int numLocalNodes = globalNodeOffsets_[localProc_+1]-globalNodeOffsets_[localProc_];
2373 eqnNumber = localStartRow_ + numLocalNodalEqns_;
2374 blkEqnNumber = localBlkOffset_ + numLocalNodes;
2376 for(
int i = 0; i < numBlocks; i++) {
2380 int numElemDOF = block->getNumElemDOFPerElement();
2382 if (numElemDOF > 0) {
2383 int numElems = block->getNumElements();
2385 for(
int j=0; j<numElems; j++) {
2387 for(
int ede=0; ede<numElemDOF; ede++) {
2388 blkEqnMapper.
setEqn(eqnNumber+ede, blkEqnNumber+ede);
2392 eqnNumber += numElemDOF;
2393 blkEqnNumber += numElemDOF;
2402 std::map<GlobalID,ConstraintType*>::const_iterator
2403 cr_iter = multCRs_.begin(),
2404 cr_end = multCRs_.end();
2406 std::vector<int> localMultEqns;
2407 localMultEqns.reserve(multCRs_.size()*2);
2408 while(cr_iter != cr_end) {
2413 CHK_ERR( blkEqnMapper_->
setEqn(eqnNumber, blkEqnNumber) );
2416 localMultEqns.push_back(eqnNumber);
2417 localMultEqns.push_back(blkEqnNumber);
2427 globalMaxBlkSize_ = 0;
2428 CHK_ERR(
fei::GlobalMax(comm_, localMaxBlkEqnSize, globalMaxBlkSize_) );
2432 if (globalMaxBlkSize_ == 1) {
2439 if (numProcs_ > 1) {
2440 std::vector<int> recvLengths, globalMultEqns;
2441 CHK_ERR(
fei::Allgatherv(comm_, localMultEqns, recvLengths, globalMultEqns));
2444 for(
int p=0; p<numProcs_; p++) {
2445 if (p == localProc_) { offset += recvLengths[p];
continue; }
2447 for(
int j=0; j<recvLengths[p]/2; j++) {
2448 blkEqnMapper_->
setEqn(globalMultEqns[offset], globalMultEqns[offset+1]);
2459 int SNL_FEI_Structure::setMultCREqnInfo()
2465 std::map<GlobalID,ConstraintType*>::const_iterator
2466 cr_iter = multCRs_.begin(),
2467 cr_end = multCRs_.end();
2469 int eqnNumber = localStartRow_ + numLocalNodalEqns_ + numLocalElemDOF_;
2470 int blkEqnNum = localBlkOffset_ + numLocalEqnBlks_ - numLocalMultCRs_;
2472 while(cr_iter != cr_end) {
2488 int SNL_FEI_Structure::writeEqn2NodeMap()
2490 FEI_OSTRINGSTREAM osstr;
2491 osstr << dbgPath_ <<
"/FEI" << name_ <<
"_nID_nNum_blkEq_ptEq."
2492 << numProcs_ <<
"." << localProc_;
2494 FEI_OFSTREAM e2nFile(osstr.str().c_str());
2497 fei::console_out() <<
"SNL_FEI_Structure::writeEqn2NodeMap: ERROR, couldn't open file "
2498 << osstr.str() << FEI_ENDL;
2502 std::map<GlobalID,ConstraintType*>::const_iterator
2503 cr_iter = multCRs_.begin(),
2504 cr_end = multCRs_.end();
2506 while(cr_iter != cr_end) {
2511 e2nFile <<
"-999 -999 " << blkEqnNumber <<
" " << eqnNumber << FEI_ENDL;
2515 std::map<GlobalID,int>& nodeIDmap = nodeDatabase_->
getNodeIDs();
2516 std::map<GlobalID,int>::iterator
2517 iter = nodeIDmap.begin(), iter_end = nodeIDmap.end();
2519 for(; iter!=iter_end; ++iter) {
2523 if (node==NULL || node->getOwnerProc() != localProc_) {
2527 const int* fieldIDList = node->getFieldIDList();
2528 const int* eqnNumbers = node->getFieldEqnNumbers();
2529 int nodeNum = node->getNodeNumber();
2530 int blkEqnNumber = node->getBlkEqnNumber();
2531 int numFields = node->getNumFields();
2533 for(
int j=0; j<numFields; j++) {
2535 assert( numFieldParams > 0 );
2537 for(
int k=0; k<numFieldParams; k++) {
2538 e2nFile << (int)node->getGlobalNodeID() <<
" " << nodeNum
2539 <<
" " << blkEqnNumber <<
" " << eqnNumbers[j]+k<<FEI_ENDL;
2544 return(FEI_SUCCESS);
2548 int SNL_FEI_Structure::calcTotalNumElemDOF()
2551 int totalNumElemDOF = 0;
2553 for(
int i = 0; i < numBlocks; i++) {
2556 int numElemDOF = block->getNumElemDOFPerElement();
2557 if (numElemDOF > 0) {
2558 int numElems = block->getNumElements();
2560 totalNumElemDOF += numElems*numElemDOF;
2564 return(totalNumElemDOF);
2568 int SNL_FEI_Structure::calcNumMultCREqns()
2570 int totalNumMultCRs = 0;
2571 int numMCRecords = getNumMultConstRecords();
2573 totalNumMultCRs = numMCRecords;
2575 return( totalNumMultCRs );
2579 void SNL_FEI_Structure::calcGlobalEqnInfo(
int numLocallyOwnedNodes,
2581 int numLocalEqnBlks)
2583 FEI_OSTREAM& os = dbgOut();
2584 if (debugOutput_) os <<
"# entering calcGlobalEqnInfo" << FEI_ENDL;
2595 std::vector<int> numProcNodes(numProcs_);
2596 std::vector<int> numProcEqns(numProcs_);
2597 std::vector<int> numProcEqnBlks(numProcs_);
2599 if (numProcs_ > 1) {
2602 std::vector<int> recvList(3*numProcs_);
2604 glist[0] = numLocallyOwnedNodes;
2605 glist[1] = numLocalEqns;
2606 glist[2] = numLocalEqnBlks;
2607 if (MPI_Gather(&glist[0], 3, MPI_INT, &recvList[0], 3,
2608 MPI_INT, masterProc_, comm_) != MPI_SUCCESS) {
2609 fei::console_out() <<
"SNL_FEI_Structure::calcGlobalEqnInfo: ERROR in MPI_Gather" << FEI_ENDL;
2610 MPI_Abort(comm_, -1);
2613 for(
int p=0; p<numProcs_; p++) {
2614 numProcNodes[p] = recvList[p*3];
2615 numProcEqns[p] = recvList[p*3+1];
2616 numProcEqnBlks[p] = recvList[p*3+2];
2621 numProcNodes[0] = numLocallyOwnedNodes;
2622 numProcEqns[0] = numLocalEqns;
2623 numProcEqnBlks[0] = numLocalEqnBlks;
2628 globalNodeOffsets_.resize(numProcs_+1);
2629 globalEqnOffsets_.resize(numProcs_+1);
2630 globalBlkEqnOffsets_.resize(numProcs_+1);
2632 globalNodeOffsets_[0] = 0;
2633 globalEqnOffsets_[0] = 0;
2634 globalBlkEqnOffsets_[0] = 0;
2636 if (localProc_ == masterProc_) {
2637 for(
int i=1;i<numProcs_;i++) {
2638 globalNodeOffsets_[i] = globalNodeOffsets_[i-1] +numProcNodes[i-1];
2639 globalEqnOffsets_[i] = globalEqnOffsets_[i-1] + numProcEqns[i-1];
2640 globalBlkEqnOffsets_[i] = globalBlkEqnOffsets_[i-1] +
2641 numProcEqnBlks[i-1];
2644 globalNodeOffsets_[numProcs_] = globalNodeOffsets_[numProcs_-1] +
2645 numProcNodes[numProcs_-1];
2646 globalEqnOffsets_[numProcs_] = globalEqnOffsets_[numProcs_-1] +
2647 numProcEqns[numProcs_-1];
2648 globalBlkEqnOffsets_[numProcs_] = globalBlkEqnOffsets_[numProcs_-1] +
2649 numProcEqnBlks[numProcs_-1];
2654 if (numProcs_ > 1) {
2656 std::vector<int> blist(3*(numProcs_+1));
2658 if (localProc_ == masterProc_) {
2660 for(
int i=0; i<numProcs_+1; i++) {
2661 blist[offset++] = globalNodeOffsets_[i];
2662 blist[offset++] = globalEqnOffsets_[i];
2663 blist[offset++] = globalBlkEqnOffsets_[i];
2667 if (MPI_Bcast(&blist[0], 3*(numProcs_+1), MPI_INT,
2668 masterProc_, comm_) != MPI_SUCCESS) {
2669 fei::console_out() <<
"SNL_FEI_Structure::calcGlobalEqnInfo: ERROR in MPI_Bcast" << FEI_ENDL;
2670 MPI_Abort(comm_, -1);
2673 if (localProc_ != masterProc_) {
2675 for(
int i=0; i<numProcs_+1; i++) {
2676 globalNodeOffsets_[i] = blist[offset++];
2677 globalEqnOffsets_[i] = blist[offset++];
2678 globalBlkEqnOffsets_[i] = blist[offset++];
2684 localStartRow_ = globalEqnOffsets_[localProc_];
2685 localEndRow_ = globalEqnOffsets_[localProc_+1]-1;
2686 numGlobalEqns_ = globalEqnOffsets_[numProcs_];
2688 firstLocalNodeNumber_ = globalNodeOffsets_[localProc_];
2689 numGlobalNodes_ = globalNodeOffsets_[numProcs_];
2691 localBlkOffset_ = globalBlkEqnOffsets_[localProc_];
2692 numGlobalEqnBlks_ = globalBlkEqnOffsets_[numProcs_];
2695 os <<
"# localStartRow_: " << localStartRow_ << FEI_ENDL;
2696 os <<
"# localEndRow_: " << localEndRow_ << FEI_ENDL;
2697 os <<
"# numGlobalEqns_: " << numGlobalEqns_ << FEI_ENDL;
2698 os <<
"# numGlobalEqnBlks_: " << numGlobalEqnBlks_ << FEI_ENDL;
2699 os <<
"# localBlkOffset_: " << localBlkOffset_ << FEI_ENDL;
2700 os <<
"# firstLocalNodeNumber_: " << firstLocalNodeNumber_ << FEI_ENDL;
2702 os <<
"# numGlobalNodes_: " << numGlobalNodes_ << FEI_ENDL;
2703 os <<
"# " << globalNodeOffsets_.size() <<
" globalNodeOffsets_: ";
2704 for(
size_t nn=0; nn<globalNodeOffsets_.size(); nn++)
2705 os << globalNodeOffsets_[nn] <<
" ";
2707 os <<
"# " << globalEqnOffsets_.size() <<
" globalEqnOffsets_: ";
2708 for(n=0; n<globalEqnOffsets_.size(); n++)
2709 os << globalEqnOffsets_[n] <<
" ";
2711 os <<
"# " << globalBlkEqnOffsets_.size() <<
" globalBlkEqnOffsets_: ";
2712 for(n=0; n<globalBlkEqnOffsets_.size(); n++)
2713 os << globalBlkEqnOffsets_[n] <<
" ";
2715 os <<
"# leaving calcGlobalEqnInfo" << FEI_ENDL;
2720 int SNL_FEI_Structure::setNodalEqnInfo()
2730 int eqn = localStartRow_;
2733 int blkEqnNumber = localBlkOffset_;
2735 std::map<GlobalID,int>& nodeIDmap = nodeDatabase_->
getNodeIDs();
2736 std::map<GlobalID,int>::iterator
2737 iter = nodeIDmap.begin(), iter_end = nodeIDmap.end();
2739 for(; iter!=iter_end; ++iter) {
2743 if (node==NULL)
continue;
2745 int numFields = node->getNumFields();
2746 const int* fieldIDs = node->getFieldIDList();
2748 if (node->getOwnerProc() == localProc_) {
2749 int numNodalDOF = 0;
2751 for(
int j=0; j<numFields; j++) {
2752 node->setFieldEqnNumber(fieldIDs[j], eqn);
2755 numNodalDOF += fieldSize;
2758 node->setNumNodalDOF(numNodalDOF);
2759 node->setBlkEqnNumber(blkEqnNumber++);
2767 void SNL_FEI_Structure::setElemDOFEqnInfo()
2777 int eqnNumber = localStartRow_ + numLocalNodalEqns_;
2779 for(
int i = 0; i < numBlocks; i++) {
2782 if (err) voidERReturn;
2784 int numElemDOF = block->getNumElemDOFPerElement();
2786 if (numElemDOF > 0) {
2787 std::vector<int>& elemDOFEqns = block->elemDOFEqnNumbers();
2788 std::map<GlobalID,int>& elemIDs = connTables_[i]->elemIDs;
2790 std::map<GlobalID,int>::const_iterator
2791 iter = elemIDs.begin(),
2792 iter_end = elemIDs.end();
2794 for(; iter != iter_end; ++iter) {
2795 elemDOFEqns[iter->second] = eqnNumber;
2797 eqnNumber += numElemDOF;
2804 int SNL_FEI_Structure::addBlock(GlobalID blockID) {
2810 int insertPoint = -1;
2814 blockIDs_.insert(blockIDs_.begin()+insertPoint, blockID);
2817 block->setGlobalBlockID(blockID);
2819 blocks_.insert(blocks_.begin()+insertPoint, block);
2822 connTables_.insert(connTables_.begin()+insertPoint, newConnTable);
2825 return(FEI_SUCCESS);
2829 int SNL_FEI_Structure::getBlockDescriptor(GlobalID blockID,
2835 fei::console_out() <<
"SNL_FEI_Structure::getBlockDescriptor: ERROR, blockID "
2836 << (int)blockID <<
" not found." << FEI_ENDL;
2840 block = blocks_[index];
2842 return(FEI_SUCCESS);
2856 if (index < 0 || index >= (
int)blockIDs_.size()) ERReturn(FEI_FATAL_ERROR);
2858 block = blocks_[index];
2860 return(FEI_SUCCESS);
2864 int SNL_FEI_Structure::allocateBlockConnectivity(GlobalID blockID) {
2869 fei::console_out() <<
"SNL_FEI_Structure::allocateConnectivityTable: ERROR, blockID "
2870 << (int)blockID <<
" not found. Aborting." << FEI_ENDL;
2871 MPI_Abort(comm_, -1);
2874 connTables_[index]->numNodesPerElem =
2875 blocks_[index]->getNumNodesPerElement();
2877 int numRows = blocks_[index]->getNumElements();
2878 int numCols = connTables_[index]->numNodesPerElem;
2880 if ((numRows <= 0) || (numCols <= 0)) {
2881 fei::console_out() <<
"SNL_FEI_Structure::allocateConnectivityTable: ERROR, either "
2882 <<
"numElems or numNodesPerElem not yet set for blockID "
2883 << (int)blockID <<
". Aborting." << FEI_ENDL;
2884 MPI_Abort(comm_, -1);
2887 connTables_[index]->elemNumbers.resize(numRows);
2889 connTables_[index]->elem_conn_ids =
new std::vector<GlobalID>(numRows*numCols);
2891 return(FEI_SUCCESS);
2900 fei::console_out() <<
"SNL_FEI_Structure::getBlockConnectivity: ERROR, blockID "
2901 << (int)blockID <<
" not found. Aborting." << FEI_ENDL;
2902 MPI_Abort(comm_, -1);
2905 return(*(connTables_[index]));
2909 int SNL_FEI_Structure::finalizeActiveNodes()
2911 FEI_OSTREAM& os = dbgOut();
2913 os <<
"# finalizeActiveNodes" << FEI_ENDL;
2918 std::vector<GlobalID>& shNodeIDs = nodeCommMgr_->getSharedNodeIDs();
2919 for(
unsigned i=0; i<shNodeIDs.size(); i++) {
2920 CHK_ERR( nodeDatabase_->
initNodeID(shNodeIDs[i]) );
2923 if (activeNodesInitialized_)
return(0);
2935 int numBlocks = blockIDs_.size();
2936 for(
int bIndex=0; bIndex<numBlocks; bIndex++) {
2938 GlobalID blockID = blocks_[bIndex]->getGlobalBlockID();
2941 GlobalID* elemConn = NULL;
2944 int numElems = conn.elemIDs.size();
2946 elemConn = &((*conn.elem_conn_ids)[0]);
2947 if (!activeNodesInitialized_) {
2948 int elemConnLen = conn.elem_conn_ids->size();
2949 conn.elem_conn_ptrs =
new std::vector<NodeDescriptor*>(elemConnLen);
2951 elemNodeDescPtrs = &((*conn.elem_conn_ptrs)[0]);
2953 int nodesPerElem = conn.numNodesPerElem;
2955 int* fieldsPerNodePtr = blocks_[bIndex]->fieldsPerNodePtr();
2956 int** fieldIDsTablePtr = blocks_[bIndex]->fieldIDsTablePtr();
2969 conn.elemNumbers.resize(numElems);
2971 int numDistinctFields = blocks_[bIndex]->getNumDistinctFields();
2972 int fieldID = fieldIDsTablePtr[0][0];
2975 for(elem=0; elem<numElems; elem++) {
2976 conn.elemNumbers[elem] = elemNumber++;
2977 GlobalID* elemNodes = &(elemConn[elem*nodesPerElem]);
2978 NodeDescriptor** elemNodePtrs = &(elemNodeDescPtrs[elem*nodesPerElem]);
2980 for(
int n=0; n<nodesPerElem; n++) {
2982 int index = nodeDatabase_->
getNodeWithID( elemNodes[n], node );
2984 fei::console_out() <<
"ERROR in SNL_FEI_Structure::initializeActiveNodes, "
2985 << FEI_ENDL <<
"failed to find node "
2986 << (int)(elemNodes[n]) << FEI_ENDL;
2989 if (numDistinctFields == 1) {
2990 node->addField(fieldID);
2993 for(
int i=0; i<fieldsPerNodePtr[n]; i++) {
2994 node->addField(fieldIDsTablePtr[n][i]);
3000 node->addBlockIndex(blk_idx);
3004 elemNodePtrs[n] = node;
3006 node->setOwnerProc(localProc_);
3007 if (numProcs_ > 1) nodeCommMgr_->informLocal(*node);
3017 if (numProcs_ > 1) {
3018 std::map<GlobalID,ConstraintType*>::const_iterator
3019 cr_iter = getPenConstRecords().begin(),
3020 cr_end = getPenConstRecords().end();
3022 while(cr_iter != cr_end) {
3024 std::vector<GlobalID>& nodeID_vec = cr.
getMasters();
3025 GlobalID* nodeIDs = &nodeID_vec[0];
3029 for(
int k=0; k<numNodes; ++k) {
3032 nodeCommMgr_->informLocal(*node);
3041 activeNodesInitialized_ =
true;
3043 if (debugOutput_) os <<
"# leaving finalizeActiveNodes" << FEI_ENDL;
3044 return(FEI_SUCCESS);
3048 int SNL_FEI_Structure::finalizeNodeCommMgr()
3055 bool safetyCheck = checkSharedNodes_;
3057 if (safetyCheck && localProc_==0 && numProcs_>1 && outputLevel_>0) {
3058 FEI_COUT <<
"FEI Info: A consistency-check of shared-node data will be "
3059 <<
"performed, which involves all-to-all communication. This check is "
3060 <<
"done only if explicitly requested by parameter "
3061 <<
"'FEI_CHECK_SHARED_IDS'."<<FEI_ENDL;
3064 CHK_ERR( nodeCommMgr_->initComplete(*nodeDatabase_, safetyCheck) );
3067 FEI_OSTREAM& os = dbgOut();
3068 int numSharedNodes = nodeCommMgr_->getNumSharedNodes();
3069 os <<
"# numSharedNodes: " << numSharedNodes << FEI_ENDL;
3070 for(
int ns=0; ns<numSharedNodes; ns++) {
3072 GlobalID nodeID = node.getGlobalNodeID();
3073 int proc = node.getOwnerProc();
3074 os <<
"# shNodeID " << (int)nodeID <<
", owned by proc "<<proc<<FEI_ENDL;
3082 int SNL_FEI_Structure::setNumNodesAndEqnsPerBlock()
3087 int numBlocks = blockIDs_.size();
3088 std::vector<int> nodesPerBlock(numBlocks);
3089 std::vector<int> eqnsPerBlock(numBlocks);
3092 for(j=0; j<numBlocks; j++) {
3093 nodesPerBlock[j] = 0;
3094 eqnsPerBlock[j] = 0;
3099 for(j=0; j<numNodes; j++) {
3102 if (node==NULL)
continue;
3104 const int* fieldIDList = node->getFieldIDList();
3106 int numFields = node->getNumFields();
3108 const std::vector<unsigned>& blkIndices = node->getBlockIndexList();
3109 for(std::vector<unsigned>::const_iterator b=blkIndices.begin(), bend=blkIndices.end();
3111 nodesPerBlock[*b]++;
3113 for(
int fld=0; fld<numFields; fld++) {
3114 if (blocks_[*b]->containsField(fieldIDList[fld])) {
3117 eqnsPerBlock[*b] += fSize;
3123 for(j=0; j<numBlocks; j++) {
3124 blocks_[j]->setNumActiveNodes(nodesPerBlock[j]);
3130 for(j=0; j<numBlocks; j++) {
3131 eqnsPerBlock[j] += blocks_[j]->getNumElemDOFPerElement() *
3132 blocks_[j]->getNumElements();
3134 blocks_[j]->setTotalNumEqns(eqnsPerBlock[j]);
3140 void SNL_FEI_Structure::initializeEqnCommMgr()
3142 FEI_OSTREAM& os = dbgOut();
3143 if (debugOutput_) os <<
"# initializeEqnCommMgr" << FEI_ENDL;
3153 int numSharedNodes = nodeCommMgr_->getNumSharedNodes();
3155 for(
int i=0; i<numSharedNodes; i++) {
3158 int numFields = node.getNumFields();
3159 const int* nodeFieldIDList = node.getFieldIDList();
3160 const int* nodeEqnNums = node.getFieldEqnNumbers();
3162 int owner = node.getOwnerProc();
3163 if (owner == localProc_) {
3164 std::vector<int>& proc = nodeCommMgr_->getSharedNodeProcs(i);
3167 for(
int p=0; p<numProcs; p++) {
3169 if (proc[p] == localProc_)
continue;
3171 for(
int j=0; j<numFields; j++) {
3173 assert(numEqns >= 0);
3176 for(eqn=0; eqn<numEqns; eqn++) {
3177 int reducedEqn = -1;
3180 if (isSlave)
continue;
3188 for(
int j=0; j<numFields; j++) {
3190 assert(numEqns >= 0);
3191 for(
int eqn=0; eqn<numEqns; eqn++) {
3192 int reducedEqn = -1;
3194 if (isSlave)
continue;
3196 eqnCommMgr_->addRemoteIndices(reducedEqn, owner, NULL, 0);
3202 if (debugOutput_) os <<
"# leaving initializeEqnCommMgr" << FEI_ENDL;
3206 void SNL_FEI_Structure::getEqnInfo(
int& numGlobalEqns,
int& numLocalEqns,
3207 int& localStartRow,
int& localEndRow){
3209 numGlobalEqns = numGlobalEqns_;
3210 numLocalEqns = numLocalEqns_;
3211 localStartRow = localStartRow_;
3212 localEndRow = localEndRow_;
3216 int SNL_FEI_Structure::getEqnNumbers(GlobalID ID,
3217 int idType,
int fieldID,
3218 int& numEqns,
int* eqnNumbers)
3221 if (idType != FEI_NODE) ERReturn(-1);
3227 if (numEqns < 0) ERReturn(-1);
3229 int nodeFieldEqnNumber = -1;
3234 for(
int i=0; i<numEqns; i++) eqnNumbers[i] = nodeFieldEqnNumber + i;
3236 return(FEI_SUCCESS);
3240 int SNL_FEI_Structure::getEqnNumbers(
int numIDs,
3241 const GlobalID* IDs,
3242 int idType,
int fieldID,
3243 int& numEqns,
int* eqnNumbers)
3246 if (idType != FEI_NODE) ERReturn(-1);
3249 if (fieldSize < 0) {
3254 for(
int i=0; i<numIDs; ++i) {
3259 for(
int ii=0; ii<fieldSize; ii++) {
3260 eqnNumbers[offset++] = -1;
3266 int nodeFieldEqnNumber = -1;
3272 for(
int ii=0; ii<fieldSize; ii++) {
3273 eqnNumbers[offset++] = -1;
3278 for(
int ii=0; ii<fieldSize; ii++) {
3279 eqnNumbers[offset++] = nodeFieldEqnNumber + ii;
3284 numEqns = fieldSize*numIDs;
3286 return(FEI_SUCCESS);
3290 int SNL_FEI_Structure::translateToReducedNodeNumber(
int nodeNumber,
int proc)
3292 if (proc != localProc_) {
3293 return(nodeNumber - globalNumNodesVanished_[proc]);
3296 int insertPoint = -1;
3300 int localAdjustment = index < 0 ? insertPoint : index + 1;
3302 return(nodeNumber - localAdjustment - globalNumNodesVanished_[proc]);
3306 void SNL_FEI_Structure::getEqnBlkInfo(
int& numGlobalEqnBlks,
3307 int& numLocalEqnBlks,
3308 int& localBlkOffset) {
3310 numGlobalEqnBlks = numGlobalEqnBlks_;
3311 numLocalEqnBlks = numLocalEqnBlks_;
3312 localBlkOffset = localBlkOffset_;
3316 int SNL_FEI_Structure::calculateSlaveEqns(MPI_Comm comm)
3318 FEI_OSTREAM& os = dbgOut();
3319 if (debugOutput_) os <<
"# calculateSlaveEqns" << FEI_ENDL;
3321 if (eqnCommMgr_ != NULL)
delete eqnCommMgr_;
3323 eqnCommMgr_->setNumRHSs(1);
3325 std::vector<int> eqns;
3326 std::vector<int> mEqns;
3327 std::vector<double> mCoefs;
3329 for(
size_t i=0; i<slaveVars_->size(); i++) {
3334 CHK_ERR( getEqnNumbers(svar->getNodeID(), FEI_NODE, svar->getFieldID(),
3335 numEqns, &eqns[0]));
3337 int slaveEqn = eqns[svar->getFieldOffset()];
3339 const std::vector<GlobalID>* mNodes = svar->getMasterNodeIDs();
3340 const std::vector<int>* mFields = svar->getMasterFields();
3341 const std::vector<double>* mWeights = svar->getWeights();
3342 const std::vector<double>& mWeightsRef = *mWeights;
3345 for(
size_t j=0; j<mNodes->size(); j++) {
3348 eqns.resize(mfSize);
3349 GlobalID mNodeID = (*mNodes)[j];
3350 int mFieldID = (*mFields)[j];
3351 CHK_ERR( getEqnNumbers( mNodeID, FEI_NODE, mFieldID,
3354 double fei_eps = 1.e-49;
3356 for(
int k=0; k<mfSize; k++) {
3357 if (std::abs(mWeightsRef[mwOffset++]) > fei_eps) {
3358 mEqns.push_back(eqns[k]);
3359 mCoefs.push_back(mWeightsRef[mwOffset-1]);
3364 CHK_ERR( slaveEqns_->
addEqn(slaveEqn, &mCoefs[0], &mEqns[0],
3365 mEqns.size(),
false) );
3371 int numLocalSlaves = slaveVars_->size();
3372 int globalMaxSlaves = 0;
3373 CHK_ERR(
fei::GlobalMax(comm_, numLocalSlaves, globalMaxSlaves) );
3375 if (globalMaxSlaves > 0) {
3376 CHK_ERR( gatherSlaveEqns(comm, eqnCommMgr_, slaveEqns_) );
3380 globalNumNodesVanished_.resize(numProcs_+1, 0);
3382 slvEqnNumbers_ = &(slaveEqns_->
eqnNumbers());
3383 numSlvs_ = slvEqnNumbers_->size();
3390 os <<
"# slave-equations:" << FEI_ENDL;
3392 os <<
"# leaving calculateSlaveEqns" << FEI_ENDL;
3395 int levelsOfCoupling;
3396 CHK_ERR( removeCouplings(*slaveEqns_, levelsOfCoupling) );
3399 os <<
"# SNL_FEI_Structure: " << levelsOfCoupling
3400 <<
" level(s) of coupling removed: " << FEI_ENDL;
3403 lowestSlv_ = (*slvEqnNumbers_)[0];
3404 highestSlv_ = (*slvEqnNumbers_)[numSlvs_-1];
3419 std::vector<int>& slvEqns = *slvEqnNumbers_;
3420 std::vector<fei::CSVec*>& mstrEqns = slaveEqns_->
eqns();
3424 int numLocalNodesVanished = 0;
3426 GlobalID lastNodeID = -1;
3428 for(
int i=0; i<numSlvs_; i++) {
3430 int reducedSlaveEqn;
3432 int numMasters = mstrEqns[i]->size();
3437 os <<
"# no local node for slave eqn " << slvEqns[i] << FEI_ENDL;
3443 if (node->getGlobalNodeID() != lastNodeID &&
3444 node->getOwnerProc() == localProc_) {
3445 if (nodalEqnsAllSlaves(node, slvEqns)) {
3446 numLocalNodesVanished++;
3452 lastNodeID = node->getGlobalNodeID();
3455 GlobalID slvNodeID = node->getGlobalNodeID();
3456 int shIndex = nodeCommMgr_->getSharedNodeIndex(slvNodeID);
3461 std::vector<int>& sharingProcs = nodeCommMgr_->getSharedNodeProcs(shIndex);
3463 for(
int j=0; j<numMasters; j++) {
3464 int masterEquation = mstrEqns[i]->indices()[j];
3467 int reducedMasterEqn;
3470 if (owner == localProc_) {
3471 int numSharing = sharingProcs.size();
3472 for(
int sp=0; sp<numSharing; sp++) {
3473 if (sharingProcs[sp] == localProc_)
continue;
3476 os <<
"# slave node " << (int)slvNodeID <<
",eqn "<<slvEqns[i]
3477 <<
", master eqn " << masterEquation <<
" eqnCommMgr_->addLocal "
3478 << reducedMasterEqn <<
", proc " << sharingProcs[sp] << FEI_ENDL;
3480 eqnCommMgr_->
addLocalEqn(reducedMasterEqn, sharingProcs[sp]);
3481 slvCommMgr_->addRemoteIndices(reducedSlaveEqn, sharingProcs[sp],
3482 &reducedMasterEqn, 1);
3487 os <<
"# slave node " << (int)slvNodeID <<
",eqn "<<slvEqns[i]
3488 <<
", master eqn " << masterEquation <<
" eqnCommMgr_->addRemote "
3489 << reducedMasterEqn <<
", proc " << owner << FEI_ENDL;
3491 eqnCommMgr_->addRemoteIndices(reducedMasterEqn, owner,
3492 &reducedMasterEqn, 1);
3498 std::vector<int> tmp(1), tmp2(numProcs_);
3499 tmp[0] = numLocalNodesVanished;
3500 CHK_ERR(
fei::Allgatherv(comm_, tmp, tmp2, globalNumNodesVanished_) );
3502 if ((
int)globalNumNodesVanished_.size() != numProcs_) {
3506 globalNumNodesVanished_.resize(numProcs_+1);
3507 int tmpNumVanished = 0;
3508 for(
int proc=0; proc<numProcs_; ++proc) {
3509 int temporary = tmpNumVanished;
3510 tmpNumVanished += globalNumNodesVanished_[proc];
3511 globalNumNodesVanished_[proc] = temporary;
3513 globalNumNodesVanished_[numProcs_] = tmpNumVanished;
3516 if (slaveMatrix_ != NULL)
delete slaveMatrix_;
3517 slaveMatrix_ =
new fei::FillableMat(*slaveEqns_);
3520 os <<
"# slave-equations:" << FEI_ENDL;
3522 os <<
"# leaving calculateSlaveEqns" << FEI_ENDL;
3529 int SNL_FEI_Structure::removeCouplings(
EqnBuffer& eqnbuf,
int& levelsOfCoupling)
3531 std::vector<int>& eqnNumbers = eqnbuf.
eqnNumbers();
3532 std::vector<fei::CSVec*>& eqns = eqnbuf.
eqns();
3534 std::vector<double> tempCoefs;
3535 std::vector<int> tempIndices;
3537 levelsOfCoupling = 0;
3538 bool finished =
false;
3540 bool foundCoupling =
false;
3541 for(
size_t i=0; i<eqnNumbers.size(); i++) {
3544 if (rowIndex == (
int)i) {
3546 <<
" illegal master-slave constraint coupling. Eqn "
3547 << eqnNumbers[i] <<
" is both master and slave. " << FEI_ENDL;
3551 while(rowIndex >= 0) {
3552 foundCoupling =
true;
3555 eqnNumbers[i], coef) );
3557 std::vector<int>& indicesRef = eqns[i]->indices();
3558 std::vector<double>& coefsRef = eqns[i]->coefs();
3560 int len = indicesRef.size();
3561 tempCoefs.resize(len);
3562 tempIndices.resize(len);
3564 double* tempCoefsPtr = &tempCoefs[0];
3565 int* tempIndicesPtr = &tempIndices[0];
3566 double* coefsPtr = &coefsRef[0];
3567 int* indicesPtr = &indicesRef[0];
3569 for(
int j=0; j<len; ++j) {
3570 tempIndicesPtr[j] = indicesPtr[j];
3571 tempCoefsPtr[j] = coef*coefsPtr[j];
3574 CHK_ERR( eqnbuf.
addEqn(eqnNumbers[rowIndex], tempCoefsPtr,
3575 tempIndicesPtr, len,
true) );
3580 if (foundCoupling) ++levelsOfCoupling;
3581 else finished =
true;
3583 if (levelsOfCoupling>1 && !finished) {
3585 <<
" too many (>1) levels of master-slave constraint coupling. "
3586 <<
"Hint: coupling is considered infinite if two slaves depend on "
3587 <<
"each other. This may or may not be the case here." << FEI_ENDL;
3597 int SNL_FEI_Structure::gatherSlaveEqns(MPI_Comm comm,
3602 if (MPI_Comm_size(comm, &numProcs) != MPI_SUCCESS)
return(-1);
3603 if (numProcs == 1)
return(0);
3605 if (MPI_Comm_rank(comm, &localProc) != MPI_SUCCESS)
return(-1);
3611 ProcEqns localProcEqns, remoteProcEqns;
3612 std::vector<int>& slvEqnNums = slaveEqns->
eqnNumbers();
3614 if (slaveEqns->
eqns().size() > 0) slvEqnsPtr = &(slaveEqns->
eqns()[0]);
3616 for(
size_t i=0; i<slvEqnNums.size(); i++) {
3617 for(
int p=0; p<numProcs; p++) {
3618 if (p == localProc)
continue;
3620 localProcEqns.
addEqn(slvEqnNums[i], slvEqnsPtr[i]->size(), p);
3624 CHK_ERR( eqnCommMgr->
mirrorProcEqns(localProcEqns, remoteProcEqns) );
3630 CHK_ERR( EqnCommMgr::exchangeEqnBuffers(comm, &localProcEqns, slaveEqns,
3631 &remoteProcEqns, &remoteEqns,
3636 CHK_ERR( slaveEqns->
addEqns(remoteEqns,
false) );
3645 if (numSlvs_ == 0)
return(
false);
3647 std::vector<int>& slvEqns = slaveEqns_->
eqnNumbers();
3648 int insertPoint = -1;
3651 if (foundOffset >= 0)
return(
true);
3658 if (numSlvs_ == 0) { reducedEqn = eqn;
return(
false); }
3660 if (eqn < lowestSlv_) {reducedEqn = eqn;
return(
false); }
3661 if (eqn > highestSlv_) {reducedEqn = eqn - numSlvs_;
return(
false); }
3666 bool isSlave =
false;
3668 if (foundOffset < 0) {
3669 reducedEqn = eqn - index;
3672 isSlave =
true; reducedEqn = eqn - (foundOffset+1);
3683 if (numSlvs == 0)
return(reducedEqn);
3685 const int* slvEqns = &(slaveEqns_->
eqnNumbers()[0]);
3687 if (reducedEqn < slvEqns[0])
return(reducedEqn);
3689 int eqn = reducedEqn;
3691 for(
int i=0; i<numSlvs; i++) {
3692 if (eqn < slvEqns[i])
return(eqn);
3701 std::vector<int>*& masterEqns)
3708 std::vector<int>& slvEqns = slaveEqns_->
eqnNumbers();
3712 if (foundOffset >= 0) {
3713 masterEqns = &(slaveEqns_->
eqns()[foundOffset]->indices());
3724 std::vector<double>*& masterCoefs)
3731 std::vector<int>& slvEqns = slaveEqns_->
eqnNumbers();
3735 if (foundOffset >= 0) {
3736 masterCoefs = &(slaveEqns_->
eqns()[foundOffset]->coefs());
3753 std::vector<int>& slvEqns = slaveEqns_->
eqnNumbers();
3757 if (foundOffset >= 0) {
3758 std::vector<double>* rhsCoefsPtr = (*(slaveEqns_->
rhsCoefsPtr()))[foundOffset];
3759 rhsValue = (*rhsCoefsPtr)[0];
3766 void SNL_FEI_Structure::getScatterIndices_ID(GlobalID blockID, GlobalID elemID,
3767 int interleaveStrategy,
3768 int* scatterIndices)
3773 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_ID: ERROR, blockID "
3774 << (int)blockID <<
" not found. Aborting." << FEI_ENDL;
3778 std::map<GlobalID,int>& elemIDs = connTables_[index]->elemIDs;
3780 std::map<GlobalID,int>::const_iterator
3781 iter = elemIDs.find(elemID);
3783 if (iter == elemIDs.end()) {
3784 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_ID: ERROR, blockID: "
3785 << (int)blockID <<
", elemID "
3786 << (
int)elemID <<
" not found. Aborting." << FEI_ENDL;
3790 int elemIndex = iter->second;
3792 getScatterIndices_index(index, elemIndex,
3793 interleaveStrategy, scatterIndices);
3797 void SNL_FEI_Structure::getScatterIndices_ID(GlobalID blockID, GlobalID elemID,
3798 int interleaveStrategy,
3799 int* scatterIndices,
3800 int* blkScatterIndices,
3806 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_ID: ERROR, blockID "
3807 << (int)blockID <<
" not found. Aborting." << FEI_ENDL;
3811 std::map<GlobalID,int>& elemIDs = connTables_[index]->elemIDs;
3813 std::map<GlobalID,int>::const_iterator
3814 iter = elemIDs.find(elemID);
3816 if (iter == elemIDs.end()) {
3817 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_ID: ERROR, blockID: "
3818 << (int)blockID <<
", elemID "
3819 << (
int)elemID <<
" not found. Aborting." << FEI_ENDL;
3823 int elemIndex = iter->second;
3825 getScatterIndices_index(index, elemIndex,
3826 interleaveStrategy, scatterIndices,
3827 blkScatterIndices, blkSizes);
3831 int SNL_FEI_Structure::getBlkScatterIndices_index(
int blockIndex,
3833 int* scatterIndices)
3836 int numNodes = block.getNumNodesPerElement();
3837 work_nodePtrs_.resize(numNodes);
3839 int err = getElemNodeDescriptors(blockIndex, elemIndex, nodes);
3841 fei::console_out() <<
"SNL_FEI_Structure::getBlkScatterIndices_index: ERROR getting"
3842 <<
" node descriptors." << FEI_ENDL;
3847 return( getNodeBlkIndices(nodes, numNodes, scatterIndices, offset) );
3851 void SNL_FEI_Structure::getScatterIndices_index(
int blockIndex,
int elemIndex,
3852 int interleaveStrategy,
3853 int* scatterIndices)
3859 int numNodes = block.getNumNodesPerElement();
3860 int* fieldsPerNode = block.fieldsPerNodePtr();
3863 work_nodePtrs_.resize(numNodes);
3866 int err = getElemNodeDescriptors(blockIndex, elemIndex, nodes);
3868 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_index: ERROR getting"
3869 <<
" node descriptors." << FEI_ENDL;
3874 if (fieldDatabase_->size() == 1) {
3875 err = getNodeIndices_simple(nodes, numNodes, fieldIDs[0][0],
3876 scatterIndices, offset);
3877 if (err)
fei::console_out() <<
"ERROR in getNodeIndices_simple." << FEI_ENDL;
3880 switch (interleaveStrategy) {
3882 err = getNodeMajorIndices(nodes, numNodes, fieldIDs, fieldsPerNode,
3883 scatterIndices, offset);
3884 if (err)
fei::console_out() <<
"ERROR in getNodeMajorIndices." << FEI_ENDL;
3888 err = getFieldMajorIndices(nodes, numNodes, fieldIDs, fieldsPerNode,
3889 scatterIndices, offset);
3890 if (err)
fei::console_out() <<
"ERROR in getFieldMajorIndices." << FEI_ENDL;
3894 fei::console_out() <<
"ERROR, unrecognized interleaveStrategy." << FEI_ENDL;
3900 int numElemDOF = blocks_[blockIndex]->getNumElemDOFPerElement();
3901 std::vector<int>& elemDOFEqns = blocks_[blockIndex]->elemDOFEqnNumbers();
3903 for(
int i=0; i<numElemDOF; i++) {
3904 scatterIndices[offset++] = elemDOFEqns[elemIndex] + i;
3909 void SNL_FEI_Structure::getScatterIndices_index(
int blockIndex,
int elemIndex,
3910 int interleaveStrategy,
3911 int* scatterIndices,
3912 int* blkScatterIndices,
3919 int numNodes = block.getNumNodesPerElement();
3920 int* fieldsPerNode = block.fieldsPerNodePtr();
3923 work_nodePtrs_.resize(numNodes);
3926 int err = getElemNodeDescriptors(blockIndex, elemIndex, nodes);
3928 fei::console_out() <<
"SNL_FEI_Structure::getScatterIndices_index: ERROR getting"
3929 <<
" node descriptors." << FEI_ENDL;
3933 int offset = 0, blkOffset = 0;
3934 if (fieldDatabase_->size() == 1) {
3935 err = getNodeIndices_simple(nodes, numNodes, fieldIDs[0][0],
3936 scatterIndices, offset,
3937 blkScatterIndices, blkSizes, blkOffset);
3938 if (err)
fei::console_out() <<
"ERROR in getNodeIndices_simple." << FEI_ENDL;
3941 switch (interleaveStrategy) {
3943 err = getNodeMajorIndices(nodes, numNodes, fieldIDs, fieldsPerNode,
3944 scatterIndices, offset,
3945 blkScatterIndices, blkSizes, blkOffset);
3946 if (err)
fei::console_out() <<
"ERROR in getNodeMajorIndices." << FEI_ENDL;
3950 err = getFieldMajorIndices(nodes, numNodes, fieldIDs, fieldsPerNode,
3951 scatterIndices, offset);
3952 if (err)
fei::console_out() <<
"ERROR in getFieldMajorIndices." << FEI_ENDL;
3956 fei::console_out() <<
"ERROR, unrecognized interleaveStrategy." << FEI_ENDL;
3962 int numElemDOF = blocks_[blockIndex]->getNumElemDOFPerElement();
3963 std::vector<int>& elemDOFEqns = blocks_[blockIndex]->elemDOFEqnNumbers();
3965 for(
int i=0; i<numElemDOF; i++) {
3966 scatterIndices[offset++] = elemDOFEqns[elemIndex] + i;
3967 if (interleaveStrategy == 0) {
3968 blkSizes[blkOffset] = 1;
3969 blkScatterIndices[blkOffset++] = elemDOFEqns[elemIndex] + i;
3975 int SNL_FEI_Structure::getElemNodeDescriptors(
int blockIndex,
int elemIndex,
3984 int numNodes = connTables_[blockIndex]->numNodesPerElem;
3986 if (activeNodesInitialized_) {
3988 &((*connTables_[blockIndex]->elem_conn_ptrs)[elemIndex*numNodes]);
3989 for(
int i=0; i<numNodes; ++i) nodes[i] = elemNodePtrs[i];
3992 const GlobalID* elemConn =
3993 &((*connTables_[blockIndex]->elem_conn_ids)[elemIndex*numNodes]);
3994 for(
int i=0; i<numNodes; ++i) {
3995 CHK_ERR( nodeDatabase_->
getNodeWithID(elemConn[i], nodes[i]));
3999 return(FEI_SUCCESS);
4003 int SNL_FEI_Structure::getNodeIndices_simple(
NodeDescriptor** nodes,
4006 int* scatterIndices,
4011 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4013 const int* eqnNumbers = node.getFieldEqnNumbers();
4014 int eqn = eqnNumbers[0];
4015 scatterIndices[offset++] = eqn;
4016 if (fieldSize > 1) {
4017 for(
int i=1; i<fieldSize; i++) {
4018 scatterIndices[offset++] = eqn+i;
4026 int SNL_FEI_Structure::getNodeIndices_simple(
NodeDescriptor** nodes,
4029 int* scatterIndices,
4031 int* blkScatterIndices,
4037 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4039 const int* eqnNumbers = node.getFieldEqnNumbers();
4040 int eqn = eqnNumbers[0];
4041 scatterIndices[offset++] = eqn;
4042 if (fieldSize > 1) {
4043 for(
int i=1; i<fieldSize; i++) {
4044 scatterIndices[offset++] = eqn+i;
4047 blkSizes[blkOffset] = node.getNumNodalDOF();
4048 blkScatterIndices[blkOffset++] = node.getBlkEqnNumber();
4054 int SNL_FEI_Structure::getNodeMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4055 int** fieldIDs,
int* fieldsPerNode,
4056 int* scatterIndices,
int& offset)
4058 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4062 const int* nodeFieldIDList = node.getFieldIDList();
4063 const int* nodeEqnNums = node.getFieldEqnNumbers();
4064 int numFields = node.getNumFields();
4066 int* fieldID_ind = fieldIDs[nodeIndex];
4068 for(
int j=0; j<fieldsPerNode[nodeIndex]; j++) {
4070 assert(numEqns >= 0);
4077 int eqn = nodeEqnNums[nind];
4080 FEI_COUT <<
"SNL_FEI_Structure::getNodeMajorIndices: ERROR, node "
4081 << (int)node.getGlobalNodeID()
4082 <<
", field " << nodeFieldIDList[nind]
4083 <<
" has equation number " << eqn << FEI_ENDL;
4087 for(
int jj=0; jj<numEqns; jj++) {
4088 scatterIndices[offset++] = eqn+jj;
4092 if (outputLevel_ > 2) {
4094 <<
" not found for node "
4095 << (int)(node.getGlobalNodeID()) << FEI_ENDL;
4101 return(FEI_SUCCESS);
4107 int* scatterIndices,
4110 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4112 scatterIndices[offset++] = node->getBlkEqnNumber();
4118 int SNL_FEI_Structure::getNodeMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4119 int** fieldIDs,
int* fieldsPerNode,
4120 int* scatterIndices,
int& offset,
4121 int* blkScatterIndices,
4125 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4129 const int* nodeFieldIDList = node.getFieldIDList();
4130 const int* nodeEqnNums = node.getFieldEqnNumbers();
4131 int numFields = node.getNumFields();
4133 blkSizes[blkOffset] = node.getNumNodalDOF();
4134 blkScatterIndices[blkOffset++] = node.getBlkEqnNumber();
4136 int* fieldID_ind = fieldIDs[nodeIndex];
4138 for(
int j=0; j<fieldsPerNode[nodeIndex]; j++) {
4140 assert(numEqns >= 0);
4147 int eqn = nodeEqnNums[nind];
4149 FEI_COUT <<
"SNL_FEI_Structure::getNodeMajorIndices: ERROR, node "
4150 << (int)node.getGlobalNodeID()
4151 <<
", field " << nodeFieldIDList[nind]
4152 <<
" has equation number " << eqn << FEI_ENDL;
4156 for(
int jj=0; jj<numEqns; jj++) {
4157 scatterIndices[offset++] = eqn+jj;
4161 if (outputLevel_ > 2) {
4163 <<
" not found for node "
4164 << (int)(node.getGlobalNodeID()) << FEI_ENDL;
4170 return(FEI_SUCCESS);
4174 int SNL_FEI_Structure::getNodeMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4175 std::vector<int>* fieldIDs,
4176 std::vector<int>& fieldsPerNode,
4177 std::vector<int>& scatterIndices)
4180 scatterIndices.resize(0);
4182 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4186 const int* nodeFieldIDList = node.getFieldIDList();
4187 const int* nodeEqnNums = node.getFieldEqnNumbers();
4188 int numFields = node.getNumFields();
4190 int* fieldID_ind = &(fieldIDs[nodeIndex][0]);
4192 for(
int j=0; j<fieldsPerNode[nodeIndex]; j++) {
4194 assert(numEqns >= 0);
4201 int eqn = nodeEqnNums[nind];
4204 FEI_COUT <<
"SNL_FEI_Structure::getNodeMajorIndices: ERROR, node "
4205 << (int)node.getGlobalNodeID()
4206 <<
", field " << nodeFieldIDList[nind]
4207 <<
" has equation number " << eqn << FEI_ENDL;
4208 MPI_Abort(comm_, -1);
4211 scatterIndices.resize(offset+numEqns);
4212 int* inds = &scatterIndices[0];
4214 for(
int jj=0; jj<numEqns; jj++) {
4215 inds[offset+jj] = eqn+jj;
4220 if (outputLevel_ > 2) {
4222 <<
" not found for node "
4223 << (int)node.getGlobalNodeID() << FEI_ENDL;
4229 return(FEI_SUCCESS);
4233 int SNL_FEI_Structure::getFieldMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4234 int** fieldIDs,
int* fieldsPerNode,
4235 int* scatterIndices,
int& offset)
4243 std::vector<int> fields;
4244 for(
int ii=0; ii<numNodes; ii++) {
4245 for(
int j=0; j<fieldsPerNode[ii]; j++) {
4246 if (std::find(fields.begin(), fields.end(), fieldIDs[ii][j]) == fields.end()) {
4247 fields.push_back(fieldIDs[ii][j]);
4252 int* fieldsPtr = fields.size()>0 ? &fields[0] : NULL;
4257 for(
size_t i=0; i<fields.size(); i++) {
4258 int field = fieldsPtr[i];
4260 for(
int nodeIndex = 0; nodeIndex < numNodes; ++nodeIndex) {
4262 fieldsPerNode[nodeIndex]);
4269 const int* nodeFieldIDList = node->getFieldIDList();
4270 const int* nodeEqnNums = node->getFieldEqnNumbers();
4271 int numFields = node->getNumFields();
4274 assert(numEqns >= 0);
4281 for(
int jj=0; jj<numEqns; ++jj) {
4282 scatterIndices[offset++] = nodeEqnNums[nind]+jj;
4291 return(FEI_SUCCESS);
4295 int SNL_FEI_Structure::getFieldMajorIndices(
NodeDescriptor** nodes,
int numNodes,
4296 std::vector<int>* fieldIDs,
4297 std::vector<int>& fieldsPerNode,
4298 std::vector<int>& scatterIndices)
4306 std::vector<int> fields;
4307 for(
int ii=0; ii<numNodes; ii++) {
4308 for(
int j=0; j<fieldsPerNode[ii]; j++) {
4309 std::vector<int>& fldIDs = fieldIDs[ii];
4310 if (std::find(fields.begin(), fields.end(), fldIDs[j]) == fields.end()) {
4311 fields.push_back(fldIDs[j]);
4320 scatterIndices.resize(0);
4322 for(
size_t i=0; i<fields.size(); i++) {
4323 for(
int nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
4325 const int* nodeFieldIDList = nodes[nodeIndex]->getFieldIDList();
4326 const int* nodeEqnNums = nodes[nodeIndex]->getFieldEqnNumbers();
4327 int numFields = nodes[nodeIndex]->getNumFields();
4330 assert(numEqns >= 0);
4337 for(
int jj=0; jj<numEqns; jj++) {
4338 scatterIndices.push_back(nodeEqnNums[nind]+jj);
4343 if (outputLevel_ > 2) {
4345 <<
" not found for node "
4346 << (int)nodes[nodeIndex]->getGlobalNodeID() << FEI_ENDL;
4352 return(FEI_SUCCESS);
4356 void SNL_FEI_Structure::addCR(
int CRID,
4360 std::map<GlobalID,snl_fei::Constraint<GlobalID>* >::iterator
4361 cr_iter = crDB.find(CRID);
4363 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)