FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
bfbt.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// FEAT3: Finite Element Analysis Toolbox, Version 3
3// Copyright (C) 2010 by Stefan Turek & the FEAT group
4// FEAT3 is released under the GNU General Public License version 3,
5// see the file 'copyright.txt' in the top level directory for details.
6
7#pragma once
8
9// includes, FEAT
10#include <kernel/global/filter.hpp>
11#include <kernel/global/matrix.hpp>
12#include <kernel/global/vector.hpp>
13#include <kernel/lafem/saddle_point_matrix.hpp>
14#include <kernel/lafem/tuple_filter.hpp>
15#include <kernel/lafem/tuple_mirror.hpp>
16#include <kernel/lafem/tuple_vector.hpp>
17#include <kernel/solver/base.hpp>
18
19namespace FEAT
20{
21 namespace Solver
22 {
23
60 template <typename MatrixA_, typename MatrixB_, typename MatrixD_, typename FilterV_, typename FilterP_>
61 class BFBT :
62 public SolverBase<typename MatrixD_::VectorTypeL>
63 {
64 public:
66 typedef typename MatrixA_::DataType DataType;
68 typedef typename MatrixB_::VectorTypeL VectorTypeV;
70 typedef typename MatrixD_::VectorTypeL VectorTypeP;
75
80
81 private:
82 const MatrixA_& _matrix_a;
83 const MatrixB_& _matrix_b;
84 const MatrixD_& _matrix_d;
86 const FilterV_& _filter_v;
87 const FilterP_& _filter_p;
88
90 std::shared_ptr<SolverLeft> _solver_left;
92 std::shared_ptr<SolverRight> _solver_right;
93
96 VectorTypeV _vec_tmp_v2;
97
98 // inverse lumped velocity mass vector
99 const VectorTypeV& _lumped_velo_mass_vec;
100
101 public:
118 explicit BFBT(
119 const MatrixA_& matrix_a,
120 const MatrixB_& matrix_b,
121 const MatrixD_& matrix_d,
122 const FilterV_& filter_v,
123 const FilterP_& filter_p,
124 std::shared_ptr<SolverLeft> solver_left,
125 std::shared_ptr<SolverRight> solver_right,
126 const VectorTypeV& lumped_velo_mass_vec) :
127 _matrix_a(matrix_a),
128 _matrix_b(matrix_b),
129 _matrix_d(matrix_d),
130 _filter_v(filter_v),
131 _filter_p(filter_p),
132 _solver_left(solver_left),
133 _solver_right(solver_right),
134 _lumped_velo_mass_vec(lumped_velo_mass_vec)
135 {
136 XASSERTM(solver_left != nullptr, "left-solver must be given");
137 XASSERTM(solver_right != nullptr, "right-solver must be given");
138 }
139
140 virtual ~BFBT()
141 {
142 }
143
144 virtual String name() const override
145 {
146 return "BFBT";
147 }
148
149 virtual void init_symbolic() override
150 {
153 {
154 _solver_left->init_symbolic();
155 }
156 else
157 {
158 _solver_left->init_symbolic();
159 _solver_right->init_symbolic();
160 }
161 // create a temporary vector
162 _vec_tmp_v1 = _matrix_b.create_vector_l();
163 _vec_tmp_v2 = _matrix_b.create_vector_l();
164 }
165
166 virtual void init_numeric() override
167 {
170 {
171 _solver_left->init_numeric();
172 }
173 else
174 {
175 _solver_left->init_numeric();
176 _solver_right->init_numeric();
177 }
178 }
179
180 virtual void done_numeric() override
181 {
182 _vec_tmp_v1.clear();
183 _vec_tmp_v2.clear();
185 {
186 _solver_left->done_numeric();
187 }
188 else
189 {
190 _solver_left->done_numeric();
191 _solver_right->done_numeric();
192 }
194 }
195
196 virtual void done_symbolic() override
197 {
199 {
200 _solver_left->done_symbolic();
201 }
202 else
203 {
204 _solver_left->done_symbolic();
205 _solver_right->done_symbolic();
206 }
208 }
209
210
211 virtual Status apply(VectorTypeP& vec_cor, const VectorTypeP& vec_def) override
212 {
213 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->name()));
214
215 // fetch references
216 VectorTypeV& tmp_v1 = this->_vec_tmp_v1;
217 VectorTypeV& tmp_v2 = this->_vec_tmp_v2;
218 VectorTypeP vec_cor_right(vec_cor.clone(LAFEM::CloneMode::Layout));
219 VectorTypeP vec_def_left(vec_cor.clone(LAFEM::CloneMode::Layout));
220
221 // vec_cor_right = L_right^{-1} * vec_def
222 Status status_right = _solver_right->apply(vec_cor_right, vec_def);
223 if(!status_success(status_right))
224 return Status::aborted;
225
226 // tmp1 = B * vec_cor_right
227 _matrix_b.apply(tmp_v1, vec_cor_right);
228 this->_filter_v.filter_def(tmp_v1);
229
230 // tmp1 = M^{-1} * tmp1
231 tmp_v1.component_product(tmp_v1, _lumped_velo_mass_vec);
232 this->_filter_v.filter_def(tmp_v1);
233
234 // tmp2 = A * tmp1
235 _matrix_a.apply(tmp_v2, tmp_v1);
236 this->_filter_v.filter_def(tmp_v2);
237
238 // tmp2 = M^{-1} * tmp2
239 tmp_v2.component_product(tmp_v2, _lumped_velo_mass_vec);
240 this->_filter_v.filter_def(tmp_v2);
241
242 // vec_tmp = D * tmp2
243 _matrix_d.apply(vec_def_left, tmp_v2);
244 this->_filter_p.filter_def(vec_def_left);
245
246 // vec_cor = L_left^{-1} * vec_tmp
247 Status status_left = _solver_left->apply(vec_cor, vec_def_left);
248 if(!status_success(status_left))
249 return Status::aborted;
250
251 vec_cor.scale(vec_cor, -1);
252 return Status::success;
253 }
254 }; // class BFBT<...>
255
261 template <
262 typename MatrixA_, typename MatrixB_, typename MatrixD_,
263 typename FilterV_, typename FilterP_, typename MirrorV_,
264 typename MirrorP_>
265 class BFBT
266 <
267 Global::Matrix<MatrixA_, MirrorV_, MirrorV_>,
268 Global::Matrix<MatrixB_, MirrorV_, MirrorP_>,
269 Global::Matrix<MatrixD_, MirrorP_, MirrorV_>,
270 Global::Filter<FilterV_, MirrorV_>,
271 Global::Filter<FilterP_, MirrorP_>
272 > :
273 public Solver::SolverBase<
274 Global::Vector<
275 LAFEM::TupleVector<
276 typename MatrixB_::VectorTypeL,
277 typename MatrixD_::VectorTypeL>,
278 LAFEM::TupleMirror<
279 MirrorV_, MirrorP_>
280 >
281 >
282 {
283 public:
287
290
291 typedef typename GlobalVectorType::DataType DataType;
292
294
298
301
302 typedef typename MatrixB_::VectorTypeL LocalVectorTypeV;
303 typedef typename MatrixD_::VectorTypeL LocalVectorTypeP;
304
307
310
311 protected:
312 const GlobalMatrixTypeA& _matrix_a;
313 const GlobalMatrixTypeB& _matrix_b;
314 const GlobalMatrixTypeD& _matrix_d;
316 const GlobalFilterTypeP& _filter_p;
317 std::shared_ptr<SolverA> _solver_left;
318 std::shared_ptr<SolverS> _solver_right;
319 GlobalVectorTypeV _vec_tmp_v1, _vec_tmp_v2;
320 const GlobalVectorTypeV& _lumped_velo_mass_vec;
321
322 public:
323 explicit BFBT(
324 const GlobalMatrixTypeA& matrix_a,
325 const GlobalMatrixTypeB& matrix_b,
326 const GlobalMatrixTypeD& matrix_d,
327 const GlobalFilterTypeV& filter_v,
328 const GlobalFilterTypeP& filter_p,
329 std::shared_ptr<SolverA> solver_left,
330 std::shared_ptr<SolverS> solver_right,
331 const GlobalVectorTypeV& lumped_velo_mass_vec
332 ) :
333 _matrix_a(matrix_a),
334 _matrix_b(matrix_b),
335 _matrix_d(matrix_d),
336 _filter_v(filter_v),
337 _filter_p(filter_p),
338 _solver_left(solver_left),
339 _solver_right(solver_right),
340 _lumped_velo_mass_vec(lumped_velo_mass_vec)
341 {
342 }
343
344 virtual String name() const override
345 {
346 return "BFBT";
347 }
348
349 virtual void init_symbolic() override
350 {
352 _solver_left->init_symbolic();
354 _solver_right->init_symbolic();
355 _vec_tmp_v1 = _matrix_b.create_vector_l();
356 _vec_tmp_v2 = _matrix_b.create_vector_l();
357 }
358
359 virtual void init_numeric() override
360 {
362 _solver_left->init_numeric();
364 _solver_right->init_numeric();
365 }
366
367 virtual void done_numeric() override
368 {
369 _vec_tmp_v1.clear();
370 _vec_tmp_v2.clear();
371 _solver_left->done_numeric();
373 _solver_right->done_numeric();
375 }
376
377 virtual void done_symbolic() override
378 {
379 _solver_left->done_symbolic();
381 _solver_right->done_symbolic();
383 }
384
385 virtual Status apply(GlobalVectorTypeP& vec_cor, const GlobalVectorTypeP& vec_def) override
386 {
387 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->name()));
388
389 GlobalVectorTypeP vec_cor_right(vec_cor.clone(LAFEM::CloneMode::Layout));
390 GlobalVectorTypeP vec_def_left(vec_cor.clone(LAFEM::CloneMode::Layout));
391
392 // vec_cor_right = S^{-1} * vec_def
393 if(!status_success(_solver_right->apply(vec_cor_right, vec_def)))
394 return Status::aborted;
395
396 // tmp_v1 = B * vec_cor_right
397 _matrix_b.apply(_vec_tmp_v1, vec_cor_right);
398 this->_filter_v.filter_def(_vec_tmp_v1);
399
400 // tmp_v1 = M^{-1} * tmp_v1
401 _vec_tmp_v1.component_product(_vec_tmp_v1, _lumped_velo_mass_vec);
402 this->_filter_v.filter_def(_vec_tmp_v1);
403
404 // tmp_v2 = A * tmp_v1
405 _matrix_a.apply(_vec_tmp_v2, _vec_tmp_v1);
406 this->_filter_v.filter_def(_vec_tmp_v2);
407
408 // tmp_v2 = M^{-1} * tmp_v2
409 _vec_tmp_v2.component_product(_vec_tmp_v2, _lumped_velo_mass_vec);
410 this->_filter_v.filter_def(_vec_tmp_v2);
411
412 // vec_def_left = D * tmp_v2
413 _matrix_d.apply(vec_def_left, _vec_tmp_v2);
414 this->_filter_p.filter_def(vec_def_left);
415
416 // vec_cor = -A^{-1} * vec_def_left
417 if(!status_success(_solver_left->apply(vec_cor, vec_def_left)))
418 return Status::aborted;
419
420 vec_cor.scale(vec_cor, -1.0);
421 Statistics::add_solver_expression(
422 std::make_shared<ExpressionEndSolve>(this->name(), Status::success, 0));
423 return Status::success;
424 }
425 };
426
448 template <typename MatrixA_, typename MatrixB_, typename MatrixD_, typename FilterV_, typename FilterP_>
449 inline std::shared_ptr<BFBT<MatrixA_, MatrixB_, MatrixD_, FilterV_, FilterP_>> new_bfbt(
450 const MatrixA_& matrix_a, const MatrixB_& matrix_b,
451 const MatrixD_& matrix_d, const FilterV_& filter_v,
452 const FilterP_& filter_p,
453 std::shared_ptr<SolverBase<typename MatrixD_::VectorTypeL>> solver_left,
454 std::shared_ptr<SolverBase<typename MatrixD_::VectorTypeL>> solver_right,
455 const typename MatrixB_::VectorTypeL& lumped_velo_mass_vec)
456 {
457 return std::make_shared<BFBT<MatrixA_, MatrixB_, MatrixD_, FilterV_, FilterP_>>
458 (matrix_a, matrix_b, matrix_d, filter_v, filter_p, solver_left, solver_right, lumped_velo_mass_vec);
459 }
460 } // namespace Solver
461} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Global Filter wrapper class template.
Definition: filter.hpp:21
Global Matrix wrapper class template.
Definition: matrix.hpp:40
VectorTypeL create_vector_l() const
Creates and returns a new L-compatible global vector object.
Definition: matrix.hpp:197
void apply(VectorTypeL &r, const VectorTypeR &x) const
Performs a matrix-vector multiplication: r <- A*x.
Definition: matrix.hpp:311
Global vector wrapper class template.
Definition: vector.hpp:68
void component_product(const Vector &x, const Vector &y)
Computes the component-wise product of two vector.
Definition: vector.hpp:481
void clear()
Clears the underlying vector.
Definition: vector.hpp:293
Saddle-Point matrix meta class template.
TupleVector meta-mirror class template.
Variadic TupleVector class template.
BFBT Schur-complement preconditioner.
Definition: bfbt.hpp:63
LAFEM::TupleVector< VectorTypeV, VectorTypeP > VectorType
system vector type
Definition: bfbt.hpp:72
std::shared_ptr< SolverRight > _solver_right
our right solver
Definition: bfbt.hpp:92
SolverBase< VectorTypeP > SolverRight
right solver type
Definition: bfbt.hpp:79
virtual void done_symbolic() override
Symbolic finalization method.
Definition: bfbt.hpp:196
virtual Status apply(VectorTypeP &vec_cor, const VectorTypeP &vec_def) override
Solver application method.
Definition: bfbt.hpp:211
MatrixA_::DataType DataType
our data type
Definition: bfbt.hpp:66
virtual void init_symbolic() override
Symbolic initialization method.
Definition: bfbt.hpp:149
virtual void init_numeric() override
Numeric initialization method.
Definition: bfbt.hpp:166
const FilterV_ & _filter_v
our system filter
Definition: bfbt.hpp:86
SolverBase< VectorTypeP > SolverLeft
left solver type
Definition: bfbt.hpp:77
std::shared_ptr< SolverLeft > _solver_left
our left solver
Definition: bfbt.hpp:90
virtual void done_numeric() override
Numeric finalization method.
Definition: bfbt.hpp:180
BFBT(const MatrixA_ &matrix_a, const MatrixB_ &matrix_b, const MatrixD_ &matrix_d, const FilterV_ &filter_v, const FilterP_ &filter_p, std::shared_ptr< SolverLeft > solver_left, std::shared_ptr< SolverRight > solver_right, const VectorTypeV &lumped_velo_mass_vec)
Constructs a scaled BFBT preconditioner.
Definition: bfbt.hpp:118
virtual String name() const override
Returns a descriptive string.
Definition: bfbt.hpp:144
SolverBase< VectorTypeP > BaseClass
base-class typedef
Definition: bfbt.hpp:74
VectorTypeV _vec_tmp_v1
a temporary defect vector
Definition: bfbt.hpp:95
MatrixB_::VectorTypeL VectorTypeV
velocity vector type
Definition: bfbt.hpp:68
MatrixD_::VectorTypeL VectorTypeP
pressure vector type
Definition: bfbt.hpp:70
Polymorphic solver interface.
Definition: base.hpp:183
virtual void init_symbolic()
Symbolic initialization method.
Definition: base.hpp:227
virtual void init_numeric()
Numeric initialization method.
Definition: base.hpp:237
virtual void done_symbolic()
Symbolic finalization method.
Definition: base.hpp:255
virtual void done_numeric()
Numeric finalization method.
Definition: base.hpp:246
String class implementation.
Definition: string.hpp:47
bool status_success(Status status)
Status success check function.
Definition: base.hpp:108
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ success
solving successful (convergence criterion fulfilled)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
std::shared_ptr< BFBT< MatrixA_, MatrixB_, MatrixD_, FilterV_, FilterP_ > > new_bfbt(const MatrixA_ &matrix_a, const MatrixB_ &matrix_b, const MatrixD_ &matrix_d, const FilterV_ &filter_v, const FilterP_ &filter_p, std::shared_ptr< SolverBase< typename MatrixD_::VectorTypeL > > solver_left, std::shared_ptr< SolverBase< typename MatrixD_::VectorTypeL > > solver_right, const typename MatrixB_::VectorTypeL &lumped_velo_mass_vec)
Creates a new BFBT solver object.
Definition: bfbt.hpp:449
FEAT namespace.
Definition: adjactor.hpp:12