10 #ifndef TPETRA_MATRIX_IO_DEF
11 #define TPETRA_MATRIX_IO_DEF
13 #include "Tpetra_CrsMatrix.hpp"
14 #include "Tpetra_MatrixIO.hpp"
20 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
21 void readHBMatrix(
const std::string &filename,
22 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm,
25 const Teuchos::RCP<Teuchos::ParameterList> ¶ms) {
28 const int myRank = comm->getRank();
29 int numRows, numCols, numNZ;
30 Teuchos::ArrayRCP<Scalar> svals;
31 Teuchos::ArrayRCP<GlobalOrdinal> colinds;
32 Teuchos::ArrayRCP<int> rowptrs;
33 Teuchos::ArrayRCP<size_t> nnzPerRow;
36 bool isSymmetric =
false;
37 Teuchos::ArrayRCP<double> dvals;
38 Teuchos::ArrayRCP<int> colptrs, rowinds;
40 Tpetra::Utils::readHBMatDouble(filename, numRows, numCols, numNZ, type, colptrs, rowinds, dvals);
41 TEUCHOS_TEST_FOR_EXCEPT(type.size() != 3);
42 if (type[0] !=
'R' && type[0] !=
'r') {
46 if (fail == 0 && numNZ > 0) {
47 if (type[1] ==
'S' || type[1] ==
's') {
53 if (fail == 0 && numNZ > 0) {
55 nnzPerRow = Teuchos::arcp<size_t>(numRows);
56 std::fill(nnzPerRow.begin(), nnzPerRow.end(), 0);
57 for (Teuchos::ArrayRCP<int>::const_iterator ri = rowinds.begin(); ri != rowinds.end(); ++ri) {
63 for (
int c = 0; c < numCols; ++c) {
65 for (
int i = colptrs[c] - 1; i != colptrs[c + 1] - 1; ++i) {
66 if (rowinds[i] != c + 1) {
74 svals = Teuchos::arcp<Scalar>(numNZ);
75 colinds = Teuchos::arcp<GlobalOrdinal>(numNZ);
76 rowptrs = Teuchos::arcp<int>(numRows + 1);
78 #ifdef HAVE_TPETRA_DEBUG
79 Teuchos::ArrayRCP<size_t> nnzPerRow_debug(nnzPerRow.size());
80 std::copy(nnzPerRow.begin(), nnzPerRow.end(), nnzPerRow_debug.begin());
82 for (
int j = 1; j <= numRows; ++j) {
83 rowptrs[j] = rowptrs[j - 1] + nnzPerRow[j - 1];
87 for (
int col = 0; col < numCols; ++col) {
88 for (
int i = colptrs[col] - 1; i != colptrs[col + 1] - 1; ++i) {
89 const int row = rowinds[i] - 1;
91 const size_t entry = rowptrs[row] + nnzPerRow[row];
92 svals[entry] = Teuchos::as<Scalar>(dvals[i]);
93 colinds[entry] = Teuchos::as<GlobalOrdinal>(col);
95 if (isSymmetric && row != col) {
97 const size_t symentry = rowptrs[col] + nnzPerRow[col];
98 svals[symentry] = Teuchos::as<Scalar>(dvals[i]);
99 colinds[symentry] = Teuchos::as<GlobalOrdinal>(row);
104 #ifdef HAVE_TPETRA_DEBUG
107 typename Teuchos::ArrayRCP<size_t>::const_iterator it1, it2;
108 for (it1 = nnzPerRow.begin(), it2 = nnzPerRow_debug.begin(); it1 != nnzPerRow.end(); ++it1, ++it2) {
114 TEUCHOS_TEST_FOR_EXCEPTION(!isequal || nnzPerRow.size() != nnzPerRow_debug.size(), std::logic_error,
115 "Tpetra::Utils::readHBMatrix(): Logic error.");
122 broadcast(*comm, 0, &fail);
123 TEUCHOS_TEST_FOR_EXCEPTION(fail == 1, std::runtime_error,
"Tpetra::Utils::readHBMatrix() can only read Real matrices.");
125 broadcast(*comm, 0, &numRows);
126 broadcast(*comm, 0, &numCols);
128 if (rowMap == Teuchos::null) {
129 rowMap = Teuchos::rcp(
new map_type(static_cast<global_size_t>(numRows),
130 static_cast<GlobalOrdinal>(0),
131 comm, GloballyDistributed));
133 TEUCHOS_TEST_FOR_EXCEPTION(rowMap->getGlobalNumElements() != (
global_size_t)numRows, std::runtime_error,
134 "Tpetra::Utils::readHBMatrix(): specified map has incorrect number of elements.");
135 TEUCHOS_TEST_FOR_EXCEPTION(rowMap->isDistributed() ==
false && comm->getSize() > 1, std::runtime_error,
136 "Tpetra::Utils::readHBMatrix(): specified map is not distributed.");
138 Teuchos::Array<size_t> myNNZ(rowMap->getLocalNumElements());
140 LocalOrdinal numRowsAlreadyDistributed = rowMap->getLocalNumElements();
141 std::copy(nnzPerRow.begin(), nnzPerRow.begin() + numRowsAlreadyDistributed, myNNZ.begin());
142 for (
int p = 1; p < Teuchos::size(*comm); ++p) {
144 Teuchos::receive(*comm, p, &numRowsForP);
146 Teuchos::send<int, size_t>(*comm, numRowsForP, nnzPerRow(numRowsAlreadyDistributed, numRowsForP).getRawPtr(), p);
147 numRowsAlreadyDistributed += numRowsForP;
151 const size_t numMyRows = rowMap->getLocalNumElements();
152 Teuchos::send(*comm, numMyRows, 0);
154 Teuchos::receive<int, size_t>(*comm, 0, numMyRows, myNNZ(0, numMyRows).getRawPtr());
157 nnzPerRow = Teuchos::null;
159 Teuchos::RCP<const map_type> domMap;
160 if (numRows == numCols) {
163 domMap = createUniformContigMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(numCols, comm);
170 Teuchos::Array<size_t> empty;
171 std::swap(myNNZ, empty);
173 if (myRank == 0 && numNZ > 0) {
174 for (
int r = 0; r < numRows; ++r) {
175 const LocalOrdinal nnz = rowptrs[r + 1] - rowptrs[r];
177 Teuchos::ArrayView<const GlobalOrdinal> inds = colinds(rowptrs[r], nnz);
178 Teuchos::ArrayView<const Scalar> vals = svals(rowptrs[r], nnz);
179 A->insertGlobalValues(r, inds, vals);
184 colinds = Teuchos::null;
185 svals = Teuchos::null;
186 rowptrs = Teuchos::null;
187 A->fillComplete(domMap, rowMap, params);
199 #define TPETRA_MATRIXIO_INSTANT(SCALAR, LO, GO, NODE) \
201 readHBMatrix<SCALAR, LO, GO, NODE>(const std::string &, \
202 const Teuchos::RCP<const Teuchos::Comm<int> > &, \
203 Teuchos::RCP<CrsMatrix<SCALAR, LO, GO, NODE> > &, \
204 Teuchos::RCP<const Tpetra::Map<LO, GO, NODE> >, \
205 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.