16#ifndef dealii_block_linear_operator_h
17#define dealii_block_linear_operator_h
32 namespace BlockLinearOperatorImplementation
36 class EmptyBlockPayload;
40template <
typename Number>
43template <
typename Range = BlockVector<
double>,
44 typename Domain = Range,
45 typename BlockPayload =
46 internal::BlockLinearOperatorImplementation::EmptyBlockPayload<>>
50template <
typename Range = BlockVector<
double>,
51 typename Domain = Range,
52 typename BlockPayload =
53 internal::BlockLinearOperatorImplementation::EmptyBlockPayload<>,
54 typename BlockMatrixType>
58template <std::size_t m,
61 typename Domain = Range,
62 typename BlockPayload =
66 const std::array<std::array<
LinearOperator<
typename Range::BlockType,
67 typename Domain::BlockType,
68 typename BlockPayload::BlockType>,
72template <std::size_t m,
74 typename Domain = Range,
75 typename BlockPayload =
80 typename Domain::BlockType,
81 typename BlockPayload::BlockType>,
84template <std::size_t m,
86 typename Domain = Range,
87 typename BlockPayload =
92 typename Domain::BlockType,
93 typename BlockPayload::BlockType> &op);
165template <
typename Range,
typename Domain,
typename BlockPayload>
167 :
public LinearOperator<Range, Domain, typename BlockPayload::BlockType>
171 typename Domain::BlockType,
172 typename BlockPayload::BlockType>;
189 "Uninitialized BlockLinearOperator<Range, Domain>::n_block_rows called"));
197 "Uninitialized BlockLinearOperator<Range, Domain>::n_block_cols called"));
205 "Uninitialized BlockLinearOperator<Range, Domain>::block called"));
221 template <
typename Op>
232 template <std::
size_t m, std::
size_t n>
243 template <std::
size_t m>
259 template <
typename Op>
272 template <std::
size_t m, std::
size_t n>
285 template <std::
size_t m>
316 namespace BlockLinearOperatorImplementation
337 tmp->reinit(v,
true);
339 const unsigned int n =
u.n_blocks();
340 const unsigned int m = v.n_blocks();
342 for (
unsigned int i = 0; i < m; ++i)
345 for (
unsigned int j = 1;
j < n; ++
j)
357 template <
typename Range,
typename Domain,
typename BlockPayload>
363 const unsigned int m = op.n_block_rows();
369 for (
unsigned int i = 0; i < m; ++i)
376 const unsigned int n = op.n_block_cols();
382 for (
unsigned int i = 0; i < n; ++i)
388 op.vmult = [&op](Range &v,
const Domain &
u) {
389 const unsigned int m = op.n_block_rows();
390 const unsigned int n = op.n_block_cols();
396 const auto first_op = [&op](Range & v,
398 const unsigned int i,
399 const unsigned int j) {
400 op.block(i,
j).vmult(v.block(i),
u.block(
j));
403 const auto loop_op = [&op](Range & v,
405 const unsigned int i,
406 const unsigned int j) {
407 op.block(i,
j).vmult_add(v.block(i),
u.block(
j));
414 for (
unsigned int i = 0; i < m; ++i)
416 op.block(i, 0).vmult(v.block(i),
u.block(0));
417 for (
unsigned int j = 1;
j < n; ++
j)
418 op.block(i,
j).vmult_add(v.block(i),
u.block(
j));
423 op.vmult_add = [&op](Range &v,
const Domain &
u) {
424 const unsigned int m = op.n_block_rows();
425 const unsigned int n = op.n_block_cols();
431 const auto first_op = [&op](Range & v,
433 const unsigned int i,
434 const unsigned int j) {
435 op.block(i,
j).vmult(v.block(i),
u.block(
j));
438 const auto loop_op = [&op](Range & v,
440 const unsigned int i,
441 const unsigned int j) {
442 op.block(i,
j).vmult_add(v.block(i),
u.block(
j));
449 for (
unsigned int i = 0; i < m; ++i)
450 for (
unsigned int j = 0;
j < n; ++
j)
451 op.block(i,
j).vmult_add(v.block(i),
u.block(
j));
455 op.Tvmult = [&op](Domain &v,
const Range &
u) {
456 const unsigned int n = op.n_block_cols();
457 const unsigned int m = op.n_block_rows();
463 const auto first_op = [&op](Range & v,
465 const unsigned int i,
466 const unsigned int j) {
467 op.block(
j, i).Tvmult(v.block(i),
u.block(
j));
470 const auto loop_op = [&op](Range & v,
472 const unsigned int i,
473 const unsigned int j) {
474 op.block(
j, i).Tvmult_add(v.block(i),
u.block(
j));
481 for (
unsigned int i = 0; i < n; ++i)
483 op.block(0, i).Tvmult(v.block(i),
u.block(0));
484 for (
unsigned int j = 1;
j < m; ++
j)
485 op.block(
j, i).Tvmult_add(v.block(i),
u.block(
j));
490 op.Tvmult_add = [&op](Domain &v,
const Range &
u) {
491 const unsigned int n = op.n_block_cols();
492 const unsigned int m = op.n_block_rows();
498 const auto first_op = [&op](Range & v,
500 const unsigned int i,
501 const unsigned int j) {
502 op.block(
j, i).Tvmult(v.block(i),
u.block(
j));
505 const auto loop_op = [&op](Range & v,
507 const unsigned int i,
508 const unsigned int j) {
509 op.block(
j, i).Tvmult_add(v.block(i),
u.block(
j));
516 for (
unsigned int i = 0; i < n; ++i)
517 for (
unsigned int j = 0;
j < m; ++
j)
518 op.block(
j, i).Tvmult_add(v.block(i),
u.block(
j));
538 template <
typename PayloadBlockType>
554 template <
typename...
Args>
580template <
typename Range,
582 typename BlockPayload,
613 populate_linear_operator_functions(
return_op);
646template <std::size_t m,
650 typename BlockPayload>
653 const std::array<std::array<
LinearOperator<
typename Range::BlockType,
654 typename Domain::BlockType,
655 typename BlockPayload::BlockType>,
659 static_assert(m > 0 && n > 0,
660 "a blocked LinearOperator must consist of at least one block");
668 return_op.n_block_rows = []() ->
unsigned int {
return m; };
670 return_op.n_block_cols = []() ->
unsigned int {
return n; };
679 populate_linear_operator_functions(
return_op);
700template <
typename Range = BlockVector<
double>,
701 typename Domain = Range,
702 typename BlockPayload =
703 internal::BlockLinearOperatorImplementation::EmptyBlockPayload<>,
704 typename BlockMatrixType>
737 populate_linear_operator_functions(
return_op);
760template <std::
size_t m,
typename Range,
typename Domain,
typename BlockPayload>
764 typename Domain::BlockType,
765 typename BlockPayload::BlockType>,
769 m > 0,
"a blockdiagonal LinearOperator must consist of at least one block");
774 std::array<std::array<BlockType, m>, m>
new_ops;
780 for (
unsigned int i = 0; i < m; ++i)
781 for (
unsigned int j = 0;
j < m; ++
j)
792 new_ops[i][
j].reinit_domain_vector =
ops[
j].reinit_domain_vector;
809template <std::
size_t m,
typename Range,
typename Domain,
typename BlockPayload>
813 typename Domain::BlockType,
814 typename BlockPayload::BlockType> &op)
817 "a blockdiagonal LinearOperator must consist of at least "
822 std::array<BlockType, m>
new_ops;
870template <
typename Range = BlockVector<
double>,
871 typename Domain = Range,
872 typename BlockPayload =
873 internal::BlockLinearOperatorImplementation::EmptyBlockPayload<>>
901 for (
unsigned int i = 1; i < m; ++i)
903 auto &dst = v.block(i);
906 for (
unsigned int j = 0;
j < i; ++
j)
935 for (
unsigned int i = 1; i < m; ++i)
941 for (
unsigned int j = 0;
j < i; ++
j)
987template <
typename Range = BlockVector<
double>,
988 typename Domain = Range,
989 typename BlockPayload =
990 internal::BlockLinearOperatorImplementation::EmptyBlockPayload<>>
1019 for (
int i = m - 2; i >= 0; --i)
1021 auto &dst = v.block(i);
1024 for (
unsigned int j = i + 1;
j < m; ++
j)
1051 .vmult_add(v.block(m - 1),
u.block(m - 1));
1053 for (
int i = m - 2; i >= 0; --i)
1059 for (
unsigned int j = i + 1;
j < m; ++
j)
void reinit(value_type *starting_element, const std::size_t n_elements)
BlockLinearOperator< Range, Domain, BlockPayload > & operator=(const std::array< std::array< BlockType, n >, m > &ops)
BlockLinearOperator(const std::array< BlockType, m > &ops)
LinearOperator< typename Range::BlockType, typename Domain::BlockType, typename BlockPayload::BlockType > BlockType
BlockLinearOperator< Range, Domain, BlockPayload > & operator=(const std::array< BlockType, m > &ops)
std::function< BlockType(unsigned int, unsigned int)> block
BlockLinearOperator(const BlockLinearOperator< Range, Domain, BlockPayload > &)=default
BlockLinearOperator< Range, Domain, BlockPayload > & operator=(const BlockLinearOperator< Range, Domain, BlockPayload > &)=default
BlockLinearOperator< Range, Domain, BlockPayload > & operator=(const Op &op)
std::function< unsigned int()> n_block_cols
std::function< unsigned int()> n_block_rows
BlockLinearOperator(const Op &op)
BlockLinearOperator(const std::array< std::array< BlockType, n >, m > &ops)
BlockLinearOperator(const BlockPayload &payload)
EmptyBlockPayload(const Args &...)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
BlockLinearOperator< Range, Domain, BlockPayload > block_diagonal_operator(const std::array< LinearOperator< typename Range::BlockType, typename Domain::BlockType, typename BlockPayload::BlockType >, m > &)
LinearOperator< Domain, Range, typename BlockPayload::BlockType > block_forward_substitution(const BlockLinearOperator< Range, Domain, BlockPayload > &block_operator, const BlockLinearOperator< Domain, Range, BlockPayload > &diagonal_inverse)
BlockLinearOperator< Range, Domain, BlockPayload > block_operator(const std::array< std::array< LinearOperator< typename Range::BlockType, typename Domain::BlockType, typename BlockPayload::BlockType >, n >, m > &ops)
BlockLinearOperator< Range, Domain, BlockPayload > block_diagonal_operator(const std::array< LinearOperator< typename Range::BlockType, typename Domain::BlockType, typename BlockPayload::BlockType >, m > &ops)
LinearOperator< Range, Domain, Payload > null_operator(const LinearOperator< Range, Domain, Payload > &)
LinearOperator< Domain, Range, typename BlockPayload::BlockType > block_back_substitution(const BlockLinearOperator< Range, Domain, BlockPayload > &block_operator, const BlockLinearOperator< Domain, Range, BlockPayload > &diagonal_inverse)
BlockLinearOperator< Range, Domain, BlockPayload > block_diagonal_operator(const BlockMatrixType &block_matrix)
BlockLinearOperator< Range, Domain, BlockPayload > block_diagonal_operator(const LinearOperator< typename Range::BlockType, typename Domain::BlockType, typename BlockPayload::BlockType > &op)
BlockLinearOperator< Range, Domain, BlockPayload > block_operator(const BlockMatrixType &block_matrix)
BlockLinearOperator< Range, Domain, BlockPayload > block_operator(const BlockMatrixType &matrix)
void populate_linear_operator_functions(::BlockLinearOperator< Range, Domain, BlockPayload > &op)
void apply_with_intermediate_storage(const Function1 &first_op, const Function2 &loop_op, Range &v, const Domain &u, bool add)
static bool equal(const T *p1, const T *p2)