188 const Thyra::EOpTransp M_trans,
189 const Thyra::MultiVectorBase<SC> &X_in,
190 const Thyra::Ptr<Thyra::MultiVectorBase<SC> > &Y_inout,
196 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
198 typedef Teuchos::ScalarTraits<SC> ST;
199 typedef Teuchos::RCP<Thyra::MultiVectorBase<SC> > MultiVectorPtr;
200 typedef Teuchos::RCP<const Thyra::MultiVectorBase<SC> > ConstMultiVectorPtr;
201 typedef Teuchos::RCP<const Thyra::LinearOpBase<SC> > ConstLinearOpPtr;
203 int rank = comm_->getRank();
205 Teuchos::RCP<const Thyra::ProductMultiVectorBase<SC> > X
206 = Teuchos::rcp_dynamic_cast<const Thyra::ProductMultiVectorBase<SC> > ( Teuchos::rcpFromRef(X_in) );
208 Teuchos::RCP< Thyra::ProductMultiVectorBase<SC> > Y
209 = Teuchos::rcp_dynamic_cast< Thyra::ProductMultiVectorBase<SC> > ( rcpFromPtr(Y_inout) );
212 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_0 = X->getMultiVectorBlock(0);
213 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_0 = Y->getNonconstMultiVectorBlock(0);
216 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_1 = X->getMultiVectorBlock(1);
217 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_1 = Y->getNonconstMultiVectorBlock(1);
220 if (type_ ==
"Diagonal"){
221 velocityInv_->apply(Thyra::NOTRANS, *X_0, Y_0.ptr(), 1., 0.);
223 pressureInv_->apply(Thyra::NOTRANS, *X_1, Y_1.ptr(), 1., 0.);
226 else if (type_ ==
"Triangular"){
228 pressureInv_->apply(Thyra::NOTRANS, *X_1, Y_1.ptr(), 1., 0.);
230 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
232 BT_->apply(Thyra::NOTRANS, *Y_1, Z_0.ptr(), -1., 1.);
234 velocityInv_->apply(Thyra::NOTRANS, *Z_0, Y_0.ptr(), 1., 0.);
237 else if (type_ ==
"PCD"){
239 TEUCHOS_TEST_FOR_EXCEPTION(laplaceInverse_.is_null(), std::runtime_error,
"laplaceInverse_ not set.");
240 TEUCHOS_TEST_FOR_EXCEPTION(convectionDiffusionOperator_.is_null(), std::runtime_error,
"convectionDiffusionOperator_ not set.");
241 TEUCHOS_TEST_FOR_EXCEPTION(massMatrixInverse_.is_null(), std::runtime_error,
"massMatrixInverse_ not set.");
246 massMatrixInverse_->apply(Thyra::NOTRANS, *X_1, Y_1.ptr(), 1., 0.);
248 convectionDiffusionOperator_->apply(Thyra::NOTRANS, *Y_1, Y_1.ptr(), 1., 0.);
250 laplaceInverse_->apply(Thyra::NOTRANS, *Y_1, Y_1.ptr(), 1., 0.);
260 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
262 BT_->apply(Thyra::NOTRANS, *Y_1, Z_0.ptr(), -1., 1.);
264 velocityInv_->apply(Thyra::NOTRANS, *Z_0, Y_0.ptr(), 1., 0.);
267 else if (type_ ==
"LSC"){
269 TEUCHOS_TEST_FOR_EXCEPTION(laplaceInverse_.is_null(), std::runtime_error,
"laplaceInverse_ not set.");
270 TEUCHOS_TEST_FOR_EXCEPTION(massMatrixVInverse_.is_null(), std::runtime_error,
"massMatrixVInverse_ not set.");
272 laplaceInverse_->apply(Thyra::NOTRANS, *X_1, Y_1.ptr(), 1., 0.);
275 Teuchos::RCP< Thyra::MultiVectorBase< SC > > X_res_0 = X_0->clone_mv();
276 BT_->apply(Thyra::NOTRANS, *Y_1, X_res_0.ptr(), 1., 0.);
277 massMatrixVInverse_->apply(Thyra::NOTRANS, *X_res_0, X_res_0.ptr(), 1., 0.);
278 F_->apply(Thyra::NOTRANS, *X_res_0, X_res_0.ptr(), 1., 0.);
279 massMatrixVInverse_->apply(Thyra::NOTRANS, *X_res_0, X_res_0.ptr(), 1., 0.);
280 BT_->apply(Thyra::TRANS, *X_res_0, Y_1.ptr(), 1., 0.);
282 laplaceInverse_->apply(Thyra::NOTRANS, *Y_1, Y_1.ptr(), -1., 0.);
284 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
285 BT_->apply(Thyra::NOTRANS, *Y_1, Z_0.ptr(), -1., 1.);
287 velocityInv_->apply(Thyra::NOTRANS, *Z_0, Y_0.ptr(), 1., 0.);
291 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"Unknow 2x2 block preconditioner type. Select Diagonal or Triangular.");