9 #include <fei_sstream.hpp>
14 #include <fei_MatrixGraph_Impl2.hpp>
16 #include <fei_utils.hpp>
17 #include "fei_TemplateUtils.hpp"
19 #include <fei_Pattern.hpp>
20 #include <fei_LogManager.hpp>
21 #include <fei_TemplateUtils.hpp>
22 #include <fei_impl_utils.hpp>
23 #include <snl_fei_Utils.hpp>
24 #include <fei_FieldMask.hpp>
25 #include <fei_Record.hpp>
26 #include <snl_fei_RecordCollection.hpp>
27 #include <fei_VectorSpace.hpp>
28 #include <fei_ParameterSet.hpp>
29 #include <fei_ostream_ops.hpp>
30 #include <fei_Reducer.hpp>
31 #include <fei_GraphReducer.hpp>
32 #include <fei_ConnectivityBlock.hpp>
33 #include <snl_fei_BlkSizeMsgHandler.hpp>
34 #include <fei_Graph_Impl.hpp>
35 #include <snl_fei_Constraint.hpp>
37 #include <fei_EqnBuffer.hpp>
38 #include <fei_EqnCommMgr.hpp>
39 #include <SNL_FEI_Structure.hpp>
42 #define fei_file "fei_MatrixGraph.cpp"
44 #include <fei_ErrMacros.hpp>
47 static unsigned getFieldSize(
int fieldID,
51 unsigned fieldsize = 0;
52 bool foundfield =
false;
63 if (!foundfield && space2 != NULL) {
67 catch (std::runtime_error& exc) {
68 std::string msg(
"snl_fei::getFieldSize: ");
70 throw std::runtime_error(msg);
96 : comm_(rowSpace->getCommunicator()),
100 haveColSpace_(false),
102 remotelyOwnedGraphRows_(NULL),
103 simpleProblem_(false),
104 blockEntryGraph_(false),
106 connectivityBlocks_(),
107 arbitraryBlockCounter_(1),
109 lagrangeConstraints_(),
110 penaltyConstraints_(),
113 newSlaveData_(false),
121 dbgprefix_(
"MatGrph: "),
124 includeAllSlaveConstraints_(false)
129 if (rowSpace_.
get() == NULL) {
132 else haveRowSpace_ =
true;
134 if (colSpace_.
get() != NULL) haveColSpace_ =
true;
135 else colSpace_ = rowSpace_;
147 connectivityBlocks_.clear();
149 int i, len = sparseBlocks_.size();
150 for(i=0; i<len; ++i) {
151 delete sparseBlocks_[i];
155 lagrangeConstraints_.clear();
158 penaltyConstraints_.clear();
161 slaveConstraints_.clear();
170 param = params.
get(
"FEI_OUTPUT_LEVEL");
171 ptype = param != NULL ? param->
getType() : fei::Param::BAD_TYPE;
172 if (ptype == fei::Param::STRING) {
178 param = params.
get(
"FEI_LOG_EQN");
179 ptype = param != NULL ? param->
getType() : fei::Param::BAD_TYPE;
180 if (ptype == fei::Param::INT) {
184 param = params.
get(
"FEI_LOG_ID");
185 ptype = param != NULL ? param->
getType() : fei::Param::BAD_TYPE;
186 if (ptype == fei::Param::INT) {
190 param = params.
get(
"name");
191 ptype = param != NULL ? param->
getType() : fei::Param::BAD_TYPE;
192 if (ptype == fei::Param::STRING) {
196 param = params.
get(
"BLOCK_GRAPH");
197 ptype = param != NULL ? param->
getType() : fei::Param::BAD_TYPE;
198 if (ptype != fei::Param::BAD_TYPE) {
199 blockEntryGraph_ =
true;
202 param = params.
get(
"BLOCK_MATRIX");
203 ptype = param != NULL ? param->
getType() : fei::Param::BAD_TYPE;
204 if (ptype != fei::Param::BAD_TYPE) {
205 if (ptype == fei::Param::BOOL) {
209 blockEntryGraph_ =
true;
213 param = params.
get(
"INCLUDE_ALL_SLAVE_CONSTRAINTS");
214 ptype = param != NULL ? param->
getType() : fei::Param::BAD_TYPE;
215 if (ptype != fei::Param::BAD_TYPE) {
216 includeAllSlaveConstraints_ =
true;
224 rowSpace_ = rowSpace;
225 haveRowSpace_ =
true;
226 if (!haveColSpace_) symmetric_ =
true;
232 colSpace_ = colSpace;
233 haveColSpace_ =
true;
234 if (colSpace_ == rowSpace_) symmetric_ =
true;
235 else symmetric_ =
false;
239 int fei::MatrixGraph_Impl2::addPattern(
fei::Pattern* pattern)
241 std::map<int,fei::Pattern*>::iterator
242 p_iter = patterns_.begin(), p_iter_end = patterns_.end();
244 bool matches_existing_pattern =
false;
246 while(p_iter != p_iter_end && !matches_existing_pattern) {
247 if (*pattern == *(p_iter->second)) {
248 matches_existing_pattern =
true;
249 pattern_id = p_iter->first;
254 if (!matches_existing_pattern) {
255 pattern_id = patterns_.size();
256 patterns_.insert(std::make_pair(pattern_id, pattern));
270 rowSpace_->getRecordCollection(idType, rec_coll);
273 return addPattern(pattern);
281 unsigned fieldsize = 0;
283 fieldsize = snl_fei::getFieldSize(fieldID, rowSpace_.get(), colSpace_.get());
285 catch (std::runtime_error& exc) {
286 FEI_OSTRINGSTREAM osstr;
287 osstr <<
"fei::MatrixGraph_Impl2::definePattern caught error: "<<exc.what();
288 throw std::runtime_error(osstr.str());
292 rowSpace_->getRecordCollection(idType, rec_coll);
295 new fei::Pattern(numIDs, idType, rec_coll, fieldID, fieldsize);
296 return addPattern(pattern);
302 const int* numFieldsPerID,
305 std::vector<int> fieldSizes;
308 for(
int i=0; i<numIDs; ++i) {
309 for(
int j=0; j<numFieldsPerID[i]; ++j) {
310 fieldSizes.push_back(snl_fei::getFieldSize(fieldIDs[offset++],
311 rowSpace_.get(), colSpace_.get()));
315 catch (std::runtime_error& exc) {
316 FEI_OSTRINGSTREAM osstr;
317 osstr <<
"fei::MatrixGraph_Impl2::definePattern caught error: "<<exc.what();
318 throw std::runtime_error(osstr.str());
322 rowSpace_->getRecordCollection(idType, rec_coll);
325 numFieldsPerID, fieldIDs, &(fieldSizes[0]));
326 return addPattern(pattern);
332 const int* numFieldsPerID,
335 std::vector<int> fieldSizes;
338 for(
int i=0; i<numIDs; ++i) {
339 for(
int j=0; j<numFieldsPerID[i]; ++j) {
340 fieldSizes.push_back(snl_fei::getFieldSize(fieldIDs[offset++],
341 rowSpace_.get(), colSpace_.get()));
345 catch (std::runtime_error& exc) {
346 FEI_OSTRINGSTREAM osstr;
347 osstr <<
"fei::MatrixGraph_Impl2::definePattern caught error: "<<exc.what();
348 throw std::runtime_error(osstr.str());
351 std::vector<snl_fei::RecordCollection*> recordCollections(numIDs);
352 for(
int i=0; i<numIDs; ++i) {
353 rowSpace_->getRecordCollection(idTypes[i], recordCollections[i]);
357 numFieldsPerID, fieldIDs, &(fieldSizes[0]));
358 return addPattern(pattern);
364 std::map<int,fei::Pattern*>::iterator
365 p_iter = patterns_.find(patternID);
367 if (p_iter == patterns_.end()) {
377 int numConnectivityLists,
381 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
382 (*output_stream_) <<dbgprefix_<<
"initConnectivityBlock symm, blkID="
383 << blockID<<
", num="<<numConnectivityLists<<
", patternID="
384 <<patternID<<FEI_ENDL;
388 fei::console_out() <<
"fei::MatrixGraph_Impl2::initConnectivityBlock: blockID ("
389 << blockID <<
") must be non-negative." << FEI_ENDL;
393 std::map<int,fei::Pattern*>::iterator
394 p_iter = patterns_.find(patternID);
396 if (p_iter == patterns_.end()) {
402 if (getConnectivityBlock(blockID) != NULL) ERReturn(-1);
407 connectivityBlocks_.insert(std::pair<int,fei::ConnectivityBlock*>(blockID, cblock));
418 int blockID = connectivityBlocks_.size();
419 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
420 (*output_stream_) <<dbgprefix_<<
"initConnectivityBlock symm, blkID="
421 << blockID<<
", num="<<numConnectivityLists<<
", patternID="
422 <<patternID<<FEI_ENDL;
425 std::map<int,fei::Pattern*>::iterator
426 p_iter = patterns_.find(patternID);
428 if (p_iter == patterns_.end()) {
429 FEI_OSTRINGSTREAM osstr;
430 osstr <<
"fei::MatrixGraph_Impl2::initConnectivityBlock: ERROR, patternID "
431 << patternID <<
" not found.";
432 throw std::runtime_error(osstr.str());
440 connectivityBlocks_.insert(std::pair<int,fei::ConnectivityBlock*>(blockID, cblock));
448 int numConnectivityLists,
452 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
453 (*output_stream_) <<dbgprefix_<<
"initConnectivityBlock nonsymm, blkID="
454 << blockID<<
", num="<<numConnectivityLists<<
", row-patternID="
455 <<rowPatternID<<
", col-patternID="<<colPatternID<<FEI_ENDL;
459 FEI_OSTRINGSTREAM osstr;
460 osstr <<
"fei::MatrixGraph_Impl2::initConnectivityBlock: blockID ("
461 << blockID <<
") must be non-negative." << FEI_ENDL;
462 throw std::runtime_error(osstr.str());
465 std::map<int,fei::Pattern*>::iterator
466 rp_iter = patterns_.find(rowPatternID);
467 if (rp_iter == patterns_.end()) ERReturn(-1);
471 std::map<int,fei::Pattern*>::iterator
472 cp_iter = patterns_.find(colPatternID);
473 if (cp_iter == patterns_.end()) ERReturn(-1);
477 if (getConnectivityBlock(blockID) != NULL) ERReturn(-1);
481 colpattern, numConnectivityLists);
483 connectivityBlocks_.insert(std::pair<int,fei::ConnectivityBlock*>(blockID, cblock));
491 const int* connectedIdentifiers)
493 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
494 (*output_stream_) <<dbgprefix_<<
"initConnectivity blkID="
495 <<blockID<<
", connID="<<connectivityID<<FEI_ENDL;
504 if (connblk == NULL) {
505 FEI_OSTRINGSTREAM osstr;
506 osstr <<
"fei::MatrixGraph_Impl2::initConnectivity ERROR, blockID " << blockID
507 <<
" doesn't correspond to an existing ConnectivityBlock.";
508 throw std::runtime_error(osstr.str());
514 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
515 for(
int ii=0; ii<numIDs; ++ii) {
516 if (isLogID(connectedIdentifiers[ii])) {
517 FEI_OSTREAM& os = *output_stream_;
518 os << dbgprefix_<<
"initConnectivity blockID " << blockID <<
", connID "
519 << connectivityID <<
": ";
520 for(
int jj=0; jj<numIDs; ++jj) {
521 os << connectedIdentifiers[jj] <<
" ";
528 if (rowSpace_.get() == NULL) ERReturn(-1);
533 std::map<int,int>::iterator
534 iter = connectivityIDs.find(connectivityID);
535 if (iter == connectivityIDs.end()) {
536 idOffset = connectivityIDs.size();
537 connectivityIDs.insert(iter, std::make_pair(connectivityID,idOffset));
540 idOffset = iter->second;
547 CHK_ERR( getConnectivityRecords(pattern, rowSpace_.get(),
548 connectedIdentifiers, rlist) );
550 for(
int i=0; i<numIDs; ++i) {
563 const int* rowOffsets,
564 const int* packedColumnIDs)
570 for(
int i=0; i<numRows; ++i) {
571 int row_len = rowOffsets[i+1]-rowOffsets[i];
572 if (row_len > max_row_len) max_row_len = row_len;
575 int patternID = definePattern(max_row_len, idType);
577 block->setRowPattern(pattern);
579 sparseBlocks_.push_back(block);
583 CHK_ERR( getConnectivityRecords(rowSpace_.get(),
584 idType, numRows, rowIDs, row_records) );
587 if (colSpace_.get() != NULL) {
588 colSpace = colSpace_.get();
593 CHK_ERR( getConnectivityRecords(colSpace, idType, rowOffsets[numRows],
594 packedColumnIDs, col_records));
603 const int* rowLengths,
604 const int*
const* columnIDs)
607 rowIDs, rowLengths,
true);
610 for(
int i=0; i<numRows; ++i) {
611 int row_len = rowLengths[i];
612 if (row_len > max_row_len) max_row_len = row_len;
615 int patternID = definePattern(max_row_len, idType);
617 block->setRowPattern(pattern);
619 sparseBlocks_.push_back(block);
623 CHK_ERR( getConnectivityRecords(rowSpace_.get(),
624 idType, numRows, rowIDs, row_records) );
627 if (colSpace_.get() != NULL) {
628 colSpace = colSpace_.get();
634 for(
int i=0; i<numRows; ++i) {
635 CHK_ERR( getConnectivityRecords(colSpace, idType, rowLengths[i],
636 columnIDs[i], &(col_records[offset])));
637 offset += rowLengths[i];
644 int fei::MatrixGraph_Impl2::getConnectivityRecords(
fei::VectorSpace* vecSpace,
653 for(
int i=0; i<numIDs; ++i) {
654 records[i] = collection->getLocalID(IDs[i]);
655 if (records[i] == -1) {
656 CHK_ERR( vecSpace->
addDOFs(idType, 1, &IDs[i], &records[i]) );
664 int fei::MatrixGraph_Impl2::getConnectivityRecords(
fei::VectorSpace* vecSpace,
674 for(
int i=0; i<numIDs; ++i) {
675 records[i] = collection->getLocalID(IDs[i]);
676 if (records[i] == -1) {
677 CHK_ERR( vecSpace->
addDOFs(fieldID, idType, 1, &IDs[i], &records[i]));
685 int fei::MatrixGraph_Impl2::getConnectivityRecords(
fei::Pattern* pattern,
687 const int* connectedIdentifiers,
695 if (pType == fei::Pattern::GENERAL) {
699 for(i=0; i<numIDs; ++i) {
700 int id = connectedIdentifiers[i];
702 for(
int nf=0; nf<numFieldsPerID[i]; ++nf) {
703 CHK_ERR( vecSpace->
addDOFs(fieldIDs[fieldOffset++],
709 else if (pType == fei::Pattern::SINGLE_IDTYPE ||
710 pType == fei::Pattern::SIMPLE ||
711 pType == fei::Pattern::NO_FIELD) {
716 case fei::Pattern::SINGLE_IDTYPE:
719 for(i=0; i<numIDs; ++i) {
720 int id = connectedIdentifiers[i];
721 for(
int nf=0; nf<numFieldsPerID[i]; ++nf) {
722 CHK_ERR( vecSpace->
addDOFs(fieldIDs[fieldOffset++],
729 case fei::Pattern::SIMPLE:
731 CHK_ERR( vecSpace->
addDOFs(fieldIDs[0], idType,
732 numIDs, connectedIdentifiers,
736 case fei::Pattern::NO_FIELD:
737 CHK_ERR( vecSpace->
addDOFs(idType, numIDs,
738 connectedIdentifiers, recordList));
740 case fei::Pattern::GENERAL:
755 const int* rowConnectedIdentifiers,
756 const int* colConnectedIdentifiers)
764 if (connblk == NULL) {
765 FEI_OSTRINGSTREAM osstr;
766 osstr <<
"fei::MatrixGraph_Impl2::initConnectivity ERROR, blockID " << blockID
767 <<
" doesn't correspond to an existing ConnectivityBlock.";
768 throw std::runtime_error(osstr.str());
775 if (rowSpace_.get() == NULL) {
778 if (colSpace_.get() == NULL) {
784 int i, idOffset = -1;
785 std::map<int,int>::iterator
786 iter = connectivityIDs.find(connectivityID);
787 if (iter == connectivityIDs.end()) {
788 idOffset = connectivityIDs.size();
789 connectivityIDs.insert(iter, std::make_pair(connectivityID,idOffset));
792 idOffset = iter->second;
799 CHK_ERR( getConnectivityRecords(pattern, rowSpace_.get(),
800 rowConnectedIdentifiers, row_rlist) );
802 for(i=0; i<numIDs; ++i)
803 pattern->
getRecordCollections()[i]->getRecordWithLocalID(row_rlist[i])->isInLocalSubdomain_ =
true;
804 CHK_ERR( getConnectivityRecords(colPattern, colSpace_.get(),
805 colConnectedIdentifiers, col_rlist) );
807 for(i=0; i<numColIDs; ++i)
808 colPattern->
getRecordCollections()[i]->getRecordWithLocalID(col_rlist[i])->isInLocalSubdomain_ =
true;
815 const int* connectedIdentifiers)
817 std::map<int,fei::Pattern*>::iterator
818 p_iter = patterns_.find(patternID);
819 if (p_iter == patterns_.end()) ERReturn(-1);
823 int blockID = -arbitraryBlockCounter_++;
826 connectivityBlocks_.insert(std::pair<int,fei::ConnectivityBlock*>(blockID, cblock));
828 CHK_ERR( initConnectivity(blockID, 0, connectedIdentifiers) );
834 const int* rowConnectedIdentifiers,
836 const int* colConnectedIdentifiers)
838 std::map<int,fei::Pattern*>::iterator
839 rp_iter = patterns_.find(rowPatternID);
840 if (rp_iter == patterns_.end()) ERReturn(-1);
844 std::map<int,fei::Pattern*>::iterator
845 cp_iter = patterns_.find(colPatternID);
846 if (cp_iter == patterns_.end()) ERReturn(-1);
850 int blockID = -arbitraryBlockCounter_++;
854 connectivityBlocks_.insert(std::pair<int,fei::ConnectivityBlock*>(blockID, cblock));
856 CHK_ERR( initConnectivity(blockID, 0,
857 rowConnectedIdentifiers,
858 colConnectedIdentifiers) );
866 std::map<int,fei::Pattern*>::iterator
867 p_iter = patterns_.find(patternID);
868 if (p_iter == patterns_.end()) ERReturn(-1);
879 std::vector<int>& indices)
881 std::map<int,fei::Pattern*>::iterator
882 p_iter = patterns_.find(patternID);
883 if (p_iter == patterns_.end()) ERReturn(-1);
894 int offset = 0, fieldOffset = 0;
895 for(
int i=0; i<numIDs; ++i) {
896 for(
int j=0; j<numFieldsPerID[i]; ++j) {
897 CHK_ERR( rowSpace_->getGlobalIndices(1, &(IDs[i]), idTypes[i],
898 fieldIDs[fieldOffset],
899 &(indices[offset])) );
900 offset += snl_fei::getFieldSize(fieldIDs[fieldOffset++],
901 rowSpace_.get(), colSpace_.get());
913 const int* rowOffsets,
914 const int* packedColumnIDs)
919 sparseBlocks_.push_back(block);
923 CHK_ERR( getConnectivityRecords(rowSpace_.get(), idType, fieldID,
924 numRows, rowIDs, row_records) );
927 if (colSpace_.get() != NULL) {
928 colSpace = colSpace_.get();
933 CHK_ERR( getConnectivityRecords(colSpace, idType, fieldID, rowOffsets[numRows],
934 packedColumnIDs, col_records));
941 int constraintIDType,
947 if (rowSpace_.get() == NULL) ERReturn(-1);
951 CHK_ERR( rowSpace_->addDOFs(constraintIDType, 1, &constraintID) );
954 if (colSpace_.get() == NULL) {
957 CHK_ERR( colSpace_->addDOFs(constraintIDType,
965 numIDs, idTypes, IDs, fieldIDs,
972 if (constraint != NULL) {
973 if (*constraint != *newconstraint) {
977 delete newconstraint;
982 lagrangeConstraints_[constraintID] = newconstraint;
989 int constraintIDType,
995 if (rowSpace_.get() == NULL) ERReturn(-1);
1003 numIDs, idTypes, IDs, fieldIDs,
1010 if (constraint != NULL) {
1011 if (*constraint != *newconstraint) {
1015 delete newconstraint;
1020 penaltyConstraints_[constraintID] = newconstraint;
1029 rowSpace_->getRecordCollection(idType, collection);
1030 if (collection == NULL) {
1031 throw std::runtime_error(
"fei::MatrixGraph_Impl2::hasSlaveDof: ERROR, unknown idType");
1037 FEI_OSTRINGSTREAM osstr;
1038 osstr <<
"fei::MatrixGraph_Impl2::hasSlaveDof: ERROR, specified ID ("
1039 << ID <<
") not found.";
1040 throw std::runtime_error(osstr.str());
1043 return( rec->hasSlaveDof() );
1050 const int* fieldIDs,
1052 int offsetIntoSlaveField,
1053 const double* weights,
1056 if (rowSpace_.get() == NULL) ERReturn(-1);
1058 FEI_OSTRINGSTREAM idosstr;
1059 idosstr << IDs[offsetOfSlave] << fieldIDs[offsetOfSlave] << offsetIntoSlaveField;
1060 FEI_ISTRINGSTREAM idisstr(idosstr.str());
1061 int crID = IDs[offsetOfSlave];
1064 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
1065 FEI_OSTREAM& dbgos = *output_stream_;
1067 dbgos << dbgprefix_<<
"initSlaveConstraint crID=" << crID <<
", slaveID="
1068 << IDs[offsetOfSlave];
1070 if (output_level_ >= fei::FULL_LOGS) {
1072 for(
int ii=0; ii<numIDs; ++ii) {
1073 dbgos <<
"("<<IDs[ii] <<
","<<fieldIDs[ii]<<
") ";
1075 dbgos <<
"}"<<FEI_ENDL;
1077 else dbgos << FEI_ENDL;
1086 numIDs, idTypes, IDs, fieldIDs,
1088 offsetIntoSlaveField,
1093 if (constraint != NULL) {
1094 if (*constraint != *newconstraint) {
1096 FEI_OSTRINGSTREAM osstr;
1097 osstr <<
"fei::MatrixGraph_Impl2::initSlaveConstraint: slave ID "<<IDs[offsetOfSlave]
1098 <<
" is already constrained, with different connectivity. Changing the"
1099 <<
" the structure of an existing constraint is not allowed.";
1100 throw std::runtime_error(osstr.str());
1102 newSlaveData_ =
true;
1106 delete newconstraint;
1111 newSlaveData_ =
true;
1114 slaveConstraints_[crID] = newconstraint;
1121 fei::MatrixGraph_Impl2::newSlaveData()
1123 bool globalBool =
false;
1125 newSlaveData_ = globalBool;
1127 return(newSlaveData_);
1134 std::map<int,ConstraintType*>::iterator
1135 c_iter = lagrangeConstraints_.find(constraintID);
1136 if (c_iter == lagrangeConstraints_.end())
return(NULL);
1138 return( (*c_iter).second );
1145 std::map<int,ConstraintType*>::iterator
1146 c_iter = slaveConstraints_.find(constraintID);
1147 if (c_iter == slaveConstraints_.end())
return(NULL);
1149 return( (*c_iter).second );
1156 std::map<int,ConstraintType*>::iterator
1157 c_iter = penaltyConstraints_.find(constraintID);
1158 if (c_iter == penaltyConstraints_.end())
return(NULL);
1160 return( (*c_iter).second );
1166 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
1167 (*output_stream_) <<dbgprefix_<<
"initComplete" << FEI_ENDL;
1169 if (rowSpace_.get() == NULL) {
1173 CHK_ERR( rowSpace_->initComplete() );
1176 if (haveColSpace_ && colSpace_.get() == NULL) ERReturn(-1);
1177 if (haveColSpace_) {
1178 CHK_ERR( colSpace_->initComplete() );
1181 if (rowSpace_->fieldMasks_.size() == 1 &&
1182 rowSpace_->fieldMasks_[0]->getNumFields() == 1) {
1183 simpleProblem_ =
true;
1186 std::vector<int>& eqnNums = rowSpace_->getEqnNumbers();
1187 vspcEqnPtr_ = eqnNums.size() > 0 ? &eqnNums[0] : NULL;
1191 localNumSlaves_ = slaveConstraints_.size();
1192 globalNumSlaves_ = 0;
1193 CHK_ERR(
fei::GlobalSum(comm_, localNumSlaves_, globalNumSlaves_) );
1195 if (globalNumSlaves_ > 0) {
1197 CHK_ERR( createSlaveMatrices() );
1204 int fei::MatrixGraph_Impl2::createAlgebraicGraph(
bool blockEntryGraph,
1206 bool gatherFromOverlap)
1211 bool wasAlreadyBlockEntry = blockEntryGraph_;
1213 blockEntryGraph_ = blockEntryGraph;
1215 for(
unsigned i=0; i<sparseBlocks_.size(); ++i) {
1217 CHK_ERR( addBlockToGraph_sparse(graph, &cblock) );
1220 std::map<int,fei::ConnectivityBlock*>::const_iterator
1221 cb_iter = connectivityBlocks_.begin(),
1222 cb_end = connectivityBlocks_.end();
1224 while(cb_iter != cb_end) {
1229 if (symmetricBlock) {
1231 if (pattern == NULL) {
1236 if (pType == fei::Pattern::GENERAL || pType == fei::Pattern::SINGLE_IDTYPE) {
1237 CHK_ERR( addBlockToGraph_multiField_symmetric(graph, &cblock) );
1239 else if (pType == fei::Pattern::SIMPLE) {
1240 CHK_ERR( addBlockToGraph_singleField_symmetric(graph, &cblock) );
1242 else if (pType == fei::Pattern::NO_FIELD) {
1243 CHK_ERR( addBlockToGraph_noField_symmetric(graph, &cblock) );
1249 if (pattern == NULL || colpattern == NULL) {
1255 if (pType == fei::Pattern::SIMPLE && colPType == fei::Pattern::SIMPLE) {
1256 CHK_ERR( addBlockToGraph_singleField_nonsymmetric(graph, &cblock) );
1259 CHK_ERR( addBlockToGraph_multiField_nonsymmetric(graph, &cblock) );
1265 CHK_ERR( addLagrangeConstraintsToGraph(graph) );
1267 CHK_ERR( addPenaltyConstraintsToGraph(graph) );
1269 if (output_level_ >= fei::FULL_LOGS && output_stream_ != NULL) {
1270 FEI_OSTREAM& os = *output_stream_;
1271 os << dbgprefix_<<
"# before graph->gatherFromOverlap()" << FEI_ENDL;
1276 if (gatherFromOverlap) {
1280 if (blockEntryGraph) {
1281 CHK_ERR( exchangeBlkEqnSizes(graph) );
1284 if (output_level_ >= fei::FULL_LOGS &&
fei::numProcs(comm_)>1 &&
1285 output_stream_ != NULL && gatherFromOverlap) {
1286 FEI_OSTREAM& os = *output_stream_;
1287 os << dbgprefix_<<
" after graph->gatherFromOverlap()" << FEI_ENDL;
1291 if (!wasAlreadyBlockEntry) {
1292 setIndicesMode(POINT_ENTRY_GRAPH);
1301 bool localRowGraph_includeSharedRows)
1305 std::vector<int> globalOffsets;
1307 if (blockEntryGraph) {
1308 if (reducer_.get() != NULL) {
1309 throw std::runtime_error(
"fei::MatrixGraph_Impl2::createGraph ERROR, can't specify both block-entry assembly and slave-constraint reduction.");
1312 rowSpace_->getGlobalBlkIndexOffsets(globalOffsets);
1315 rowSpace_->getGlobalIndexOffsets(globalOffsets);
1318 if ((
int)globalOffsets.size() < localProc_+2)
return localRows;
1320 int firstOffset = globalOffsets[localProc_];
1321 int lastOffset = globalOffsets[localProc_+1] - 1;
1323 if (reducer_.get() != NULL) {
1324 std::vector<int>& reduced_eqns = reducer_->getLocalReducedEqns();
1325 if (!reduced_eqns.empty()) {
1326 firstOffset = reduced_eqns[0];
1327 lastOffset = reduced_eqns[reduced_eqns.size()-1];
1334 if (reducer_.get() == NULL) {
1335 graph = inner_graph;
1341 bool gatherFromOverlap = !localRowGraph_includeSharedRows;
1342 int err = createAlgebraicGraph(blockEntryGraph, graph.
get(),
1352 remotelyOwnedGraphRows_->
blockEntries = blockEntryGraph;
1354 if (localRowGraph_includeSharedRows &&
1355 remotelyOwnedGraphRows_->rowNumbers.size() > 0) {
1358 snl_fei::mergeSparseRowGraphs(localRows.
get(), remotelyOwnedGraphRows_.get());
1359 localRows = localPlusShared;
1366 int fei::MatrixGraph_Impl2::exchangeBlkEqnSizes(
fei::Graph* graph)
1371 if ( rowSpace_->getPointBlockMap()->ptEqualBlk() ) {
1377 CHK_ERR( blkHandler.do_the_exchange() );
1393 if (!newSlaveData()) {
1397 std::vector<int>& eqnNums = rowSpace_->getEqnNumbers();
1398 vspcEqnPtr_ = eqnNums.size() > 0 ? &eqnNums[0] : NULL;
1403 std::vector<int> masterEqns;
1404 std::vector<double> masterCoefs;
1406 std::map<int,ConstraintType*>::const_iterator
1407 cr_iter = slaveConstraints_.begin(),
1408 cr_end = slaveConstraints_.end();
1410 for(; cr_iter != cr_end; ++cr_iter) {
1414 int slaveID = slaveRecord->
getID();
1419 CHK_ERR( rowSpace_->getGlobalIndex(slaveIDType, slaveID,
1420 slaveFieldID, 0, offsetIntoSlaveField,
1423 std::vector<int>& masterRecords_vec = cr->
getMasters();
1424 int* masterRecords = &masterRecords_vec[0];
1429 double* masterWtPtr = &masterWeights[0];
1431 masterEqns.resize(masterWeights.size());
1432 masterCoefs.resize(masterWeights.size());
1434 int* masterEqnsPtr = &(masterEqns[0]);
1435 double* masterCoefsPtr = &(masterCoefs[0]);
1438 for(
size_t j=0; j<masterIDTypes.size(); ++j) {
1439 fei::Record<int>* masterRecord = masterRecColls[j]->getRecordWithLocalID(masterRecords[j]);
1443 if (!simpleProblem_) {
1446 throw std::runtime_error(
"FEI ERROR, failed to get eqn-offset for constraint master-field.");
1450 unsigned fieldSize = rowSpace_->getFieldSize(masterFieldIDs[j]);
1452 int eqn = eqnNumbers[eqnOffset];
1453 for(
unsigned k=0; k<fieldSize; ++k) {
1454 masterEqnsPtr[offset++] = eqn+k;
1458 double fei_eps = 1.e-49;
1461 for(
size_t jj=0; jj<masterEqns.size(); ++jj) {
1462 if ( includeAllSlaveConstraints_ ||
1463 (std::abs(masterWtPtr[jj]) > fei_eps) ) {
1464 masterCoefsPtr[offset] = masterWtPtr[jj];
1465 masterEqnsPtr[offset++] = masterEqnsPtr[jj];
1469 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
1470 bool log_eqn = isLogEqn(slaveEqn);
1472 for(
unsigned ii=0; ii<masterEqns.size(); ++ii) {
1473 if (isLogEqn(masterEqnsPtr[ii])) {
1481 FEI_OSTREAM& os = *output_stream_;
1482 os <<
"createSlaveMatrices: " << slaveEqn <<
" = ";
1483 for(
unsigned ii=0; ii<masterEqns.size(); ++ii) {
1484 if (ii!=0) os <<
"+ ";
1485 os << masterCoefsPtr[ii]<<
"*"<<masterEqnsPtr[ii]<<
" ";
1491 local_D->putRow(slaveEqn, masterEqnsPtr, masterCoefsPtr, offset);
1493 if ( includeAllSlaveConstraints_ ||
1495 fei::put_entry(*local_g, slaveEqn, cr->
getRHSValue());
1499 if (D_.get() == NULL) {
1500 D_.reset(
new fei::FillableMat);
1503 if (g_.get() == NULL) {
1508 if (numProcs_ > 1) {
1509 fei::impl_utils::global_union(comm_, *local_D, *D_);
1510 fei::impl_utils::global_union(comm_, *local_g, *g_);
1521 if (output_level_ >= fei::FULL_LOGS && output_stream_ != NULL) {
1522 (*output_stream_) <<
"# D_ (pre-removeCouplings):"<<FEI_ENDL;
1523 (*output_stream_) << *D_;
1526 int levelsOfCoupling = fei::impl_utils::remove_couplings(*D_);
1527 (void)levelsOfCoupling;
1529 if (reducer_.get() == NULL) {
1530 reducer_.reset(
new fei::Reducer(D_, g_, comm_));
1532 std::vector<int> indices;
1533 rowSpace_->getIndices_Owned(indices);
1535 reducer_->setLocalUnreducedEqns(indices);
1538 reducer_->initialize();
1541 if (output_level_ >= fei::FULL_LOGS && output_stream_ != NULL) {
1542 (*output_stream_) <<
"# D_:"<<FEI_ENDL;
1543 (*output_stream_) << *D_;
1546 double fei_eps = 1.e-49;
1549 for(
size_t j=0; j<g_->size(); ++j) {
1550 double coef = g_->coefs()[j];
1551 if ( includeAllSlaveConstraints_ ||
1552 (std::abs(coef) > fei_eps) ) {
1557 newSlaveData_ =
false;
1573 return( remotelyOwnedGraphRows_ );
1579 if (constrained_indices_.empty()) {
1584 std::set<int>::const_iterator
1585 s_iter = constrained_indices_.begin(),
1586 s_end = constrained_indices_.end();
1588 crindices.resize(constrained_indices_.size());
1591 for(; s_iter != s_end; ++s_iter) {
1592 crindices[offset++] = *s_iter;
1597 int fei::MatrixGraph_Impl2::addLagrangeConstraintsToGraph(
fei::Graph* graph)
1599 std::vector<int> indices;
1600 std::map<int,ConstraintType*>::const_iterator
1601 cr_iter = lagrangeConstraints_.begin(),
1602 cr_end = lagrangeConstraints_.end();
1604 constrained_indices_.clear();
1606 while(cr_iter != cr_end) {
1610 CHK_ERR( getConstraintConnectivityIndices(cr, indices) );
1612 int numIndices = indices.size();
1613 int* indicesPtr = &(indices[0]);
1615 for(
int i=0; i<numIndices; ++i) {
1616 constrained_indices_.insert(indicesPtr[i]);
1619 int crEqnRow = -1, tmp;
1620 if (blockEntryGraph_) {
1621 CHK_ERR( rowSpace_->getGlobalBlkIndex(cr->
getIDType(),
1624 CHK_ERR( rowSpace_->getGlobalIndex(cr->
getIDType(),
1629 CHK_ERR( rowSpace_->getGlobalIndex(cr->
getIDType(),
1632 CHK_ERR( rowSpace_->getGlobalBlkIndex(cr->
getIDType(),
1638 CHK_ERR( graph->
addIndices(crEqnRow, numIndices, &(indices[0])) );
1643 CHK_ERR( graph->
addIndices(crEqnRow, 1, &crEqnRow) );
1647 for(
int k=0; k<numIndices; ++k) {
1648 CHK_ERR( graph->
addIndices(indicesPtr[k], 1, &crEqnRow) );
1660 std::vector<int>& globalIndices)
1662 std::vector<int>& fieldSizes = tmpIntArray1_;
1663 std::vector<int>& ones = tmpIntArray2_;
1665 std::vector<int>& constrainedRecords = cr->
getMasters();
1669 int len = constrainedRecords.size();
1670 fieldSizes.resize(len);
1672 ones.assign(len, 1);
1675 if (blockEntryGraph_) {
1679 for(
int j=0; j<len; ++j) {
1680 unsigned fieldSize = rowSpace_->getFieldSize(constrainedFieldIDs[j]);
1681 fieldSizes[j] = fieldSize;
1682 numIndices += fieldSize;
1686 globalIndices.resize(numIndices);
1689 CHK_ERR( getConnectivityIndices_multiField(&recordCollections[0],
1690 &constrainedRecords[0],
1692 &constrainedFieldIDs[0],
1694 numIndices, &globalIndices[0],
1696 if (numIndices != checkNum) {
1704 int fei::MatrixGraph_Impl2::addPenaltyConstraintsToGraph(
fei::Graph* graph)
1706 std::vector<int> indices;
1707 std::map<int,ConstraintType*>::const_iterator
1708 cr_iter = penaltyConstraints_.begin(),
1709 cr_end = penaltyConstraints_.end();
1711 while(cr_iter != cr_end) {
1714 CHK_ERR( getConstraintConnectivityIndices(cr, indices) );
1716 int numIndices = indices.size();
1729 bool& equivalent)
const
1735 int myNumBlocks = getNumConnectivityBlocks();
1738 if (myNumBlocks != numBlocks) {
1740 equivalent = globalCode > 0 ?
false :
true;
1744 if (numBlocks > 0) {
1745 std::vector<int> myBlockIDs;
1746 std::vector<int> blockIDs;
1748 CHK_ERR( getConnectivityBlockIDs(myBlockIDs) );
1751 for(
int i=0; i<numBlocks; ++i) {
1752 if (myBlockIDs[i] != blockIDs[i]) {
1754 equivalent = globalCode > 0 ?
false :
true;
1764 if (myNumLists != numLists ||
1767 equivalent = globalCode > 0 ?
false :
true;
1774 if (myNumIDsPerList != numIDsPerList) {
1776 equivalent = globalCode > 0 ?
false :
true;
1782 int numMyLagrangeConstraints = getLocalNumLagrangeConstraints();
1783 int numMySlaveConstraints = getGlobalNumSlaveConstraints();
1787 if (numMyLagrangeConstraints != numLagrangeConstraints ||
1788 numMySlaveConstraints != numSlaveConstraints) {
1790 equivalent = globalCode > 0 ?
false :
true;
1796 equivalent = globalCode > 0 ?
false :
true;
1803 return(connectivityBlocks_.size());
1809 blockIDs.resize(connectivityBlocks_.size());
1811 std::map<int,fei::ConnectivityBlock*>::const_iterator
1812 cdb_iter = connectivityBlocks_.begin();
1814 for(
size_t i=0; i<blockIDs.size(); ++i, ++cdb_iter) {
1815 int blockID = (*cdb_iter).first;
1816 blockIDs[i] = blockID;
1826 if (cblock == NULL)
return(-1);
1836 if (cblock == NULL)
return(-1);
1839 return( blockEntryGraph_ ?
1849 if (cblock == NULL)
return(-1);
1863 std::map<int,fei::ConnectivityBlock*>::const_iterator
1864 c_iter = connectivityBlocks_.find(blockID);
1865 if (c_iter == connectivityBlocks_.end())
return(0);
1867 return( (*c_iter).second );
1873 std::map<int,fei::ConnectivityBlock*>::iterator
1874 c_iter = connectivityBlocks_.find(blockID);
1875 if (c_iter == connectivityBlocks_.end())
return(0);
1877 return( (*c_iter).second );
1883 int indicesAllocLen,
1888 if (cblock == NULL)
return(-1);
1890 std::vector<int>& eqnNums = rowSpace_->getEqnNumbers();
1891 vspcEqnPtr_ = eqnNums.size() > 0 ? &eqnNums[0] : NULL;
1896 int len = numIndices > indicesAllocLen ? indicesAllocLen : numIndices;
1899 if (records == NULL) {
1905 if (pType == fei::Pattern::GENERAL || pType == fei::Pattern::SINGLE_IDTYPE) {
1910 std::vector<int> fieldSizes(totalNumFields);
1912 for(
int j=0; j<totalNumFields; ++j) {
1913 fieldSizes[j] = snl_fei::getFieldSize(fieldIDs[j], rowSpace_.get(),
1920 fieldIDs, &fieldSizes[0],
1921 len, indices, numIndices) );
1923 else if (pType == fei::Pattern::SIMPLE) {
1926 int fieldID = fieldIDs[0];
1927 unsigned fieldSize = snl_fei::getFieldSize(fieldID,
1934 len, indices, numIndices) );
1936 else if (pType == fei::Pattern::NO_FIELD) {
1939 len, indices, numIndices) );
1948 int rowIndicesAllocLen,
1951 int colIndicesAllocLen,
1956 if (cblock == NULL)
return(-1);
1958 std::vector<int>& eqnNums = rowSpace_->getEqnNumbers();
1959 vspcEqnPtr_ = eqnNums.size() > 0 ? &eqnNums[0] : NULL;
1964 int len = numRowIndices > rowIndicesAllocLen ?
1965 rowIndicesAllocLen : numRowIndices;
1968 if (records == NULL) {
1974 if (pType == fei::Pattern::GENERAL || pType == fei::Pattern::SINGLE_IDTYPE) {
1979 std::vector<int> fieldSizes(totalNumFields);
1981 for(
int j=0; j<totalNumFields; ++j) {
1982 fieldSizes[j] = snl_fei::getFieldSize(fieldIDs[j], rowSpace_.get(),
1989 fieldIDs, &fieldSizes[0],
1990 len, rowIndices, numRowIndices) );
1992 else if (pType == fei::Pattern::SIMPLE) {
1995 int fieldID = fieldIDs[0];
1996 unsigned fieldSize = snl_fei::getFieldSize(fieldID, rowSpace_.get(),
2002 len, rowIndices, numRowIndices) );
2004 else if (pType == fei::Pattern::NO_FIELD) {
2007 len, rowIndices, numRowIndices) );
2014 len = numColIndices > colIndicesAllocLen ?
2015 colIndicesAllocLen : numColIndices;
2020 if (records == NULL) {
2024 if (pType == fei::Pattern::GENERAL || pType == fei::Pattern::SINGLE_IDTYPE) {
2029 std::vector<int> fieldSizes(totalNumFields);
2031 for(
int j=0; j<totalNumFields; ++j) {
2032 fieldSizes[j] = snl_fei::getFieldSize(fieldIDs[j], rowSpace_.get(),
2039 fieldIDs, &fieldSizes[0],
2040 len, colIndices, numColIndices) );
2042 else if (pType == fei::Pattern::SIMPLE) {
2045 int fieldID = fieldIDs[0];
2046 unsigned fieldSize = snl_fei::getFieldSize(fieldID, rowSpace_.get(),
2052 len, colIndices, numColIndices) );
2054 else if (pType == fei::Pattern::NO_FIELD) {
2057 len, colIndices, numColIndices) );
2066 return( lagrangeConstraints_.size() );
2070 int fei::MatrixGraph_Impl2::addBlockToGraph_multiField_symmetric(
fei::Graph* graph,
2076 int numIndices = blockEntryGraph_ ?
2078 int checkNumIndices = numIndices;
2079 std::vector<int> indices(numIndices);
2080 int* indicesPtr = &indices[0];
2086 std::vector<int> fieldSizes(totalNumFields);
2088 for(j=0; j<totalNumFields; ++j) {
2089 fieldSizes[j] = snl_fei::getFieldSize(fieldIDs[j], rowSpace_.get(),
2096 std::map<int,int>::iterator
2097 c_iter = connIDs.begin(),
2098 c_end = connIDs.end();
2100 for(; c_iter != c_end; ++c_iter) {
2101 int offset = c_iter->second;
2102 int* records = &values[offset*numIDs];
2113 if (checkNumIndices != numIndices) {
2117 if (output_level_ > fei::BRIEF_LOGS && output_stream_ != NULL) {
2118 FEI_OSTREAM& os = *output_stream_;
2121 unsigned thisoffset = 0;
2122 for(
int ii=0; ii<numIDs; ++ii) {
2123 const fei::Record<int>* record = recordColls[ii]->getRecordWithLocalID(records[ii]);
2124 int ID = record->
getID();
2125 os << dbgprefix_<<
"scatterIndices: ID=" <<ID<<
": ";
2127 for(
int jj=0; jj<num; ++jj) {
2128 os << indicesPtr[thisoffset++] <<
" ";
2133 for(
int ii=0; ii<numIndices; ++ii) {
2134 if (isLogEqn(indicesPtr[ii])) {
2135 os <<
"adding Symm inds: ";
2136 for(
int jj=0; jj<numIndices; ++jj) {
2137 os << indicesPtr[jj] <<
" ";
2147 if (numIndices == numIDs || !cblock->
isDiagonal()) {
2153 int* fieldSizesPtr = &fieldSizes[0];
2154 for(
int i=0; i<numIDs; ++i) {
2156 ioffset += fieldSizesPtr[i];
2165 int fei::MatrixGraph_Impl2::addBlockToGraph_multiField_nonsymmetric(
fei::Graph* graph,
2172 int numIndices = blockEntryGraph_ ? numIDs : pattern->
getNumIndices();
2173 int checkNumIndices = numIndices;
2174 std::vector<int> indices(numIndices);
2175 int* indicesPtr = &indices[0];
2177 int numColIDs = colpattern->
getNumIDs();
2178 int numColIndices = blockEntryGraph_ ? numColIDs : colpattern->
getNumIndices();
2179 int checkNumColIndices = numColIndices;
2180 std::vector<int> colindices(numColIndices);
2181 int* colindicesPtr = &colindices[0];
2188 const int* colfieldIDs = colpattern->
getFieldIDs();
2191 std::vector<int> fieldSizes(totalNumFields);
2192 std::vector<int> colfieldSizes(totalNumColFields);
2194 for(j=0; j<totalNumFields; ++j) {
2195 fieldSizes[j] = snl_fei::getFieldSize(fieldIDs[j], rowSpace_.get(),
2198 for(j=0; j<totalNumColFields; ++j) {
2199 colfieldSizes[j] = snl_fei::getFieldSize(colfieldIDs[j], rowSpace_.get(),
2207 std::map<int,int>::iterator
2208 c_iter = connIDs.begin(),
2209 c_end = connIDs.end();
2211 for(; c_iter != c_end; ++c_iter) {
2212 int offset = c_iter->second;
2213 int* records = &rowrecords[offset*numIDs];
2215 int* colRecords = &colrecords[offset*numColIDs];
2226 if (checkNumIndices != numIndices) {
2232 colRecords, numColIDs,
2238 checkNumColIndices) );
2240 if (checkNumColIndices != numColIndices) {
2246 for(
int r=0; r<numIndices; ++r) {
2247 CHK_ERR( graph->
addIndices(indicesPtr[r], numColIndices, colindicesPtr));
2258 const int* numFieldsPerID,
2259 const int* fieldIDs,
2260 const int* fieldSizes,
2261 int indicesAllocLen,
2268 for(
int i=0; i<numRecords; ++i) {
2269 const fei::Record<int>* record = recordCollections[i]->getRecordWithLocalID(records[i]);
2270 if (record==NULL)
continue;
2272 if (blockEntryGraph_) {
2273 indices[numIndices++] = record->
getNumber();
2280 for(
int nf=0; nf<numFieldsPerID[i]; ++nf) {
2282 if (!simpleProblem_) {
2285 for(
int fs=0; fs<fieldSizes[fld_offset]; ++fs) {
2286 indices[numIndices++] = -1;
2292 for(
int fs=0; fs<fieldSizes[fld_offset]; ++fs) {
2293 indices[numIndices++] = eqnNumbers[eqnOffset+fs];
2304 int fei::MatrixGraph_Impl2::addBlockToGraph_singleField_symmetric(
fei::Graph* graph,
2309 int numIndices = blockEntryGraph_ ? numIDs : pattern->
getNumIndices();
2310 int checkNumIndices = numIndices;
2311 std::vector<int> indices(numIndices);
2312 int* indicesPtr = &indices[0];
2316 int fieldID = fieldIDs[0];
2317 unsigned fieldSize = snl_fei::getFieldSize(fieldID, rowSpace_.get(),
2323 std::map<int,int>::iterator
2324 c_iter = connIDs.begin(),
2325 c_end = connIDs.end();
2327 for(; c_iter != c_end; ++c_iter) {
2328 int offset = c_iter->second;
2329 int* records = &rowrecords[offset*numIDs];
2338 if (checkNumIndices != numIndices) {
2342 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
2343 for(
int ii=0; ii<numIndices; ++ii) {
2344 if (isLogEqn(indicesPtr[ii])) {
2345 FEI_OSTREAM& os = *output_stream_;
2346 os <<
"adding Symm inds: ";
2347 for(
int jj=0; jj<numIndices; ++jj) {
2348 os << indicesPtr[jj] <<
" ";
2358 if (numIndices == numIDs || !cblock->
isDiagonal()) {
2364 for(
int i=0; i<numIDs; ++i) {
2366 ioffset += fieldSize;
2375 int fei::MatrixGraph_Impl2::addBlockToGraph_singleField_nonsymmetric(
fei::Graph* graph,
2381 int numIndices = blockEntryGraph_ ? numIDs : pattern->
getNumIndices();
2382 int checkNumIndices = numIndices;
2383 std::vector<int> indices(numIndices);
2384 int* indicesPtr = &indices[0];
2386 int numColIDs = colpattern->
getNumIDs();
2387 int numColIndices = blockEntryGraph_ ?
2389 int checkNumColIndices = numColIndices;
2390 std::vector<int> colindices(numColIndices);
2391 int* colindicesPtr = &colindices[0];
2395 int rowFieldID = fieldIDs[0];
2396 int rowFieldSize = snl_fei::getFieldSize(rowFieldID, rowSpace_.get(),
2404 int colFieldSize = snl_fei::getFieldSize(colFieldID, rowSpace_.get(),
2407 std::map<int,int>::iterator
2408 c_iter = connIDs.begin(),
2409 c_end = connIDs.end();
2411 for(; c_iter != c_end; ++c_iter) {
2412 int offset = c_iter->second;
2413 int* records = &rowrecords[offset*numIDs];
2415 int* colRecords = &colrecords[offset*numColIDs];
2417 if (blockEntryGraph_) {
2419 records, checkNumIndices,
2420 indicesPtr, numIndices);
2423 colRecords, checkNumColIndices,
2424 colindicesPtr, numColIndices);
2428 records, rowFieldID,
2429 rowFieldSize, checkNumIndices,
2430 indicesPtr, numIndices);
2433 colRecords, colFieldID,
2434 colFieldSize, checkNumColIndices,
2435 colindicesPtr, numColIndices);
2438 if (checkNumIndices != numIndices || checkNumColIndices != numColIndices) {
2442 for(
int r=0; r<numIndices; ++r) {
2443 CHK_ERR( graph->
addIndices(indicesPtr[r], numColIndices, colindicesPtr));
2451 int fei::MatrixGraph_Impl2::getConnectivityIndices_singleField(
const snl_fei::RecordCollection*
const* recordCollections,
2456 int indicesAllocLen,
2462 for(
int i=0; i<numRecords; ++i) {
2463 if (numIndices == indicesAllocLen)
break;
2465 const fei::Record<int>* record = recordCollections[i]->getRecordWithLocalID(records[i]);
2467 if (blockEntryGraph_) {
2468 indices[numIndices++] = record->
getNumber();
2475 if (!simpleProblem_) {
2479 indices[numIndices++] = -1;
2480 if (fieldSize > 1) {
2481 for(
int fs=1; fs<fieldSize; ++fs) {
2482 indices[numIndices++] = -1;
2489 indices[numIndices++] = eqnNumbers[eqnOffset];
2490 if (fieldSize > 1) {
2491 for(
int fs=1; fs<fieldSize; ++fs) {
2492 indices[numIndices++] = eqnOffset >= 0 ? eqnNumbers[eqnOffset+fs] : -1;
2504 int indicesAllocLen,
2510 for(
int i=0; i<numRecords; ++i) {
2512 const fei::Record<int>* record = recordCollections[i]->getRecordWithLocalID(records[i]);
2515 if (blockEntryGraph_) {
2516 indices[numIndices++] = record->
getNumber();
2519 indices[numIndices++] = eqnNumbers[0];
2527 int fei::MatrixGraph_Impl2::addBlockToGraph_noField_symmetric(
fei::Graph* graph,
2533 std::vector<int> indices(numIndices);
2534 int* indicesPtr = &indices[0];
2539 std::map<int,int>::iterator
2540 c_iter = connIDs.begin(),
2541 c_end = connIDs.end();
2543 for(; c_iter != c_end; ++c_iter) {
2544 int offset = c_iter->second;
2545 int* records = &rowrecords[offset*numIDs];
2547 int checkNumIndices;
2548 CHK_ERR( getConnectivityIndices_noField(pattern->
getRecordCollections(), records, numIDs, numIndices,
2549 indicesPtr, checkNumIndices) );
2551 if (checkNumIndices != numIndices) {
2555 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
2556 for(
int ii=0; ii<numIndices; ++ii) {
2557 if (isLogEqn(indicesPtr[ii])) {
2558 FEI_OSTREAM& os = *output_stream_;
2559 os <<
"adding Symm inds: ";
2560 for(
int jj=0; jj<numIndices; ++jj) {
2561 os << indicesPtr[jj] <<
" ";
2578 int fei::MatrixGraph_Impl2::addBlockToGraph_sparse(
fei::Graph* graph,
2581 std::vector<int> row_indices;
2582 std::vector<int> indices;
2592 int fieldID = cblock->
fieldID();
2596 fieldSize = snl_fei::getFieldSize(fieldID, rowSpace_.get(),
2600 std::map<int,int>::iterator
2601 c_iter = connIDs.begin(),
2602 c_end = connIDs.end();
2604 for(; c_iter != c_end; ++c_iter) {
2605 int offset = c_iter->second;
2606 int rowlen = connOffsets[offset+1] - offset;
2608 int* records = &(rowrecords[offset]);
2610 int checkNumIndices;
2611 row_indices.resize(fieldSize);
2614 CHK_ERR( getConnectivityIndices_singleField(recordCollections, records, 1,
2621 CHK_ERR( getConnectivityIndices_noField(recordCollections, records, 1, fieldSize,
2626 indices.resize(fieldSize*rowlen);
2627 int* indicesPtr = &indices[0];
2628 int* crecords = &(colrecords[offset]);
2631 CHK_ERR( getConnectivityIndices_singleField(recordCollections, crecords, rowlen,
2638 CHK_ERR( getConnectivityIndices_noField(recordCollections, crecords, rowlen, rowlen,
2639 indicesPtr, checkNumIndices) );
2641 if (checkNumIndices != rowlen) {
2647 int* row_ind_ptr = &row_indices[0];
2648 for(
int i=0; i<fieldSize; ++i) {
2649 CHK_ERR( graph->
addIndices(row_ind_ptr[i], fieldSize*rowlen,
2658 void fei::MatrixGraph_Impl2::setName(
const char* name)
2660 if (name == NULL)
return;
2662 if (name_ == name)
return;
2665 dbgprefix_ =
"MatGraph_"+name_+
": ";
2671 if (mode == BLOCK_ENTRY_GRAPH) {
2672 blockEntryGraph_ =
true;
2676 if (mode == POINT_ENTRY_GRAPH) {
2677 blockEntryGraph_ =
false;
int initLagrangeConstraint(int constraintID, int constraintIDType, int numIDs, const int *idTypes, const int *IDs, const int *fieldIDs)
int GlobalSum(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
GlobalIDType getNumber() const
int definePattern(int numIDs, int idType)
int getLocalNumLagrangeConstraints() const
snl_fei::RecordCollection *const * getRecordCollections() const
ParamType getType() const
const int * getRowConnectivity(int ID) const
const int * getIDTypes() const
virtual int getGlobalNumSlaveConstraints() const =0
virtual int writeRemoteGraph(FEI_OSTREAM &os)=0
const std::map< int, int > & getConnectivityIDs() const
std::vector< int > & getMasterFieldIDs()
int getNumIndices() const
const Param * get(const char *name) const
double getRHSValue() const
const int * getNumFieldsPerID() const
fei::SharedPtr< fei::SparseRowGraph > createGraph(bool blockEntryGraph, bool localRowGraph_includeSharedRows=false)
fei::Pattern * getPattern(int patternID)
int createSlaveMatrices()
int getConnectivityIndices(int blockID, int connectivityID, int indicesAllocLen, int *indices, int &numIndices)
fei::OutputLevel string_to_output_level(const std::string &str)
bool getBoolValue() const
snl_fei::Constraint< fei::Record< int > * > ConstraintType
virtual int gatherFromOverlap()=0
virtual const fei::ConnectivityBlock * getConnectivityBlock(int blockID) const =0
const int * getFieldIDs() const
int getTotalNumFields() const
int initConnectivityBlock(int blockID, int numConnectivityLists, int patternID, bool diagonal=false)
std::vector< int > & getColConnectivities()
int getNumConnectivityBlocks() const
void setEqnNumber(int eqn)
int addDOFs(int fieldID, int idType, int numIDs, const int *IDs)
virtual table_type * getLocalGraph()=0
bool structurallySame(const Constraint< RecordType > &rhs)
virtual int writeLocalGraph(FEI_OSTREAM &os, bool debug=false, bool prefixLinesWithPoundSign=true)=0
int getSlaveFieldID() const
std::vector< int > & getRowConnectivities()
void setBlkEqnNumber(int blkEqn)
int getConnectivityBlockIDs(std::vector< int > &blockIDs) const
virtual int addIndices(int row, int len, const int *indices)=0
std::vector< double > & getMasterWeights()
fei::SharedPtr< FillableMat > getSlaveDependencyMatrix()
const fei::Pattern * getColPattern() const
int getConstraintID() const
MatrixGraph_Impl2(fei::SharedPtr< fei::VectorSpace > rowSpace, fei::SharedPtr< fei::VectorSpace > colSpace, const char *name=NULL)
void setIndicesMode(int mode)
int getConnectivityNumIndices(int blockID) const
void setRowSpace(fei::SharedPtr< fei::VectorSpace > rowSpace)
const fei::ConnectivityBlock * getConnectivityBlock(int blockID) const
int initSlaveConstraint(int numIDs, const int *idTypes, const int *IDs, const int *fieldIDs, int offsetOfSlave, int offsetIntoSlaveField, const double *weights, double rhsValue)
int getNumIDsPerConnectivityList(int blockID) const
virtual fei::SharedPtr< fei::MatrixGraph > createMatrixGraph(fei::SharedPtr< fei::VectorSpace > rowSpace, fei::SharedPtr< fei::VectorSpace > columnSpace, const char *name)
ConstraintType * getPenaltyConstraint(int constraintID)
void setOutputLevel(OutputLevel olevel)
PatternType getPatternType() const
int Allreduce(MPI_Comm comm, bool localBool, bool &globalBool)
ConstraintType * getSlaveConstraint(int constraintID)
virtual ~MatrixGraph_Impl2()
int getPatternNumIndices(int patternID, int &numIndices)
void getConstrainedIndices(std::vector< int > &crindices) const
fei::SharedPtr< fei::SparseRowGraph > createSparseRowGraph(const std::vector< snl_fei::RaggedTable< MAP_TYPE, SET_TYPE > * > &tables)
int initConnectivity(int blockID, int connectivityID, const int *connectedIdentifiers)
const int * getNumIndicesPerID() const
int getOffsetIntoSlaveField() const
virtual std::vector< remote_table_type * > & getRemoteGraph()=0
int getPatternIndices(int patternID, const int *IDs, std::vector< int > &indices)
virtual int addSymmetricIndices(int numIndices, int *indices, bool diagonal=false)=0
std::ostream & console_out()
void setParameters(const fei::ParameterSet ¶ms)
int GlobalMax(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
int compareStructure(const fei::MatrixGraph &matrixGraph, bool &equivalent) const
const std::string & getStringValue() const
ConstraintType * getLagrangeConstraint(int constraintID)
int getConstraintConnectivityIndices(ConstraintType *cr, std::vector< int > &globalIndices)
fei::SharedPtr< fei::Reducer > getReducer()
int localProc(MPI_Comm comm)
static LogManager & getLogManager()
int getFieldEqnOffset(int fieldID, int &offset) const
GlobalIDType getID() const
int initPenaltyConstraint(int constraintID, int constraintIDType, int numIDs, const int *idTypes, const int *IDs, const int *fieldIDs)
unsigned getFieldSize(int fieldID)
std::vector< snl_fei::RecordCollection * > & getMasterRecordCollections()
std::vector< int > & getMasters()
virtual int getLocalNumLagrangeConstraints() const =0
void destroyValues(MAP_TYPE &map_obj)
std::vector< int > & getConnectivityOffsets()
const int * getColConnectivity(int ID) const
int getOffsetIntoEqnNumbers() const
virtual int getNumConnectivityBlocks() const =0
virtual int getConnectivityBlockIDs(std::vector< int > &blockIDs) const =0
fei::FieldMask * getFieldMask()
bool hasSlaveDof(int ID, int idType)
int getRecordCollection(int idType, snl_fei::RecordCollection *&records)
fei::Record< int > * getRecordWithID(int ID)
void setIsDiagonal(bool flag)
fei::SharedPtr< fei::SparseRowGraph > getRemotelyOwnedGraphRows()
const fei::Pattern * getRowPattern() const
std::vector< int > & getMasterIDTypes()
int numProcs(MPI_Comm comm)
void setColumnSpace(fei::SharedPtr< fei::VectorSpace > columnSpace)