46 #ifndef MUELU_AMESOS2SMOOTHER_DEF_HPP
47 #define MUELU_AMESOS2SMOOTHER_DEF_HPP
52 #if defined (HAVE_MUELU_TPETRA) && defined(HAVE_MUELU_AMESOS2)
53 #include <Xpetra_Matrix.hpp>
55 #include <Amesos2_config.h>
56 #include <Amesos2.hpp>
60 #include "MueLu_Utilities.hpp"
65 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
67 : type_(type), useTransformation_(false) {
73 std::transform(
type_.begin(), ++
type_.begin(),
type_.begin(), ::toupper);
75 if (
type_ ==
"Superlu_dist")
76 type_ =
"Superludist";
81 if (
type_ ==
"" || Amesos2::query(
type_) ==
false) {
82 std::string oldtype =
type_;
83 #if defined(HAVE_AMESOS2_SUPERLU)
85 #elif defined(HAVE_AMESOS2_KLU2)
87 #elif defined(HAVE_AMESOS2_SUPERLUDIST)
88 type_ =
"Superludist";
89 #elif defined(HAVE_AMESOS2_BASKER)
92 throw Exceptions::RuntimeError(
"Amesos2 has been compiled without SuperLU_DIST, SuperLU, Klu, or Basker. By default, MueLu tries"
93 "to use one of these libraries. Amesos2 must be compiled with one of these solvers, "
94 "or a valid Amesos2 solver has to be specified explicitly.");
97 this->
GetOStream(
Warnings0) <<
"MueLu::Amesos2Smoother: \"" << oldtype <<
"\" is not available. Using \"" <<
type_ <<
"\" instead" << std::endl;
103 TEUCHOS_TEST_FOR_EXCEPTION(Amesos2::query(
type_) ==
false,
Exceptions::RuntimeError,
"The Amesos2 library reported that the solver '" <<
type_ <<
"' is not available. "
104 "Amesos2 has been compiled without the support of this solver, or the solver name is misspelled.");
107 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
110 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
112 RCP<ParameterList> validParamList = rcp(
new ParameterList());
113 validParamList->set< RCP<const FactoryBase> >(
"A",
null,
"Factory of the coarse matrix");
114 validParamList->set< RCP<const FactoryBase> >(
"Nullspace",
null,
"Factory of the nullspace");
115 validParamList->set<
bool>(
"fix nullspace",
false,
"Remove zero eigenvalue by adding rank one correction.");
116 return validParamList;
119 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
121 ParameterList pL = this->GetParameterList();
123 this->Input(currentLevel,
"A");
124 if (pL.get<
bool>(
"fix nullspace"))
125 this->Input(currentLevel,
"Nullspace");
128 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
133 this->GetOStream(
Warnings0) <<
"MueLu::Amesos2Smoother::Setup(): Setup() has already been called" << std::endl;
135 RCP<Matrix> A = Factory::Get< RCP<Matrix> >(currentLevel,
"A");
138 RCP<const Map> rowMap = A->getRowMap();
139 if (rowMap->getGlobalNumElements() != as<size_t>((rowMap->getMaxAllGlobalIndex() - rowMap->getMinAllGlobalIndex())+1)) {
148 this->GetOStream(
Runtime1) <<
"MueLu::Amesos2Smoother::Setup(): using system transformation" << std::endl;
151 "MueLu::Amesos2Smoother::Setup Fixing coarse matrix for Amesos2 for multiple processors has not been implemented yet.");
153 "MueLu::Amesos2Smoother::Setup Fixing coarse matrix for Amesos2 when row map is different from column map has not been implemented yet.");
155 RCP<CrsMatrixWrap> Acrs = rcp_dynamic_cast<CrsMatrixWrap>(A);
157 "MueLu::Amesos2Smoother::Setup Fixing coarse matrix for Amesos2 when matrix is not a Crs matrix has not been implemented yet.");
159 useTransformation_ =
true;
161 ArrayRCP<const size_t> rowPointers;
162 ArrayRCP<const LO> colIndices;
163 ArrayRCP<const SC> values;
164 Acrs->getCrsMatrix()->getAllValues(rowPointers, colIndices, values);
167 RCP<Map> map = MapFactory::Build(rowMap->lib(), rowMap->getGlobalNumElements(), 0, rowMap->getComm());
168 RCP<Matrix> newA = rcp(
new CrsMatrixWrap(map, map, 0, Xpetra::StaticProfile));
169 RCP<CrsMatrix> newAcrs = rcp_dynamic_cast<CrsMatrixWrap>(newA)->getCrsMatrix();
171 using Teuchos::arcp_const_cast;
172 newAcrs->setAllValues(arcp_const_cast<size_t>(rowPointers), arcp_const_cast<LO>(colIndices), arcp_const_cast<SC>(values));
173 newAcrs->expertStaticFillComplete(map, map);
177 X_ = MultiVectorFactory::Build(map, 1);
178 B_ = MultiVectorFactory::Build(map, 1);
182 Teuchos::ParameterList pL = this->GetParameterList();
183 if (pL.get<
bool>(
"fix nullspace")) {
184 this->GetOStream(
Runtime1) <<
"MueLu::Amesos2Smoother::Setup(): fixing nullspace" << std::endl;
186 rowMap = A->getRowMap();
187 size_t M = rowMap->getGlobalNumElements();
189 RCP<MultiVector> Nullspace = Factory::Get< RCP<MultiVector> >(currentLevel,
"Nullspace");
192 "MueLu::Amesos2Smoother::Setup Fixing nullspace for coarse matrix for Amesos2 for nullspace of dim > 1 has not been implemented yet.");
194 RCP<MultiVector> NullspaceImp;
195 RCP<const Map> colMap;
196 RCP<const Import> importer;
197 if (rowMap->getComm()->getSize() > 1) {
198 this->GetOStream(
Warnings0) <<
"MueLu::Amesos2Smoother::Setup(): Applying nullspace fix on distributed matrix. Try rebalancing to single rank!" << std::endl;
199 ArrayRCP<GO> elements_RCP;
200 elements_RCP.resize(M);
201 ArrayView<GO> elements = elements_RCP();
202 for (
size_t k = 0; k<M; k++)
203 elements[k] = Teuchos::as<GO>(k);
204 colMap = MapFactory::Build(rowMap->lib(),M*rowMap->getComm()->getSize(),elements,Teuchos::ScalarTraits<GO>::zero(),rowMap->getComm());
205 importer = ImportFactory::Build(rowMap,colMap);
206 NullspaceImp = MultiVectorFactory::Build(colMap, Nullspace->getNumVectors());
207 NullspaceImp->doImport(*Nullspace,*importer,Xpetra::INSERT);
209 NullspaceImp = Nullspace;
213 ArrayRCP<const SC> nullspaceRCP, nullspaceImpRCP;
214 ArrayView<const SC> nullspace, nullspaceImp;
215 nullspaceRCP = Nullspace->getData(0);
216 nullspace = nullspaceRCP();
217 nullspaceImpRCP = NullspaceImp->getData(0);
218 nullspaceImp = nullspaceImpRCP();
220 RCP<CrsMatrixWrap> Acrs = rcp_dynamic_cast<CrsMatrixWrap>(A);
223 "MueLu::Amesos2Smoother::Setup Fixing nullspace for coarse matrix for Amesos2 when matrix is not a Crs matrix has not been implemented yet.");
225 ArrayRCP<const size_t> rowPointers;
226 ArrayRCP<const LO> colIndices;
227 ArrayRCP<const SC> values;
228 Acrs->getCrsMatrix()->getAllValues(rowPointers, colIndices, values);
230 ArrayRCP<size_t> newRowPointers_RCP;
231 ArrayRCP<LO> newColIndices_RCP;
232 ArrayRCP<SC> newValues_RCP;
234 size_t N = rowMap->getNodeNumElements();
235 newRowPointers_RCP.resize(N+1);
236 newColIndices_RCP.resize(N*M);
237 newValues_RCP.resize(N*M);
239 ArrayView<size_t> newRowPointers = newRowPointers_RCP();
240 ArrayView<LO> newColIndices = newColIndices_RCP();
241 ArrayView<SC> newValues = newValues_RCP();
243 SC normalization = Nullspace->getVector(0)->norm2();
244 normalization = Teuchos::ScalarTraits<Scalar>::one()/(normalization*normalization);
247 for (
size_t i = 0; i < N; i++) {
248 newRowPointers[i] = i*M;
249 for (
size_t j = 0; j < M; j++) {
250 newColIndices[i*M+j] = Teuchos::as<LO>(j);
251 newValues[i*M+j] = normalization * nullspace[i]*Teuchos::ScalarTraits<Scalar>::conjugate(nullspaceImp[j]);
254 newRowPointers[N] = N*M;
257 for (
size_t i = 0; i < N; i++) {
258 for (
size_t jj = rowPointers[i]; jj < rowPointers[i+1]; jj++) {
259 LO j = colMap->getLocalElement(A->getColMap()->getGlobalElement(colIndices[jj]));
261 newValues[i*M+j] += v;
265 RCP<Matrix> newA = rcp(
new CrsMatrixWrap(rowMap, colMap, 0, Xpetra::StaticProfile));
266 RCP<CrsMatrix> newAcrs = rcp_dynamic_cast<CrsMatrixWrap>(newA)->getCrsMatrix();
268 using Teuchos::arcp_const_cast;
269 newAcrs->setAllValues(arcp_const_cast<size_t>(newRowPointers_RCP), arcp_const_cast<LO>(newColIndices_RCP), arcp_const_cast<SC>(newValues_RCP));
270 newAcrs->expertStaticFillComplete(A->getDomainMap(), A->getRangeMap(),
271 importer, A->getCrsGraph()->getExporter());
280 prec_ = Amesos2::create<Tpetra_CrsMatrix,Tpetra_MultiVector>(type_, tA);
281 TEUCHOS_TEST_FOR_EXCEPTION(prec_ == Teuchos::null,
Exceptions::RuntimeError,
"Amesos2::create returns Teuchos::null");
286 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
290 RCP<Tpetra_MultiVector> tX, tB;
291 if (!useTransformation_) {
296 size_t numVectors = X.getNumVectors();
297 size_t length = X.getLocalLength();
300 "MueLu::Amesos2Smoother::Apply: Fixing coarse matrix for Amesos2 for multivectors has not been implemented yet.");
301 ArrayRCP<const SC> Xdata = X. getData(0), Bdata = B. getData(0);
302 ArrayRCP<SC> X_data = X_->getDataNonConst(0), B_data = B_->getDataNonConst(0);
304 for (
size_t i = 0; i < length; i++) {
305 X_data[i] = Xdata[i];
306 B_data[i] = Bdata[i];
318 prec_->setX(Teuchos::null);
319 prec_->setB(Teuchos::null);
321 if (useTransformation_) {
323 size_t length = X.getLocalLength();
325 ArrayRCP<SC> Xdata = X. getDataNonConst(0);
326 ArrayRCP<const SC> X_data = X_->getData(0);
328 for (
size_t i = 0; i < length; i++)
329 Xdata[i] = X_data[i];
333 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
334 RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
341 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
343 std::ostringstream out;
346 out << prec_->description();
350 out <<
"{type = " << type_ <<
"}";
355 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
360 out0 <<
"Prec. type: " << type_ << std::endl;
363 out0 <<
"Parameter list: " << std::endl;
364 Teuchos::OSTab tab2(out);
365 out << this->GetParameterList();
368 if ((verbLevel &
External) && prec_ != Teuchos::null) {
369 Teuchos::OSTab tab2(out);
370 out << *prec_ << std::endl;
373 if (verbLevel &
Debug)
376 <<
"RCP<prec_>: " << prec_ << std::endl;
379 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
382 return prec_->getStatus().getNnzLU();
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
Class that encapsulates Amesos2 direct solvers.
void DeclareInput(Level ¤tLevel) const
Input.
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
std::string type_
amesos2-specific key phrase that denote smoother type
RCP< SmootherPrototype > Copy() const
std::string description() const
Return a simple one-line description of this object.
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
virtual ~Amesos2Smoother()
Destructor.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void Setup(Level ¤tLevel)
Set up the direct solver. This creates the underlying Amesos2 solver object according to the paramete...
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply the direct solver. Solves the linear system AX=B using the constructed solver.
Amesos2Smoother(const std::string &type="", const Teuchos::ParameterList ¶mList=Teuchos::ParameterList())
Constructor Creates a MueLu interface to the direct solvers in the Amesos2 package....
virtual std::string description() const
Return a simple one-line description of this object.
Exception throws to report errors in the internal logical of the program.
Timer to be used in factories. Similar to Monitor but with additional timers.
Class that holds all level-specific information.
virtual void SetParameterList(const Teuchos::ParameterList ¶mList)
Set parameters from a parameter list and return with default values.
bool IsSetup() const
Get the state of a smoother prototype.
static RCP< Tpetra::CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Op2NonConstTpetraCrs(RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Op)
static RCP< Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > MV2NonConstTpetraMV2(Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &vec)
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
std::string tolower(const std::string &str)
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line)
@ Debug
Print additional debugging information.
@ External
Print external lib objects.
@ Runtime1
Description of what is happening (more verbose)
@ Parameters0
Print class parameters.
@ Parameters1
Print class parameters (more parameters, more verbose)
std::string toString(const T &what)
Little helper function to convert non-string types to strings.