22 const int n = x.
Size();
24 MFEM_FORALL(i, n, d_x[i] = 1.0/d_x[i]; );
31 const int n = diag.
Size();
40 int *I = diag_spmat.
WriteI();
41 int *J = diag_spmat.
WriteJ();
44 MFEM_FORALL(i, n+1, I[i] = i;);
70 : minres(mesh.GetComm()),
71 order(fes_rt_.GetMaxElementOrder()),
72 fec_l2(order - 1, mesh.Dimension(), b2, mt),
73 fes_l2(&mesh, &fec_l2),
74 fec_rt(order - 1, mesh.Dimension(), b1, b2),
75 fes_rt(&mesh, &fec_rt),
76 ess_rt_dofs(ess_rt_dofs_),
79 convert_map_type(fes_l2_.GetTypicalFE()->GetMapType() ==
FiniteElement::VALUE),
89 W_mix_coeff(W_mix_coeff_qf)
93 zero_l2_block = (L_const_coeff && L_const_coeff->constant == 0.0);
97 MFEM_VERIFY(!zero_l2_block,
98 "Mode::GRAD_DIV incompatible with zero coefficient.");
108 Dt.reset(D->Transpose());
135 if (convert_map_type)
139 det_J_qf = geom->detJ;
149 L_diag_unweighted.
SetSize(n_l2);
160 ess_rt_dofs_,
Mode::DARCY)
168 if (!zero_l2_block) { L_coeff.
Project(W_coeff_qf); }
173 else { W_mix_coeff_qf = 1.0; }
178 if (convert_map_type)
180 const int n = W_mix_coeff_qf.
Size();
181 const real_t *d_detJ = geom->detJ.Read();
184 const bool zero_l2 = zero_l2_block;
187 const real_t detJ = d_detJ[i];
188 if (!zero_l2) { d_w[i] *= detJ*detJ; }
218 const real_t *d_L_diag_unweighted = L_diag_unweighted.
Read();
220 MFEM_FORALL(i, L_diag.
Size(),
222 const real_t d = d_L_diag_unweighted[i];
237 const int *d_I = ess_rt_dofs.
Read();
239 MFEM_FORALL(i, ess_rt_dofs.
Size(), d_R_diag[d_I[i]] = 1.0;);
248 S.reset(
RAP(R_diag_inv.get(), Dt.get()));
252 std::unique_ptr<HypreParMatrix> D_Minv_Dt(
RAP(R_diag_inv.get(), Dt.get()));
254 S.reset(
ParAdd(D_Minv_Dt.get(), L_diag_inv.get()));
265 if (A_11) { A_block->SetBlock(0, 0, A_11.get()); }
266 A_block->SetBlock(0, 1, D.get());
267 A_block->SetBlock(1, 0, Dt.get());
268 A_block->SetBlock(1, 1, R.
Ptr(), -1.0);
271 D_prec->SetDiagonalBlock(0, &S_inv);
272 D_prec->SetDiagonalBlock(1, R_inv.get());
280 const int n_ess_dofs = ess_rt_dofs.
Size();
283 const int n_l2 = offsets[1];
284 const int n_rt = offsets[2]-offsets[1];
289 MFEM_VERIFY(x_bc.
Size() == n_rt || n_ess_dofs == 0,
"BCs not set");
295 const int *d_I = ess_rt_dofs.
Read();
298 MFEM_FORALL(i, n_ess_dofs,
300 const int j = d_I[i];
309 D_e->Mult(-1.0, w, 1.0, bE);
320 MFEM_FORALL(i, n_ess_dofs,
322 const int j = d_I[i];
338 Vector bE_prime(b_prime, offsets[0], offsets[1]-offsets[0]);
339 Vector bF_prime(b_prime, offsets[1], offsets[2]-offsets[1]);
341 const Vector bE(
const_cast<Vector&
>(
b), offsets[0], offsets[1]-offsets[0]);
342 const Vector bF(
const_cast<Vector&
>(
b), offsets[1], offsets[2]-offsets[1]);
348 L_inv->Mult(z, bE_prime);
358 minres.
Mult(b_prime, x_prime);
361 Vector xE_prime(x_prime, offsets[0], offsets[1]-offsets[0]);
362 Vector xF_prime(x_prime, offsets[1], offsets[2]-offsets[1]);
364 Vector xE(x, offsets[0], offsets[1]-offsets[0]);
365 Vector xF(x, offsets[1], offsets[2]-offsets[1]);
368 L_inv->Mult(xE_prime, z);
370 basis_l2.
Mult(z, xE);
371 basis_rt.Mult(xF_prime, xF);
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
A class to handle Block diagonal preconditioners in a matrix-free implementation.
A class to handle Block systems in a matrix-free implementation.
void MultTranspose(const Vector &x, Vector &y) const override
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
void Mult(const Vector &x, Vector &y) const override
Operator application: y=A(x).
void MultTranspose(const Vector &x, Vector &y) const override
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
void MultInverse(const Vector &x, Vector &y) const
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
virtual void Project(QuadratureFunction &qf)
Fill the QuadratureFunction qf by evaluating the coefficient at the quadrature points.
A coefficient that is constant across space and time.
Solver for the discontinuous Galerkin mass matrix.
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Mesh * GetMesh() const
Returns the mesh.
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
Abstract class for all finite elements.
Solve the H(div) saddle-point system using MINRES with matrix-free block-diagonal preconditioning.
HdivSaddlePointSolver(ParMesh &mesh_, ParFiniteElementSpace &fes_rt_, ParFiniteElementSpace &fes_l2_, Coefficient &L_coeff_, Coefficient &R_coeff_, const Array< int > &ess_rt_dofs_, Mode mode_)
Creates a solver for the H(div) saddle-point system.
void Setup()
Build the linear operator and solver. Must be called when the coefficients change.
void EliminateBC(Vector &) const
Eliminates the BCs (called internally, not public interface).
Mode
Which type of saddle-point problem is being solved?
@ GRAD_DIV
Grad-div problem.
@ DARCY
Darcy/mixed Poisson problem.
void Mult(const Vector &b, Vector &x) const override
Solve the linear system for L2 (scalar) and RT (flux) unknowns.
void SetPrintLevel(int print_level)
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
Wrapper for hypre's ParCSR matrix class.
Class for an integration rule - an Array of IntegrationPoint.
void SetRelTol(real_t rtol)
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void SetMaxIter(int max_it)
void SetAbsTol(real_t atol)
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the MINRES method.
void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
void SetPreconditioner(Solver &pr) override
This should be called before SetOperator.
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &Trans)
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
ElementTransformation * GetTypicalElementTransformation()
If the local mesh is not empty return GetElementTransformation(0); otherwise, return the identity tra...
const GeometricFactors * GetGeometricFactors(const IntegrationRule &ir, const int flags, MemoryType d_mt=MemoryType::DEFAULT)
Return the mesh geometric factors corresponding to the given integration rule.
Operator * Ptr() const
Access the underlying Operator pointer.
Jacobi smoothing for a given bilinear form (no matrix necessary).
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Abstract parallel finite element space.
HYPRE_BigInt * GetTrueDofOffsets() const
HYPRE_BigInt GlobalTrueVSize() const
int GetTrueVSize() const override
Return the number of local vector true dofs.
ParMesh * GetParMesh() const
Class for parallel meshes.
long long ReduceInt(int value) const override
Utility function: sum integers from all processors (Allreduce).
Quadrature function coefficient which requires that the quadrature rules used for this coefficient be...
Represents values or vectors of values at quadrature points on a mesh.
const IntegrationRule & GetIntRule(int idx) const
Return the IntegrationRule associated with entity idx.
The operator x -> R*A*P*x constructed through the actions of R^T, A and P.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
int * WriteJ(bool on_dev=true)
Memory< int > & GetMemoryI()
int * WriteI(bool on_dev=true)
void OverrideSize(int height_, int width_)
Sets the height and width of the matrix.
Memory< int > & GetMemoryJ()
Memory< real_t > & GetMemoryData()
real_t * WriteData(bool on_dev=true)
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(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.
HypreParMatrix * MakeDiagonalMatrix(Vector &diag, const ParFiniteElementSpace &fes)
Return a new HypreParMatrix with given diagonal entries.
HypreParMatrix * FormDiscreteDivergenceMatrix(ParFiniteElementSpace &fes_rt, ParFiniteElementSpace &fes_l2, const Array< int > &ess_dofs)
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
HypreParMatrix * ParAdd(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A + B.
void Reciprocal(Vector &x)
Replace x[i] with 1.0/x[i] for all i.
const IntegrationRule & GetMassIntRule(FiniteElementSpace &fes_l2)
Settings for the output behavior of the IterativeSolver.