1#ifndef PrecOpFaCSI_DEF_hpp
2#define PrecOpFaCSI_DEF_hpp
4#include <Thyra_TpetraMultiVector_decl.hpp>
5#include <Teuchos_VerboseObject.hpp>
6#include <Teuchos_Range1D.hpp>
21template<
class SC,
class LO,
class GO,
class NO>
22PrecOpFaCSI<SC,LO,GO,NO>::PrecOpFaCSI()
24fluidPrecMonolithic_(false),
25useSolidPreconditioner_(true)
30template<
class SC,
class LO,
class GO,
class NO>
31PrecOpFaCSI<SC,LO,GO,NO>::PrecOpFaCSI(CommConstPtr_Type comm,
bool fluidPrecMonolithic,
bool useFluidPreconditioner,
bool useSolidPreconditioner,
bool onlyDiagonal)
32:PreconditionerOperator<SC,LO,GO,NO>(),
33fluidPrecMonolithic_(fluidPrecMonolithic),
34useFluidPreconditioner_(useFluidPreconditioner),
35useSolidPreconditioner_(useSolidPreconditioner),
36onlyDiagonal_(onlyDiagonal)
42template<
class SC,
class LO,
class GO,
class NO>
43void PrecOpFaCSI<SC,LO,GO,NO>::setGE(ThyraLinOpPtr_Type C1,
44 ThyraLinOpPtr_Type C1T,
45 ThyraLinOpPtr_Type C2,
46 ThyraLinOpPtr_Type sInv,
47 ThyraLinOpPtr_Type fInv,
48 ThyraLinOpPtr_Type fF,
49 ThyraLinOpPtr_Type fBT){
62template<
class SC,
class LO,
class GO,
class NO>
63void PrecOpFaCSI<SC,LO,GO,NO>::setGI(ThyraLinOpPtr_Type C1,
64 ThyraLinOpPtr_Type C1T,
65 ThyraLinOpPtr_Type C2,
66 ThyraLinOpPtr_Type C4,
67 ThyraLinOpPtr_Type sInv,
68 ThyraLinOpPtr_Type fInv,
69 ThyraLinOpPtr_Type fF,
70 ThyraLinOpPtr_Type fBT,
71 ThyraLinOpPtr_Type gInv){
86template<
class SC,
class LO,
class GO,
class NO>
87void PrecOpFaCSI<SC,LO,GO,NO>::setGIShape(ThyraLinOpPtr_Type C1,
88 ThyraLinOpPtr_Type C1T,
89 ThyraLinOpPtr_Type C2,
90 ThyraLinOpPtr_Type C4,
91 ThyraLinOpPtr_Type sInv,
92 ThyraLinOpPtr_Type fInv,
93 ThyraLinOpPtr_Type fF,
94 ThyraLinOpPtr_Type fBT,
95 ThyraLinOpPtr_Type gInv,
96 ThyraLinOpPtr_Type shape_v,
97 ThyraLinOpPtr_Type shape_p){
108 setShapeDeriv(shape_v, shape_p);
114template<
class SC,
class LO,
class GO,
class NO>
115void PrecOpFaCSI<SC,LO,GO,NO>::setC1(ThyraLinOpPtr_Type C1){
118template<
class SC,
class LO,
class GO,
class NO>
119void PrecOpFaCSI<SC,LO,GO,NO>::setC1T(ThyraLinOpPtr_Type C1T){
122template<
class SC,
class LO,
class GO,
class NO>
123void PrecOpFaCSI<SC,LO,GO,NO>::setC2(ThyraLinOpPtr_Type C2){
126template<
class SC,
class LO,
class GO,
class NO>
127void PrecOpFaCSI<SC,LO,GO,NO>::setC4(ThyraLinOpPtr_Type C4){
130template<
class SC,
class LO,
class GO,
class NO>
131void PrecOpFaCSI<SC,LO,GO,NO>::setShapeDeriv(ThyraLinOpPtr_Type shape_v, ThyraLinOpPtr_Type shape_p){
135template<
class SC,
class LO,
class GO,
class NO>
136void PrecOpFaCSI<SC,LO,GO,NO>::setStructInv(ThyraLinOpPtr_Type sInv){
139template<
class SC,
class LO,
class GO,
class NO>
140void PrecOpFaCSI<SC,LO,GO,NO>::setFluidInv(ThyraLinOpPtr_Type fInv){
143template<
class SC,
class LO,
class GO,
class NO>
144void PrecOpFaCSI<SC,LO,GO,NO>::setGeoInv(ThyraLinOpPtr_Type gInv){
147template<
class SC,
class LO,
class GO,
class NO>
148void PrecOpFaCSI<SC,LO,GO,NO>::setFluidF(ThyraLinOpPtr_Type fF){
151template<
class SC,
class LO,
class GO,
class NO>
152void PrecOpFaCSI<SC,LO,GO,NO>::setFluidBT(ThyraLinOpPtr_Type fBT){
156template<
class SC,
class LO,
class GO,
class NO>
157void PrecOpFaCSI<SC,LO,GO,NO>::initialize(){
158 TEUCHOS_TEST_FOR_EXCEPTION(fInv_.is_null(), std::runtime_error,
"Can not initialize FaCSI preconditioner: Fluid preconditioner not set.");
159 TEUCHOS_TEST_FOR_EXCEPTION(sInv_.is_null(), std::runtime_error,
"Can not initialize FaCSI preconditioner: Structure preconditioner not set.");
160 TEUCHOS_TEST_FOR_EXCEPTION(C1_.is_null(), std::runtime_error,
"Can not initialize FaCSI preconditioner: C1 not set.");
161 Teuchos::Array< Teuchos::RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesRange( 4 );
162 Teuchos::Array< Teuchos::RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesDomain( 4 );
163 vectorSpacesRange[0] = fF_->range();
164 vectorSpacesRange[1] = fBT_->domain();
165 vectorSpacesRange[2] = sInv_->range();
166 vectorSpacesRange[3] = C1_->range();
168 vectorSpacesDomain[0] = fF_->domain();
169 vectorSpacesDomain[1] = fBT_->domain();
170 vectorSpacesDomain[2] = sInv_->domain();
171 vectorSpacesDomain[3] = C1T_->domain();
172 if ( !gInv_.is_null() ) {
173 vectorSpacesRange.push_back( gInv_->range() );
174 vectorSpacesDomain.push_back( gInv_->domain() );
179 Teuchos::RCP<const Thyra::DefaultProductVectorSpace<SC> > pR = Thyra::productVectorSpace<SC>( vectorSpacesRange );
180 Teuchos::RCP<const Thyra::DefaultProductVectorSpace<SC> > pD = Thyra::productVectorSpace<SC>( vectorSpacesDomain );
187 this->defaultProductRange_ = pR;
188 this->defaultProductDomain_ = pD;
191template<
class SC,
class LO,
class GO,
class NO>
192void PrecOpFaCSI<SC,LO,GO,NO>::applyIt(
193 const Thyra::EOpTransp M_trans,
194 const Thyra::MultiVectorBase<SC> &X_in,
195 const Thyra::Ptr<Thyra::MultiVectorBase<SC> > &Y_inout,
200 applyImpl(M_trans, X_in, Y_inout, alpha, beta);
204template<
class SC,
class LO,
class GO,
class NO>
206 const Thyra::EOpTransp M_trans,
207 const Thyra::MultiVectorBase<SC> &X_in,
208 const Thyra::Ptr<Thyra::MultiVectorBase<SC> > &Y_inout,
213 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
215 typedef Teuchos::ScalarTraits<SC> ST;
216 typedef Teuchos::RCP<Thyra::MultiVectorBase<SC> > MultiVectorPtr;
217 typedef Teuchos::RCP<const Thyra::MultiVectorBase<SC> > ConstMultiVectorPtr;
218 typedef Teuchos::RCP<const Thyra::LinearOpBase<SC> > ConstLinearOpPtr;
220 int rank = comm_->getRank();
223 Teuchos::RCP<const Thyra::ProductMultiVectorBase<SC> > X
224 = Teuchos::rcp_dynamic_cast<const Thyra::ProductMultiVectorBase<SC> > ( Teuchos::rcpFromRef(X_in) );
226 Teuchos::RCP< Thyra::ProductMultiVectorBase<SC> > Y
227 = Teuchos::rcp_dynamic_cast< Thyra::ProductMultiVectorBase<SC> > ( rcpFromPtr(Y_inout) );
231 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_s = X->getMultiVectorBlock(2);
232 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_s = Y->getNonconstMultiVectorBlock(2);
235 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_fv = X->getMultiVectorBlock(0);
236 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_fv = Y->getNonconstMultiVectorBlock(0);
237 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_fp = X->getMultiVectorBlock(1);
238 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_fp = Y->getNonconstMultiVectorBlock(1);
241 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_l = Y->getNonconstMultiVectorBlock(3);
242 Teuchos::RCP<const Thyra::MultiVectorBase< SC > > X_l = X->getMultiVectorBlock(3);
244 assign(Y_fv.ptr(), *X_fv);
245 assign(Y_fp.ptr(), *X_fp);
246 assign(Y_s.ptr(), *X_s);
247 assign(Y_l.ptr(), *X_l);
368 Teuchos::RCP<const Thyra::ProductMultiVectorBase<SC> > X
369 = Teuchos::rcp_dynamic_cast<const Thyra::ProductMultiVectorBase<SC> > ( Teuchos::rcpFromRef(X_in) );
371 Teuchos::RCP< Thyra::ProductMultiVectorBase<SC> > Y
372 = Teuchos::rcp_dynamic_cast< Thyra::ProductMultiVectorBase<SC> > ( rcpFromPtr(Y_inout) );
390 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_s = X->getMultiVectorBlock(2);
391 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_s = Y->getNonconstMultiVectorBlock(2);
394 Teuchos::RCP< const Thyra::TpetraMultiVector< SC, LO, GO, NO > > XsTpetra =
395 Teuchos::rcp_dynamic_cast< const Thyra::TpetraMultiVector< SC, LO, GO, NO > > ( X_s );
415 if (useSolidPreconditioner_)
416 sInv_->apply(Thyra::NOTRANS, *X_s, Y_s.ptr(), 1., 0.);
418 assign(Y_s.ptr(), *X_s);
423 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_g;
424 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_g;
426 if ( !gInv_.is_null() ) {
427 X_g = X->getMultiVectorBlock(4);
428 Y_g = Y->getNonconstMultiVectorBlock(4);
430 assign(Y_g.ptr(), *X_g);
432 C4_->apply(Thyra::NOTRANS, *Y_s, Y_g.ptr(), -1., 1.);
434 gInv_->apply(Thyra::NOTRANS, *Y_g, Y_g.ptr(), 1., 0.);
437 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_l = X->getMultiVectorBlock(3);
438 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_l = Y->getNonconstMultiVectorBlock(3);
440 assign(Y_l.ptr(), *X_l);
445 C2_->apply( Thyra::NOTRANS, *Y_s, Y_l.ptr(), -1., 1. );
456 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_fv = X->getMultiVectorBlock(0);
457 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_fv = Y->getNonconstMultiVectorBlock(0);
458 assign(Y_fv.ptr(), *X_fv);
466 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_fp = X->getMultiVectorBlock(1);
467 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_fp = Y->getNonconstMultiVectorBlock(1);
468 assign(Y_fp.ptr(), *X_fp);
480 if (!shape_v_.is_null() && !shape_p_.is_null()) {
481 shape_v_->apply(Thyra::NOTRANS, *Y_g, Y_fv.ptr(), -1., 1.);
482 shape_p_->apply(Thyra::NOTRANS, *Y_g, Y_fp.ptr(), -1., 1.);
487 Z_fv_ = Y_fv->clone_mv();
489 assign(Z_fv_.ptr(), *Y_fv);
501 if (tmp_l_.is_null())
502 tmp_l_ = Y_l->clone_mv();
504 C1_->apply(Thyra::NOTRANS, *Y_fv, tmp_l_.ptr(), 1., 0);
505 C1T_->apply(Thyra::NOTRANS, *tmp_l_, Y_fv.ptr(), -1., 1.);
507 C1T_->apply(Thyra::NOTRANS, *Y_l, Y_fv.ptr(), 1., 1.);
513 if (productRangeFluid_.is_null()) {
514 Teuchos::Array< Teuchos::RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesRangeFluid( 2 );
516 vectorSpacesRangeFluid[0] = X_fv->range();
517 vectorSpacesRangeFluid[1] = X_fp->range();
519 productRangeFluid_ = Thyra::productVectorSpace<SC>( vectorSpacesRangeFluid );
522 Teuchos::Array< Teuchos::RCP< Thyra::MultiVectorBase< SC > > > X_fluid( 2 );
523 Teuchos::Array< Teuchos::RCP< Thyra::MultiVectorBase< SC > > > Y_fluid( 2 );
536 if (useFluidPreconditioner_){
538 if (fluidPrecMonolithic_) {
539 Teuchos::RCP< const Thyra::VectorSpaceBase< SC > > fMonoVS = fInv_->domain();
541 if ( X_fmono_.is_null() ){
542 X_fmono_ = createMembers( fMonoVS, X_fluid[0]->domain()->dim() );
543 Y_fmono_ = createMembers( fMonoVS, Y_fluid[0]->domain()->dim() );
547 fInv_->apply(Thyra::NOTRANS, *X_fmono_, Y_fmono_.ptr(), 1., 0.);
548 copyFromMono(Y_fluid);
551 Teuchos::RCP< Thyra::ProductMultiVectorBase<SC> > prodX_f = Thyra::defaultProductMultiVector<SC>( productRangeFluid_, X_fluid );
552 Teuchos::RCP< Thyra::ProductMultiVectorBase<SC> > prodY_f = Thyra::defaultProductMultiVector<SC>( productRangeFluid_, Y_fluid );
554 Teuchos::RCP< Thyra::MultiVectorBase<SC> > X_f = Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase< SC > >(prodX_f);
555 Teuchos::RCP< Thyra::MultiVectorBase<SC> > Y_f = Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase< SC > >(prodY_f);
557 fInv_->apply(Thyra::NOTRANS, *X_f, Y_f.ptr(), 1., 0.);
561 assign(Y_fv.ptr(), *X_fv);
562 assign(Y_fp.ptr(), *X_fp);
573 fBT_->apply(Thyra::NOTRANS, *Y_fp, Z_fv_.ptr(), -1., 1.);
579 fF_->apply(Thyra::NOTRANS, *Y_fv, Z_fv_.ptr(), -1., 1.);
589 C1_->apply(Thyra::NOTRANS, *Z_fv_, Y_l.ptr(), 1., 0.);
607 Teuchos::RCP< Thyra::TpetraMultiVector< SC, LO, GO, NO > > Y_fvT =
608 Teuchos::rcp_dynamic_cast< Thyra::TpetraMultiVector< SC, LO, GO, NO > > ( Y_fv );
609 Teuchos::RCP< Thyra::TpetraMultiVector< SC, LO, GO, NO > > Y_fpT =
610 Teuchos::rcp_dynamic_cast< Thyra::TpetraMultiVector< SC, LO, GO, NO > > ( Y_fp );
611 Teuchos::RCP< Thyra::TpetraMultiVector< SC, LO, GO, NO > > Y_sT =
612 Teuchos::rcp_dynamic_cast< Thyra::TpetraMultiVector< SC, LO, GO, NO > > ( Y_s );
613 Teuchos::RCP< Thyra::TpetraMultiVector< SC, LO, GO, NO > > Y_lT =
614 Teuchos::rcp_dynamic_cast< Thyra::TpetraMultiVector< SC, LO, GO, NO > > ( Y_l );
635template<
class SC,
class LO,
class GO,
class NO>
636void PrecOpFaCSI<SC,LO,GO,NO>::copyToMono( Teuchos::Array< Teuchos::RCP< Thyra::MultiVectorBase< SC > > > X_fluid )
const{
638 Teuchos::RCP<const Thyra::SpmdVectorSpaceBase<SC> > mpiVS_v = Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorSpaceBase<SC> >(X_fluid[0]->range());
639 Teuchos::RCP<const Thyra::SpmdVectorSpaceBase<SC> > mpiVS_p = Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorSpaceBase<SC> >(X_fluid[1]->range());
641 const LO localOffset_v = mpiVS_v->localOffset();
642 const LO localSubDim_v = mpiVS_v->localSubDim();
644 const LO localOffset_p = mpiVS_p->localOffset();
645 const LO localSubDim_p = mpiVS_p->localSubDim();
647 Teuchos::RCP<Thyra::DetachedMultiVectorView<SC> > thyData_v =
648 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<SC>( X_fluid[0] ,Teuchos::Range1D(localOffset_v,localOffset_v+localSubDim_v-1) ) );
650 Teuchos::RCP<Thyra::DetachedMultiVectorView<SC> > thyData_p =
651 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<SC>( X_fluid[1] ,Teuchos::Range1D(localOffset_p,localOffset_p+localSubDim_p-1) ) );
653 Teuchos::RCP<const Thyra::SpmdVectorSpaceBase<SC> > mpiVS_mono = Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorSpaceBase<SC> >(X_fmono_->range());
655 const LO localOffset_mono = mpiVS_mono->localOffset();
656 const LO localSubDim_mono = mpiVS_mono->localSubDim();
658 Teuchos::RCP<Thyra::DetachedMultiVectorView<SC> > thyData_fluid =
659 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<SC>( X_fmono_ ,Teuchos::Range1D(localOffset_mono,localOffset_mono+localSubDim_mono-1) ) );
661 for (
int j=0; j<X_fluid[0]->domain()->dim(); j++) {
663 for (LO i=0; i < localSubDim_v; i++)
664 (*thyData_fluid)(i,j) = (*thyData_v)(i,j);
666 for (LO i=0; i<localSubDim_p; i++)
667 (*thyData_fluid)( i + localSubDim_v, j ) = (*thyData_p)(i,j);
672template<
class SC,
class LO,
class GO,
class NO>
673void PrecOpFaCSI<SC,LO,GO,NO>::copyFromMono(Teuchos::Array< Teuchos::RCP< Thyra::MultiVectorBase< SC > > > Y_fluid)
const{
676 Teuchos::RCP<const Thyra::SpmdVectorSpaceBase<SC> > mpiVS_v = Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorSpaceBase<SC> >(Y_fluid[0]->range());
677 Teuchos::RCP<const Thyra::SpmdVectorSpaceBase<SC> > mpiVS_p = Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorSpaceBase<SC> >(Y_fluid[1]->range());
679 const LO localOffset_v = mpiVS_v->localOffset();
680 const LO localSubDim_v = mpiVS_v->localSubDim();
682 const LO localOffset_p = mpiVS_p->localOffset();
683 const LO localSubDim_p = mpiVS_p->localSubDim();
685 Teuchos::RCP<Thyra::DetachedMultiVectorView<SC> > thyData_v =
686 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<SC>( Y_fluid[0] ,Teuchos::Range1D(localOffset_v,localOffset_v+localSubDim_v-1) ) );
688 Teuchos::RCP<Thyra::DetachedMultiVectorView<SC> > thyData_p =
689 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<SC>( Y_fluid[1] ,Teuchos::Range1D(localOffset_p,localOffset_p+localSubDim_p-1) ) );
691 Teuchos::RCP<const Thyra::SpmdVectorSpaceBase<SC> > mpiVS_mono = Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorSpaceBase<SC> >(Y_fmono_->range());
693 const LO localOffset_mono = mpiVS_mono->localOffset();
694 const LO localSubDim_mono = mpiVS_mono->localSubDim();
696 Teuchos::RCP<Thyra::DetachedMultiVectorView<SC> > thyData_fluid =
697 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<SC>( Y_fmono_ ,Teuchos::Range1D(localOffset_mono,localOffset_mono+localSubDim_mono-1) ) );
699 for (
int j=0; j<Y_fluid[0]->domain()->dim(); j++) {
701 for (LO i=0; i < localSubDim_v; i++)
702 (*thyData_v)(i,j) = (*thyData_fluid)(i,j);
704 for (LO i=0; i<localSubDim_p; i++)
705 (*thyData_p)(i,j) = (*thyData_fluid)( i + localSubDim_v, j );
virtual void applyImpl(const Thyra::EOpTransp M_trans, const Thyra::MultiVectorBase< SC > &X, const Teuchos::Ptr< Thyra::MultiVectorBase< SC > > &Y, const SC alpha, const SC beta) const
Definition PrecOpFaCSI_def.hpp:205
Definition PreconditionerOperator_decl.hpp:23
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36