189 const EOpTransp M_trans,
190 const MultiVectorBase<SC> &X_in,
191 const Ptr<MultiVectorBase<SC> > &Y_inout,
197 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
199 using Teuchos::rcpFromRef;
200 typedef Teuchos::ScalarTraits<SC> ST;
201 typedef RCP<MultiVectorBase<SC> > MultiVectorPtr;
202 typedef RCP<const MultiVectorBase<SC> > ConstMultiVectorPtr;
203 typedef RCP<const LinearOpBase<SC> > ConstLinearOpPtr;
205 int rank = comm_->getRank();
207 Teuchos::RCP<const Thyra::ProductMultiVectorBase<SC> > X
208 = Teuchos::rcp_dynamic_cast<const Thyra::ProductMultiVectorBase<SC> > ( rcpFromRef(X_in) );
210 Teuchos::RCP< Thyra::ProductMultiVectorBase<SC> > Y
211 = Teuchos::rcp_dynamic_cast< Thyra::ProductMultiVectorBase<SC> > ( rcpFromPtr(Y_inout) );
214 Teuchos::RCP< const MultiVectorBase< SC > > X_0 = X->getMultiVectorBlock(0);
215 Teuchos::RCP< MultiVectorBase< SC > > Y_0 = Y->getNonconstMultiVectorBlock(0);
218 Teuchos::RCP< const MultiVectorBase< SC > > X_1 = X->getMultiVectorBlock(1);
219 Teuchos::RCP< MultiVectorBase< SC > > Y_1 = Y->getNonconstMultiVectorBlock(1);
222 if (type_ ==
"Diagonal"){
223 velocityInv_->apply(NOTRANS, *X_0, Y_0.ptr(), 1., 0.);
225 pressureInv_->apply(NOTRANS, *X_1, Y_1.ptr(), 1., 0.);
228 else if (type_ ==
"Triangular"){
230 pressureInv_->apply(NOTRANS, *X_1, Y_1.ptr(), 1., 0.);
232 Teuchos::RCP< MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
234 BT_->apply(NOTRANS, *Y_1, Z_0.ptr(), -1., 1.);
236 velocityInv_->apply(NOTRANS, *Z_0, Y_0.ptr(), 1., 0.);
239 else if (type_ ==
"PCD"){
241 TEUCHOS_TEST_FOR_EXCEPTION(laplaceInverse_.is_null(), std::runtime_error,
"laplaceInverse_ not set.");
242 TEUCHOS_TEST_FOR_EXCEPTION(convectionDiffusionOperator_.is_null(), std::runtime_error,
"convectionDiffusionOperator_ not set.");
243 TEUCHOS_TEST_FOR_EXCEPTION(massMatrixInverse_.is_null(), std::runtime_error,
"massMatrixInverse_ not set.");
248 massMatrixInverse_->apply(NOTRANS, *X_1, Y_1.ptr(), 1., 0.);
250 convectionDiffusionOperator_->apply(NOTRANS, *Y_1, Y_1.ptr(), 1., 0.);
252 laplaceInverse_->apply(NOTRANS, *Y_1, Y_1.ptr(), 1., 0.);
262 Teuchos::RCP< MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
264 BT_->apply(NOTRANS, *Y_1, Z_0.ptr(), -1., 1.);
266 velocityInv_->apply(NOTRANS, *Z_0, Y_0.ptr(), 1., 0.);
269 else if (type_ ==
"LSC"){
271 TEUCHOS_TEST_FOR_EXCEPTION(laplaceInverse_.is_null(), std::runtime_error,
"laplaceInverse_ not set.");
272 TEUCHOS_TEST_FOR_EXCEPTION(massMatrixVInverse_.is_null(), std::runtime_error,
"massMatrixVInverse_ not set.");
274 laplaceInverse_->apply(NOTRANS, *X_1, Y_1.ptr(), 1., 0.);
277 Teuchos::RCP< MultiVectorBase< SC > > X_res_0 = X_0->clone_mv();
278 BT_->apply(NOTRANS, *Y_1, X_res_0.ptr(), 1., 0.);
279 massMatrixVInverse_->apply(NOTRANS, *X_res_0, X_res_0.ptr(), 1., 0.);
280 F_->apply(NOTRANS, *X_res_0, X_res_0.ptr(), 1., 0.);
281 massMatrixVInverse_->apply(NOTRANS, *X_res_0, X_res_0.ptr(), 1., 0.);
282 BT_->apply(TRANS, *X_res_0, Y_1.ptr(), 1., 0.);
284 laplaceInverse_->apply(NOTRANS, *Y_1, Y_1.ptr(), -1., 0.);
286 Teuchos::RCP< MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
287 BT_->apply(NOTRANS, *Y_1, Z_0.ptr(), -1., 1.);
289 velocityInv_->apply(NOTRANS, *Z_0, Y_0.ptr(), 1., 0.);
293 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"Unknow 2x2 block preconditioner type. Select Diagonal or Triangular.");