9 #ifndef _fei_Matrix_Impl_hpp_
10 #define _fei_Matrix_Impl_hpp_
12 #include <fei_fwd.hpp>
15 #include "fei_iostream.hpp"
16 #include "fei_fstream.hpp"
17 #include "fei_sstream.hpp"
18 #include <fei_ArrayUtils.hpp>
19 #include <fei_MatrixTraits.hpp>
20 #include <fei_MatrixTraits_LinProbMgr.hpp>
21 #include <fei_MatrixTraits_LinSysCore.hpp>
22 #include <fei_MatrixTraits_FEData.hpp>
23 #include <fei_MatrixTraits_FillableMat.hpp>
24 #include <fei_FillableMat.hpp>
26 #include <snl_fei_FEMatrixTraits.hpp>
27 #include <snl_fei_FEMatrixTraits_FED.hpp>
28 #include <snl_fei_BlockMatrixTraits.hpp>
29 #include <fei_Matrix.hpp>
30 #include <fei_MatrixGraph.hpp>
31 #include <fei_Matrix_core.hpp>
32 #include <snl_fei_Utils.hpp>
35 #define fei_file "fei_Matrix_Impl.hpp"
36 #include <fei_ErrMacros.hpp>
59 bool zeroSharedRows=
true);
69 if (haveBlockMatrix()) {
72 else if (haveFEMatrix()) {
91 {
return( Matrix_core::getMatrixGraph() ); }
100 if ((
int)(globalOffsets().size()) <
numProcs()+1)
return(-1);
101 return(globalOffsets()[
numProcs()]);
108 return(lastLocalOffset() - firstLocalOffset() + 1);
130 int copyOutRow(
int row,
int len,
double* coefs,
int* indices)
const;
143 int sumIn(
int numRows,
const int* rows,
144 int numCols,
const int* cols,
145 const double*
const* values,
159 int copyIn(
int numRows,
const int* rows,
160 int numCols,
const int* cols,
161 const double*
const* values,
183 const double*
const* data,
219 int sumIn(
int blockID,
int connectivityID,
220 const double*
const* values,
245 bool matrixMarketFormat=
true);
250 bool matrixMarketFormat=
true);
254 return(haveBlockMatrix());
259 int numCols,
const int* cols,
260 const double*
const* values,
271 const double*
const* values,
278 double* getBeginPointer()
283 int getOffset(
int row,
int col)
288 int row_index, col_index;
297 int giveToMatrix(
int numRows,
const int* rows,
298 int numCols,
const int* cols,
299 const double*
const* values,
303 int giveToBlockMatrix(
int numRows,
const int* rows,
304 int numCols,
const int* cols,
305 const double*
const* values,
309 bool globalAssembleCalled_;
310 bool changedSinceMark_;
311 std::string dbgprefix_;
319 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
320 FEI_OSTREAM& os = *output_stream_;
321 os << dbgprefix_<<
"globalAssemble"<<FEI_ENDL;
324 globalAssembleCalled_ =
true;
326 if (haveBlockMatrix()) {
336 Matrix_core::setMatrixGraph(matrixGraph);
343 if(changedSinceMark_)
344 changedSinceMark_ =
false;
351 return(changedSinceMark_);
357 int numCols,
const int* cols,
358 const double*
const* values,
362 if (format != FEI_DENSE_ROW) {
366 if (output_level_ > fei::BRIEF_LOGS && output_stream_ != 0) {
367 FEI_OSTREAM& os = *output_stream_;
368 for(
int i=0; i<numRows; ++i) {
369 os << dbgprefix_<<
"giveToUnderlyingMatrix ";
370 for(
int j=0; j<numCols; ++j) {
371 os <<
"("<<rows[i]<<
","<<cols[j]<<
","<<values[i][j]<<
") ";
378 numCols, cols, values, sumInto);
383 changedSinceMark_ =
true;
395 const double*
const* values,
400 row, rowDim, numCols, cols,
401 LDAs, colDims, values) != 0) {
407 row, rowDim, numCols, cols,
408 LDAs, colDims, values) != 0) {
413 changedSinceMark_ =
true;
418 #include <fei_macros.hpp>
419 #include <fei_chk_mpi.hpp>
421 #include <fei_TemplateUtils.hpp>
423 #include <fei_Pattern.hpp>
424 #include <fei_VectorSpace.hpp>
426 #include <fei_ConnectivityBlock.hpp>
428 #include <snl_fei_PointBlockMap.hpp>
430 #include <fei_Record.hpp>
432 #include <snl_fei_Utils.hpp>
440 : Matrix_core(matrixGraph, numLocalEqns),
442 globalAssembleCalled_(false),
443 changedSinceMark_(true),
444 dbgprefix_(
"MatImpl: ")
454 setBlockMatrix(
true);
457 setBlockMatrix(
false);
461 std::vector<double> zeros;
463 if (srg.
get() != NULL) {
464 for(
size_t row=0; row<srg->
rowNumbers.size(); ++row) {
466 if (rowLength == 0)
continue;
467 zeros.resize(rowLength, 0.0);
468 const double* zerosPtr = &zeros[0];
473 std::map<int,FillableMat*>& remote = getRemotelyOwnedMatrices();
474 for(std::map<int,FillableMat*>::iterator iter=remote.begin(), end=remote.end(); iter!=end; ++iter)
476 iter->second->clear();
492 Matrix_core::parameters(paramset);
500 if (haveBlockMatrix()) {
507 int proc = getOwnerProc(row);
508 const FillableMat* remote_mat = getRemotelyOwnedMatrix(proc);
509 if (remote_mat->hasRow(row)) {
510 const CSVec* row_entries = remote_mat->getRow(row);
511 length = row_entries->size();
525 if (output_level_ > fei::BRIEF_LOGS && output_stream_ != 0) {
526 FEI_OSTREAM& os = *output_stream_;
527 os << dbgprefix_<<
"putScalar("<<scalar<<
")"<<FEI_ENDL;
530 if (haveFEMatrix()) {
531 if (scalar != 0.0)
return(-1);
534 else if (haveBlockMatrix()) {
535 if (globalAssembleCalled_ ==
true) {
543 putScalar_remotelyOwned(scalar);
545 changedSinceMark_ =
true;
553 double* coefs,
int* indices)
const
559 if (haveBlockMatrix()) {
563 coefs, indices, dummy));
569 int proc = getOwnerProc(row);
570 const FillableMat* remote_mat = getRemotelyOwnedMatrix(proc);
571 if (remote_mat->hasRow(row)) {
572 const CSVec* row_entries = remote_mat->getRow(row);
573 const std::vector<int>& row_indices = row_entries->indices();
574 const std::vector<double>& row_coefs = row_entries->coefs();
575 for(
size_t i=0; i<row_indices.size(); ++i) {
576 indices[i] = row_indices[i];
577 coefs[i] = row_coefs[i];
588 int numCols,
const int* cols,
589 const double*
const* values,
592 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
593 FEI_OSTREAM& os = *output_stream_;
594 os << dbgprefix_<<
"sumIn"<<FEI_ENDL;
595 if (output_level_ >= fei::FULL_LOGS) {
596 for(
int i=0; i<numRows; ++i) {
597 for(
int j=0; j<numCols; ++j) {
598 os <<
"("<<rows[i]<<
","<<cols[j]<<
","<<values[i][j]<<
") ";
605 return( giveToMatrix( numRows, rows, numCols, cols, values,
true, format) );
611 int numCols,
const int* cols,
612 const double*
const* values,
615 if (output_level_ > fei::BRIEF_LOGS && output_stream_ != NULL) {
616 FEI_OSTREAM& os = *output_stream_;
617 os <<
"copyIn"<<FEI_ENDL;
618 if (output_level_ >= fei::FULL_LOGS) {
619 for(
int i=0; i<numRows; ++i) {
620 for(
int j=0; j<numCols; ++j) {
621 os <<
"("<<rows[i]<<
","<<cols[j]<<
","<<values[i][j]<<
") ";
627 return( giveToMatrix( numRows, rows, numCols, cols, values,
false, format) );
636 const double*
const* data,
643 if (fieldSize <= 0) ERReturn(-1);
645 work_indices_.resize(fieldSize*2);
646 int* indicesPtr = &work_indices_[0];
650 for(i=1; i<fieldSize; ++i) {
651 indicesPtr[i] = indicesPtr[i-1]+1;
655 &(indicesPtr[fieldSize])) );
656 for(i=fieldSize+1; i<2*fieldSize; ++i) {
657 indicesPtr[i] = indicesPtr[i-1]+1;
660 CHK_ERR( sumIn(fieldSize, indicesPtr, fieldSize, &(indicesPtr[fieldSize]),
679 if (fieldSize <= 0) ERReturn(-1);
681 work_data2D_.resize(fieldSize);
683 const double** data2DPtr = &work_data2D_[0];
684 for(
int i=0; i<fieldSize; ++i) {
685 data2DPtr[i] = &(data[i*fieldSize]);
688 CHK_ERR( sumInFieldData(fieldID, idType, rowID, colID, data2DPtr, format) );
696 const double*
const* values,
int format)
698 if (output_level_ > fei::BRIEF_LOGS && output_stream_ != NULL) {
699 FEI_OSTREAM& os = *output_stream_;
700 os << dbgprefix_<<
"sumIn blkID=" << blockID
701 <<
", connID=" << connectivityID << FEI_ENDL;
706 if (mgraph.
get() == NULL) ERReturn(-1);
710 FEI_OSTRINGSTREAM osstr;
711 osstr <<
"fei::Matrix_Impl::sumIn ERROR, unable to "
712 <<
"look up connectivity-block with ID "<<blockID;
713 throw std::runtime_error(osstr.str());
722 rspace->getGlobalIndicesL(pattern, rowConn, work_indices2_);
724 int numRowIndices = work_indices2_.size();
725 int* rowIndices = &work_indices2_[0];
727 if (haveFEMatrix() || haveBlockMatrix()) {
730 std::map<int,int>::const_iterator
731 iter = connIDs.find(connectivityID);
732 if (iter == connIDs.end()) ERReturn(-1);
733 int connOffset = iter->second;
740 for(
int ii=0; ii<numIDs; ++ii) {
741 numDofs += indicesPerID[ii];
745 work_indices_.resize(numIDs+numDofs);
746 int i, *nodeNumbers = &work_indices_[0];
747 int* dof_ids = nodeNumbers+numIDs;
754 for(i=0; i<numIDs; ++i) {
757 for(
int ii=0; ii<fieldsPerID[i]; ++ii) {
758 int fieldSize = rspace->
getFieldSize(fieldIDs[foffset]);
759 int dof_id = fdofmap.get_dof_id(fieldIDs[foffset++], 0);
760 for(
int j=0; j<fieldSize; ++j) {
761 dof_ids[doffset++] = dof_id + j;
766 if (haveFEMatrix()) {
769 numIndicesPerID, dof_ids, values) );
770 changedSinceMark_ =
true;
773 if (haveBlockMatrix()) {
774 if (format != FEI_DENSE_ROW && format != FEI_DENSE_COL &&
775 format != FEI_BLOCK_DIAGONAL_ROW) {
776 fei::console_out() <<
"fei::Matrix_Impl::sumIn ERROR, for block-matrix, format must"
777 <<
" be FEI_DENSE_ROW or FEI_DENSE_COL."<<FEI_ENDL;
782 int* ptIndices = &work_indices2_[0];
784 int numPtColIndices = symmetric ? numPtIndices : colpattern->
getNumIndices();
786 int len = numPtIndices*numPtColIndices;
788 if (format == FEI_BLOCK_DIAGONAL_ROW) {
790 for(i=0; i<numIDs; ++i) {
791 len += numIndicesPerID[i]*numIndicesPerID[i];
795 double* ccvalues =
new double[len];
797 if (format == FEI_BLOCK_DIAGONAL_ROW) {
798 snl_fei::copy2DBlockDiagToColumnContig(numIDs, numIndicesPerID,
799 values, format, ccvalues);
802 snl_fei::copy2DToColumnContig(numPtIndices, numPtColIndices, values, format,
807 for(i=0; i<numIDs; ++i) {
812 int numColIDs = numIDs;
813 int* colNodeNums = nodeNumbers;
814 const int* colDims = numIndicesPerID;
815 int LDA = numPtColIndices;
816 if (format == FEI_BLOCK_DIAGONAL_ROW) {
818 colNodeNums = &(nodeNumbers[i]);
819 colDims = &(numIndicesPerID[i]);
820 LDA = numIndicesPerID[i];
826 numColIDs, colNodeNums,
828 &(ccvalues[ptRowOffset])) );
829 changedSinceMark_ =
true;
832 if (output_level_ >= fei::FULL_LOGS && output_stream_ != NULL) {
833 FEI_OSTREAM& os = *output_stream_;
834 for(
int ii=0; ii<numIndicesPerID[i]; ++ii) {
835 os <<
"# remote pt-row " << ptIndices[ptRowOffset]+ii <<
" ";
836 for(
int jj=0; jj<numPtIndices; ++jj) {
837 os <<
"("<<ptIndices[jj]<<
","<<values[ptRowOffset+ii][jj]<<
") ";
843 for(
int ii=0; ii<numIndicesPerID[i]; ++ii) {
844 int p=eqnComm_->getOwnerProc(ptIndices[ptRowOffset]+ii);
845 FillableMat* remote_mat = getRemotelyOwnedMatrix(p);
846 remote_mat->sumInRow(ptIndices[ptRowOffset]+ii,
848 values[ptRowOffset+ii],
850 changedSinceMark_ =
true;
854 ptRowOffset += numIndicesPerID[i];
863 int numColIndices = symmetric ? numRowIndices : colpattern->
getNumIndices();
864 int* colIndices = rowIndices;
865 const int* colConn = NULL;
869 mgraph->
getColSpace()->getGlobalIndicesL(colpattern,
870 colConn, work_indices_);
871 colIndices = &work_indices_[0];
875 if (format == FEI_DENSE_ROW || format == FEI_DENSE_COL) {
876 CHK_ERR( sumIn(numRowIndices, rowIndices, numRowIndices, rowIndices,
879 else if (format == FEI_BLOCK_DIAGONAL_ROW) {
885 for(
int i=0; i<totalnumfields; ++i) {
887 if (ioffset+fieldsize > numRowIndices) {
888 FEI_OSTRINGSTREAM osstr;
889 osstr<<
"snl_fei::sumIn, format=FEI_BLOCK_DIAGONAL_ROW, block-sizes"
890 <<
" not consistent with total num-indices."<<FEI_ENDL;
891 throw std::runtime_error(osstr.str());
894 CHK_ERR( sumIn(fieldsize, &(rowIndices[ioffset]),
895 fieldsize, &(rowIndices[ioffset]),
896 &(values[ioffset]), FEI_DENSE_ROW) );
897 ioffset += fieldsize;
898 changedSinceMark_ =
true;
902 FEI_OSTRINGSTREAM osstr;
903 osstr <<
"fei::Matrix_Impl::sumIn, format="<<format<<
" not supported."
905 throw std::runtime_error(osstr.str());
909 if (format != FEI_DENSE_ROW && format != FEI_DENSE_COL) {
910 FEI_OSTRINGSTREAM osstr;
911 osstr <<
"fei::Matrix_Impl::sumIn, format="<<format<<
" not valid with"
912 <<
" un-symmetric matrix contributions."<<FEI_ENDL;
913 throw std::runtime_error(osstr.str());
916 CHK_ERR( sumIn(numRowIndices, rowIndices, numColIndices, colIndices,
918 changedSinceMark_ =
true;
936 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
937 (*output_stream_) << dbgprefix_<<
"setCommSizes"<<FEI_ENDL;
940 Matrix_core::setCommSizes();
947 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
948 (*output_stream_) << dbgprefix_<<
"gatherFromOverlap"<<FEI_ENDL;
951 CHK_ERR( Matrix_core::gatherFromOverlap(accumulate) );
959 int numCols,
const int* cols,
960 const double*
const* values,
964 if (numRows == 0 || numCols == 0) {
968 if (format != FEI_DENSE_ROW && format != FEI_DENSE_COL) {
972 const double** myvalues =
const_cast<const double**
>(values);
973 if (format != FEI_DENSE_ROW) {
974 copyTransposeToWorkArrays(numRows, numCols, values,
975 work_data1D_, work_data2D_);
976 myvalues = &work_data2D_[0];
979 if ((
int)work_ints_.size() < numRows) {
980 work_ints_.resize(numRows);
983 if (haveBlockMatrix()) {
984 return( giveToBlockMatrix(numRows, rows, numCols, cols,
985 myvalues, sumInto) );
990 int* workIntPtr = &work_ints_[0];
991 for(i=0; i<numRows; ++i) {
993 if (row < firstLocalOffset() || row > lastLocalOffset()) {
1002 if (numRemote < 1) {
1003 int err = giveToUnderlyingMatrix(numRows, rows, numCols, cols, myvalues,
1004 sumInto, FEI_DENSE_ROW);
1005 changedSinceMark_ =
true;
1007 FEI_OSTRINGSTREAM osstr;
1008 osstr <<
"fei::Matrix_Impl::giveToMatrix ERROR: err="<<err
1009 <<
" returned from giveToUnderlyingMatrix.";
1010 throw std::runtime_error(osstr.str());
1015 for(i=0; i<numRows; ++i) {
1017 const double*
const rowvalues = myvalues[i];
1019 if (workIntPtr[i] > 0) {
1020 int proc = eqnComm_->getOwnerProc(row);
1021 FillableMat* remote_mat = getRemotelyOwnedMatrix(proc);
1023 if (output_level_ >= fei::FULL_LOGS && output_stream_ != NULL) {
1024 FEI_OSTREAM& os = *output_stream_;
1025 os << dbgprefix_<<
" remote_mat["<<proc<<
"]: ";
1026 for(
int jj=0; jj<numCols; ++jj) {
1027 os <<
"("<<row<<
","<<cols[jj]<<
","<<rowvalues[jj]<<
") ";
1033 remote_mat->sumInRow(row, cols, rowvalues, numCols);
1036 remote_mat->putRow(row, cols, rowvalues, numCols);
1040 CHK_ERR( giveToUnderlyingMatrix(1, &row, numCols, cols, &rowvalues,
1045 changedSinceMark_ =
true;
1051 template<
typename T>
1053 int numCols,
const int* cols,
1054 const double*
const* values,
1057 if (output_level_ >= fei::FULL_LOGS && output_stream_ != NULL) {
1058 FEI_OSTREAM& os = *output_stream_;
1059 os <<
"# giveToBlockMatrix numRows: " << numRows
1060 <<
", numCols: " << numCols << FEI_ENDL;
1063 if (numRows == 0 || numCols == 0) {
1070 std::vector<int> temp((numRows+numCols)*2);
1071 int* tempPtr = &temp[0];
1072 int* blkRows = tempPtr;
1073 int* blkRowOffsets = tempPtr+numRows;
1074 int* blkCols = blkRowOffsets+numRows;
1075 int* blkColOffsets = blkCols+numCols;
1077 CHK_ERR( convertPtToBlk(numRows, rows, numCols, cols,
1078 blkRows, blkRowOffsets,
1079 blkCols, blkColOffsets) );
1081 std::vector<int> blockRows, blockRowSizes;
1082 std::vector<int> blockCols, blockColSizes;
1086 int rowSizeTotal = 0, colSizeTotal = 0;
1088 for(
size_t i=0; i<blockRows.size(); ++i) {
1090 blockRowSizes.push_back(size);
1091 rowSizeTotal += size;
1093 for(
size_t i=0; i<blockCols.size(); ++i) {
1095 blockColSizes.push_back(size);
1096 colSizeTotal += size;
1098 std::vector<double> coefs_1d(rowSizeTotal*colSizeTotal, 0.0);
1099 double* coefs1dPtr = &coefs_1d[0];
1100 std::vector<double*> coefs_2d(blockRows.size()*blockCols.size());
1101 double** coefs2dPtr = &coefs_2d[0];
1105 for(
size_t i=0; i<blockRows.size(); ++i) {
1106 for(
size_t j=0; j<blockCols.size(); ++j) {
1107 coefs2dPtr[blkCounter++] = &(coefs1dPtr[offset]);
1108 offset += blockRowSizes[i]*blockColSizes[j];
1112 for(
int i=0; i<numRows; ++i) {
1114 int rowsize = blockRowSizes[rowind];
1116 for(
int j=0; j<numCols; ++j) {
1118 int pos = blkColOffsets[j]*rowsize + blkRowOffsets[i];
1120 coefs2dPtr[rowind*blockCols.size()+colind][pos] += values[i][j];
1124 for(
size_t i=0; i<blockRows.size(); ++i) {
1125 CHK_ERR( giveToUnderlyingBlockMatrix(blockRows[i],
1131 &coefs2dPtr[i*blockCols.size()],
1134 changedSinceMark_ =
true;
1140 int coefBlkLen = maxBlkEqnSize*maxBlkEqnSize*2;
1142 for(
int i=0; i<numRows; ++i) {
1145 if (row < firstLocalOffset() || row > lastLocalOffset()) {
1146 int proc = eqnComm_->getOwnerProc(row);
1147 FillableMat* remote_mat = getRemotelyOwnedMatrix(proc);
1149 remote_mat->sumInRow(row, cols, values[i], numCols);
1152 remote_mat->putRow(row, cols, values[i], numCols);
1154 changedSinceMark_ =
true;
1162 int blockRowLength = 0;
1166 std::vector<int> blkCols(blockRowLength);
1167 int* blkCols_ptr = &blkCols[0];
1168 std::vector<int> blkColDims(blockRowLength);
1169 int* blkColDims_ptr = &blkColDims[0];
1170 std::vector<double> coefs_1D(blockRowLength*coefBlkLen);
1171 double* coefs_1D_ptr = &coefs_1D[0];
1172 int coefsLen = coefs_1D.size();
1173 std::vector<double*> coefs_2D(blockRowLength);
1174 double** coefs_2D_ptr = &coefs_2D[0];
1176 std::vector<int> LDAs(blockRowLength);
1177 std::fill(LDAs.begin(), LDAs.end(), blockRowSize);
1178 std::fill(coefs_1D.begin(), coefs_1D.end(), 0.0);
1180 int checkRowLen = 0;
1182 blockRow, blockRowLength,
1189 int coefs_1D_offset = 0;
1190 for(
int j=0; j<checkRowLen; ++j) {
1191 coefs_2D_ptr[j] = &(coefs_1D_ptr[coefs_1D_offset]);
1192 coefs_1D_offset += blockRowSize*blkColDims_ptr[j];
1195 for(
int j=0; j<numCols; ++j) {
1196 int blockCol, blkOffset;
1197 CHK_ERR( pointBlockMap->
getPtEqnInfo(cols[j], blockCol, blkOffset) );
1199 for(
int jj=0; jj<blockRowLength; ++jj) {
1201 if (blockCol == blkCols_ptr[jj]) {
1203 coefs_2D_ptr[jj][blkOffset*blockRowSize+blockRowOffset] += values[i][j];
1206 coefs_2D_ptr[jj][blkOffset*blockRowSize+blockRowOffset] = values[i][j];
1215 CHK_ERR( giveToUnderlyingBlockMatrix(blockRow, blockRowSize,
1216 blockRowLength, blkCols_ptr,
1222 changedSinceMark_ =
true;
1229 template<
typename T>
1231 bool matrixMarketFormat)
1234 if (mgraph.
get() == NULL) {
1238 if (haveFEMatrix()) {
1242 if (haveBlockMatrix()) {
1246 static char mmbanner[] =
"%%MatrixMarket matrix coordinate real general";
1255 int globalNumCols = globalNumRows;
1256 if (cspace.
get() != NULL) {
1260 std::vector<int> indices_owned;
1263 int* rowsPtr = &indices_owned[0];
1264 for(
int i=0; i<localNumRows; ++i) {
1266 CHK_ERR( getRowLength(rowsPtr[i], len) );
1270 CHK_MPI(
GlobalSum(getCommunicator(), localNNZ, globalNNZ) );
1273 fei::Barrier(getCommunicator());
1276 FEI_OFSTREAM* outFile = NULL;
1278 outFile =
new FEI_OFSTREAM(filename, IOS_OUT);
1279 FEI_OFSTREAM& ofs = *outFile;
1280 if (matrixMarketFormat) {
1281 ofs << mmbanner << FEI_ENDL;
1282 ofs <<globalNumRows <<
" " <<globalNumCols <<
" " <<globalNNZ <<FEI_ENDL;
1285 ofs <<globalNumRows <<
" " <<globalNumCols <<FEI_ENDL;
1288 else outFile =
new FEI_OFSTREAM(filename, IOS_APP);
1290 outFile->setf(IOS_SCIENTIFIC, IOS_FLOATFIELD);
1291 outFile->precision(13);
1292 FEI_OFSTREAM& ofs = *outFile;
1296 for(
int i=firstLocalOffset(); i<=lastLocalOffset(); ++i) {
1297 CHK_ERR( getRowLength(i, rowLength) );
1299 work_indices_.resize(rowLength);
1300 work_data1D_.resize(rowLength);
1302 int* indPtr = &work_indices_[0];
1303 double* coefPtr = &work_data1D_[0];
1305 CHK_ERR( copyOutRow(i, rowLength, coefPtr, indPtr) );
1307 fei::insertion_sort_with_companions<double>(rowLength,
1310 for(
int j=0; j<rowLength; ++j) {
1311 if (matrixMarketFormat) {
1312 ofs << i+1 <<
" "<<indPtr[j]+1<<
" "<<coefPtr[j]<<FEI_ENDL;
1315 ofs << i <<
" "<<indPtr[j]<<
" "<<coefPtr[j]<<FEI_ENDL;
1327 template<
typename T>
1329 bool matrixMarketFormat)
1332 if (mgraph.
get() == NULL) {
1336 if (haveFEMatrix()) {
1340 if (haveBlockMatrix()) {
1344 static char mmbanner[] =
"%%MatrixMarket matrix coordinate real general";
1350 std::vector<int> indices_owned;
1353 int* rowsPtr = &indices_owned[0];
1354 for(
int i=0; i<localNumRows; ++i) {
1356 CHK_ERR( getRowLength(rowsPtr[i], len) );
1360 CHK_MPI(
fei::GlobalSum(getCommunicator(), localNNZ, globalNNZ) );
1362 IOS_FMTFLAGS oldf = ostrm.setf(IOS_SCIENTIFIC, IOS_FLOATFIELD);
1365 fei::Barrier(getCommunicator());
1369 int globalSize = globalOffsets()[
numProcs()]-1;
1370 if (matrixMarketFormat) {
1371 ostrm << mmbanner << FEI_ENDL;
1372 ostrm << globalSize <<
" " << globalSize <<
" " << globalNNZ << FEI_ENDL;
1375 ostrm << globalSize <<
" " << globalSize << FEI_ENDL;
1381 for(
int i=firstLocalOffset(); i<=lastLocalOffset(); ++i) {
1382 CHK_ERR( getRowLength(i, rowLength) );
1384 work_indices_.resize(rowLength);
1385 work_data1D_.resize(rowLength);
1387 int* indPtr = &work_indices_[0];
1388 double* coefPtr = &work_data1D_[0];
1390 CHK_ERR( copyOutRow(i, rowLength, coefPtr, indPtr) );
1392 for(
int j=0; j<rowLength; ++j) {
1393 ostrm << i <<
" " << indPtr[j] <<
" " << coefPtr[j] << FEI_ENDL;
1398 ostrm.setf(oldf, IOS_FLOATFIELD);
1403 #endif // _fei_Matrix_Impl_hpp_
int GlobalSum(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
GlobalIDType getNumber() const
int copyIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)
int sortedListInsert(const T &item, std::vector< T > &list)
const int * getRowConnectivity(int ID) const
virtual int getGlobalNumSlaveConstraints() const =0
int writeToStream(FEI_OSTREAM &ostrm, bool matrixMarketFormat=true)
int sumInFieldData(int fieldID, int idType, int rowID, int colID, const double *const *data, int format=0)
const std::map< int, int > & getConnectivityIDs() const
int getGlobalNumIndices() const
int getNumIndices() const
const int * getNumFieldsPerID() const
Matrix_Impl(fei::SharedPtr< T > matrix, fei::SharedPtr< fei::MatrixGraph > matrixGraph, int numLocalEqns, bool zeroSharedRows=true)
int getLocalNumRows() const
std::vector< int > rowNumbers
int copyOutRow(int row, int len, double *coefs, int *indices) const
virtual const fei::ConnectivityBlock * getConnectivityBlock(int blockID) const =0
const int * getFieldIDs() const
bool usingBlockEntryStorage()
int getTotalNumFields() const
int multiply(fei::Vector *x, fei::Vector *y)
virtual fei::SharedPtr< fei::SparseRowGraph > getRemotelyOwnedGraphRows()=0
int giveToUnderlyingMatrix(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, bool sumInto, int format)
int giveToUnderlyingBlockMatrix(int row, int rowDim, int numCols, const int *cols, const int *LDAs, const int *colDims, const double *const *values, bool sumInto)
std::vector< int > packedColumnIndices
std::vector< int > rowOffsets
int gatherFromOverlap(bool accumulate=true)
int getGlobalIndex(int idType, int ID, int fieldID, int fieldOffset, int whichComponentOfField, int &globalIndex)
int getGlobalIndices(int numIDs, const int *IDs, int idType, int fieldID, int *globalIndices)
virtual fei::SharedPtr< fei::VectorSpace > getRowSpace()=0
int binarySearch(const T &item, const T *list, int len)
fei::SharedPtr< fei::MatrixGraph > getMatrixGraph() const
const fei::Pattern * getColPattern() const
static int getRowLength(T *mat, int row, int &length)
int putScalar(double scalar)
void setMatrixGraph(fei::SharedPtr< fei::MatrixGraph > matrixGraph)
int getBlkEqnOffset(int blkEqn, int ptEqn)
virtual fei::SharedPtr< fei::VectorSpace > getColSpace()=0
fei::SharedPtr< T > getMatrix()
int eqnToBlkEqn(int eqn) const
const int * getNumIndicesPerID() const
int getIndices_Owned(std::vector< int > &globalIndices) const
std::ostream & console_out()
int parameters(const fei::ParameterSet ¶mset)
int getBlkEqnSize(int blkEqn)
int localProc(MPI_Comm comm)
int getGlobalNumRows() const
int writeToFile(const char *filename, bool matrixMarketFormat=true)
unsigned getFieldSize(int fieldID)
int getPtEqnInfo(int ptEqn, int &blkEqn, int &blkOffset)
static int copyOutRow(T *mat, int row, int len, double *coefs, int *indices)
const int * getColConnectivity(int ID) const
int getRecordCollection(int idType, snl_fei::RecordCollection *&records)
int sumIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)
int getRowLength(int row, int &length) const
const fei::Pattern * getRowPattern() const
static int putValuesIn(T *mat, int numRows, const int *rows, int numCols, const int *cols, const double *const *values, bool sum_into)
int numProcs(MPI_Comm comm)
int getNumIndices_Owned() const