10 #ifndef TPETRA_MATRIX_IO_DEF
11 #define TPETRA_MATRIX_IO_DEF
13 #include "Tpetra_CrsMatrix.hpp"
14 #include "Tpetra_MatrixIO.hpp"
21 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
23 readHBMatrix (
const std::string &filename,
24 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
27 const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
31 const int myRank = comm->getRank();
32 int numRows,numCols,numNZ;
33 Teuchos::ArrayRCP<Scalar> svals;
34 Teuchos::ArrayRCP<GlobalOrdinal> colinds;
35 Teuchos::ArrayRCP<int> rowptrs;
36 Teuchos::ArrayRCP<size_t> nnzPerRow;
39 bool isSymmetric=
false;
40 Teuchos::ArrayRCP<double> dvals;
41 Teuchos::ArrayRCP<int> colptrs, rowinds;
43 Tpetra::Utils::readHBMatDouble(filename,numRows,numCols,numNZ,type,colptrs,rowinds,dvals);
44 TEUCHOS_TEST_FOR_EXCEPT(type.size() != 3);
45 if (type[0] !=
'R' && type[0] !=
'r') {
49 if (fail == 0 && numNZ > 0) {
50 if (type[1] ==
'S' || type[1] ==
's') {
57 if (fail == 0 && numNZ > 0) {
59 nnzPerRow = Teuchos::arcp<size_t>(numRows);
60 std::fill(nnzPerRow.begin(), nnzPerRow.end(), 0);
61 for (Teuchos::ArrayRCP<int>::const_iterator ri=rowinds.begin(); ri != rowinds.end(); ++ri) {
67 for (
int c=0; c < numCols; ++c) {
69 for (
int i=colptrs[c]-1; i != colptrs[c+1]-1; ++i) {
70 if (rowinds[i] != c+1) {
78 svals = Teuchos::arcp<Scalar>(numNZ);
79 colinds = Teuchos::arcp<GlobalOrdinal>(numNZ);
80 rowptrs = Teuchos::arcp<int>(numRows+1);
82 #ifdef HAVE_TPETRA_DEBUG
83 Teuchos::ArrayRCP<size_t> nnzPerRow_debug(nnzPerRow.size());
84 std::copy(nnzPerRow.begin(), nnzPerRow.end(), nnzPerRow_debug.begin());
86 for (
int j=1; j <= numRows; ++j) {
87 rowptrs[j] = rowptrs[j-1] + nnzPerRow[j-1];
91 for (
int col=0; col<numCols; ++col) {
92 for (
int i=colptrs[col]-1; i != colptrs[col+1]-1; ++i) {
93 const int row = rowinds[i]-1;
95 const size_t entry = rowptrs[row] + nnzPerRow[row];
96 svals[entry] = Teuchos::as<Scalar>(dvals[i]);
97 colinds[entry] = Teuchos::as<GlobalOrdinal>(col);
99 if (isSymmetric && row != col) {
101 const size_t symentry = rowptrs[col] + nnzPerRow[col];
102 svals[symentry] = Teuchos::as<Scalar>(dvals[i]);
103 colinds[symentry] = Teuchos::as<GlobalOrdinal>(row);
108 #ifdef HAVE_TPETRA_DEBUG
111 typename Teuchos::ArrayRCP<size_t>::const_iterator it1, it2;
112 for (it1 = nnzPerRow.begin(), it2 = nnzPerRow_debug.begin(); it1 != nnzPerRow.end(); ++it1, ++it2) {
118 TEUCHOS_TEST_FOR_EXCEPTION(!isequal || nnzPerRow.size() != nnzPerRow_debug.size(), std::logic_error,
119 "Tpetra::Utils::readHBMatrix(): Logic error.");
126 broadcast(*comm,0,&fail);
127 TEUCHOS_TEST_FOR_EXCEPTION(fail == 1, std::runtime_error,
"Tpetra::Utils::readHBMatrix() can only read Real matrices.");
129 broadcast(*comm,0,&numRows);
130 broadcast(*comm,0,&numCols);
132 if (rowMap == Teuchos::null) {
133 rowMap = Teuchos::rcp (
new map_type (static_cast<global_size_t> (numRows),
134 static_cast<GlobalOrdinal> (0),
135 comm, GloballyDistributed));
138 TEUCHOS_TEST_FOR_EXCEPTION( rowMap->getGlobalNumElements() != (
global_size_t)numRows, std::runtime_error,
139 "Tpetra::Utils::readHBMatrix(): specified map has incorrect number of elements.");
140 TEUCHOS_TEST_FOR_EXCEPTION( rowMap->isDistributed() ==
false && comm->getSize() > 1, std::runtime_error,
141 "Tpetra::Utils::readHBMatrix(): specified map is not distributed.");
143 Teuchos::Array<size_t> myNNZ (rowMap->getLocalNumElements ());
145 LocalOrdinal numRowsAlreadyDistributed = rowMap->getLocalNumElements();
146 std::copy(nnzPerRow.begin(), nnzPerRow.begin()+numRowsAlreadyDistributed, myNNZ.begin());
147 for (
int p=1; p < Teuchos::size(*comm); ++p) {
149 Teuchos::receive(*comm,p,&numRowsForP);
151 Teuchos::send<int,size_t>(*comm,numRowsForP,nnzPerRow(numRowsAlreadyDistributed,numRowsForP).getRawPtr(),p);
152 numRowsAlreadyDistributed += numRowsForP;
157 const size_t numMyRows = rowMap->getLocalNumElements();
158 Teuchos::send(*comm,numMyRows,0);
160 Teuchos::receive<int,size_t>(*comm,0,numMyRows,myNNZ(0,numMyRows).getRawPtr());
163 nnzPerRow = Teuchos::null;
165 Teuchos::RCP<const map_type> domMap;
166 if (numRows == numCols) {
170 domMap = createUniformContigMapWithNode<LocalOrdinal,GlobalOrdinal,Node>(numCols,comm);
177 Teuchos::Array<size_t> empty;
178 std::swap (myNNZ, empty);
180 if (myRank == 0 && numNZ > 0) {
181 for (
int r=0; r < numRows; ++r) {
182 const LocalOrdinal nnz = rowptrs[r+1] - rowptrs[r];
184 Teuchos::ArrayView<const GlobalOrdinal> inds = colinds(rowptrs[r],nnz);
185 Teuchos::ArrayView<const Scalar> vals = svals( rowptrs[r],nnz);
186 A->insertGlobalValues(r, inds, vals);
191 colinds = Teuchos::null;
192 svals = Teuchos::null;
193 rowptrs = Teuchos::null;
194 A->fillComplete(domMap,rowMap,params);
208 #define TPETRA_MATRIXIO_INSTANT(SCALAR,LO,GO,NODE) \
210 readHBMatrix< SCALAR, LO, GO, NODE > (const std::string&, \
211 const Teuchos::RCP<const Teuchos::Comm<int> > &, \
212 Teuchos::RCP<CrsMatrix< SCALAR, LO, GO, NODE > >&, \
213 Teuchos::RCP<const Tpetra::Map< LO, GO, NODE> >, \
214 const Teuchos::RCP<Teuchos::ParameterList>& );
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
size_t global_size_t
Global size_t object.
A parallel distribution of indices over processes.