Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
PrecBlock2x2_def.hpp
1#ifndef PrecBlock2x2_DEF_hpp
2#define PrecBlock2x2_DEF_hpp
3
4#include <Thyra_TpetraMultiVector_decl.hpp>
5#include <Teuchos_VerboseObject.hpp>
14
15
16
17namespace FEDD {
18
19// Constructors
20
21template<class SC, class LO, class GO, class NO>
22PrecBlock2x2<SC,LO,GO,NO>::PrecBlock2x2()
23:PreconditionerOperator<SC,LO,GO,NO>()
24{
25// TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Still a problem for FaCSI, cant be used yet.");
26}
27
28template<class SC, class LO, class GO, class NO>
29PrecBlock2x2<SC,LO,GO,NO>::PrecBlock2x2( CommConstPtr_Type comm )
30:PreconditionerOperator<SC,LO,GO,NO>()
31{
32 comm_=comm;
33// TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Still a problem for FaCSI, cant be used yet.");
34}
35
36template<class SC, class LO, class GO, class NO>
38 ThyraLinOpPtr_Type velocityInv,
39 ThyraLinOpPtr_Type pressureInv
40 ){
41 setVeloctiyInv(velocityInv);
42
43 setPressureInv(pressureInv);
44
45 setType("Diagonal");
46
47 initialize();
48}
49
50template<class SC, class LO, class GO, class NO>
52 ThyraLinOpPtr_Type velocityInv,
53 ThyraLinOpPtr_Type pressureInv,
54 ThyraLinOpPtr_Type BT
55 ){
56 setVeloctiyInv(velocityInv);
57
58 setPressureInv(pressureInv);
59
60 setType("Triangular");
61
62 BT_ = BT;
63
64 initialize();
65}
66
67
68template<class SC, class LO, class GO, class NO>
69void PrecBlock2x2<SC,LO,GO,NO>::setTriangular(ThyraLinOpPtr_Type velocityInv,
70 ThyraLinOpPtr_Type laplaceInverse,
71 ThyraLinOpPtr_Type convectionDiffusionOperator,
72 ThyraLinOpPtr_Type massMatrixInverse,
73 ThyraLinOpPtr_Type massMatrixVInverse,
74 ThyraLinOpPtr_Type BT){
75
76 setVeloctiyInv(velocityInv);
77
78 setPressureInvs(laplaceInverse,convectionDiffusionOperator,massMatrixInverse,massMatrixVInverse);
79
80 setType("PCD");
81
82 BT_ = BT;
83
84 initialize();
85}
86
87template<class SC, class LO, class GO, class NO>
88void PrecBlock2x2<SC,LO,GO,NO>::setTriangular(ThyraLinOpPtr_Type velocityInv,
89 ThyraLinOpPtr_Type laplaceInverse,
90 ThyraLinOpPtr_Type massMatrixVInverse,
91 ThyraLinOpPtr_Type BT){
92
93 setVeloctiyInv(velocityInv);
94
95 setPressureInvs(laplaceInverse,massMatrixVInverse);
96
97 setType("LSC");
98
99 BT_ = BT;
100
101 initialize();
102}
103
104
105template<class SC, class LO, class GO, class NO>
106void PrecBlock2x2<SC,LO,GO,NO>::setVeloctiyInv(ThyraLinOpPtr_Type velocityInv){
107 velocityInv_ = velocityInv;
108}
109
110template<class SC, class LO, class GO, class NO>
111void PrecBlock2x2<SC,LO,GO,NO>::setPressureInv(ThyraLinOpPtr_Type pressureInv){
112 pressureInv_ = pressureInv;
113}
114
115template<class SC, class LO, class GO, class NO>
116void PrecBlock2x2<SC,LO,GO,NO>::setPressureInvs(ThyraLinOpPtr_Type laplaceInverse,
117 ThyraLinOpPtr_Type convectionDiffusionOperator,
118 ThyraLinOpPtr_Type massMatrixInverse,
119 ThyraLinOpPtr_Type massMatrixVInverse){
120
121 laplaceInverse_ = laplaceInverse;
122 convectionDiffusionOperator_=convectionDiffusionOperator;
123 massMatrixInverse_=massMatrixInverse;
124 massMatrixVInverse_=massMatrixVInverse;
125}
126
127template<class SC, class LO, class GO, class NO>
128void PrecBlock2x2<SC,LO,GO,NO>::setPressureInvs(ThyraLinOpPtr_Type laplaceInverse,
129 ThyraLinOpPtr_Type massMatrixVInverse){
130
131 laplaceInverse_ = laplaceInverse;
132 massMatrixVInverse_=massMatrixVInverse;
133}
134
135template<class SC, class LO, class GO, class NO>
137 type_ = type;
138}
139
140template<class SC, class LO, class GO, class NO>
141void PrecBlock2x2<SC,LO,GO,NO>::initialize(){
142 TEUCHOS_TEST_FOR_EXCEPTION(velocityInv_.is_null(), std::runtime_error,"Can not initialize Block2x2 preconditioner: 1 preconditioner not set.");
143 TEUCHOS_TEST_FOR_EXCEPTION(pressureInv_.is_null() && laplaceInverse_.is_null(), std::runtime_error,"Can not initialize Block2x2 preconditioner: 2 preconditioner not set.");
144 Teuchos::Array< Teuchos::RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesRange( 2 );
145 Teuchos::Array< Teuchos::RCP< const Thyra::VectorSpaceBase< SC > > > vectorSpacesDomain( 2 );
146 vectorSpacesRange[0] = velocityInv_->range();
147
148 vectorSpacesDomain[0] = velocityInv_->domain();
149
150 if(!pressureInv_.is_null()){
151 vectorSpacesRange[1] = pressureInv_->domain();
152 vectorSpacesDomain[1] = pressureInv_->domain();
153 }
154 else{
155 vectorSpacesRange[1] = laplaceInverse_->domain();
156 vectorSpacesDomain[1] = laplaceInverse_->domain();
157 }
158 Teuchos::RCP<const Thyra::DefaultProductVectorSpace<SC> > pR = Thyra::productVectorSpace<SC>( vectorSpacesRange );
159 Teuchos::RCP<const Thyra::DefaultProductVectorSpace<SC> > pD = Thyra::productVectorSpace<SC>( vectorSpacesDomain );
160
161 this->defaultProductRange_ = pR;
162 this->defaultProductDomain_ = pD;
163}
164
165template<class SC, class LO, class GO, class NO>
166void PrecBlock2x2<SC,LO,GO,NO>::applyIt(
167 const Thyra::EOpTransp M_trans,
168 const Thyra::MultiVectorBase<SC> &X_in,
169 const Thyra::Ptr<Thyra::MultiVectorBase<SC> > &Y_inout,
170 const SC alpha,
171 const SC beta
172 ) const
173{
174 applyImpl(M_trans, X_in, Y_inout, alpha, beta);
175
176}
177
180// Block Preconditioners:
181// - 'Diagonal' Prec: where the Schur complement is replaced by - 1/nu M_p
182// - 'Triangular' Prec: where the Schur complement is replaced by - 1/nu M_p
183// - 'PCD' Prec: where the Schur complement is replaced by -M_p F_p^-1 A_p
184// - 'LSC' Prec: where the Schur complement is replaced by -A_p^-1 (B (M_v^-1) F (M_v^-1) B^T ) A_p^-1
185
186template<class SC, class LO, class GO, class NO>
188 const Thyra::EOpTransp M_trans,
189 const Thyra::MultiVectorBase<SC> &X_in,
190 const Thyra::Ptr<Thyra::MultiVectorBase<SC> > &Y_inout,
191 const SC alpha,
192 const SC beta
193 ) const
194{
195 // alpha and beta are ignored!
196 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
197
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;
202
203 int rank = comm_->getRank();
204
205 Teuchos::RCP<const Thyra::ProductMultiVectorBase<SC> > X
206 = Teuchos::rcp_dynamic_cast<const Thyra::ProductMultiVectorBase<SC> > ( Teuchos::rcpFromRef(X_in) );
207
208 Teuchos::RCP< Thyra::ProductMultiVectorBase<SC> > Y
209 = Teuchos::rcp_dynamic_cast< Thyra::ProductMultiVectorBase<SC> > ( rcpFromPtr(Y_inout) );
210
211 // First component correspondig to velocity block
212 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_0 = X->getMultiVectorBlock(0);
213 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_0 = Y->getNonconstMultiVectorBlock(0);
214
215 // Second component corresponding to pressure block
216 Teuchos::RCP< const Thyra::MultiVectorBase< SC > > X_1 = X->getMultiVectorBlock(1);
217 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Y_1 = Y->getNonconstMultiVectorBlock(1);
218
219 // We distinguish between the different preconditioning types here
220 if (type_ == "Diagonal"){
221 velocityInv_->apply(Thyra::NOTRANS, *X_0, Y_0.ptr(), 1., 0.); // Apply input vector to fluid inverse approximation
222
223 pressureInv_->apply(Thyra::NOTRANS, *X_1, Y_1.ptr(), 1., 0.); // Apply input vector to Schur complement inverse approximation
224 // Here: 1/nu Mp
225 }
226 else if (type_ == "Triangular"){
227
228 pressureInv_->apply(Thyra::NOTRANS, *X_1, Y_1.ptr(), 1., 0.); // Apply input vector pressure component to Schur complement inverse approximation
229
230 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
231
232 BT_->apply(Thyra::NOTRANS, *Y_1, Z_0.ptr(), -1., 1.); //Z0= BT*Y1 + X0
233
234 velocityInv_->apply(Thyra::NOTRANS, *Z_0, Y_0.ptr(), 1., 0.);
235
236 }
237 else if (type_ == "PCD"){
238 // PCD block triangular preconditioner
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.");
242 // For PCD we need apply the 'pressure inverse' differently, as it is made up of three components.
243 // X_1->describe(*out,Teuchos::VERB_EXTREME); // Examplary print
244
245 // Apply input vector to Schur complement inverse approximation
246 massMatrixInverse_->apply(Thyra::NOTRANS, *X_1, Y_1.ptr(), 1., 0.); // 1. pressure mass matrix inverse approximation
247
248 convectionDiffusionOperator_->apply(Thyra::NOTRANS, *Y_1, Y_1.ptr(), 1., 0.); // 2. pressure convection-diffusion operator
249
250 laplaceInverse_->apply(Thyra::NOTRANS, *Y_1, Y_1.ptr(), 1., 0.); // 3. pressure laplace inverse approximation
251
252 // Alternative option to use the Laplace constructed via B M_v B^T
253 // else{ // We operate in different dimensions here
254 // Teuchos::RCP< MultiVectorBase< SC > > X_res_0 = X_0->clone_mv();
255 // BT_->apply(Thyra::NOTRANS, *Y_1, X_res_0.ptr(), 1., 0.); //BT*y
256 // massMatrixVInverse_->apply(Thyra::NOTRANS, *X_res_0, X_res_0.ptr(), 1., 0.);
257 // BT_->apply(Thyra::TRANS, *X_res_0, Y_1.ptr(), 1., 0.);
258 // }
259
260 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
261
262 BT_->apply(Thyra::NOTRANS, *Y_1, Z_0.ptr(), -1., 1.); //Z0= - BT*Y1 + X0
263
264 velocityInv_->apply(Thyra::NOTRANS, *Z_0, Y_0.ptr(), 1., 0.); // Apply input vector to fluid inverse approximation
265
266 }
267 else if (type_ == "LSC"){
268 // LSC block triangular preconditioner
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.");
271
272 laplaceInverse_->apply(Thyra::NOTRANS, *X_1, Y_1.ptr(), 1., 0.); // 1. pressure laplace inverse approximation
273
274 // 2. Component: B (M_v^-1) F (M_v^-1) B^T
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.);
281
282 laplaceInverse_->apply(Thyra::NOTRANS, *Y_1, Y_1.ptr(), -1., 0.); // 3. pressure laplace inverse approximation
283
284 Teuchos::RCP< Thyra::MultiVectorBase< SC > > Z_0 = X_0->clone_mv();
285 BT_->apply(Thyra::NOTRANS, *Y_1, Z_0.ptr(), -1., 1.); //Z0= BT*Y1 + X0
286
287 velocityInv_->apply(Thyra::NOTRANS, *Z_0, Y_0.ptr(), 1., 0.);
288
289 }
290 else{
291 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,"Unknow 2x2 block preconditioner type. Select Diagonal or Triangular.");
292 }
293}
294}
295
296#endif
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
Apply of preconditioner in e.g. GMRES.
Definition PrecBlock2x2_def.hpp:187
void setType(std::string type)
Setting the preconditioning ype.
Definition PrecBlock2x2_def.hpp:136
void setDiagonal(ThyraLinOpPtr_Type velocityInv, ThyraLinOpPtr_Type pressureInv)
Diagonal preconditioner with \hat{S}= -1/nu M_p schur complement approximation.
Definition PrecBlock2x2_def.hpp:37
void setPressureInv(ThyraLinOpPtr_Type pressureInv)
Setting inverse approximation of Schur complement.
Definition PrecBlock2x2_def.hpp:111
void setVeloctiyInv(ThyraLinOpPtr_Type veloctiyInv)
Setting velocity inverse approximation.
Definition PrecBlock2x2_def.hpp:106
void setTriangular(ThyraLinOpPtr_Type velocityInv, ThyraLinOpPtr_Type pressureInv, ThyraLinOpPtr_Type BT)
Triangular preconditioner with \hat{S}= -1/nu M_p schur complement approximation.
Definition PrecBlock2x2_def.hpp:51
void setPressureInvs(ThyraLinOpPtr_Type laplaceInverse, ThyraLinOpPtr_Type convectionDiffusionOperator, ThyraLinOpPtr_Type massMatrixInverse, ThyraLinOpPtr_Type massMatrixVInverse)
Setting inverse approximation of Schur complement by multiple operators. Corresponds to PCD.
Definition PrecBlock2x2_def.hpp:116
Definition PreconditionerOperator_decl.hpp:23
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36