MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_BlockedDirectSolver_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10/*
11 * MueLu_BlockedDirectSolver_def.hpp
12 *
13 * Created on: 09.02.2014
14 * Author: tobias
15 */
16
17#ifndef MUELU_BLOCKEDDIRECTSOLVER_DEF_HPP_
18#define MUELU_BLOCKEDDIRECTSOLVER_DEF_HPP_
19
20#include "Teuchos_ArrayViewDecl.hpp"
21#include "Teuchos_ScalarTraits.hpp"
22
23#include "MueLu_ConfigDefs.hpp"
24
25#include <Xpetra_Matrix.hpp>
26#include <Xpetra_BlockedCrsMatrix.hpp>
27#include <Xpetra_MultiVectorFactory.hpp>
28
30#include "MueLu_MergedBlockedMatrixFactory.hpp"
31#include "MueLu_Level.hpp"
32#include "MueLu_Monitor.hpp"
33#include "MueLu_DirectSolver.hpp"
34#include "MueLu_Behavior.hpp"
35
36namespace MueLu {
37
38template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
39BlockedDirectSolver<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BlockedDirectSolver(const std::string &type, const Teuchos::ParameterList &paramList) {
40 MergedAFact_ = Teuchos::rcp(new MergedBlockedMatrixFactory());
41 s_ = Teuchos::rcp(new DirectSolver(type, paramList));
42 type_ = "blocked direct solver (" + type + ")";
43}
44
45template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
47 RCP<ParameterList> validParamList = rcp(new ParameterList());
48
49 validParamList->set<RCP<const FactoryBase> >("A", null, "Generating factory of the matrix A");
50
51 return validParamList;
52}
53
54template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
56 // Note that we have a nested smoother/solver object (of type DirectSolver), so we have to declare the dependencies by hand
57 // call DeclareInput by hand, since this->Input(currentLevel, "A") would not properly free A in the release mode (dependencies)
58 // We need the blocked version of A as input for the MergedAFact_
59 currentLevel.DeclareInput("A", this->GetFactory("A").get());
60
61 // syncronize input factory for "A" and nested representation for "A"
62 MergedAFact_->SetFactory("A", this->GetFactory("A"));
63
64 // declare input factories for nested direct solver
65 s_->SetFactory("A", MergedAFact_);
66 s_->DeclareInput(currentLevel);
67}
68
69template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
71 RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
72
73 FactoryMonitor m(*this, "Setup BlockedDirectSolver", currentLevel);
74 if (this->IsSetup() == true)
75 this->GetOStream(Warnings0) << "MueLu::BlockedDirectSolver::Setup(): Setup() has already been called";
76
77 // extract blocked operator A from current level
78 A_ = Factory::Get<RCP<Matrix> >(currentLevel, "A"); // A needed for extracting map extractors
79 RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
80 TEUCHOS_TEST_FOR_EXCEPTION(bA.is_null(), Exceptions::BadCast,
81 "MueLu::BlockedDirectSolver::Build: input matrix A is not of type BlockedCrsMatrix.");
82
83 s_->Setup(currentLevel);
84
85 this->IsSetup(true);
86}
87
88template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
89void BlockedDirectSolver<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero) const {
90 TEUCHOS_TEST_FOR_EXCEPTION(this->IsSetup() == false, Exceptions::RuntimeError,
91 "MueLu::BlockedDirectSolver::Apply(): Setup() has not been called");
92
93 RCP<MultiVector> rcpX = Teuchos::rcpFromRef(X);
94 RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
95 RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
96 RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
97
98 if (Behavior::debug()) {
99 RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
100 if (bB.is_null() == false) {
101 // TEUCHOS_TEST_FOR_EXCEPTION(A_->getRangeMap()->isSameAs(*(B.getMap())) == false, Exceptions::RuntimeError, "MueLu::BlockedDirectSolver::Apply(): The map of RHS vector B is not the same as range map of the blocked operator A. Please check the map of B and A.");
102 } else {
103 TEUCHOS_TEST_FOR_EXCEPTION(bA->getFullRangeMap()->isSameAs(*(B.getMap())) == false, Exceptions::RuntimeError, "MueLu::BlockedDirectSolver::Apply(): The map of RHS vector B is not the same as range map of the blocked operator A. Please check the map of B and A.");
104 }
105 if (bX.is_null() == false) {
106 // TEUCHOS_TEST_FOR_EXCEPTION(A_->getDomainMap()->isSameAs(*(X.getMap())) == false, Exceptions::RuntimeError, "MueLu::BlockedDirectSolver::Apply(): The map of the solution vector X is not the same as domain map of the blocked operator A. Please check the map of X and A.");
107 } else {
108 TEUCHOS_TEST_FOR_EXCEPTION(bA->getFullDomainMap()->isSameAs(*(X.getMap())) == false, Exceptions::RuntimeError, "MueLu::BlockedDirectSolver::Apply(): The map of the solution vector X is not the same as domain map of the blocked operator A. Please check the map of X and A.");
109 }
110 }
111
112 if (bB.is_null() == true && bX.is_null() == true) {
113 // standard case (neither B nor X are blocked)
114 s_->Apply(X, B, InitialGuessIsZero);
115 } else if (bB.is_null() == false && bX.is_null() == false) {
116 // both B and X are blocked
117 RCP<MultiVector> mergedX = bX->Merge();
118 RCP<const MultiVector> mergedB = bB->Merge();
119 s_->Apply(*mergedX, *mergedB, InitialGuessIsZero);
120 RCP<MultiVector> xx = Teuchos::rcp(new BlockedMultiVector(bX->getBlockedMap(), mergedX));
121 SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();
122 X.update(one, *xx, zero);
123 } else if (bB.is_null() == true && bX.is_null() == false) {
124 // the solution vector is blocked
125 RCP<MultiVector> mergedX = bX->Merge();
126 s_->Apply(*mergedX, B, InitialGuessIsZero);
127 RCP<MultiVector> xx = Teuchos::rcp(new BlockedMultiVector(bX->getBlockedMap(), mergedX));
128 SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();
129 X.update(one, *xx, zero);
130 } else if (bB.is_null() == false && bX.is_null() == true) {
131 // only the RHS vector is blocked
132 RCP<const MultiVector> mergedB = bB->Merge();
133 s_->Apply(X, *mergedB, InitialGuessIsZero);
134 }
135}
136
137template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
138RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
142
143template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
145 std::ostringstream out;
147 out << "{type = " << type_ << "}";
148 return out.str();
149}
150
151template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
152void BlockedDirectSolver<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream &out, const VerbLevel verbLevel) const {
154
155 if (verbLevel & Parameters0)
156 out0 << "Prec. type: " << type_ << std::endl;
157
158 if (verbLevel & Debug)
159 out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl;
160}
161
162template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
164 // FIXME: This is a placeholder
165 return Teuchos::OrdinalTraits<size_t>::invalid();
166}
167
168} // namespace MueLu
169
170#endif /* MUELU_BLOCKEDDIRECTSOLVER_DEF_HPP_ */
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
static bool debug()
Whether MueLu is in debug mode.
direct solver for nxn blocked matrices
void Setup(Level &currentLevel)
Setup routine Call the underlaying Setup routine of the nested direct solver once the input block mat...
BlockedDirectSolver(const std::string &type="", const Teuchos::ParameterList &paramList=Teuchos::ParameterList())
Constructor.
RCP< const ParameterList > GetValidParameterList() const
Input.
void DeclareInput(Level &currentLevel) const
Input.
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.
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.
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
RCP< SmootherPrototype > Copy() const
virtual std::string description() const
Return a simple one-line description of this object.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
Exception indicating invalid cast attempted.
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.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
bool IsSetup() const
Get the state of a smoother prototype.
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line)
@ Debug
Print additional debugging information.
@ Parameters0
Print class parameters.