deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
precondition_block_base.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2010 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_precondition_block_base_h
14#define dealii_precondition_block_base_h
15
16
17#include <deal.II/base/config.h>
18
24
27
28#include <vector>
29
31
32// Forward declarations
33#ifndef DOXYGEN
34template <typename number>
35class FullMatrix;
36template <typename number>
37class Vector;
38#endif
39
55template <typename number>
57{
58public:
63
84
89 const Inversion method = gauss_jordan);
90
95
100 void
102
107 void
108 reinit(const unsigned int nblocks,
109 const size_type blocksize,
110 const bool compress,
111 const Inversion method = gauss_jordan);
112
116 void
117 inverses_computed(const bool are_they);
118
122 bool
124
128 bool
130
134 bool
136
140 unsigned int
141 size() const;
142
146 template <typename number2>
147 void
149 Vector<number2> &dst,
150 const Vector<number2> &src) const;
151
155 template <typename number2>
156 void
158 Vector<number2> &dst,
159 const Vector<number2> &src) const;
160
166
172
178
182 const FullMatrix<number> &
183 inverse(const size_type i) const;
184
188 const Householder<number> &
190
195 inverse_svd(const size_type i) const;
196
202
206 const FullMatrix<number> &
207 diagonal(const size_type i) const;
208
214 void
216
221 std::size_t
223
229
236
237protected:
242
243private:
247 unsigned int n_diagonal_blocks;
248
255 std::vector<FullMatrix<number>> var_inverse_full;
256
263 std::vector<Householder<number>> var_inverse_householder;
264
271 std::vector<LAPACKFullMatrix<number>> var_inverse_svd;
272
278 std::vector<FullMatrix<number>> var_diagonal;
279
280
285
290
296};
297
298//----------------------------------------------------------------------//
299
300template <typename number>
302 const bool store,
303 const Inversion method)
304 : inversion(method)
305 , n_diagonal_blocks(0)
306 , var_store_diagonals(store)
307 , var_same_diagonal(false)
308 , var_inverses_ready(false)
309{}
310
311
312template <typename number>
313inline void
315{
316 if (var_inverse_full.size() != 0)
317 var_inverse_full.erase(var_inverse_full.begin(), var_inverse_full.end());
318 if (var_inverse_householder.size() != 0)
319 var_inverse_householder.erase(var_inverse_householder.begin(),
320 var_inverse_householder.end());
321 if (var_inverse_svd.size() != 0)
322 var_inverse_svd.erase(var_inverse_svd.begin(), var_inverse_svd.end());
323 if (var_diagonal.size() != 0)
324 var_diagonal.erase(var_diagonal.begin(), var_diagonal.end());
325 var_same_diagonal = false;
326 var_inverses_ready = false;
327 n_diagonal_blocks = 0;
328}
329
330template <typename number>
331inline void
333 const size_type b,
334 const bool compress,
335 const Inversion method)
336{
337 inversion = method;
338 var_same_diagonal = compress;
339 var_inverses_ready = false;
340 n_diagonal_blocks = n;
341
342 if (compress)
343 {
344 switch (inversion)
345 {
346 case gauss_jordan:
347 var_inverse_full.resize(1);
348 var_inverse_full[0].reinit(b, b);
349 break;
350 case householder:
351 var_inverse_householder.resize(1);
352 break;
353 case svd:
354 var_inverse_svd.resize(1);
355 var_inverse_svd[0].reinit(b, b);
356 break;
357 default:
359 }
360
361 if (store_diagonals())
362 {
363 var_diagonal.resize(1);
364 var_diagonal[0].reinit(b, b);
365 }
366 }
367 else
368 {
369 // set the arrays to the right
370 // size. we could do it like this:
371 // var_inverse = vector<>(nblocks,FullMatrix<>())
372 // but this would involve copying many
373 // FullMatrix objects.
374 //
375 // the following is a neat trick which
376 // avoids copying
377 if (store_diagonals())
378 {
379 std::vector<FullMatrix<number>> tmp(n, FullMatrix<number>(b));
380 var_diagonal.swap(tmp);
381 }
382
383 switch (inversion)
384 {
385 case gauss_jordan:
386 {
387 std::vector<FullMatrix<number>> tmp(n, FullMatrix<number>(b));
388 var_inverse_full.swap(tmp);
389 break;
390 }
391 case householder:
392 var_inverse_householder.resize(n);
393 break;
394 case svd:
395 {
396 std::vector<LAPACKFullMatrix<number>> tmp(
398 var_inverse_svd.swap(tmp);
399 break;
400 }
401 default:
403 }
404 }
405}
406
407
408template <typename number>
409inline unsigned int
411{
412 return n_diagonal_blocks;
413}
414
415
416
417template <typename number>
418template <typename number2>
419inline void
421 Vector<number2> &dst,
422 const Vector<number2> &src) const
423{
424 const size_type ii = same_diagonal() ? 0U : i;
425
426 switch (inversion)
427 {
428 case gauss_jordan:
429 AssertIndexRange(ii, var_inverse_full.size());
430 var_inverse_full[ii].vmult(dst, src);
431 break;
432 case householder:
433 AssertIndexRange(ii, var_inverse_householder.size());
434 var_inverse_householder[ii].vmult(dst, src);
435 break;
436 case svd:
437 AssertIndexRange(ii, var_inverse_svd.size());
438 var_inverse_svd[ii].vmult(dst, src);
439 break;
440 default:
442 }
443}
444
445
446template <typename number>
447template <typename number2>
448inline void
450 Vector<number2> &dst,
451 const Vector<number2> &src) const
452{
453 const size_type ii = same_diagonal() ? 0U : i;
454
455 switch (inversion)
456 {
457 case gauss_jordan:
458 AssertIndexRange(ii, var_inverse_full.size());
459 var_inverse_full[ii].Tvmult(dst, src);
460 break;
461 case householder:
462 AssertIndexRange(ii, var_inverse_householder.size());
463 var_inverse_householder[ii].Tvmult(dst, src);
464 break;
465 case svd:
466 AssertIndexRange(ii, var_inverse_svd.size());
467 var_inverse_svd[ii].Tvmult(dst, src);
468 break;
469 default:
471 }
472}
473
474
475template <typename number>
476inline const FullMatrix<number> &
478{
479 if (same_diagonal())
480 return var_inverse_full[0];
481
482 AssertIndexRange(i, var_inverse_full.size());
483 return var_inverse_full[i];
484}
485
486
487template <typename number>
488inline const Householder<number> &
490{
491 if (same_diagonal())
492 return var_inverse_householder[0];
493
494 AssertIndexRange(i, var_inverse_householder.size());
495 return var_inverse_householder[i];
496}
497
498
499template <typename number>
500inline const LAPACKFullMatrix<number> &
502{
503 if (same_diagonal())
504 return var_inverse_svd[0];
505
506 AssertIndexRange(i, var_inverse_svd.size());
507 return var_inverse_svd[i];
508}
509
510
511template <typename number>
512inline const FullMatrix<number> &
514{
515 Assert(store_diagonals(), ExcDiagonalsNotStored());
516
517 if (same_diagonal())
518 return var_diagonal[0];
519
520 AssertIndexRange(i, var_diagonal.size());
521 return var_diagonal[i];
522}
523
524
525template <typename number>
526inline FullMatrix<number> &
528{
529 Assert(var_inverse_full.size() != 0, ExcInverseNotAvailable());
530
531 if (same_diagonal())
532 return var_inverse_full[0];
533
534 AssertIndexRange(i, var_inverse_full.size());
535 return var_inverse_full[i];
536}
537
538
539template <typename number>
540inline Householder<number> &
542{
543 Assert(var_inverse_householder.size() != 0, ExcInverseNotAvailable());
544
545 if (same_diagonal())
546 return var_inverse_householder[0];
547
548 AssertIndexRange(i, var_inverse_householder.size());
549 return var_inverse_householder[i];
550}
551
552
553template <typename number>
556{
557 Assert(var_inverse_svd.size() != 0, ExcInverseNotAvailable());
558
559 if (same_diagonal())
560 return var_inverse_svd[0];
561
562 AssertIndexRange(i, var_inverse_svd.size());
563 return var_inverse_svd[i];
564}
565
566
567template <typename number>
568inline FullMatrix<number> &
570{
571 Assert(store_diagonals(), ExcDiagonalsNotStored());
572
573 if (same_diagonal())
574 return var_diagonal[0];
575
576 AssertIndexRange(i, var_diagonal.size());
577 return var_diagonal[i];
578}
579
580
581template <typename number>
582inline bool
584{
585 return var_same_diagonal;
586}
587
588
589template <typename number>
590inline bool
592{
593 return var_store_diagonals;
594}
595
596
597template <typename number>
598inline void
600{
601 var_inverses_ready = x;
602}
603
604
605template <typename number>
606inline bool
608{
609 return var_inverses_ready;
610}
611
612
613template <typename number>
614inline void
616{
617 deallog << "PreconditionBlockBase: " << size() << " blocks; ";
618
619 if (inversion == svd)
620 {
621 unsigned int kermin = 100000000, kermax = 0;
622 double sigmin = 1.e300, sigmax = -1.e300;
623 double kappamin = 1.e300, kappamax = -1.e300;
624
625 for (size_type b = 0; b < size(); ++b)
626 {
627 const LAPACKFullMatrix<number> &matrix = inverse_svd(b);
628 size_type k = 1;
629 while (k <= matrix.n_cols() &&
630 matrix.singular_value(matrix.n_cols() - k) == 0)
631 ++k;
632 const double s0 = matrix.singular_value(0);
633 const double sm = matrix.singular_value(matrix.n_cols() - k);
634 const double co = sm / s0;
635
636 if (kermin > k)
637 kermin = k - 1;
638 if (kermax < k)
639 kermax = k - 1;
640 if (s0 < sigmin)
641 sigmin = s0;
642 if (sm > sigmax)
643 sigmax = sm;
644 if (co < kappamin)
645 kappamin = co;
646 if (co > kappamax)
647 kappamax = co;
648 }
649 deallog << "dim ker [" << kermin << ':' << kermax << "] sigma [" << sigmin
650 << ':' << sigmax << "] kappa [" << kappamin << ':' << kappamax
651 << ']' << std::endl;
652 }
653 else if (inversion == householder)
654 {
655 }
656 else if (inversion == gauss_jordan)
657 {
658 }
659 else
660 {
662 }
663}
664
665
666template <typename number>
667inline std::size_t
669{
670 std::size_t mem = sizeof(*this);
671 for (size_type i = 0; i < var_inverse_full.size(); ++i)
672 mem += MemoryConsumption::memory_consumption(var_inverse_full[i]);
673 for (size_type i = 0; i < var_diagonal.size(); ++i)
674 mem += MemoryConsumption::memory_consumption(var_diagonal[i]);
675 return mem;
676}
677
678
680
681#endif
std::vector< FullMatrix< number > > var_diagonal
std::size_t memory_consumption() const
std::vector< LAPACKFullMatrix< number > > var_inverse_svd
FullMatrix< number > & inverse(const size_type i)
const FullMatrix< number > & inverse(const size_type i) const
const FullMatrix< number > & diagonal(const size_type i) const
FullMatrix< number > & diagonal(const size_type i)
LAPACKFullMatrix< number > & inverse_svd(const size_type i)
std::vector< FullMatrix< number > > var_inverse_full
std::vector< Householder< number > > var_inverse_householder
PreconditionBlockBase(const bool store_diagonals=false, const Inversion method=gauss_jordan)
void reinit(const unsigned int nblocks, const size_type blocksize, const bool compress, const Inversion method=gauss_jordan)
void inverse_vmult(const size_type i, Vector< number2 > &dst, const Vector< number2 > &src) const
void inverse_Tvmult(const size_type i, Vector< number2 > &dst, const Vector< number2 > &src) const
void inverses_computed(const bool are_they)
const Householder< number > & inverse_householder(const size_type i) const
~PreconditionBlockBase()=default
Householder< number > & inverse_householder(const size_type i)
const LAPACKFullMatrix< number > & inverse_svd(const size_type i) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
#define DeclException0(Exception0)
static ::ExceptionBase & ExcDiagonalsNotStored()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInverseNotAvailable()
LogStream deallog
Definition logstream.cc:36
std::size_t size
Definition mpi.cc:733
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
unsigned int global_dof_index
Definition types.h:92