24 bVarf.TestFESpace()->GetTrueVSize())
32 std::unique_ptr<HypreParMatrix> invDBt(B_->Transpose());
33 invDBt->InvScaleRows(diagM);
34 S_.reset(
ParMult(B_.get(), invDBt.get(),
true));
49 Init(M, B, Q, M0, M1, param);
58 Bt_ = std::make_unique<TransposeOperator>(&B);
65 oop_ = std::make_unique<BlockOperator>(
offsets_);
66 oop_->SetBlock(0, 0, &M);
67 oop_->SetBlock(0, 1, Bt_.get());
68 oop_->SetBlock(1, 0, &B);
71 temp_cpc->SetDiagonalBlock(0, invQ);
72 temp_cpc->SetDiagonalBlock(1, &M1);
79 temp_tri->SetBlock(0, 0, id_m);
80 temp_tri->SetBlock(1, 1, id_b, -1.0);
81 temp_tri->SetBlock(1, 0, BinvQ);
82 temp_tri->owns_blocks = 1;
84 ppc_ = std::make_unique<ProductOperator>(temp_cpc, temp_tri,
true,
true);
86 ipc_ = std::make_unique<BlockOperator>(
offsets_);
87 ipc_->SetDiagonalBlock(0, invQ);
88 ipc_->owns_blocks = 1;
91 solver_ = std::make_unique<BPCGSolver>(M.
GetComm(), ipc_.get(), ppc_.get());
92 solver_->SetOperator(*oop_);
98 temp_oop->SetBlock(0, 0, &M);
99 temp_oop->SetBlock(0, 1, Bt_.get());
100 temp_oop->SetBlock(1, 0, &B);
104 temp_ipc->SetDiagonalBlock(0, invQ);
105 temp_ipc->owns_blocks = 1;
112 map_ = std::make_unique<SumOperator>(temp_AN, 1.0,
id, -1.0,
true,
true);
113 mop_ = std::make_unique<ProductOperator>(map_.get(), temp_oop,
false,
false);
115 cpc_ = std::make_unique<BlockDiagonalPreconditioner>(
offsets_);
116 cpc_->SetDiagonalBlock(0, &M0);
117 cpc_->SetDiagonalBlock(1, &M1);
120 solver_ = std::make_unique<CGSolver>(M.
GetComm());
121 solver_->SetOperator(*mop_);
122 solver_->SetPreconditioner(*cpc_);
130 MFEM_ASSERT((q_scaling > 0.0) && (q_scaling < 1.0),
131 "Invalid Q-scaling factor: q_scaling = " << q_scaling );
134#ifndef MFEM_USE_LAPACK
137 mfem::out <<
"Warning: Using inverse power method to compute the minimum "
138 <<
"eigenvalue of the small eigenvalue problem.\n";
139 mfem::out <<
" Consider compiling MFEM with LAPACK support.\n";
142 for (
int i = 0; i < mVarf.
ParFESpace()->GetNE(); ++i)
146 real_t scaling = 0.0, eval_i = 0.0;
152#ifdef MFEM_USE_LAPACK
162 x.Randomize(
static_cast<int>(696383552LL+779345LL*i));
163#if defined(MFEM_USE_DOUBLE)
164 const real_t rel_tol = 1e-12;
165#elif defined(MFEM_USE_SINGLE)
166 const real_t rel_tol = 1e-6;
168#error "Only single and double precision are supported!"
169 const real_t rel_tol = 1e-12;
176 eval_i = Mx.Norml2();
177 x.Set(1.0/eval_i, Mx);
180 while ((iter < 1000) && (fabs(eval_i - eval_prev)/fabs(eval_i) > rel_tol));
181 MFEM_VERIFY(fabs(eval_i - eval_prev)/fabs(eval_i) <= rel_tol,
182 "Inverse power method did not converge."
183 <<
"\n\t iter = " << iter
184 <<
"\n\t eval_i = " << eval_i
185 <<
"\n\t eval_prev = " << eval_prev
186 <<
"\n\t fabs(eval_i - eval_prev)/fabs(eval_i) = "
187 << fabs(eval_i - eval_prev)/fabs(eval_i));
190 scaling = q_scaling*eval_i;
191 diag_i.
Set(scaling, diag_i);
204 map_->Mult(x, transformed_rhs);
205 solver_->Mult(transformed_rhs, y);
211 for (
int dof : ess_zero_dofs_) { y[dof] = 0.0; }
258 mfem::out <<
" Iteration : " << setw(3) << 0 <<
" (P r, r) = "
267 mfem::out <<
"BPCG: The preconditioner is not positive definite. (Pr, r) = "
287 MFEM_ASSERT(
IsFinite(gamma),
"den (gamma) = " << gamma);
292 mfem::out <<
"BPCG: The operator is not positive definite. (Ar, r) = "
309 alpha = delta0/gamma;
324 mfem::out <<
"BPCG: The preconditioner is not positive definite. (Pr, r) = "
333 mfem::out <<
" Iteration : " << setw(3) << i <<
" (Pr, r) = "
334 <<
delta << std::endl;
356 MFEM_ASSERT(
IsFinite(gamma),
"den (gamma) = " << gamma);
361 mfem::out <<
"BPCG: The operator is not positive definite. (Ar, r) = "
384 const auto arf = pow (gamma/delta0, 0.5/
final_iter);
385 mfem::out <<
"Average reduction factor = " << arf <<
'\n';
389 mfem::out <<
"BPCG: No convergence!" <<
'\n';
A class to handle Block diagonal preconditioners in a matrix-free implementation.
A class to handle Block systems in a matrix-free implementation.
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.
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.
bool 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.
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.
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.
void Mult(const Vector &b, Vector &x) const override
Operator application: y=A(x).
void UpdateVectors()
Bramble-Pasciak CG.
BramblePasciakSolver(ParBilinearForm &mVarf, ParMixedBilinearForm &bVarf, const BPSParameters ¶m)
System and mass preconditioner are constructed from bilinear forms.
void Mult(const Vector &x, Vector &y) const override
Operator application: y=A(x).
static HypreParMatrix * ConstructMassPreconditioner(const ParBilinearForm &mVarf, const real_t alpha=0.5)
Assemble a preconditioner for the mass matrix.
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.