27 bVarf->TestFESpace()->GetTrueVSize())
35 auto BT = B_->Transpose();
37 invDBt->InvScaleRows(diagM);
38 auto S =
ParMult(B_.get(), invDBt);
52 Init(M, B, Q, M0, M1, param);
55void BramblePasciakSolver::Init(
75 temp_cpc->owns_blocks =
true;
76 temp_cpc->SetDiagonalBlock(0, invQ);
77 temp_cpc->SetDiagonalBlock(1, &M1);
84 temp_tri->owns_blocks =
true;
85 temp_tri->SetBlock(0, 0, id_m);
86 temp_tri->SetBlock(1, 1, id_b, -1.0);
87 temp_tri->SetBlock(1, 0, BinvQ);
97 solver_->SetOperator(*oop_);
103 temp_oop->owns_blocks =
false;
104 temp_oop->SetBlock(0, 0, &M);
105 temp_oop->SetBlock(0, 1, Bt);
106 temp_oop->SetBlock(1, 0, &B);
110 temp_ipc->owns_blocks =
false;
111 temp_ipc->SetDiagonalBlock(0, invQ);
118 map_ =
new SumOperator(temp_AN, 1.0,
id, -1.0,
true,
true);
129 solver_->SetOperator(*mop_);
130 solver_->SetPreconditioner(*cpc_);
138 MFEM_ASSERT((q_scaling > 0.0) && (q_scaling < 1.0),
139 "Invalid Q-scaling factor: q_scaling = " << q_scaling );
142#ifndef MFEM_USE_LAPACK
145 mfem::out <<
"Warning: Using inverse power method to compute the minimum "
146 <<
"eigenvalue of the small eigenvalue problem.\n";
147 mfem::out <<
" Consider compiling MFEM with LAPACK support.\n";
150 for (
int i = 0; i < mVarf.
ParFESpace()->GetNE(); ++i)
154 real_t scaling = 0.0, eval_i = 0.0;
160#ifdef MFEM_USE_LAPACK
170 x.Randomize(696383552+779345*i);
171#if defined(MFEM_USE_DOUBLE)
172 const real_t rel_tol = 1e-12;
173#elif defined(MFEM_USE_SINGLE)
174 const real_t rel_tol = 1e-6;
176#error "Only single and double precision are supported!"
177 const real_t rel_tol = 1e-12;
184 eval_i = Mx.Norml2();
185 x.Set(1.0/eval_i, Mx);
188 while ((iter < 1000) && (fabs(eval_i - eval_prev)/fabs(eval_i) > rel_tol));
189 MFEM_VERIFY(fabs(eval_i - eval_prev)/fabs(eval_i) <= rel_tol,
190 "Inverse power method did not converge."
191 <<
"\n\t iter = " << iter
192 <<
"\n\t eval_i = " << eval_i
193 <<
"\n\t eval_prev = " << eval_prev
194 <<
"\n\t fabs(eval_i - eval_prev)/fabs(eval_i) = "
195 << fabs(eval_i - eval_prev)/fabs(eval_i));
198 scaling = q_scaling*eval_i;
199 diag_i.
Set(scaling, diag_i);
212 map_->
Mult(x, transformed_rhs);
213 solver_->Mult(transformed_rhs, y);
219 for (
int dof : ess_zero_dofs_) { y[dof] = 0.0; }
266 mfem::out <<
" Iteration : " << setw(3) << 0 <<
" (P r, r) = "
275 mfem::out <<
"BPCG: The preconditioner is not positive definite. (Pr, r) = "
295 MFEM_ASSERT(
IsFinite(gamma),
"den (gamma) = " << gamma);
300 mfem::out <<
"BPCG: The operator is not positive definite. (Ar, r) = "
317 alpha = delta0/gamma;
332 mfem::out <<
"BPCG: The preconditioner is not positive definite. (Pr, r) = "
341 mfem::out <<
" Iteration : " << setw(3) << i <<
" (Pr, r) = "
342 <<
delta << std::endl;
364 MFEM_ASSERT(
IsFinite(gamma),
"den (gamma) = " << gamma);
369 mfem::out <<
"BPCG: The operator is not positive definite. (Ar, r) = "
392 const auto arf = pow (gamma/delta0, 0.5/
final_iter);
393 mfem::out <<
"Average reduction factor = " << arf <<
'\n';
397 mfem::out <<
"BPCG: No convergence!" <<
'\n';
A class to handle Block diagonal preconditioners in a matrix-free implementation.
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
A class to handle Block systems in a matrix-free implementation.
void SetDiagonalBlock(int iblock, Operator *op, real_t c=1.0)
Add block op in the block-entry (iblock, iblock).
void SetBlock(int iRow, int iCol, Operator *op, real_t c=1.0)
Add a block op in the block-entry (iblock, jblock).
Conjugate gradient method.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication with the inverse of dense matrix.
Data type dense matrix using column-major storage.
void GetDiag(Vector &d) const
Returns the diagonal of the matrix.
void Eigenvalues(Vector &ev)
Compute eigenvalues of A x = ev x where A = *this.
void Diag(real_t c, int n)
Creates n x n diagonal matrix with diagonal elements c.
void InvSymmetricScaling(const Vector &s)
InvSymmetricScaling this = diag(sqrt(1./s)) * this * diag(sqrt(1./s))
The BoomerAMG solver in hypre.
Jacobi preconditioner in hypre.
Wrapper for hypre's ParCSR matrix class.
MPI_Comm GetComm() const
MPI communicator.
Identity Operator I: x -> x.
A class to initialize the size of a Tensor.
real_t abs_tol
Absolute tolerance.
void Monitor(int it, real_t norm, const Vector &r, const Vector &x, bool final=false) const
Monitor both the residual r and the solution x.
real_t rel_tol
Relative tolerance.
PrintLevel print_options
Output behavior for the iterative solver.
virtual real_t Dot(const Vector &x, const Vector &y) const
Return the standard (l2, i.e., Euclidean) inner product of x and y.
int max_iter
Limit for the number of iterations the solver is allowed to do.
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
virtual MemoryClass GetMemoryClass() const
Return the MemoryClass preferred by the Operator.
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().
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
General product operator: x -> (A*B)(x) = A(B(x)).
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
General linear combination operator: x -> a A(x) + b B(x).
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
The transpose of a given operator. Switches the roles of the methods Mult() and MultTranspose().
Vector & Set(const real_t a, const Vector &x)
(*this) = a * x
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.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
real_t Min() const
Returns the minimal element of the vector.
Bramble-Pasciak Conjugate Gradient.
void UpdateVectors()
Bramble-Pasciak CG.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
static HypreParMatrix * ConstructMassPreconditioner(ParBilinearForm &mVarf, real_t alpha=0.5)
Assemble a preconditioner for the mass matrix.
BramblePasciakSolver(ParBilinearForm *mVarf, ParMixedBilinearForm *bVarf, const BPSParameters ¶m)
System and mass preconditioner are constructed from bilinear forms.
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Abstract solver class for Darcy's flow.
void SetOptions(IterativeSolver &solver, const IterSolveParameters ¶m)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void add(const Vector &v1, const Vector &v2, Vector &v)
bool IsFinite(const real_t &val)
MemoryType GetMemoryType(MemoryClass mc)
Return a suitable MemoryType for a given MemoryClass.
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B, bool own_matrix)
void subtract(const Vector &x, const Vector &y, Vector &z)
MemoryType
Memory types supported by MFEM.
bool iterations
Detailed information about each iteration will be reported to mfem::out.
bool warnings
If a non-fatal problem has been detected some context-specific information will be reported to mfem::...
bool first_and_last
Information about the first and last iteration will be printed to mfem::out.
bool summary
A summary of the solver process will be reported after the last iteration to mfem::out.
Parameters for the BramblePasciakSolver method.