16 #ifndef dealii__block_linear_operator_h 17 #define dealii__block_linear_operator_h 19 #include <deal.II/base/config.h> 20 #include <deal.II/base/exceptions.h> 22 #include <deal.II/lac/linear_operator.h> 24 #ifdef DEAL_II_WITH_CXX11 26 DEAL_II_NAMESPACE_OPEN
34 template<
typename PayloadBlockType =
internal::LinearOperator::EmptyPayload>
41 template <
typename Range = BlockVector<
double>,
42 typename Domain = Range,
43 typename BlockPayload =
internal::BlockLinearOperator::EmptyBlockPayload<> >
46 template <
typename Range = BlockVector<
double>,
47 typename Domain = Range,
48 typename BlockPayload =
internal::BlockLinearOperator::EmptyBlockPayload<>,
49 typename BlockMatrixType>
53 template <
size_t m,
size_t n,
55 typename Domain = Range,
62 typename Domain = Range,
69 typename Domain = Range,
81 template <
typename Range = BlockVector<
double>,
82 typename Domain = Range,
83 typename BlockPayload =
internal::BlockLinearOperator::EmptyBlockPayload<>,
84 typename BlockMatrixType>
88 template <
typename Range = BlockVector<
double>,
89 typename Domain = Range,
90 typename BlockPayload =
internal::BlockLinearOperator::EmptyBlockPayload<> >
95 template <
typename Range = BlockVector<
double>,
96 typename Domain = Range,
97 typename BlockPayload =
internal::BlockLinearOperator::EmptyBlockPayload<> >
145 template <
typename Range,
typename Domain,
typename BlockPayload>
164 Assert(
false,
ExcMessage(
"Uninitialized BlockLinearOperator<Range, Domain>::n_block_rows called"));
170 Assert(
false,
ExcMessage(
"Uninitialized BlockLinearOperator<Range, Domain>::n_block_cols called"));
176 Assert(
false,
ExcMessage(
"Uninitialized BlockLinearOperator<Range, Domain>::block called"));
192 template<
typename Op>
195 *
this = block_operator<Range, Domain, BlockPayload, Op>(op);
203 template<
size_t m,
size_t n>
206 *
this = block_operator<m, n, Range, Domain, BlockPayload>(ops);
217 *
this = block_diagonal_operator<m, Range, Domain, BlockPayload>(ops);
230 template <
typename Op>
233 *
this = block_operator<Range, Domain, BlockPayload, Op>(op);
242 template <
size_t m,
size_t n>
244 operator=(
const std::array<std::array<BlockType, n>, m> &ops)
246 *
this = block_operator<m, n, Range, Domain, BlockPayload>(ops);
259 *
this = block_diagonal_operator<m, Range, Domain, BlockPayload>(ops);
280 std::function<BlockType(unsigned int, unsigned int)>
block;
291 template <
typename Range,
typename Domain,
typename BlockPayload>
293 populate_linear_operator_functions(
304 for (
unsigned int i = 0; i < m; ++i)
305 op.
block(i, 0).reinit_range_vector(v.block(i), omit_zeroing_entries);
318 for (
unsigned int i = 0; i < n; ++i)
319 op.
block(0, i).reinit_domain_vector(v.block(i), omit_zeroing_entries);
324 op.
vmult = [=](Range &v,
const Domain &u)
331 for (
unsigned int i = 0; i < m; ++i)
333 op.
block(i, 0).vmult(v.block(i), u.block(0));
334 for (
unsigned int j = 1; j < n; ++j)
335 op.
block(i, j).vmult_add(v.block(i), u.block(j));
339 op.
vmult_add = [=](Range &v,
const Domain &u)
346 for (
unsigned int i = 0; i < m; ++i)
347 for (
unsigned int j = 0; j < n; ++j)
348 op.
block(i, j).vmult_add(v.block(i), u.block(j));
351 op.
Tvmult = [=](Domain &v,
const Range &u)
358 for (
unsigned int i = 0; i < n; ++i)
360 op.
block(0, i).Tvmult(v.block(i), u.block(0));
361 for (
unsigned int j = 1; j < m; ++j)
362 op.
block(j, i).Tvmult_add(v.block(i), u.block(j));
366 op.
Tvmult_add = [=](Domain &v,
const Range &u)
373 for (
unsigned int i = 0; i < n; ++i)
374 for (
unsigned int j = 0; j < m; ++j)
375 op.
block(j, i).Tvmult_add(v.block(i), u.block(j));
394 template<
typename PayloadBlockType>
395 class EmptyBlockPayload
410 template <
typename... Args>
436 template <
typename Range,
438 typename BlockPayload,
439 typename BlockMatrixType>
447 return_op.
n_block_rows = [&block_matrix]() ->
unsigned int 449 return block_matrix.n_block_rows();
452 return_op.
n_block_cols = [&block_matrix]() ->
unsigned int 454 return block_matrix.n_block_cols();
457 return_op.
block = [&block_matrix](
unsigned int i,
unsigned int j) ->
BlockType 460 const unsigned int m = block_matrix.n_block_rows();
461 const unsigned int n = block_matrix.n_block_cols();
466 return BlockType(block_matrix.block(i, j));
469 internal::BlockLinearOperator::populate_linear_operator_functions(return_op);
502 template <
size_t m,
size_t n,
typename Range,
typename Domain,
typename BlockPayload>
506 static_assert(m > 0 && n > 0,
507 "a blocked LinearOperator must consist of at least one block");
523 return_op.
block = [ops](
unsigned int i,
unsigned int j) ->
BlockType 531 internal::BlockLinearOperator::populate_linear_operator_functions(return_op);
552 template <
typename Range,
554 typename BlockPayload,
555 typename BlockMatrixType>
563 return_op.
n_block_rows = [&block_matrix]() ->
unsigned int 565 return block_matrix.n_block_rows();
568 return_op.
n_block_cols = [&block_matrix]() ->
unsigned int 570 return block_matrix.n_block_cols();
573 return_op.
block = [&block_matrix](
unsigned int i,
unsigned int j) ->
BlockType 576 const unsigned int m = block_matrix.n_block_rows();
577 const unsigned int n = block_matrix.n_block_cols();
583 return BlockType(block_matrix.block(i, j));
588 internal::BlockLinearOperator::populate_linear_operator_functions(return_op);
611 template <
size_t m,
typename Range,
typename Domain,
typename BlockPayload>
616 "a blockdiagonal LinearOperator must consist of at least one block");
620 std::array<std::array<BlockType, m>, m> new_ops;
626 for (
unsigned int i = 0; i < m; ++i)
627 for (
unsigned int j = 0; j < m; ++j)
631 new_ops[i][j] = ops[i];
638 new_ops[i][j].reinit_domain_vector = ops[j].reinit_domain_vector;
641 return block_operator<m,m,Range,Domain>(new_ops);
655 template <
size_t m,
typename Range,
typename Domain,
typename BlockPayload>
660 "a blockdiagonal LinearOperator must consist of at least " 664 std::array<BlockType, m> new_ops;
713 template <
typename Range,
typename Domain,
typename BlockPayload>
738 diagonal_inverse.
block(0, 0).vmult(v.block(0), u.block(0));
739 for (
unsigned int i = 1; i < m; ++i)
741 auto &dst = v.block(i);
744 for (
unsigned int j = 0; j < i; ++j)
747 diagonal_inverse.
block(i, i).vmult(dst, dst);
767 typename Range::BlockType *tmp = vector_memory.
alloc();
769 diagonal_inverse.
block(0, 0).vmult_add(v.block(0), u.block(0));
771 for (
unsigned int i = 1; i < m; ++i)
773 diagonal_inverse.
block(i, i).reinit_range_vector(*tmp,
true);
776 for (
unsigned int j = 0; j < i; ++j)
779 diagonal_inverse.
block(i, i).vmult_add(v.block(i),*tmp);
782 vector_memory.
free(tmp);
825 template <
typename Range,
typename Domain,
typename BlockPayload>
850 diagonal_inverse.
block(m-1, m-1).vmult(v.block(m-1),u.block(m-1));
852 for (
int i = m - 2; i >= 0; --i)
854 auto &dst = v.block(i);
857 for (
unsigned int j = i + 1; j < m; ++j)
860 diagonal_inverse.
block(i, i).vmult(dst, dst);
876 typename Range::BlockType *tmp = vector_memory.
alloc();
881 diagonal_inverse.
block(m-1, m-1).vmult_add(v.block(m-1),u.block(m-1));
883 for (
int i = m - 2; i >= 0; --i)
885 diagonal_inverse.
block(i, i).reinit_range_vector(*tmp,
true);
888 for (
unsigned int j = i + 1; j < m; ++j)
891 diagonal_inverse.
block(i, i).vmult_add(v.block(i),*tmp);
894 vector_memory.
free(tmp);
902 DEAL_II_NAMESPACE_CLOSE
904 #endif // DEAL_II_WITH_CXX11 BlockLinearOperator(const std::array< BlockType, m > &ops)
LinearOperator< Domain, Range, typename BlockPayload::BlockType > block_forward_substitution(const BlockLinearOperator< Range, Domain, BlockPayload > &block_operator, const BlockLinearOperator< Domain, Range, BlockPayload > &diagonal_inverse)
BlockLinearOperator(const Op &op)
std::function< void(Range &v, bool omit_zeroing_entries)> reinit_range_vector
BlockLinearOperator< Range, Domain, BlockPayload > block_operator(const std::array< std::array< LinearOperator< typename Range::BlockType, typename Domain::BlockType, typename BlockPayload::BlockType >, n >, m > &ops)
std::function< void(Domain &v, const Range &u)> Tvmult_add
std::function< void(Domain &v, const Range &u)> Tvmult
BlockLinearOperator< Range, Domain, BlockPayload > & operator=(const std::array< BlockType, m > &ops)
BlockLinearOperator< Range, Domain, BlockPayload > & operator=(const Op &op)
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
LinearOperator< Range, Domain, Payload > null_operator(const LinearOperator< Range, Domain, Payload > &op)
BlockLinearOperator< Range, Domain, BlockPayload > & operator=(const std::array< std::array< BlockType, n >, m > &ops)
static ::ExceptionBase & ExcMessage(std::string arg1)
BlockLinearOperator< Range, Domain, BlockPayload > block_operator(const BlockMatrixType &block_matrix)
virtual VectorType * alloc()
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
BlockLinearOperator< Range, Domain, BlockPayload > & operator=(const BlockLinearOperator< Range, Domain, BlockPayload > &)=default
LinearOperator< Domain, Range, typename BlockPayload::BlockType > block_back_substitution(const BlockLinearOperator< Range, Domain, BlockPayload > &block_operator, const BlockLinearOperator< Domain, Range, BlockPayload > &diagonal_inverse)
std::function< void(Range &v, const Domain &u)> vmult
virtual void free(const VectorType *const)
std::function< void(Domain &v, bool omit_zeroing_entries)> reinit_domain_vector
BlockLinearOperator(const std::array< std::array< BlockType, n >, m > &ops)
std::function< void(Range &v, const Domain &u)> vmult_add
std::function< BlockType(unsigned int, unsigned int)> block
std::function< unsigned int()> n_block_cols
BlockLinearOperator(const BlockPayload &payload)
BlockLinearOperator< Range, Domain, BlockPayload > block_diagonal_operator(const BlockMatrixType &block_matrix)
std::function< unsigned int()> n_block_rows
PayloadBlockType BlockType
BlockLinearOperator< Range, Domain, BlockPayload > block_diagonal_operator(const LinearOperator< typename Range::BlockType, typename Domain::BlockType, typename BlockPayload::BlockType > &op)
BlockLinearOperator< Range, Domain, BlockPayload > block_diagonal_operator(const std::array< LinearOperator< typename Range::BlockType, typename Domain::BlockType, typename BlockPayload::BlockType >, m > &ops)
EmptyBlockPayload(const Args &...)