MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_BlockedDirectSolver_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/*
47 * MueLu_BlockedDirectSolver_def.hpp
48 *
49 * Created on: 09.02.2014
50 * Author: tobias
51 */
52
53#ifndef MUELU_BLOCKEDDIRECTSOLVER_DEF_HPP_
54#define MUELU_BLOCKEDDIRECTSOLVER_DEF_HPP_
55
56#include "Teuchos_ArrayViewDecl.hpp"
57#include "Teuchos_ScalarTraits.hpp"
58
59#include "MueLu_ConfigDefs.hpp"
60
61#include <Xpetra_Matrix.hpp>
62#include <Xpetra_BlockedCrsMatrix.hpp>
63#include <Xpetra_MultiVectorFactory.hpp>
64
66#include "MueLu_MergedBlockedMatrixFactory.hpp"
67#include "MueLu_Level.hpp"
68#include "MueLu_Monitor.hpp"
69#include "MueLu_DirectSolver.hpp"
70
71namespace MueLu {
72
73 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
74 BlockedDirectSolver<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BlockedDirectSolver(const std::string& type, const Teuchos::ParameterList& paramList)
75 {
76 MergedAFact_ = Teuchos::rcp(new MergedBlockedMatrixFactory());
77 s_ = Teuchos::rcp(new DirectSolver(type, paramList));
78 type_ = "blocked direct solver (" + type + ")";
79 }
80
81 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
83 RCP<ParameterList> validParamList = rcp(new ParameterList());
84
85 validParamList->set< RCP<const FactoryBase> >("A", null, "Generating factory of the matrix A");
86
87 return validParamList;
88 }
89
90 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
92 // Note that we have a nested smoother/solver object (of type DirectSolver), so we have to declare the dependencies by hand
93 // call DeclareInput by hand, since this->Input(currentLevel, "A") would not properly free A in the release mode (dependencies)
94 // We need the blocked version of A as input for the MergedAFact_
95 currentLevel.DeclareInput("A",this->GetFactory("A").get());
96
97 // syncronize input factory for "A" and nested representation for "A"
98 MergedAFact_->SetFactory("A", this->GetFactory("A"));
99
100 // declare input factories for nested direct solver
101 s_->SetFactory("A",MergedAFact_);
102 s_->DeclareInput(currentLevel);
103 }
104
105 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
107 RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
108
109 FactoryMonitor m(*this, "Setup BlockedDirectSolver", currentLevel);
110 if (this->IsSetup() == true)
111 this->GetOStream(Warnings0) << "MueLu::BlockedDirectSolver::Setup(): Setup() has already been called";
112
113 // extract blocked operator A from current level
114 A_ = Factory::Get< RCP<Matrix> >(currentLevel, "A"); // A needed for extracting map extractors
115 RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
116 TEUCHOS_TEST_FOR_EXCEPTION(bA.is_null(), Exceptions::BadCast,
117 "MueLu::BlockedDirectSolver::Build: input matrix A is not of type BlockedCrsMatrix.");
118
119 s_->Setup(currentLevel);
120
121 this->IsSetup(true);
122 }
123
124 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
125 void BlockedDirectSolver<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector &X, const MultiVector& B, bool InitialGuessIsZero) const {
126 TEUCHOS_TEST_FOR_EXCEPTION(this->IsSetup() == false, Exceptions::RuntimeError,
127 "MueLu::BlockedDirectSolver::Apply(): Setup() has not been called");
128
129 RCP<MultiVector> rcpX = Teuchos::rcpFromRef(X);
130 RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
131 RCP<BlockedMultiVector> bX = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rcpX);
132 RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
133
134#ifdef HAVE_MUELU_DEBUG
135 RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_);
136 if(bB.is_null() == false) {
137 //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.");
138 } else {
139 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.");
140 }
141 if(bX.is_null() == false) {
142 //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.");
143 } else {
144 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.");
145 }
146#endif
147
148 if (bB.is_null() == true && bX.is_null() == true) {
149 // standard case (neither B nor X are blocked)
150 s_->Apply(X, B, InitialGuessIsZero);
151 } else if(bB.is_null() == false && bX.is_null() == false) {
152 // both B and X are blocked
153 RCP<MultiVector> mergedX = bX->Merge();
154 RCP<const MultiVector> mergedB = bB->Merge();
155 s_->Apply(*mergedX, *mergedB, InitialGuessIsZero);
156 RCP<MultiVector> xx = Teuchos::rcp(new BlockedMultiVector(bX->getBlockedMap(),mergedX));
157 SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();
158 X.update(one,*xx,zero);
159 } else if (bB.is_null() == true && bX.is_null() == false) {
160 // the solution vector is blocked
161 RCP<MultiVector> mergedX = bX->Merge();
162 s_->Apply(*mergedX, B, InitialGuessIsZero);
163 RCP<MultiVector> xx = Teuchos::rcp(new BlockedMultiVector(bX->getBlockedMap(),mergedX));
164 SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();
165 X.update(one,*xx,zero);
166 } else if (bB.is_null() == false && bX.is_null() == true) {
167 // only the RHS vector is blocked
168 RCP<const MultiVector> mergedB = bB->Merge();
169 s_->Apply(X, *mergedB, InitialGuessIsZero);
170 }
171 }
172
173 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
174 RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
178
179 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
181 std::ostringstream out;
183 out << "{type = " << type_ << "}";
184 return out.str();
185 }
186
187 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
188 void BlockedDirectSolver<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream &out, const VerbLevel verbLevel) const {
190
191 if (verbLevel & Parameters0)
192 out0 << "Prec. type: " << type_ << std::endl;
193
194 if (verbLevel & Debug)
195 out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl;
196 }
197
198 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
200 // FIXME: This is a placeholder
201 return Teuchos::OrdinalTraits<size_t>::invalid();
202 }
203
204
205} // namespace MueLu
206
207
208
209#endif /* MUELU_BLOCKEDDIRECTSOLVER_DEF_HPP_ */
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
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.
MueLu::MergedBlockedMatrixFactory< Scalar, LocalOrdinal, GlobalOrdinal, Node > MergedBlockedMatrixFactory
RCP< DirectSolver > s_
Direct solver.
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.
RCP< MergedBlockedMatrixFactory > MergedAFact_
Factory to generate merged block matrix.
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.
T Get(Level &level, const std::string &varName) const
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory().
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.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line).
@ Debug
Print additional debugging information.
@ Parameters0
Print class parameters.