24 nRowBlocks(offsets.Size() - 1),
25 nColBlocks(offsets.Size() - 1),
28 op(nRowBlocks, nRowBlocks),
29 coef(nRowBlocks, nColBlocks)
36 :
Operator(row_offsets_.Last(), col_offsets_.Last()),
38 nRowBlocks(row_offsets_.Size()-1),
39 nColBlocks(col_offsets_.Size()-1),
40 row_offsets(row_offsets_),
41 col_offsets(col_offsets_),
42 op(nRowBlocks, nColBlocks),
43 coef(nRowBlocks, nColBlocks)
57 delete op(iRow, iCol);
62 MFEM_VERIFY(row_offsets[iRow+1] - row_offsets[iRow] == opt->
NumRows() &&
63 col_offsets[iCol+1] - col_offsets[iCol] == opt->
NumCols(),
64 "incompatible Operator dimensions");
70 MFEM_ASSERT(x.
Size() ==
width,
"incorrect input Vector size");
71 MFEM_ASSERT(y.
Size() ==
height,
"incorrect output Vector size");
78 yblock.
Update(y, row_offsets);
80 for (
int iRow=0; iRow < nRowBlocks; ++iRow)
82 tmp.
SetSize(row_offsets[iRow+1] - row_offsets[iRow]);
84 for (
int jCol=0; jCol < nColBlocks; ++jCol)
86 if (op(iRow,jCol) && coef(iRow,jCol) != 0.)
88 op(iRow,jCol)->Mult(xblock.
GetBlock(jCol), tmp);
94 for (
int iRow=0; iRow < nRowBlocks; ++iRow)
103 MFEM_ASSERT(x.
Size() ==
height,
"incorrect input Vector size");
104 MFEM_ASSERT(y.
Size() ==
width,
"incorrect output Vector size");
111 yblock.
Update(y, col_offsets);
113 for (
int iRow=0; iRow < nColBlocks; ++iRow)
115 tmp.
SetSize(col_offsets[iRow+1] - col_offsets[iRow]);
117 for (
int jCol=0; jCol < nRowBlocks; ++jCol)
119 if (op(jCol,iRow) && coef(jCol,iRow) != 0.)
121 op(jCol,iRow)->MultTranspose(xblock.
GetBlock(jCol), tmp);
127 for (
int iRow=0; iRow < nColBlocks; ++iRow)
138 for (
int i = 0; i < nRowBlocks; ++i)
140 for (
int j = 0; j < nColBlocks; ++j)
144 blocks(i, j) =
nullptr;
149 MFEM_VERIFY(mat,
"BlockOperator block (" << i <<
"," << j
150 <<
") is not a HypreParMatrix.");
164 for (
int iRow=0; iRow < nRowBlocks; ++iRow)
166 for (
int jCol=0; jCol < nColBlocks; ++jCol)
168 delete op(iRow, jCol);
178 nBlocks(offsets_.Size() - 1),
188 MFEM_VERIFY(offsets[iblock+1] - offsets[iblock] == op->
Height() &&
189 offsets[iblock+1] - offsets[iblock] == op->
Width(),
190 "incompatible Operator dimensions");
202 MFEM_ASSERT(x.
Size() ==
width,
"incorrect input Vector size");
203 MFEM_ASSERT(y.
Size() ==
height,
"incorrect output Vector size");
210 yblock.
Update(y, offsets);
212 for (
int i=0; i<nBlocks; ++i)
224 for (
int i=0; i<nBlocks; ++i)
234 MFEM_ASSERT(x.
Size() ==
height,
"incorrect input Vector size");
235 MFEM_ASSERT(y.
Size() ==
width,
"incorrect output Vector size");
244 for (
int i=0; i<nBlocks; ++i)
256 for (
int i=0; i<nBlocks; ++i)
266 for (
int i=0; i<nBlocks; ++i)
275 :
Solver(offsets_.Last()),
277 nBlocks(offsets_.Size() - 1),
279 ops(nBlocks, nBlocks)
288 MFEM_VERIFY(offsets[iblock+1] - offsets[iblock] == op->
Height() &&
289 offsets[iblock+1] - offsets[iblock] == op->
Width(),
290 "incompatible Operator dimensions");
298 MFEM_VERIFY(iRow >= iCol,
"cannot set block in upper triangle");
299 MFEM_VERIFY(offsets[iRow+1] - offsets[iRow] == op->
NumRows() &&
300 offsets[iCol+1] - offsets[iCol] == op->
NumCols(),
301 "incompatible Operator dimensions");
303 ops(iRow, iCol) = op;
310 MFEM_ASSERT(x.
Size() ==
width,
"incorrect input Vector size");
311 MFEM_ASSERT(y.
Size() ==
height,
"incorrect output Vector size");
320 for (
int iRow=0; iRow < nBlocks; ++iRow)
322 tmp.
SetSize(offsets[iRow+1] - offsets[iRow]);
324 tmp2.
SetSize(offsets[iRow+1] - offsets[iRow]);
328 for (
int jCol=0; jCol < iRow; ++jCol)
332 ops(iRow,jCol)->Mult(yblock.
GetBlock(jCol), tmp);
338 ops(iRow,iRow)->Mult(tmp2, yblock.
GetBlock(iRow));
346 for (
int iRow=0; iRow < nBlocks; ++iRow)
356 MFEM_ASSERT(x.
Size() ==
height,
"incorrect input Vector size");
357 MFEM_ASSERT(y.
Size() ==
width,
"incorrect output Vector size");
364 yblock.
Update(y, offsets);
366 for (
int iRow=nBlocks-1; iRow >=0; --iRow)
368 tmp.
SetSize(offsets[iRow+1] - offsets[iRow]);
370 tmp2.
SetSize(offsets[iRow+1] - offsets[iRow]);
374 for (
int jCol=iRow+1; jCol < nBlocks; ++jCol)
378 ops(jCol,iRow)->MultTranspose(yblock.
GetBlock(jCol), tmp);
384 ops(iRow,iRow)->MultTranspose(tmp2, yblock.
GetBlock(iRow));
392 for (
int iRow=nBlocks-1; iRow >=0; --iRow)
402 for (
int iRow=0; iRow < nBlocks; ++iRow)
404 for (
int jCol=0; jCol < nBlocks; ++jCol)
406 delete ops(jCol,iRow);
Dynamic 2D array using row-major layout.
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
void Mult(const Vector &x, Vector &y) const override
Operator application.
~BlockDiagonalPreconditioner()
void MultTranspose(const Vector &x, Vector &y) const override
Action of the transpose operator.
BlockDiagonalPreconditioner(const Array< int > &offsets)
Constructor that specifies the block structure.
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
void SetDiagonalBlock(int iblock, Operator *op)
Add block op in the block-entry (iblock, iblock).
void Mult(const Vector &x, Vector &y) const override
Operator application.
BlockLowerTriangularPreconditioner(const Array< int > &offsets)
void SetBlock(int iRow, int iCol, Operator *op)
Add a block opt in the block-entry (iblock, jblock).
~BlockLowerTriangularPreconditioner()
void MultTranspose(const Vector &x, Vector &y) const override
Action of the transpose operator.
int IsZeroBlock(int i, int j) const
Check if block (i,j) is a zero block.
void SetDiagonalBlock(int iblock, Operator *op, real_t c=1.0)
Add block op in the block-entry (iblock, iblock).
void Mult(const Vector &x, Vector &y) const override
Operator application.
BlockOperator(const Array< int > &offsets)
void SetBlock(int iRow, int iCol, Operator *op, real_t c=1.0)
Add a block op in the block-entry (iblock, jblock).
Operator & GetBlock(int i, int j)
Return a reference to block i,j.
void MultTranspose(const Vector &x, Vector &y) const override
Action of the transpose operator.
HypreParMatrix * GetMonolithicHypreParMatrix() const
Returns a monolithic HypreParMatrix formed by merging the blocks of this BlockOperator,...
void Update(real_t *data, const Array< int > &bOffsets)
Update method.
Vector & GetBlock(int i)
Get the i-th vector in the block.
Wrapper for hypre's ParCSR matrix class.
int width
Dimension of the input / number of columns in the matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
int Size() const
Returns the size of the vector.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
void SetSize(int s)
Resize the vector to size s.
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
HypreParMatrix * HypreParMatrixFromBlocks(Array2D< const HypreParMatrix * > &blocks, Array2D< real_t > *blockCoeff)
Returns a merged hypre matrix constructed from hypre matrix blocks.