56 RCP<Matrix> A = Get<RCP<Matrix>>(currentLevel,
"A");
57 RCP<BlockedCrsMatrix> bA = rcp_dynamic_cast<BlockedCrsMatrix>(A);
60 "MueLu::SchurComplementFactory::Build: input matrix A is not of type BlockedCrsMatrix!");
62 "MueLu::SchurComplementFactory::Build: input matrix A is a " << bA->Rows() <<
"x" << bA->Cols() <<
" block matrix. We expect a 2x2 blocked operator.");
65 RCP<Matrix> Ainv = currentLevel.
Get<RCP<Matrix>>(
"Ainv", this->GetFactory(
"Ainv").get());
66 RCP<Matrix> S = ComputeSchurComplement(bA, Ainv);
68 GetOStream(
Statistics1) <<
"S has " << S->getGlobalNumRows() <<
"x" << S->getGlobalNumCols() <<
" rows and columns." << std::endl;
72 Set(currentLevel,
"A", S);
76RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
78 using STS = Teuchos::ScalarTraits<SC>;
79 const SC zero = STS::zero(), one = STS::one();
81 RCP<Matrix> A01 = bA->getMatrix(0, 1);
82 RCP<Matrix> A10 = bA->getMatrix(1, 0);
83 RCP<Matrix> A11 = bA->getMatrix(1, 1);
85 RCP<BlockedCrsMatrix> bA01 = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A01);
86 const bool isBlocked = (bA01 == Teuchos::null ? false :
true);
88 const ParameterList& pL = GetParameterList();
89 const SC omega = pL.get<
Scalar>(
"omega");
92 "MueLu::SchurComplementFactory::Build: Scaling parameter omega must not be zero to avoid division by zero.");
94 RCP<Matrix> S = Teuchos::null;
95 RCP<Matrix> D = Teuchos::null;
98 if (A01.is_null() ==
false && A10.is_null() ==
false) {
100 Ainv->scale(Teuchos::as<Scalar>(-one / omega));
104 RCP<ParameterList> myparams = rcp(
new ParameterList);
105 myparams->set(
"compute global constants",
true);
108 TEUCHOS_TEST_FOR_EXCEPTION(A01->getRangeMap()->isSameAs(*(Ainv->getDomainMap())) ==
false,
Exceptions::RuntimeError,
109 "MueLu::SchurComplementFactory::Build: RangeMap of A01 and domain map of Ainv are not the same.");
110 RCP<Matrix> C = MatrixMatrix::Multiply(*Ainv,
false, *A01,
false, GetOStream(
Statistics2),
true,
true, std::string(
"SchurComplementFactory"), myparams);
114 "MueLu::SchurComplementFactory::Build: RangeMap of A10 and domain map A01 are not the same.");
115 D = MatrixMatrix::Multiply(*A10,
false, *C,
false, GetOStream(
Statistics2),
true,
true, std::string(
"SchurComplementFactory"), myparams);
118 auto bA10 = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A10);
119 auto bAinv = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(Ainv);
121 "MueLu::SchurComplementFactory::Build: Casting Ainv to BlockedCrsMatrix not possible.");
125 "MueLu::SchurComplementFactory::Build: Block rows and cols of bA01 and bAinv are not compatible.");
126 RCP<BlockedCrsMatrix> C = MatrixMatrix::TwoMatrixMultiplyBlock(*bAinv,
false, *bA01,
false, GetOStream(
Statistics2));
130 "MueLu::SchurComplementFactory::Build: Block rows and cols of bA10 and bA01 are not compatible.");
131 D = MatrixMatrix::TwoMatrixMultiplyBlock(*bA10,
false, *C,
false, GetOStream(
Statistics2));
133 if (!A11.is_null()) {
134 MatrixMatrix::TwoMatrixAdd(*A11,
false, one, *D,
false, one, S, GetOStream(
Statistics2));
138 "MueLu::SchurComplementFactory::Build: RangeMap of A11 and S are not the same.");
140 "MueLu::SchurComplementFactory::Build: DomainMap of A11 and S are not the same.");
142 S = MatrixFactory::BuildCopy(D);
145 if (!A11.is_null()) {
146 S = MatrixFactory::BuildCopy(A11);
149 "MueLu::SchurComplementFactory::Build: Constructing Schur complement for matrix with zero block row or column.");
160 RCP<BlockedCrsMatrix> bS = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(S);
162 if (bS != Teuchos::null && bS->Rows() == 1 && bS->Cols() == 1) {
163 RCP<Matrix> temp = bS->getCrsMatrix();
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....