MueLu  Version of the Day
MueLu_Utilities_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef MUELU_UTILITIES_DEF_HPP
47 #define MUELU_UTILITIES_DEF_HPP
48 
49 #include <Teuchos_DefaultComm.hpp>
50 #include <Teuchos_ParameterList.hpp>
51 
52 #include "MueLu_ConfigDefs.hpp"
53 
54 #ifdef HAVE_MUELU_EPETRA
55 # ifdef HAVE_MPI
56 # include "Epetra_MpiComm.h"
57 # endif
58 #endif
59 
60 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_EPETRAEXT)
61 #include <EpetraExt_MatrixMatrix.h>
62 #include <EpetraExt_RowMatrixOut.h>
64 #include <EpetraExt_CrsMatrixIn.h>
66 #include <EpetraExt_BlockMapIn.h>
67 #include <Xpetra_EpetraUtils.hpp>
68 #include <Xpetra_EpetraMultiVector.hpp>
69 #include <EpetraExt_BlockMapOut.h>
70 #endif
71 
72 #ifdef HAVE_MUELU_TPETRA
73 #include <MatrixMarket_Tpetra.hpp>
74 #include <Tpetra_RowMatrixTransposer.hpp>
75 #include <TpetraExt_MatrixMatrix.hpp>
76 #include <Xpetra_TpetraMultiVector.hpp>
77 #include <Xpetra_TpetraCrsMatrix.hpp>
78 #include <Xpetra_TpetraBlockCrsMatrix.hpp>
79 #endif
80 
81 #ifdef HAVE_MUELU_EPETRA
82 #include <Xpetra_EpetraMap.hpp>
83 #endif
84 
85 #include <Xpetra_BlockedCrsMatrix.hpp>
86 //#include <Xpetra_DefaultPlatform.hpp>
87 #include <Xpetra_Import.hpp>
88 #include <Xpetra_ImportFactory.hpp>
89 #include <Xpetra_Map.hpp>
90 #include <Xpetra_MapFactory.hpp>
91 #include <Xpetra_Matrix.hpp>
92 #include <Xpetra_MatrixFactory.hpp>
93 #include <Xpetra_MultiVector.hpp>
94 #include <Xpetra_MultiVectorFactory.hpp>
95 #include <Xpetra_Operator.hpp>
96 #include <Xpetra_Vector.hpp>
97 #include <Xpetra_VectorFactory.hpp>
98 
99 #include <Xpetra_MatrixMatrix.hpp>
100 
101 #include <MueLu_Utilities_decl.hpp>
102 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_ML)
103 #include <ml_operator.h>
104 #include <ml_epetra_utils.h>
105 #endif
106 
107 namespace MueLu {
108 
109 #ifdef HAVE_MUELU_EPETRA
110  using Xpetra::EpetraCrsMatrix; // TODO: mv in Xpetra_UseShortNamesScalar
111  using Xpetra::EpetraMultiVector;
112 #endif
113 
114 #ifdef HAVE_MUELU_EPETRA
115  //defined after Utils class
116  template<typename SC,typename LO,typename GO,typename NO>
117  RCP<Xpetra::CrsMatrixWrap<SC,LO,GO,NO> > Convert_Epetra_CrsMatrix_ToXpetra_CrsMatrixWrap(RCP<Epetra_CrsMatrix> &epAB);
118 #endif
119 
120 #ifdef HAVE_MUELU_EPETRA
121  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
122  RCP<const Epetra_MultiVector> Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MV2EpetraMV(const RCP<MultiVector> Vec) {
123  RCP<const EpetraMultiVector > tmpVec = rcp_dynamic_cast<EpetraMultiVector>(Vec);
124  if (tmpVec == Teuchos::null)
125  throw Exceptions::BadCast("Cast from Xpetra::MultiVector to Xpetra::EpetraMultiVector failed");
126  return tmpVec->getEpetra_MultiVector();
127  }
128 
129  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
130  RCP<Epetra_MultiVector> Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MV2NonConstEpetraMV(RCP<MultiVector> Vec) {
131  RCP<const EpetraMultiVector> tmpVec = rcp_dynamic_cast<EpetraMultiVector>(Vec);
132  if (tmpVec == Teuchos::null)
133  throw Exceptions::BadCast("Cast from Xpetra::MultiVector to Xpetra::EpetraMultiVector failed");
134  return tmpVec->getEpetra_MultiVector();
135  }
136 
137  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
139  const EpetraMultiVector& tmpVec = dynamic_cast<const EpetraMultiVector&>(Vec);
140  return *(tmpVec.getEpetra_MultiVector());
141  }
142 
143  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
144  const Epetra_MultiVector& Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MV2EpetraMV(const MultiVector& Vec) {
145  const EpetraMultiVector& tmpVec = dynamic_cast<const EpetraMultiVector&>(Vec);
146  return *(tmpVec.getEpetra_MultiVector());
147  }
148 
149  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
150  RCP<const Epetra_CrsMatrix> Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2EpetraCrs(RCP<const Matrix> Op) {
151  RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(Op);
152  if (crsOp == Teuchos::null)
153  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
154  const RCP<const EpetraCrsMatrix>& tmp_ECrsMtx = rcp_dynamic_cast<const EpetraCrsMatrix>(crsOp->getCrsMatrix());
155  if (tmp_ECrsMtx == Teuchos::null)
156  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
157  return tmp_ECrsMtx->getEpetra_CrsMatrix();
158  }
159 
160  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
162  RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(Op);
163  if (crsOp == Teuchos::null)
164  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
165  const RCP<const EpetraCrsMatrix> &tmp_ECrsMtx = rcp_dynamic_cast<const EpetraCrsMatrix>(crsOp->getCrsMatrix());
166  if (tmp_ECrsMtx == Teuchos::null)
167  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
168  return tmp_ECrsMtx->getEpetra_CrsMatrixNonConst();
169  }
170 
171  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
172  const Epetra_CrsMatrix& Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2EpetraCrs(const Matrix& Op) {
173  try {
174  const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
175  try {
176  const EpetraCrsMatrix& tmp_ECrsMtx = dynamic_cast<const EpetraCrsMatrix&>(*crsOp.getCrsMatrix());
177  return *tmp_ECrsMtx.getEpetra_CrsMatrix();
178  } catch (std::bad_cast) {
179  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
180  }
181  } catch (std::bad_cast) {
182  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
183  }
184  }
185 
186  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
188  try {
189  CrsMatrixWrap& crsOp = dynamic_cast<CrsMatrixWrap&>(Op);
190  try {
191  EpetraCrsMatrix& tmp_ECrsMtx = dynamic_cast<EpetraCrsMatrix&>(*crsOp.getCrsMatrix());
192  return *tmp_ECrsMtx.getEpetra_CrsMatrixNonConst();
193  } catch (std::bad_cast) {
194  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
195  }
196  } catch (std::bad_cast) {
197  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
198  }
199  }
200 
201  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
203  RCP<const Xpetra::EpetraMap> xeMap = rcp_dynamic_cast<const Xpetra::EpetraMap>(rcpFromRef(map));
204  if (xeMap == Teuchos::null)
205  throw Exceptions::BadCast("Utils::Map2EpetraMap : Cast from Xpetra::Map to Xpetra::EpetraMap failed");
206  return xeMap->getEpetra_Map();
207  }
208 #endif
209 
210 #ifdef HAVE_MUELU_TPETRA
211  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
212  RCP<const Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
214  RCP<const TpetraMultiVector > tmpVec = rcp_dynamic_cast<TpetraMultiVector>(Vec);
215  if (tmpVec == Teuchos::null)
216  throw Exceptions::BadCast("Cast from Xpetra::MultiVector to Xpetra::TpetraMultiVector failed");
217  return tmpVec->getTpetra_MultiVector();
218  }
219 
220  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
221  RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MV2NonConstTpetraMV(RCP<MultiVector> Vec) {
222  RCP<const TpetraMultiVector> tmpVec = rcp_dynamic_cast<TpetraMultiVector>(Vec);
223  if (tmpVec == Teuchos::null)
224  throw Exceptions::BadCast("Cast from Xpetra::MultiVector to Xpetra::TpetraMultiVector failed");
225  return tmpVec->getTpetra_MultiVector();
226  }
227 
228  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
229  Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> & Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MV2NonConstTpetraMV(MultiVector& Vec) {
230  const TpetraMultiVector& tmpVec = dynamic_cast<const TpetraMultiVector&>(Vec);
231  return *(tmpVec.getTpetra_MultiVector());
232  }
233 
234  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
235  RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MV2NonConstTpetraMV2(MultiVector &Vec) {
236  const TpetraMultiVector& tmpVec = dynamic_cast<const TpetraMultiVector&>(Vec);
237  return tmpVec.getTpetra_MultiVector();
238  }
239 
240  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
241  const Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>&
243  const TpetraMultiVector& tmpVec = dynamic_cast<const TpetraMultiVector&>(Vec);
244  return *(tmpVec.getTpetra_MultiVector());
245  }
246 
247  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
248  RCP<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2TpetraCrs(RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Op) {
249  // Get the underlying Tpetra Mtx
250  RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(Op);
251  if (crsOp == Teuchos::null)
252  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
253  const RCP<const TpetraCrsMatrix> &tmp_ECrsMtx = rcp_dynamic_cast<const TpetraCrsMatrix>(crsOp->getCrsMatrix());
254  if (tmp_ECrsMtx == Teuchos::null)
255  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
256  return tmp_ECrsMtx->getTpetra_CrsMatrix();
257  }
258 
259  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
260  RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2NonConstTpetraCrs(RCP<Matrix> Op) {
261  RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(Op);
262  if (crsOp == Teuchos::null)
263  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
264  const RCP<const TpetraCrsMatrix> &tmp_ECrsMtx = rcp_dynamic_cast<const TpetraCrsMatrix>(crsOp->getCrsMatrix());
265  if (tmp_ECrsMtx == Teuchos::null)
266  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
267  return tmp_ECrsMtx->getTpetra_CrsMatrixNonConst();
268  }
269 
270  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
271  const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2TpetraCrs(const Matrix& Op) {
272  try {
273  const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
274  try {
275  const TpetraCrsMatrix& tmp_ECrsMtx = dynamic_cast<const TpetraCrsMatrix&>(*crsOp.getCrsMatrix());
276  return *tmp_ECrsMtx.getTpetra_CrsMatrix();
277  } catch (std::bad_cast) {
278  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
279  }
280  } catch (std::bad_cast) {
281  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
282  }
283  }
284 
285  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
286  Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2NonConstTpetraCrs(Matrix& Op) {
287  try {
288  CrsMatrixWrap& crsOp = dynamic_cast<CrsMatrixWrap&>(Op);
289  try {
290  TpetraCrsMatrix& tmp_ECrsMtx = dynamic_cast<TpetraCrsMatrix&>(*crsOp.getCrsMatrix());
291  return *tmp_ECrsMtx.getTpetra_CrsMatrixNonConst();
292  } catch (std::bad_cast) {
293  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
294  }
295  } catch (std::bad_cast) {
296  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
297  }
298  }
299 
300  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
301  RCP<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2TpetraRow(RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Op) {
302  RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(Op);
303  if (crsOp == Teuchos::null)
304  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
305 
306  RCP<const CrsMatrix> crsMat = crsOp->getCrsMatrix();
307  const RCP<const TpetraCrsMatrix> tmp_Crs = rcp_dynamic_cast<const TpetraCrsMatrix>(crsMat);
308  RCP<const Xpetra::TpetraBlockCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmp_BlockCrs;
309  if(!tmp_Crs.is_null()) {
310  return tmp_Crs->getTpetra_CrsMatrixNonConst();
311  }
312  else {
313  tmp_BlockCrs= rcp_dynamic_cast<const Xpetra::TpetraBlockCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(crsMat);
314  if (tmp_BlockCrs.is_null())
315  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix and Xpetra::TpetraBlockCrsMatrix failed");
316  return tmp_BlockCrs->getTpetra_BlockCrsMatrixNonConst();
317  }
318  }
319 
320  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
321  RCP<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2NonConstTpetraRow(RCP<Matrix> Op) {
322  RCP<const CrsMatrixWrap> crsOp = rcp_dynamic_cast<const CrsMatrixWrap>(Op);
323  if (crsOp == Teuchos::null)
324  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
325 
326  RCP<const CrsMatrix> crsMat = crsOp->getCrsMatrix();
327  const RCP<const TpetraCrsMatrix> tmp_Crs = rcp_dynamic_cast<const TpetraCrsMatrix>(crsMat);
328  RCP<const Xpetra::TpetraBlockCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmp_BlockCrs;
329  if(!tmp_Crs.is_null()) {
330  return tmp_Crs->getTpetra_CrsMatrixNonConst();
331  }
332  else {
333  tmp_BlockCrs= rcp_dynamic_cast<const Xpetra::TpetraBlockCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(crsMat);
334  if (tmp_BlockCrs.is_null())
335  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix and Xpetra::TpetraBlockCrsMatrix failed");
336  return tmp_BlockCrs->getTpetra_BlockCrsMatrixNonConst();
337  }
338  }
339 
340 
341  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
342  const RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal,Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Map2TpetraMap(const Map& map) {
343  const RCP<const TpetraMap>& tmp_TMap = rcp_dynamic_cast<const TpetraMap>(rcpFromRef(map));
344  if (tmp_TMap == Teuchos::null)
345  throw Exceptions::BadCast("Utils::Map2TpetraMap : Cast from Xpetra::Map to Xpetra::TpetraMap failed");
346  return tmp_TMap->getTpetra_Map();
347  }
348 #endif
349 
350  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
351  RCP<Xpetra::Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > Utils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Crs2Op(RCP<Xpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > Op) {
352  if (Op.is_null())
353  return Teuchos::null;
354 
355  return rcp(new CrsMatrixWrap(Op));
356  }
357 
358  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
359  Teuchos::ArrayRCP<Scalar> Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetMatrixDiagonal(const Matrix& A) {
360 
361  size_t numRows = A.getRowMap()->getNodeNumElements();
362  Teuchos::ArrayRCP<SC> diag(numRows);
363 
364  Teuchos::ArrayView<const LO> cols;
365  Teuchos::ArrayView<const SC> vals;
366  for (size_t i = 0; i < numRows; ++i) {
367  A.getLocalRowView(i, cols, vals);
368 
369  LO j = 0;
370  for (; j < cols.size(); ++j) {
371  if (Teuchos::as<size_t>(cols[j]) == i) {
372  diag[i] = vals[j];
373  break;
374  }
375  }
376  if (j == cols.size()) {
377  // Diagonal entry is absent
378  diag[i] = Teuchos::ScalarTraits<SC>::zero();
379  }
380  }
381 
382  return diag;
383  } //GetMatrixDiagonal
384 
385  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
386  Teuchos::RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetMatrixDiagonalInverse(const Matrix& A,Magnitude tol) {
387  RCP<const Map> rowMap = A.getRowMap();
388  RCP<Vector> diag = VectorFactory::Build(rowMap);
389  ArrayRCP<SC> diagVals = diag->getDataNonConst(0);
390 
391  size_t numRows = rowMap->getNodeNumElements();
392 
393  Teuchos::ArrayView<const LO> cols;
394  Teuchos::ArrayView<const SC> vals;
395  for (size_t i = 0; i < numRows; ++i) {
396  A.getLocalRowView(i, cols, vals);
397 
398  LO j = 0;
399  for (; j < cols.size(); ++j) {
400  if (Teuchos::as<size_t>(cols[j]) == i) {
401  if(Teuchos::ScalarTraits<SC>::magnitude(vals[j]) > tol)
402  diagVals[i] = Teuchos::ScalarTraits<SC>::one() / vals[j];
403  else
404  diagVals[i]=Teuchos::ScalarTraits<SC>::zero();
405  break;
406  }
407  }
408  if (j == cols.size()) {
409  // Diagonal entry is absent
410  diagVals[i]=Teuchos::ScalarTraits<SC>::zero();
411  }
412  }
413  diagVals=null;
414 
415  return diag;
416  } //GetMatrixDiagonalInverse
417 
418 
419 
420  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
422  size_t numRows = A.getRowMap()->getNodeNumElements();
423  Teuchos::ArrayRCP<SC> diag(numRows);
424 
425  Teuchos::ArrayView<const LO> cols;
426  Teuchos::ArrayView<const SC> vals;
427  for (size_t i = 0; i < numRows; ++i) {
428  A.getLocalRowView(i, cols, vals);
429 
430  diag[i] = Teuchos::ScalarTraits<Scalar>::zero();
431  for (LO j = 0; j < cols.size(); ++j) {
432  diag[i] += Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]);
433  }
434  }
435 
436  return diag;
437  } //GetMatrixDiagonal
438 
439  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
440  RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetMatrixOverlappedDiagonal(const Matrix& A) {
441  RCP<const Map> rowMap = A.getRowMap(), colMap = A.getColMap();
442  RCP<Vector> localDiag = VectorFactory::Build(rowMap);
443 
444  try {
445  const CrsMatrixWrap* crsOp = dynamic_cast<const CrsMatrixWrap*>(&A);
446  if (crsOp == NULL) {
447  throw Exceptions::RuntimeError("cast to CrsMatrixWrap failed");
448  }
449  Teuchos::ArrayRCP<size_t> offsets;
450  crsOp->getLocalDiagOffsets(offsets);
451  crsOp->getLocalDiagCopy(*localDiag,offsets());
452  }
453  catch (...) {
454  ArrayRCP<SC> localDiagVals = localDiag->getDataNonConst(0);
455  Teuchos::ArrayRCP<SC> diagVals = GetMatrixDiagonal(A);
456  for (LO i = 0; i < localDiagVals.size(); i++)
457  localDiagVals[i] = diagVals[i];
458  localDiagVals = diagVals = null;
459  }
460 
461  RCP<Vector> diagonal = VectorFactory::Build(colMap);
462  RCP< const Import> importer;
463  importer = A.getCrsGraph()->getImporter();
464  if (importer == Teuchos::null) {
465  importer = ImportFactory::Build(rowMap, colMap);
466  }
467  diagonal->doImport(*localDiag, *(importer), Xpetra::INSERT);
468 
469  return diagonal;
470  } //GetMatrixOverlappedDiagonal
471 
472  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
473  void Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ScaleMatrix(Matrix& Op, const Teuchos::ArrayRCP<SC>& scalingVector, bool doInverse) {
474 #ifdef HAVE_MUELU_TPETRA
475  try {
476  Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& tpOp = Op2NonConstTpetraCrs(Op);
477 
478  Tpetra::Vector<SC,LO,GO,NO> x(tpOp.getRowMap(), scalingVector());
479  if (doInverse){
480  Tpetra::Vector<SC,LO,GO,NO> xi(tpOp.getRowMap());
481  xi.reciprocal(x);
482  tpOp.leftScale(xi);
483 
484  } else {
485  tpOp.leftScale(x);
486  }
487  } catch(...) {
488  throw Exceptions::RuntimeError("Matrix scaling has not been implemented Epetra");
489  }
490 #else
491  throw Exceptions::RuntimeError("Matrix scaling has not been implemented Epetra");
492 #endif // HAVE_MUELU_TPETRA
493  } //ScaleMatrix()
494 
495  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
496  Teuchos::Array<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>
497  Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ResidualNorm(const Operator& Op, const MultiVector& X, const MultiVector& RHS) {
498  TEUCHOS_TEST_FOR_EXCEPTION(X.getNumVectors() != RHS.getNumVectors(), Exceptions::RuntimeError, "Number of solution vectors != number of right-hand sides")
499  const size_t numVecs = X.getNumVectors();
500 
501  RCP<MultiVector> RES = Residual(Op, X, RHS);
502  Teuchos::Array<Magnitude> norms(numVecs);
503  RES->norm2(norms);
504 
505  return norms;
506  }
507 
508  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
509  RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
510  Residual(const Operator& Op, const MultiVector& X, const MultiVector& RHS) {
511  TEUCHOS_TEST_FOR_EXCEPTION(X.getNumVectors() != RHS.getNumVectors(), Exceptions::RuntimeError, "Number of solution vectors != number of right-hand sides")
512  const size_t numVecs = X.getNumVectors();
513 
514  SC one = Teuchos::ScalarTraits<Scalar>::one(), negone = -one, zero = Teuchos::ScalarTraits<Scalar>::zero();
515 
516  RCP<MultiVector> RES = MultiVectorFactory::Build(Op.getRangeMap(), numVecs, false); // no need to initialize to zero
517  Op.apply(X, *RES, Teuchos::NO_TRANS, one, zero);
518  RES->update(one, RHS, negone);
519 
520  return RES;
521  }
522 
523  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
524  void Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Write(const std::string& fileName, const Matrix& Op) {
525  Write("rowmap_" + fileName, *(Op.getRowMap()));
526  Write("colmap_" + fileName, *(Op.getColMap()));
527  Write("domainmap_" + fileName, *(Op.getDomainMap()));
528  Write("rangemap_" + fileName, *(Op.getRangeMap()));
529 
530  const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
531  RCP<const CrsMatrix> tmp_CrsMtx = crsOp.getCrsMatrix();
532 #if defined(HAVE_MUELU_EPETRA)
533  const RCP<const EpetraCrsMatrix>& tmp_ECrsMtx = rcp_dynamic_cast<const EpetraCrsMatrix>(tmp_CrsMtx);
534  if (tmp_ECrsMtx != Teuchos::null) {
535 #if defined(HAVE_MUELU_EPETRAEXT)
536  RCP<const Epetra_CrsMatrix> A = tmp_ECrsMtx->getEpetra_CrsMatrix();
537  int rv = EpetraExt::RowMatrixToMatrixMarketFile(fileName.c_str(), *A);
538  if (rv != 0)
539  throw Exceptions::RuntimeError("EpetraExt::RowMatrixToMatrixMarketFile return value of " + toString(rv));
540 #else
541  throw Exceptions::RuntimeError("Compiled without EpetraExt");
542 #endif
543  return;
544  }
545 #endif
546 
547 #ifdef HAVE_MUELU_TPETRA
548  const RCP<const TpetraCrsMatrix>& tmp_TCrsMtx = rcp_dynamic_cast<const TpetraCrsMatrix>(tmp_CrsMtx);
549  if (tmp_TCrsMtx != Teuchos::null) {
550  RCP<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > A = tmp_TCrsMtx->getTpetra_CrsMatrix();
551  Tpetra::MatrixMarket::Writer<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >::writeSparseFile(fileName, A);
552  return;
553  }
554 #endif // HAVE_MUELU_TPETRA
555 
556  throw Exceptions::BadCast("Could not cast to EpetraCrsMatrix or TpetraCrsMatrix in matrix writing");
557  } //Write
558 
559  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
560  RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Utils2<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ReadMultiVector(const std::string& fileName, const RCP<const Map>& map){
561  Xpetra::UnderlyingLib lib = map->lib();
562 
563  if (lib == Xpetra::UseEpetra) {
564  TEUCHOS_TEST_FOR_EXCEPTION(true, ::Xpetra::Exceptions::BadCast, "Epetra can only be used with Scalar=double and Ordinal=int");
565 
566  } else if (lib == Xpetra::UseTpetra) {
567 #ifdef HAVE_MUELU_TPETRA
568  typedef Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> sparse_matrix_type;
569  typedef Tpetra::MatrixMarket::Reader<sparse_matrix_type> reader_type;
570  typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> map_type;
571  typedef Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> multivector_type;
572 
573  RCP<const map_type> temp = toTpetra(map);
574  RCP<multivector_type> TMV = reader_type::readDenseFile(fileName,map->getComm(),map->getNode(),temp);
575  RCP<MultiVector> rmv = Xpetra::toXpetra(TMV);
576  return rmv;
577 #else
578  throw Exceptions::RuntimeError("MueLu has not been compiled with Tpetra support.");
579 #endif
580  } else {
581  throw Exceptions::RuntimeError("Utils::Read : you must specify Xpetra::UseEpetra or Xpetra::UseTpetra.");
582  }
583 
584  return Teuchos::null;
585  }
586 
587  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
588  RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> >
589  Utils2<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ReadMap(const std::string& fileName, Xpetra::UnderlyingLib lib, const RCP<const Teuchos::Comm<int> >& comm) {
590  if (lib == Xpetra::UseEpetra) {
591  TEUCHOS_TEST_FOR_EXCEPTION(true, ::Xpetra::Exceptions::BadCast, "Epetra can only be used with Scalar=double and Ordinal=int");
592  } else if (lib == Xpetra::UseTpetra) {
593 #ifdef HAVE_MUELU_TPETRA
594  typedef Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> sparse_matrix_type;
595  typedef Tpetra::MatrixMarket::Reader<sparse_matrix_type> reader_type;
596 
597  RCP<Node> node = rcp(new Node());
598 
599  RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > tMap = reader_type::readMapFile(fileName, comm, node);
600  if (tMap.is_null())
601  throw Exceptions::RuntimeError("The Tpetra::Map returned from readSparseFile() is null.");
602 
603  return Xpetra::toXpetra(tMap);
604 #else
605  throw Exceptions::RuntimeError("MueLu has not been compiled with Tpetra support.");
606 #endif
607  } else {
608  throw Exceptions::RuntimeError("Utils::Read : you must specify Xpetra::UseEpetra or Xpetra::UseTpetra.");
609  }
610 
611  return Teuchos::null;
612  }
613 
614 
615  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
616  RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
617  Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Read(const std::string& fileName, Xpetra::UnderlyingLib lib, const RCP<const Teuchos::Comm<int> >& comm, bool binary) {
618  if (binary == false) {
619  // Matrix Market file format (ASCII)
620  if (lib == Xpetra::UseEpetra) {
621 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_EPETRAEXT)
622  Epetra_CrsMatrix *eA;
623  const RCP<const Epetra_Comm> epcomm = Xpetra::toEpetra(comm);
624  int rv = EpetraExt::MatrixMarketFileToCrsMatrix(fileName.c_str(), *epcomm, eA);
625  if (rv != 0)
626  throw Exceptions::RuntimeError("EpetraExt::MatrixMarketFileToCrsMatrix return value of " + toString(rv));
627 
628  RCP<Epetra_CrsMatrix> tmpA = rcp(eA);
629  RCP<Matrix> A = Convert_Epetra_CrsMatrix_ToXpetra_CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tmpA);
630 
631  return A;
632 #else
633  throw Exceptions::RuntimeError("MueLu has not been compiled with Epetra and EpetraExt support.");
634 #endif
635  } else if (lib == Xpetra::UseTpetra) {
636 #ifdef HAVE_MUELU_TPETRA
637  typedef Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> sparse_matrix_type;
638 
639  typedef Tpetra::MatrixMarket::Reader<sparse_matrix_type> reader_type;
640 
641  //RCP<Node> node = Xpetra::DefaultPlatform::getDefaultPlatform().getNode();
642  Teuchos::ParameterList pl = Teuchos::ParameterList();
643  RCP<Node> node = rcp(new Node(pl));
644  bool callFillComplete = true;
645 
646  RCP<sparse_matrix_type> tA = reader_type::readSparseFile(fileName, comm, node, callFillComplete);
647 
648  if (tA.is_null())
649  throw Exceptions::RuntimeError("The Tpetra::CrsMatrix returned from readSparseFile() is null.");
650 
651  RCP<TpetraCrsMatrix> tmpA1 = rcp(new TpetraCrsMatrix(tA));
652  RCP<CrsMatrix> tmpA2 = rcp_implicit_cast<CrsMatrix>(tmpA1);
653  RCP<Matrix> A = rcp(new CrsMatrixWrap(tmpA2));
654 
655  return A;
656 #else
657  throw Exceptions::RuntimeError("MueLu has not been compiled with Tpetra support.");
658 #endif
659  } else {
660  throw Exceptions::RuntimeError("Utils::Read : you must specify Xpetra::UseEpetra or Xpetra::UseTpetra.");
661  }
662  } else {
663  // Custom file format (binary)
664  std::ifstream ifs(fileName.c_str(), std::ios::binary);
665  TEUCHOS_TEST_FOR_EXCEPTION(!ifs.good(), Exceptions::RuntimeError, "Can not read \"" << fileName << "\"");
666  int m, n, nnz;
667  ifs.read(reinterpret_cast<char*>(&m), sizeof(m));
668  ifs.read(reinterpret_cast<char*>(&n), sizeof(n));
669  ifs.read(reinterpret_cast<char*>(&nnz), sizeof(nnz));
670 
671  int myRank = comm->getRank();
672 
673  GO indexBase = 0;
674  RCP<Map> rowMap = MapFactory::Build(lib, m, (myRank == 0 ? m : 0), indexBase, comm), rangeMap = rowMap;
675  RCP<Map> colMap = MapFactory::Build(lib, n, (myRank == 0 ? n : 0), indexBase, comm), domainMap = colMap;
676  RCP<Matrix> A = MatrixFactory::Build(rowMap, colMap, 1);
677 
678  TEUCHOS_TEST_FOR_EXCEPTION(sizeof(int) != sizeof(GO), Exceptions::RuntimeError, "Incompatible sizes");
679 
680  if (myRank == 0) {
681  Teuchos::Array<GO> inds;
682  Teuchos::Array<SC> vals;
683  for (int i = 0; i < m; i++) {
684  int row, rownnz;
685  ifs.read(reinterpret_cast<char*>(&row), sizeof(row));
686  ifs.read(reinterpret_cast<char*>(&rownnz), sizeof(rownnz));
687  inds.resize(rownnz);
688  vals.resize(rownnz);
689  for (int j = 0; j < rownnz; j++) {
690  int index;
691  ifs.read(reinterpret_cast<char*>(&index), sizeof(index));
692  inds[j] = Teuchos::as<GO>(index);
693  }
694  for (int j = 0; j < rownnz; j++) {
695  double value;
696  ifs.read(reinterpret_cast<char*>(&value), sizeof(value));
697  vals[j] = Teuchos::as<SC>(value);
698  }
699  A->insertGlobalValues(row, inds, vals);
700  }
701  }
702 
703  A->fillComplete(domainMap, rangeMap);
704 
705  return A;
706  }
707 
708  return Teuchos::null;
709 
710  } //Read()
711 
712  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
713  RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
715  const RCP<const Map> rowMap,
716  RCP<const Map> colMap,
717  const RCP<const Map> domainMap,
718  const RCP<const Map> rangeMap,
719  const bool callFillComplete,
720  const bool binary,
721  const bool tolerant,
722  const bool debug
723  ) {
724  TEUCHOS_TEST_FOR_EXCEPTION(rowMap.is_null(), Exceptions::RuntimeError, "Utils::Read() : rowMap cannot be null");
725 
726  RCP<const Map> domain = (domainMap.is_null() ? rowMap : domainMap);
727  RCP<const Map> range = (rangeMap .is_null() ? rowMap : rangeMap);
728 
729  const Xpetra::UnderlyingLib lib = rowMap->lib();
730  if (binary == false) {
731  if (lib == Xpetra::UseEpetra) {
732 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_EPETRAEXT)
733  Epetra_CrsMatrix *eA;
734  const RCP<const Epetra_Comm> epcomm = Xpetra::toEpetra(rowMap->getComm());
735  const Epetra_Map& epetraRowMap = Map2EpetraMap(*rowMap);
736  const Epetra_Map& epetraDomainMap = (domainMap.is_null() ? epetraRowMap : Map2EpetraMap(*domainMap));
737  const Epetra_Map& epetraRangeMap = (rangeMap .is_null() ? epetraRowMap : Map2EpetraMap(*rangeMap));
738  int rv;
739  if (colMap.is_null()) {
740  rv = EpetraExt::MatrixMarketFileToCrsMatrix(fileName.c_str(), epetraRowMap, epetraRangeMap, epetraDomainMap, eA);
741 
742  } else {
743  const Epetra_Map& epetraColMap = Map2EpetraMap(*colMap);
744  rv = EpetraExt::MatrixMarketFileToCrsMatrix(fileName.c_str(), epetraRowMap, epetraColMap, epetraRangeMap, epetraDomainMap, eA);
745  }
746 
747  if (rv != 0)
748  throw Exceptions::RuntimeError("EpetraExt::MatrixMarketFileToCrsMatrix return value of " + toString(rv));
749 
750  RCP<Epetra_CrsMatrix> tmpA = rcp(eA);
751  RCP<Matrix> A = Convert_Epetra_CrsMatrix_ToXpetra_CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tmpA);
752 
753  return A;
754 #else
755  throw Exceptions::RuntimeError("MueLu has not been compiled with Epetra and EpetraExt support.");
756 #endif
757  } else if (lib == Xpetra::UseTpetra) {
758 #ifdef HAVE_MUELU_TPETRA
759  typedef Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> sparse_matrix_type;
760  typedef Tpetra::MatrixMarket::Reader<sparse_matrix_type> reader_type;
761  typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> map_type;
762 
763  const RCP<const map_type> tpetraRowMap = Map2TpetraMap(*rowMap);
764  RCP<const map_type> tpetraColMap = (colMap.is_null() ? Teuchos::null : Map2TpetraMap(*colMap));
765  const RCP<const map_type> tpetraRangeMap = (rangeMap.is_null() ? tpetraRowMap : Map2TpetraMap(*rangeMap));
766  const RCP<const map_type> tpetraDomainMap = (domainMap.is_null() ? tpetraRowMap : Map2TpetraMap(*domainMap));
767 
768  RCP<sparse_matrix_type> tA = reader_type::readSparseFile(fileName, tpetraRowMap, tpetraColMap, tpetraDomainMap, tpetraRangeMap,
769  callFillComplete, tolerant, debug);
770  if (tA.is_null())
771  throw Exceptions::RuntimeError("The Tpetra::CrsMatrix returned from readSparseFile() is null.");
772 
773  RCP<TpetraCrsMatrix> tmpA1 = rcp(new TpetraCrsMatrix(tA));
774  RCP<CrsMatrix> tmpA2 = rcp_implicit_cast<CrsMatrix>(tmpA1);
775  RCP<Matrix> A = rcp(new CrsMatrixWrap(tmpA2));
776 
777  return A;
778 #else
779  throw Exceptions::RuntimeError("MueLu has not been compiled with Tpetra support.");
780 #endif
781  } else {
782  throw Exceptions::RuntimeError("Utils::Read : you must specify Xpetra::UseEpetra or Xpetra::UseTpetra.");
783  }
784  } else {
785  // Custom file format (binary)
786  std::ifstream ifs(fileName.c_str(), std::ios::binary);
787  TEUCHOS_TEST_FOR_EXCEPTION(!ifs.good(), Exceptions::RuntimeError, "Can not read \"" << fileName << "\"");
788  int m, n, nnz;
789  ifs.read(reinterpret_cast<char*>(&m), sizeof(m));
790  ifs.read(reinterpret_cast<char*>(&n), sizeof(n));
791  ifs.read(reinterpret_cast<char*>(&nnz), sizeof(nnz));
792 
793  RCP<Matrix> A = MatrixFactory::Build(rowMap, colMap, 1);
794 
795  TEUCHOS_TEST_FOR_EXCEPTION(sizeof(int) != sizeof(GO), Exceptions::RuntimeError, "Incompatible sizes");
796 
797  Teuchos::ArrayView<const GO> rowElements = rowMap->getNodeElementList();
798  Teuchos::ArrayView<const GO> colElements = colMap->getNodeElementList();
799 
800  Teuchos::Array<GO> inds;
801  Teuchos::Array<SC> vals;
802  for (int i = 0; i < m; i++) {
803  int row, rownnz;
804  ifs.read(reinterpret_cast<char*>(&row), sizeof(row));
805  ifs.read(reinterpret_cast<char*>(&rownnz), sizeof(rownnz));
806  inds.resize(rownnz);
807  vals.resize(rownnz);
808  for (int j = 0; j < rownnz; j++) {
809  int index;
810  ifs.read(reinterpret_cast<char*>(&index), sizeof(index));
811  inds[j] = colElements[Teuchos::as<LO>(index)];
812  }
813  for (int j = 0; j < rownnz; j++) {
814  double value;
815  ifs.read(reinterpret_cast<char*>(&value), sizeof(value));
816  vals[j] = Teuchos::as<SC>(value);
817  }
818  A->insertGlobalValues(rowElements[row], inds, vals);
819  }
820  A->fillComplete(domainMap, rangeMap);
821  return A;
822  }
823 
824  return Teuchos::null;
825  }
826 
827  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
828  void Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Write(const std::string& fileName, const MultiVector& x) {
829 
830  std::string mapfile = "map_" + fileName;
831  Write(mapfile, *(x.getMap()));
832 
833  RCP<const MultiVector> tmp_Vec = rcpFromRef(x);
834 #ifdef HAVE_MUELU_EPETRA
835  const RCP<const EpetraMultiVector>& tmp_EVec = rcp_dynamic_cast<const EpetraMultiVector>(tmp_Vec);
836  if (tmp_EVec != Teuchos::null) {
837 #ifdef HAVE_MUELU_EPETRAEXT
838  int rv = EpetraExt::MultiVectorToMatrixMarketFile(fileName.c_str(), *(tmp_EVec->getEpetra_MultiVector()));
839  if (rv != 0)
840  throw Exceptions::RuntimeError("EpetraExt::RowMatrixToMatrixMarketFile return value of " + toString(rv));
841 #else
842  throw Exceptions::RuntimeError("Compiled without EpetraExt");
843 #endif
844  return;
845  }
846 #endif // HAVE_MUELU_EPETRAEXT
847 
848 #ifdef HAVE_MUELU_TPETRA
849  const RCP<const TpetraMultiVector> &tmp_TVec = rcp_dynamic_cast<const TpetraMultiVector>(tmp_Vec);
850  if (tmp_TVec != Teuchos::null) {
851  RCP<const Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > TVec = tmp_TVec->getTpetra_MultiVector();
852  Tpetra::MatrixMarket::Writer<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >::writeDenseFile(fileName, TVec);
853  return;
854  }
855 #endif // HAVE_MUELU_TPETRA
856 
857  throw Exceptions::BadCast("Could not cast to EpetraMultiVector or TpetraMultiVector in multivector writing");
858 
859  } //Write
860 
861  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
862  void Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Write(const std::string& fileName, const Map& M) {
863  RCP<const Map> tmp_Map = rcpFromRef(M);
864 #ifdef HAVE_MUELU_EPETRAEXT
865  const RCP<const Xpetra::EpetraMap>& tmp_EMap = rcp_dynamic_cast<const Xpetra::EpetraMap>(tmp_Map);
866  if (tmp_EMap != Teuchos::null) {
867 #ifdef HAVE_MUELU_EPETRAEXT
868  int rv = EpetraExt::BlockMapToMatrixMarketFile(fileName.c_str(), tmp_EMap->getEpetra_Map());
869  if (rv != 0)
870  throw Exceptions::RuntimeError("EpetraExt::BlockMapToMatrixMarketFile() return value of " + toString(rv));
871 #else
872  throw(Exceptions::RuntimeError("Compiled without EpetraExt"));
873 #endif
874  return;
875  }
876 #endif // HAVE_MUELU_EPETRAEXT
877 
878 #ifdef HAVE_MUELU_TPETRA
879  const RCP<const TpetraMap> &tmp_TMap = rcp_dynamic_cast<const TpetraMap>(tmp_Map);
880  if (tmp_TMap != Teuchos::null) {
881  RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > TMap = tmp_TMap->getTpetra_Map();
882  Tpetra::MatrixMarket::Writer<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >::writeMapFile(fileName, *TMap);
883  return;
884  }
885 #endif // HAVE_MUELU_TPETRA
886 
887  throw Exceptions::BadCast("Could not cast to EpetraMap or TpetraMap in map writing");
888 
889  } //Write
890 
891 #ifndef _WIN32
892 #include <unistd.h>
893 
894  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
896  RCP<const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();
897 
898  int myPID = comm->getRank();
899  int pid = getpid();
900 
901  char hostname[80];
902  for (int i = 0; i <comm->getSize(); i++) {
903  if (i == myPID) {
904  gethostname(hostname, sizeof(hostname));
905  std::cout << "Host: " << hostname << "\tMPI rank: " << myPID << ",\tPID: " << pid << "\n\tattach " << pid << std::endl;
906  sleep(1);
907  }
908  }
909 
910  if (myPID == 0) {
911  std::cout << "** Enter a character to continue > " << std::endl;
912  char go = ' ';
913  int r = scanf("%c", &go);
914  (void)r;
915  assert(r > 0);
916  }
917  comm->barrier();
918  } //PauseForDebugger
919 #else
920  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
922  throw(Exceptions::RuntimeError("MueLu Utils: PauseForDebugger not implemented on Windows."));
923  }
924 
925 #endif
926 
927  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
929  PowerMethod(const Matrix& A, bool scaleByDiag, LO niters, Magnitude tolerance, bool verbose, unsigned int seed) {
930  TEUCHOS_TEST_FOR_EXCEPTION(!(A.getRangeMap()->isSameAs(*(A.getDomainMap()))), Exceptions::Incompatible,
931  "Utils::PowerMethod: operator must have domain and range maps that are equivalent.");
932 
933  // Create three vectors, fill z with random numbers
934  RCP<Vector> q = VectorFactory::Build(A.getDomainMap());
935  RCP<Vector> r = VectorFactory::Build(A.getRangeMap());
936  RCP<Vector> z = VectorFactory::Build(A.getRangeMap());
937 
938  z->setSeed(seed); // seed random number generator
939  z->randomize(true);// use Xpetra implementation: -> same results for Epetra and Tpetra
940 
941  Teuchos::Array<Magnitude> norms(1);
942 
943  typedef Teuchos::ScalarTraits<SC> STS;
944 
945  const SC zero = STS::zero(), one = STS::one();
946 
947  SC lambda = zero;
948  Magnitude residual = STS::magnitude(zero);
949 
950  // power iteration
951  RCP<Vector> diagInvVec;
952  if (scaleByDiag) {
953  RCP<Vector> diagVec = VectorFactory::Build(A.getRowMap());
954  A.getLocalDiagCopy(*diagVec);
955  diagInvVec = VectorFactory::Build(A.getRowMap());
956  diagInvVec->reciprocal(*diagVec);
957  }
958 
959  for (int iter = 0; iter < niters; ++iter) {
960  z->norm2(norms); // Compute 2-norm of z
961  q->update(one/norms[0], *z, zero); // Set q = z / normz
962  A.apply(*q, *z); // Compute z = A*q
963  if (scaleByDiag)
964  z->elementWiseMultiply(one, *diagInvVec, *z, zero);
965  lambda = q->dot(*z); // Approximate maximum eigenvalue: lamba = dot(q,z)
966 
967  if (iter % 100 == 0 || iter + 1 == niters) {
968  r->update(1.0, *z, -lambda, *q, zero); // Compute A*q - lambda*q
969  r->norm2(norms);
970  residual = STS::magnitude(norms[0] / lambda);
971  if (verbose) {
972  std::cout << "Iter = " << iter
973  << " Lambda = " << lambda
974  << " Residual of A*q - lambda*q = " << residual
975  << std::endl;
976  }
977  }
978  if (residual < tolerance)
979  break;
980  }
981 
982  return lambda;
983  }
984 
985  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
986  void Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MyOldScaleMatrix(Matrix& Op, const Teuchos::ArrayRCP<const SC>& scalingVector, bool doInverse,
987  bool doFillComplete,
988  bool doOptimizeStorage)
989  {
990  SC one = Teuchos::ScalarTraits<SC>::one();
991  Teuchos::ArrayRCP<SC> sv(scalingVector.size());
992  if (doInverse) {
993  for (int i = 0; i < scalingVector.size(); ++i)
994  sv[i] = one / scalingVector[i];
995  } else {
996  for (int i = 0; i < scalingVector.size(); ++i)
997  sv[i] = scalingVector[i];
998  }
999 
1000  switch (Op.getRowMap()->lib()) {
1001  case Xpetra::UseTpetra:
1002  MyOldScaleMatrix_Tpetra(Op, sv, doFillComplete, doOptimizeStorage);
1003  break;
1004 
1005  case Xpetra::UseEpetra:
1006  Utils2<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MyOldScaleMatrix_Epetra(Op, sv, doFillComplete, doOptimizeStorage);
1007  break;
1008 
1009  default:
1010  throw Exceptions::RuntimeError("Only Epetra and Tpetra matrices can be scaled.");
1011  break;
1012  }
1013  }
1014 
1015  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
1016  void Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MyOldScaleMatrix_Tpetra(Matrix& Op, const Teuchos::ArrayRCP<SC>& scalingVector,
1017  bool doFillComplete,
1018  bool doOptimizeStorage)
1019  {
1020 #ifdef HAVE_MUELU_TPETRA
1021  try {
1022  Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& tpOp = Op2NonConstTpetraCrs(Op);
1023 
1024  const RCP<const Tpetra::Map<LO,GO,NO> > rowMap = tpOp.getRowMap();
1025  const RCP<const Tpetra::Map<LO,GO,NO> > domainMap = tpOp.getDomainMap();
1026  const RCP<const Tpetra::Map<LO,GO,NO> > rangeMap = tpOp.getRangeMap();
1027 
1028  size_t maxRowSize = tpOp.getNodeMaxNumRowEntries();
1029  if (maxRowSize == Teuchos::as<size_t>(-1)) // hasn't been determined yet
1030  maxRowSize = 20;
1031 
1032  std::vector<SC> scaledVals(maxRowSize);
1033  if (tpOp.isFillComplete())
1034  tpOp.resumeFill();
1035 
1036  if (Op.isLocallyIndexed() == true) {
1037  Teuchos::ArrayView<const LO> cols;
1038  Teuchos::ArrayView<const SC> vals;
1039 
1040  for (size_t i = 0; i < rowMap->getNodeNumElements(); ++i) {
1041  tpOp.getLocalRowView(i, cols, vals);
1042  size_t nnz = tpOp.getNumEntriesInLocalRow(i);
1043  if (nnz > maxRowSize) {
1044  maxRowSize = nnz;
1045  scaledVals.resize(maxRowSize);
1046  }
1047  for (size_t j = 0; j < nnz; ++j)
1048  scaledVals[j] = vals[j]*scalingVector[i];
1049 
1050  if (nnz > 0) {
1051  Teuchos::ArrayView<const SC> valview(&scaledVals[0], nnz);
1052  tpOp.replaceLocalValues(i, cols, valview);
1053  }
1054  } //for (size_t i=0; ...
1055 
1056  } else {
1057  Teuchos::ArrayView<const GO> cols;
1058  Teuchos::ArrayView<const SC> vals;
1059 
1060  for (size_t i = 0; i < rowMap->getNodeNumElements(); ++i) {
1061  GO gid = rowMap->getGlobalElement(i);
1062  tpOp.getGlobalRowView(gid, cols, vals);
1063  size_t nnz = tpOp.getNumEntriesInGlobalRow(gid);
1064  if (nnz > maxRowSize) {
1065  maxRowSize = nnz;
1066  scaledVals.resize(maxRowSize);
1067  }
1068  // FIXME FIXME FIXME FIXME FIXME FIXME
1069  for (size_t j = 0; j < nnz; ++j)
1070  scaledVals[j] = vals[j]*scalingVector[i]; //FIXME i or gid?
1071 
1072  if (nnz > 0) {
1073  Teuchos::ArrayView<const SC> valview(&scaledVals[0], nnz);
1074  tpOp.replaceGlobalValues(gid, cols, valview);
1075  }
1076  } //for (size_t i=0; ...
1077  }
1078 
1079  if (doFillComplete) {
1080  if (domainMap == Teuchos::null || rangeMap == Teuchos::null)
1081  throw Exceptions::RuntimeError("In Utils::Scaling: cannot fillComplete because the domain and/or range map hasn't been defined");
1082 
1083  RCP<Teuchos::ParameterList> params = rcp(new Teuchos::ParameterList());
1084  params->set("Optimize Storage", doOptimizeStorage);
1085  params->set("No Nonlocal Changes", true);
1086  Op.fillComplete(Op.getDomainMap(), Op.getRangeMap(), params);
1087  }
1088  } catch(...) {
1089  throw Exceptions::RuntimeError("Only Tpetra::CrsMatrix types can be scaled (Err.1)");
1090  }
1091 #else
1092  throw Exceptions::RuntimeError("Matrix scaling is not possible because Tpetra has not been enabled.");
1093 #endif
1094  } //MyOldScaleMatrix_Tpetra()
1095 
1096  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
1097  RCP<Teuchos::FancyOStream> Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MakeFancy(std::ostream& os) {
1098  RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(os));
1099  return fancy;
1100  }
1101 
1102  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
1103  typename Teuchos::ScalarTraits<Scalar>::magnitudeType
1104  Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Distance2(const MultiVector& v, LocalOrdinal i0, LocalOrdinal i1) {
1105  size_t numVectors = v.getNumVectors();
1106 
1107  Scalar d = Teuchos::ScalarTraits<Scalar>::zero();
1108  for (size_t j = 0; j < numVectors; j++) {
1109  Teuchos::ArrayRCP<const Scalar> vv = v.getData(j);
1110  d += (vv[i0] - vv[i1])*(vv[i0] - vv[i1]);
1111  }
1112 
1113  return Teuchos::ScalarTraits<SC>::magnitude(d);
1114  }
1115 
1116  template <class SC, class LO, class GO, class NO>
1117  ArrayRCP<const bool> Utils<SC, LO, GO, NO>::DetectDirichletRows(const Matrix& A, const typename Teuchos::ScalarTraits<SC>::magnitudeType& tol) {
1118  LO numRows = A.getNodeNumRows();
1119 
1120  typedef Teuchos::ScalarTraits<SC> STS;
1121 
1122  ArrayRCP<bool> boundaryNodes(numRows, true);
1123  for (LO row = 0; row < numRows; row++) {
1124  ArrayView<const LO> indices;
1125  ArrayView<const SC> vals;
1126  A.getLocalRowView(row, indices, vals);
1127 
1128  size_t nnz = A.getNumEntriesInLocalRow(row);
1129  if (nnz > 1)
1130  for (size_t col = 0; col < nnz; col++)
1131  if ( (indices[col] != row) && STS::magnitude(vals[col]) > tol) {
1132  boundaryNodes[row] = false;
1133  break;
1134  }
1135  }
1136 
1137  return boundaryNodes;
1138  }
1139 
1140  //pulled directly from ml_utils.cpp
1141  template <class SC, class LO, class GO, class NO>
1143  // Distribute the seeds evenly in [1,maxint-1]. This guarantees nothing
1144  // about where in random number stream we are, but avoids overflow situations
1145  // in parallel when multiplying by a PID. It would be better to use
1146  // a good parallel random number generator.
1147 
1148  double one = 1.0;
1149  int maxint = INT_MAX; //= 2^31-1 = 2147483647 for 32-bit integers
1150  int mySeed = Teuchos::as<int>((maxint-1) * (one -(comm.getRank()+1)/(comm.getSize()+one)) );
1151  if (mySeed < 1 || mySeed == maxint) {
1152  std::ostringstream errStr;
1153  errStr << "Error detected with random seed = " << mySeed << ". It should be in the interval [1,2^31-2].";
1154  throw Exceptions::RuntimeError(errStr.str());
1155  }
1156 
1157  std::srand(mySeed);
1158 
1159  // For Tpetra, we could use Kokkos' random number generator here.
1160  Teuchos::ScalarTraits<SC>::seedrandom(mySeed);
1161 
1162  // Epetra
1163  // MultiVector::Random() -> Epetra_Util::RandomDouble() -> Epetra_Utils::RandomInt()
1164  // Its own random number generator, based on Seed_. Seed_ is initialized in Epetra_Util constructor with std::rand()
1165  // So our setting std::srand() affects that too
1166  }
1167 
1168  template <class SC, class LO, class GO, class NO>
1169  void Utils<SC, LO, GO, NO>::findDirichletRows(Teuchos::RCP<Matrix> A,
1170  std::vector<LO>& dirichletRows) {
1171  dirichletRows.resize(0);
1172  for(size_t i=0; i<A->getNodeNumRows(); i++) {
1173  Teuchos::ArrayView<const LO> indices;
1174  Teuchos::ArrayView<const SC> values;
1175  A->getLocalRowView(i,indices,values);
1176  int nnz=0;
1177  for (int j=0; j<indices.size(); j++) {
1178  // FIXME (mfh 12 Sep 2015) I just replaced abs with the
1179  // appropriate ScalarTraits call. However, this is NOT
1180  // correct for arbitrary scalar types!!! I'm guessing you
1181  // should use the equivalent of LAPACK's SFMIN or machine
1182  // epsilon here.
1183  if (Teuchos::ScalarTraits<SC>::magnitude(values[j]) > 1.0e-16) {
1184  nnz++;
1185  }
1186  }
1187  if (nnz == 1 || nnz == 2) {
1188  dirichletRows.push_back(i);
1189  }
1190  }
1191  }
1192 
1193  template<class SC, class LO, class GO, class NO>
1194  void Utils<SC, LO, GO, NO>::findDirichletCols(Teuchos::RCP<Matrix> A,
1195  std::vector<LO>& dirichletRows,
1196  std::vector<LO>& dirichletCols) {
1197  Teuchos::RCP<const Map> domMap = A->getDomainMap();
1198  Teuchos::RCP<const Map> colMap = A->getColMap();
1199  Teuchos::RCP< Xpetra::Export<LO,GO,NO> > exporter
1200  = Xpetra::ExportFactory<LO,GO,NO>::Build(colMap,domMap);
1201  Teuchos::RCP<MultiVector> myColsToZero = MultiVectorFactory::Build(colMap,1);
1202  Teuchos::RCP<MultiVector> globalColsToZero = MultiVectorFactory::Build(domMap,1);
1203  myColsToZero->putScalar((SC)0.0);
1204  globalColsToZero->putScalar((SC)0.0);
1205  for(size_t i=0; i<dirichletRows.size(); i++) {
1206  Teuchos::ArrayView<const LO> indices;
1207  Teuchos::ArrayView<const SC> values;
1208  A->getLocalRowView(dirichletRows[i],indices,values);
1209  for(int j=0; j<indices.size(); j++)
1210  myColsToZero->replaceLocalValue(indices[j],0,(SC)1.0);
1211  }
1212  globalColsToZero->doExport(*myColsToZero,*exporter,Xpetra::ADD);
1213  myColsToZero->doImport(*globalColsToZero,*exporter,Xpetra::INSERT);
1214  Teuchos::ArrayRCP<const SC> myCols = myColsToZero->getData(0);
1215  dirichletCols.resize(colMap->getNodeNumElements());
1216  for(size_t i=0; i<colMap->getNodeNumElements(); i++) {
1217  if(Teuchos::ScalarTraits<SC>::magnitude(myCols[i])>0.0)
1218  dirichletCols[i]=1;
1219  else
1220  dirichletCols[i]=0;
1221  }
1222  }
1223 
1224  template<class SC, class LO, class GO, class NO>
1225  void Utils<SC, LO, GO, NO>::Apply_BCsToMatrixRows(Teuchos::RCP<Matrix>& A,
1226  std::vector<LO>& dirichletRows) {
1227  for(size_t i=0; i<dirichletRows.size(); i++) {
1228  Teuchos::ArrayView<const LO> indices;
1229  Teuchos::ArrayView<const SC> values;
1230  A->getLocalRowView(dirichletRows[i],indices,values);
1231  std::vector<SC> vec;
1232  vec.resize(indices.size());
1233  Teuchos::ArrayView<SC> zerovalues(vec);
1234  for(int j=0; j<indices.size(); j++)
1235  zerovalues[j]=(SC)1.0e-32;
1236  A->replaceLocalValues(dirichletRows[i],indices,zerovalues);
1237  }
1238  }
1239 
1240  template<class SC, class LO, class GO, class NO>
1241  void Utils<SC, LO, GO, NO>::Apply_BCsToMatrixCols(Teuchos::RCP<Matrix>& A,
1242  std::vector<LO>& dirichletCols) {
1243  for(size_t i=0; i<A->getNodeNumRows(); i++) {
1244  Teuchos::ArrayView<const LO> indices;
1245  Teuchos::ArrayView<const SC> values;
1246  A->getLocalRowView(i,indices,values);
1247  std::vector<SC> vec;
1248  vec.resize(indices.size());
1249  Teuchos::ArrayView<SC> zerovalues(vec);
1250  for(int j=0; j<indices.size(); j++) {
1251  if(dirichletCols[indices[j]]==1)
1252  zerovalues[j]=(SC)1.0e-32;
1253  else
1254  zerovalues[j]=values[j];
1255  }
1256  A->replaceLocalValues(i,indices,zerovalues);
1257  }
1258  }
1259 
1260  template<class SC, class LO, class GO, class NO>
1261  void Utils<SC, LO, GO, NO>::Remove_Zeroed_Rows(Teuchos::RCP<Matrix>& A,
1262  double tol) {
1263  Teuchos::RCP<const Map> rowMap = A->getRowMap();
1264  RCP<Matrix> DiagMatrix = MatrixFactory::Build(rowMap,1);
1265  RCP<Matrix> NewMatrix = MatrixFactory::Build(rowMap,1);
1266  for(size_t i=0; i<A->getNodeNumRows(); i++) {
1267  Teuchos::ArrayView<const LO> indices;
1268  Teuchos::ArrayView<const SC> values;
1269  A->getLocalRowView(i,indices,values);
1270  int nnz=0;
1271  for (int j=0; j<indices.size(); j++) {
1272  if (Teuchos::ScalarTraits<SC>::magnitude(values[j]) > tol) {
1273  nnz++;
1274  }
1275  }
1276  SC one = (SC)1.0;
1277  SC zero = (SC)0.0;
1278  GO row = rowMap->getGlobalElement(i);
1279  if (nnz == 0) {
1280  DiagMatrix->insertGlobalValues(row,
1281  Teuchos::ArrayView<GO>(&row,1),
1282  Teuchos::ArrayView<SC>(&one,1));
1283  }
1284  else {
1285  DiagMatrix->insertGlobalValues(row,
1286  Teuchos::ArrayView<GO>(&row,1),
1287  Teuchos::ArrayView<SC>(&zero,1));
1288  }
1289  }
1290  DiagMatrix->fillComplete();
1291  A->fillComplete();
1292  // add matrices together
1293  RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
1294  Xpetra::MatrixMatrix<SC,LO,GO,NO>::TwoMatrixAdd(*DiagMatrix,false,(SC)1.0,*A,false,(SC)1.0,NewMatrix,*out);
1295  NewMatrix->fillComplete();
1296  A=NewMatrix;
1297 
1298  }
1299 
1300 
1301 
1302  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
1303  RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1305  Transpose (Matrix& Op, bool optimizeTranspose,const std::string & label) {
1306 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_EPETRAEXT)
1307  std::string TorE = "epetra";
1308 #else
1309  std::string TorE = "tpetra";
1310 #endif
1311 
1312 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_EPETRAEXT)
1313  try {
1314  const Epetra_CrsMatrix& epetraOp = Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2NonConstEpetraCrs(Op);
1315  (void) epetraOp; // silence "unused variable" compiler warning
1316  } catch (...) {
1317  TorE = "tpetra";
1318  }
1319 #endif
1320 
1321 #ifdef HAVE_MUELU_TPETRA
1322  if (TorE == "tpetra") {
1323  try {
1324  const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& tpetraOp = Utils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Op2TpetraCrs(Op);
1325 
1326  RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > A;
1327  Tpetra::RowMatrixTransposer<Scalar, LocalOrdinal, GlobalOrdinal, Node> transposer(rcpFromRef(tpetraOp),label); //more than meets the eye
1328  A = transposer.createTranspose();
1329 
1330  RCP<TpetraCrsMatrix> AA = rcp(new TpetraCrsMatrix(A) );
1331  RCP<CrsMatrix> AAA = rcp_implicit_cast<CrsMatrix>(AA);
1332  RCP<Matrix> AAAA = rcp( new CrsMatrixWrap(AAA) );
1333  if (!AAAA->isFillComplete())
1334  AAAA->fillComplete(Op.getRangeMap(),Op.getDomainMap());
1335 
1336  return AAAA;
1337 
1338  } catch (std::exception& e) {
1339  std::cout << "threw exception '" << e.what() << "'" << std::endl;
1340  throw Exceptions::RuntimeError("Utils::Transpose failed, perhaps because matrix is not a Crs matrix");
1341  }
1342  } //if
1343 #endif
1344 
1345  // Epetra case
1346  std::cout << "Utilities::Transpose() not implemented for Epetra" << std::endl;
1347  return Teuchos::null;
1348 
1349  } // Transpose
1350 
1351  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
1352  void Utils2<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MyOldScaleMatrix_Epetra(Matrix& Op, const Teuchos::ArrayRCP<SC>& scalingVector,
1353  bool doFillComplete,
1354  bool doOptimizeStorage)
1355  {
1356  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MyOldScalematrix and Epetra cannot be used with Scalar != double, LocalOrdinal != int, GlobalOrdinal != int");
1357  }
1358 } //namespace MueLu
1359 
1360 #define MUELU_UTILITIES_SHORT
1361 #endif // MUELU_UTILITIES_DEF_HPP
1362 
1363 // LocalWords: LocalOrdinal
static void SetRandomSeed(const Teuchos::Comm< int > &comm)
Set seed for random number generator.
Exception indicating invalid cast attempted.
static void Remove_Zeroed_Rows(Teuchos::RCP< Matrix > &A, double tol=1.0e-14)
static RCP< Epetra_MultiVector > MV2NonConstEpetraMV(RCP< MultiVector > Vec)
static void Write(const std::string &fileName, const Map &M)
Read/Write methods.
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
static RCP< Matrix > Transpose(Matrix &Op, bool optimizeTranspose=false, const std::string &label=std::string())
Transpose a Xpetra::Matrix.
static const Epetra_Map & Map2EpetraMap(const Map &map)
int BlockMapToMatrixMarketFile(const char *filename, const Epetra_BlockMap &blockMap, const char *mapName=0, const char *mapDescription=0, bool writeHeader=true)
static Teuchos::ArrayRCP< SC > GetLumpedMatrixDiagonal(const Matrix &A)
Extract Matrix Diagonal of lumped matrix.
static void findDirichletCols(Teuchos::RCP< Matrix > A, std::vector< LO > &dirichletRows, std::vector< LO > &dirichletCols)
static RCP< const Tpetra::MultiVector< SC, LO, GO, NO > > MV2TpetraMV(RCP< MultiVector > const Vec)
Helper utility to pull out the underlying Tpetra objects from an Xpetra object.
static Teuchos::Array< Magnitude > ResidualNorm(const Operator &Op, const MultiVector &X, const MultiVector &RHS)
Teuchos::ScalarTraits< SC >::magnitudeType Magnitude
static const RCP< const Tpetra::Map< LO, GO, NO > > Map2TpetraMap(const Map &map)
Namespace for MueLu classes and methods.
static RCP< Tpetra::MultiVector< SC, LO, GO, NO > > MV2NonConstTpetraMV(RCP< MultiVector > Vec)
Exception throws to report incompatible objects (like maps).
static RCP< Xpetra::Matrix< SC, LO, GO, NO > > Crs2Op(RCP< CrsMatrix > Op)
static void PauseForDebugger()
static RCP< Tpetra::MultiVector< SC, LO, GO, NO > > MV2NonConstTpetraMV2(MultiVector &Vec)
static RCP< Vector > GetMatrixOverlappedDiagonal(const Matrix &A)
Extract Overlapped Matrix Diagonal.
static RCP< const Epetra_MultiVector > MV2EpetraMV(RCP< MultiVector > const Vec)
Helper utility to pull out the underlying Epetra objects from an Xpetra object.
static RCP< const Tpetra::RowMatrix< SC, LO, GO, NO > > Op2TpetraRow(RCP< const Matrix > Op)
static Teuchos::RCP< Matrix > Read(const std::string &fileName, Xpetra::UnderlyingLib lib, const RCP< const Teuchos::Comm< int > > &comm, bool binary=false)
Read matrix from file in Matrix Market or binary format.
int MatrixMarketFileToCrsMatrix(const char *filename, const Epetra_Comm &comm, Epetra_CrsMatrix *&A)
static void Apply_BCsToMatrixRows(Teuchos::RCP< Matrix > &A, std::vector< LO > &dirichletRows)
static void MyOldScaleMatrix_Epetra(Matrix &Op, const Teuchos::ArrayRCP< SC > &scalingVector, bool doFillComplete, bool doOptimizeStorage)
Scale an Epetra matrix.
static RCP< const Epetra_CrsMatrix > Op2EpetraCrs(RCP< const Matrix > Op)
static RCP< const Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2TpetraCrs(RCP< const Matrix > Op)
int MultiVectorToMatrixMarketFile(const char *filename, const Epetra_MultiVector &A, const char *matrixName=0, const char *matrixDescription=0, bool writeHeader=true)
static void ScaleMatrix(Matrix &Op, const Teuchos::ArrayRCP< SC > &scalingVector, bool doInverse=true)
Left scale matrix by an arbitrary vector.
static RCP< Teuchos::FancyOStream > MakeFancy(std::ostream &os)
static void MyOldScaleMatrix(Matrix &Op, const Teuchos::ArrayRCP< const SC > &scalingVector, bool doInverse=true, bool doFillComplete=true, bool doOptimizeStorage=true)
static void MyOldScaleMatrix_Tpetra(Matrix &Op, const Teuchos::ArrayRCP< SC > &scalingVector, bool doFillComplete, bool doOptimizeStorage)
RCP< Xpetra::CrsMatrixWrap< SC, LO, GO, NO > > Convert_Epetra_CrsMatrix_ToXpetra_CrsMatrixWrap(RCP< Epetra_CrsMatrix > &epAB)
static RCP< Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2NonConstTpetraCrs(RCP< Matrix > Op)
int RowMatrixToMatrixMarketFile(const char *filename, const Epetra_RowMatrix &A, const char *matrixName=0, const char *matrixDescription=0, bool writeHeader=true)
static RCP< Tpetra::RowMatrix< SC, LO, GO, NO > > Op2NonConstTpetraRow(RCP< Matrix > Op)
static Teuchos::ScalarTraits< Scalar >::magnitudeType Distance2(const MultiVector &v, LocalOrdinal i0, LocalOrdinal i1)
Squared distance between two rows in a multivector.
static RCP< const Map > ReadMap(const std::string &fileName, Xpetra::UnderlyingLib lib, const RCP< const Teuchos::Comm< int > > &comm)
static RCP< MultiVector > ReadMultiVector(const std::string &fileName, const RCP< const Map > &map)
static Teuchos::ArrayRCP< SC > GetMatrixDiagonal(const Matrix &A)
Extract Matrix Diagonal.
static Teuchos::ArrayRCP< const bool > DetectDirichletRows(const Matrix &A, const Magnitude &tol=Teuchos::ScalarTraits< SC >::zero())
Detect Dirichlet rows.
static Scalar PowerMethod(const Matrix &A, bool scaleByDiag=true, LO niters=10, Magnitude tolerance=1e-2, bool verbose=false, unsigned int seed=123)
Simple transpose for Tpetra::CrsMatrix types.
Exception throws to report errors in the internal logical of the program.
static RCP< Epetra_CrsMatrix > Op2NonConstEpetraCrs(RCP< Matrix > Op)
static RCP< Vector > GetMatrixDiagonalInverse(const Matrix &A, Magnitude tol=Teuchos::ScalarTraits< SC >::eps()*100)
Extract Matrix Diagonal.
static RCP< MultiVector > Residual(const Operator &Op, const MultiVector &X, const MultiVector &RHS)
static void Apply_BCsToMatrixCols(Teuchos::RCP< Matrix > &A, std::vector< LO > &dirichletCols)
static void findDirichletRows(Teuchos::RCP< Matrix > A, std::vector< LO > &dirichletRows)