MFEM  v4.2.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
blockoperator.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_BLOCKOPERATOR
13 #define MFEM_BLOCKOPERATOR
14 
15 #include "../config/config.hpp"
16 #include "../general/array.hpp"
17 #include "operator.hpp"
18 #include "blockvector.hpp"
19 
20 namespace mfem
21 {
22 
23 //! @class BlockOperator
24 /**
25  * \brief A class to handle Block systems in a matrix-free implementation.
26  *
27  * Usage:
28  * - Use one of the constructors to define the block structure.
29  * - Use SetDiagonalBlock or SetBlock to fill the BlockOperator
30  * - Use the method Mult and MultTranspose to apply the operator to a vector.
31  *
32  * If a block is not set, it is assumed to be a zero block.
33  */
34 class BlockOperator : public Operator
35 {
36 public:
37  //! Constructor for BlockOperators with the same block-structure for rows and
38  //! columns.
39  /**
40  * offsets: offsets that mark the start of each row/column block (size
41  * nRowBlocks+1). Note: BlockOperator will not own/copy the data contained
42  * in offsets.
43  */
44  BlockOperator(const Array<int> & offsets);
45  //! Constructor for general BlockOperators.
46  /**
47  * row_offsets: offsets that mark the start of each row block (size
48  * nRowBlocks+1). col_offsets: offsets that mark the start of each column
49  * block (size nColBlocks+1). Note: BlockOperator will not own/copy the
50  * data contained in offsets.
51  */
52  BlockOperator(const Array<int> & row_offsets, const Array<int> & col_offsets);
53 
54  //! Add block op in the block-entry (iblock, iblock).
55  /**
56  * iblock: The block will be inserted in location (iblock, iblock).
57  * op: the Operator to be inserted.
58  * c: optional scalar multiple for this block.
59  */
60  void SetDiagonalBlock(int iblock, Operator *op, double c = 1.0);
61  //! Add a block op in the block-entry (iblock, jblock).
62  /**
63  * irow, icol: The block will be inserted in location (irow, icol).
64  * op: the Operator to be inserted.
65  * c: optional scalar multiple for this block.
66  */
67  void SetBlock(int iRow, int iCol, Operator *op, double c = 1.0);
68 
69  //! Return the number of row blocks
70  int NumRowBlocks() const { return nRowBlocks; }
71  //! Return the number of column blocks
72  int NumColBlocks() const { return nColBlocks; }
73 
74  //! Check if block (i,j) is a zero block
75  int IsZeroBlock(int i, int j) const { return (op(i,j)==NULL) ? 1 : 0; }
76  //! Return a reference to block i,j
77  Operator & GetBlock(int i, int j)
78  { MFEM_VERIFY(op(i,j), ""); return *op(i,j); }
79  //! Return a reference to block i,j (const version)
80  const Operator & GetBlock(int i, int j) const
81  { MFEM_VERIFY(op(i,j), ""); return *op(i,j); }
82  //! Return the coefficient for block i,j
83  double GetBlockCoef(int i, int j) const
84  { MFEM_VERIFY(op(i,j), ""); return coef(i,j); }
85  //! Set the coefficient for block i,j
86  void SetBlockCoef(int i, int j, double c)
87  { MFEM_VERIFY(op(i,j), ""); coef(i,j) = c; }
88 
89  //! Return the row offsets for block starts
90  Array<int> & RowOffsets() { return row_offsets; }
91  //! Read only access to the row offsets for block starts
92  const Array<int> & RowOffsets() const { return row_offsets; }
93  //! Return the columns offsets for block starts
94  Array<int> & ColOffsets() { return col_offsets; }
95  //! Read only access to the columns offsets for block starts
96  const Array<int> & ColOffsets() const { return col_offsets; }
97 
98  /// Operator application
99  virtual void Mult (const Vector & x, Vector & y) const;
100 
101  /// Action of the transpose operator
102  virtual void MultTranspose (const Vector & x, Vector & y) const;
103 
104  ~BlockOperator();
105 
106  //! Controls the ownership of the blocks: if nonzero, BlockOperator will
107  //! delete all blocks that are set (non-NULL); the default value is zero.
109 
110 private:
111  //! Number of block rows
112  int nRowBlocks;
113  //! Number of block columns
114  int nColBlocks;
115  //! Row offsets for the starting position of each block
116  Array<int> row_offsets;
117  //! Column offsets for the starting position of each block
118  Array<int> col_offsets;
119  //! 2D array that stores each block of the operator.
121  //! 2D array that stores a coefficient for each block of the operator.
122  Array2D<double> coef;
123 
124  //! Temporary Vectors used to efficiently apply the Mult and MultTranspose methods.
125  mutable BlockVector xblock;
126  mutable BlockVector yblock;
127  mutable Vector tmp;
128 };
129 
130 //! @class BlockDiagonalPreconditioner
131 /**
132  * \brief A class to handle Block diagonal preconditioners in a matrix-free implementation.
133  *
134  * Usage:
135  * - Use the constructors to define the block structure
136  * - Use SetDiagonalBlock to fill the BlockOperator
137  * - Use the method Mult and MultTranspose to apply the operator to a vector.
138  *
139  * If a block is not set, it is assumed to be an identity block.
140  *
141  */
143 {
144 public:
145  //! Constructor that specifies the block structure
146  BlockDiagonalPreconditioner(const Array<int> & offsets);
147  //! Add a square block op in the block-entry (iblock, iblock).
148  /**
149  * iblock: The block will be inserted in location (iblock, iblock).
150  * op: the Operator to be inserted.
151  */
152  void SetDiagonalBlock(int iblock, Operator *op);
153  //! This method is present since required by the abstract base class Solver
154  virtual void SetOperator(const Operator &op) { }
155 
156  //! Return the number of blocks
157  int NumBlocks() const { return nBlocks; }
158 
159  //! Return a reference to block i,i.
161  { MFEM_VERIFY(op[iblock], ""); return *op[iblock]; }
162 
163  //! Return a reference to block i,i (const version).
164  const Operator & GetDiagonalBlock(int iblock) const
165  { MFEM_VERIFY(op[iblock], ""); return *op[iblock]; }
166 
167  //! Return the offsets for block starts
168  Array<int> & Offsets() { return offsets; }
169 
170  //! Read only access to the offsets for block starts
171  const Array<int> & Offsets() const { return offsets; }
172 
173  /// Operator application
174  virtual void Mult (const Vector & x, Vector & y) const;
175 
176  /// Action of the transpose operator
177  virtual void MultTranspose (const Vector & x, Vector & y) const;
178 
180 
181  //! Controls the ownership of the blocks: if nonzero,
182  //! BlockDiagonalPreconditioner will delete all blocks that are set
183  //! (non-NULL); the default value is zero.
185 
186 private:
187  //! Number of Blocks
188  int nBlocks;
189  //! Offsets for the starting position of each block
190  Array<int> offsets;
191  //! 1D array that stores each block of the operator.
193  //! Temporary Vectors used to efficiently apply the Mult and MultTranspose
194  //! methods.
195  mutable BlockVector xblock;
196  mutable BlockVector yblock;
197 };
198 
199 //! @class BlockLowerTriangularPreconditioner
200 /**
201  * \brief A class to handle Block lower triangular preconditioners in a
202  * matrix-free implementation.
203  *
204  * Usage:
205  * - Use the constructors to define the block structure
206  * - Use SetBlock() to fill the BlockOperator
207  * - Diagonal blocks of the preconditioner should approximate the inverses of
208  * the diagonal block of the matrix
209  * - Off-diagonal blocks of the preconditioner should match/approximate those of
210  * the original matrix
211  * - Use the method Mult() and MultTranspose() to apply the operator to a vector.
212  *
213  * If a diagonal block is not set, it is assumed to be an identity block, if an
214  * off-diagonal block is not set, it is assumed to be a zero block.
215  *
216  */
218 {
219 public:
220  //! Constructor for BlockLowerTriangularPreconditioners with the same
221  //! block-structure for rows and columns.
222  /**
223  * @param offsets Offsets that mark the start of each row/column block
224  * (size nBlocks+1).
225  *
226  * @note BlockLowerTriangularPreconditioner will not own/copy the data
227  * contained in @a offsets.
228  */
230 
231  //! Add block op in the block-entry (iblock, iblock).
232  /**
233  * @param iblock The block will be inserted in location (iblock, iblock).
234  * @param op The Operator to be inserted.
235  */
236  void SetDiagonalBlock(int iblock, Operator *op);
237  //! Add a block op in the block-entry (iblock, jblock).
238  /**
239  * @param iRow, iCol The block will be inserted in location (iRow, iCol).
240  * @param op The Operator to be inserted.
241  */
242  void SetBlock(int iRow, int iCol, Operator *op);
243  //! This method is present since required by the abstract base class Solver
244  virtual void SetOperator(const Operator &op) { }
245 
246  //! Return the number of blocks
247  int NumBlocks() const { return nBlocks; }
248 
249  //! Return a reference to block i,j.
250  Operator & GetBlock(int iblock, int jblock)
251  { MFEM_VERIFY(op(iblock,jblock), ""); return *op(iblock,jblock); }
252 
253  //! Return the offsets for block starts
254  Array<int> & Offsets() { return offsets; }
255 
256  /// Operator application
257  virtual void Mult (const Vector & x, Vector & y) const;
258 
259  /// Action of the transpose operator
260  virtual void MultTranspose (const Vector & x, Vector & y) const;
261 
263 
264  //! Controls the ownership of the blocks: if nonzero,
265  //! BlockLowerTriangularPreconditioner will delete all blocks that are set
266  //! (non-NULL); the default value is zero.
268 
269 private:
270  //! Number of block rows/columns
271  int nBlocks;
272  //! Offsets for the starting position of each block
273  Array<int> offsets;
274  //! 2D array that stores each block of the operator.
276 
277  //! Temporary Vectors used to efficiently apply the Mult and MultTranspose
278  //! methods.
279  mutable BlockVector xblock;
280  mutable BlockVector yblock;
281  mutable Vector tmp;
282  mutable Vector tmp2;
283 };
284 
285 }
286 
287 #endif /* MFEM_BLOCKOPERATOR */
Array< int > & Offsets()
Return the offsets for block starts.
A class to handle Vectors in a block fashion.
Definition: blockvector.hpp:30
Array< int > & RowOffsets()
Return the row offsets for block starts.
Array< int > & Offsets()
Return the offsets for block starts.
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator.
int IsZeroBlock(int i, int j) const
Check if block (i,j) is a zero block.
virtual void SetOperator(const Operator &op)
This method is present since required by the abstract base class Solver.
Operator & GetBlock(int i, int j)
Return a reference to block i,j.
int NumBlocks() const
Return the number of blocks.
A class to handle Block lower triangular preconditioners in a matrix-free implementation.
Operator & GetDiagonalBlock(int iblock)
Return a reference to block i,i.
A class to handle Block diagonal preconditioners in a matrix-free implementation. ...
void SetBlock(int iRow, int iCol, Operator *op)
Add a block op in the block-entry (iblock, jblock).
Operator & GetBlock(int iblock, int jblock)
Return a reference to block i,j.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
BlockDiagonalPreconditioner(const Array< int > &offsets)
Constructor that specifies the block structure.
Dynamic 2D array using row-major layout.
Definition: array.hpp:333
BlockOperator(const Array< int > &offsets)
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
void SetDiagonalBlock(int iblock, Operator *op, double c=1.0)
Add block op in the block-entry (iblock, iblock).
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator.
void SetBlockCoef(int i, int j, double c)
Set the coefficient for block i,j.
virtual void SetOperator(const Operator &op)
This method is present since required by the abstract base class Solver.
const Array< int > & RowOffsets() const
Read only access to the row offsets for block starts.
const Array< int > & ColOffsets() const
Read only access to the columns offsets for block starts.
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator.
void SetDiagonalBlock(int iblock, Operator *op)
Add block op in the block-entry (iblock, iblock).
int NumBlocks() const
Return the number of blocks.
const Operator & GetBlock(int i, int j) const
Return a reference to block i,j (const version)
const Array< int > & Offsets() const
Read only access to the offsets for block starts.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
double GetBlockCoef(int i, int j) const
Return the coefficient for block i,j.
int NumRowBlocks() const
Return the number of row blocks.
Vector data type.
Definition: vector.hpp:51
BlockLowerTriangularPreconditioner(const Array< int > &offsets)
Base class for solvers.
Definition: operator.hpp:634
Abstract operator.
Definition: operator.hpp:24
A class to handle Block systems in a matrix-free implementation.
const Operator & GetDiagonalBlock(int iblock) const
Return a reference to block i,i (const version).
int NumColBlocks() const
Return the number of column blocks.
void SetBlock(int iRow, int iCol, Operator *op, double c=1.0)
Add a block op in the block-entry (iblock, jblock).
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
Array< int > & ColOffsets()
Return the columns offsets for block starts.