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