1#ifndef PrecOpFaCSI_DEF_hpp
2#define PrecOpFaCSI_DEF_hpp
3#include "PrecOpFaCSI_decl.hpp"
4#include <Thyra_TpetraMultiVector_decl.hpp>
5#include <Teuchos_VerboseObject.hpp>
20template<
class SC,
class LO,
class GO,
class NO>
21PrecOpFaCSI<SC,LO,GO,NO>::PrecOpFaCSI()
23fluidPrecMonolithic_(false),
24useSolidPreconditioner_(true)
29template<
class SC,
class LO,
class GO,
class NO>
30PrecOpFaCSI<SC,LO,GO,NO>::PrecOpFaCSI(CommConstPtr_Type comm,
bool fluidPrecMonolithic,
bool useFluidPreconditioner,
bool useSolidPreconditioner,
bool onlyDiagonal)
31:PreconditionerOperator<SC,LO,GO,NO>(),
32fluidPrecMonolithic_(fluidPrecMonolithic),
33useFluidPreconditioner_(useFluidPreconditioner),
34useSolidPreconditioner_(useSolidPreconditioner),
35onlyDiagonal_(onlyDiagonal)
41template<
class SC,
class LO,
class GO,
class NO>
42void PrecOpFaCSI<SC,LO,GO,NO>::setGE(ThyraLinOpPtr_Type C1,
43 ThyraLinOpPtr_Type C1T,
44 ThyraLinOpPtr_Type C2,
45 ThyraLinOpPtr_Type sInv,
46 ThyraLinOpPtr_Type fInv,
47 ThyraLinOpPtr_Type fF,
48 ThyraLinOpPtr_Type fBT){
61template<
class SC,
class LO,
class GO,
class NO>
62void PrecOpFaCSI<SC,LO,GO,NO>::setGI(ThyraLinOpPtr_Type C1,
63 ThyraLinOpPtr_Type C1T,
64 ThyraLinOpPtr_Type C2,
65 ThyraLinOpPtr_Type C4,
66 ThyraLinOpPtr_Type sInv,
67 ThyraLinOpPtr_Type fInv,
68 ThyraLinOpPtr_Type fF,
69 ThyraLinOpPtr_Type fBT,
70 ThyraLinOpPtr_Type gInv){
85template<
class SC,
class LO,
class GO,
class NO>
86void PrecOpFaCSI<SC,LO,GO,NO>::setGIShape(ThyraLinOpPtr_Type C1,
87 ThyraLinOpPtr_Type C1T,
88 ThyraLinOpPtr_Type C2,
89 ThyraLinOpPtr_Type C4,
90 ThyraLinOpPtr_Type sInv,
91 ThyraLinOpPtr_Type fInv,
92 ThyraLinOpPtr_Type fF,
93 ThyraLinOpPtr_Type fBT,
94 ThyraLinOpPtr_Type gInv,
95 ThyraLinOpPtr_Type shape_v,
96 ThyraLinOpPtr_Type shape_p){
107 setShapeDeriv(shape_v, shape_p);
113template<
class SC,
class LO,
class GO,
class NO>
114void PrecOpFaCSI<SC,LO,GO,NO>::setC1(ThyraLinOpPtr_Type C1){
117template<
class SC,
class LO,
class GO,
class NO>
118void PrecOpFaCSI<SC,LO,GO,NO>::setC1T(ThyraLinOpPtr_Type C1T){
121template<
class SC,
class LO,
class GO,
class NO>
122void PrecOpFaCSI<SC,LO,GO,NO>::setC2(ThyraLinOpPtr_Type C2){
125template<
class SC,
class LO,
class GO,
class NO>
126void PrecOpFaCSI<SC,LO,GO,NO>::setC4(ThyraLinOpPtr_Type C4){
129template<
class SC,
class LO,
class GO,
class NO>
130void PrecOpFaCSI<SC,LO,GO,NO>::setShapeDeriv(ThyraLinOpPtr_Type shape_v, ThyraLinOpPtr_Type shape_p){
134template<
class SC,
class LO,
class GO,
class NO>
135void PrecOpFaCSI<SC,LO,GO,NO>::setStructInv(ThyraLinOpPtr_Type sInv){
138template<
class SC,
class LO,
class GO,
class NO>
139void PrecOpFaCSI<SC,LO,GO,NO>::setFluidInv(ThyraLinOpPtr_Type fInv){
142template<
class SC,
class LO,
class GO,
class NO>
143void PrecOpFaCSI<SC,LO,GO,NO>::setGeoInv(ThyraLinOpPtr_Type gInv){
146template<
class SC,
class LO,
class GO,
class NO>
147void PrecOpFaCSI<SC,LO,GO,NO>::setFluidF(ThyraLinOpPtr_Type fF){
150template<
class SC,
class LO,
class GO,
class NO>
151void PrecOpFaCSI<SC,LO,GO,NO>::setFluidBT(ThyraLinOpPtr_Type fBT){
155template<
class SC,
class LO,
class GO,
class NO>
156void PrecOpFaCSI<SC,LO,GO,NO>::initialize(){
157 TEUCHOS_TEST_FOR_EXCEPTION(fInv_.is_null(), std::runtime_error,
"Can not initialize FaCSI preconditioner: Fluid preconditioner not set.");
158 TEUCHOS_TEST_FOR_EXCEPTION(sInv_.is_null(), std::runtime_error,
"Can not initialize FaCSI preconditioner: Structure preconditioner not set.");
159 TEUCHOS_TEST_FOR_EXCEPTION(C1_.is_null(), std::runtime_error,
"Can not initialize FaCSI preconditioner: C1 not set.");
160 Teuchos::Array< Teuchos::RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesRange( 4 );
161 Teuchos::Array< Teuchos::RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesDomain( 4 );
162 vectorSpacesRange[0] = fF_->range();
163 vectorSpacesRange[1] = fBT_->domain();
164 vectorSpacesRange[2] = sInv_->range();
165 vectorSpacesRange[3] = C1_->range();
167 vectorSpacesDomain[0] = fF_->domain();
168 vectorSpacesDomain[1] = fBT_->domain();
169 vectorSpacesDomain[2] = sInv_->domain();
170 vectorSpacesDomain[3] = C1T_->domain();
171 if ( !gInv_.is_null() ) {
172 vectorSpacesRange.push_back( gInv_->range() );
173 vectorSpacesDomain.push_back( gInv_->domain() );
178 Teuchos::RCP<const Thyra::DefaultProductVectorSpace<SC> > pR = Thyra::productVectorSpace<SC>( vectorSpacesRange );
179 Teuchos::RCP<const Thyra::DefaultProductVectorSpace<SC> > pD = Thyra::productVectorSpace<SC>( vectorSpacesDomain );
186 this->defaultProductRange_ = pR;
187 this->defaultProductDomain_ = pD;
190template<
class SC,
class LO,
class GO,
class NO>
191void PrecOpFaCSI<SC,LO,GO,NO>::applyIt(
192 const EOpTransp M_trans,
193 const MultiVectorBase<SC> &X_in,
194 const Ptr<MultiVectorBase<SC> > &Y_inout,
199 applyImpl(M_trans, X_in, Y_inout, alpha, beta);
203template<
class SC,
class LO,
class GO,
class NO>
205 const EOpTransp M_trans,
206 const MultiVectorBase<SC> &X_in,
207 const Ptr<MultiVectorBase<SC> > &Y_inout,
212 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
214 using Teuchos::rcpFromRef;
215 typedef Teuchos::ScalarTraits<SC> ST;
216 typedef RCP<MultiVectorBase<SC> > MultiVectorPtr;
217 typedef RCP<const MultiVectorBase<SC> > ConstMultiVectorPtr;
218 typedef RCP<const 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> > ( 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 MultiVectorBase< SC > > X_s = X->getMultiVectorBlock(2);
232 Teuchos::RCP< MultiVectorBase< SC > > Y_s = Y->getNonconstMultiVectorBlock(2);
235 Teuchos::RCP< const MultiVectorBase< SC > > X_fv = X->getMultiVectorBlock(0);
236 Teuchos::RCP< MultiVectorBase< SC > > Y_fv = Y->getNonconstMultiVectorBlock(0);
237 Teuchos::RCP< const MultiVectorBase< SC > > X_fp = X->getMultiVectorBlock(1);
238 Teuchos::RCP< MultiVectorBase< SC > > Y_fp = Y->getNonconstMultiVectorBlock(1);
241 Teuchos::RCP< MultiVectorBase< SC > > Y_l = Y->getNonconstMultiVectorBlock(3);
242 Teuchos::RCP<const 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> > ( 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 MultiVectorBase< SC > > X_s = X->getMultiVectorBlock(2);
391 Teuchos::RCP< 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(NOTRANS, *X_s, Y_s.ptr(), 1., 0.);
418 assign(Y_s.ptr(), *X_s);
423 Teuchos::RCP< const MultiVectorBase< SC > > X_g;
424 Teuchos::RCP< 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(NOTRANS, *Y_s, Y_g.ptr(), -1., 1.);
434 gInv_->apply(NOTRANS, *Y_g, Y_g.ptr(), 1., 0.);
437 Teuchos::RCP< const MultiVectorBase< SC > > X_l = X->getMultiVectorBlock(3);
438 Teuchos::RCP< MultiVectorBase< SC > > Y_l = Y->getNonconstMultiVectorBlock(3);
440 assign(Y_l.ptr(), *X_l);
445 C2_->apply( NOTRANS, *Y_s, Y_l.ptr(), -1., 1. );
456 Teuchos::RCP< const MultiVectorBase< SC > > X_fv = X->getMultiVectorBlock(0);
457 Teuchos::RCP< MultiVectorBase< SC > > Y_fv = Y->getNonconstMultiVectorBlock(0);
458 assign(Y_fv.ptr(), *X_fv);
466 Teuchos::RCP< const MultiVectorBase< SC > > X_fp = X->getMultiVectorBlock(1);
467 Teuchos::RCP< 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(NOTRANS, *Y_g, Y_fv.ptr(), -1., 1.);
482 shape_p_->apply(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(NOTRANS, *Y_fv, tmp_l_.ptr(), 1., 0);
505 C1T_->apply(NOTRANS, *tmp_l_, Y_fv.ptr(), -1., 1.);
507 C1T_->apply(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(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< MultiVectorBase<SC> > X_f = Teuchos::rcp_dynamic_cast<MultiVectorBase< SC > >(prodX_f);
555 Teuchos::RCP< MultiVectorBase<SC> > Y_f = Teuchos::rcp_dynamic_cast<MultiVectorBase< SC > >(prodY_f);
557 fInv_->apply(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(NOTRANS, *Y_fp, Z_fv_.ptr(), -1., 1.);
579 fF_->apply(NOTRANS, *Y_fv, Z_fv_.ptr(), -1., 1.);
589 C1_->apply(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] ,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] ,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_ ,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] ,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] ,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_ ,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:204
Definition PreconditionerOperator_decl.hpp:23
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5