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;);
69 : minres(mesh.GetComm()),
70 order(fes_rt_.GetMaxElementOrder()),
71 fec_l2(order - 1, mesh.Dimension(), b2, mt),
72 fes_l2(&mesh, &fec_l2),
73 fec_rt(order - 1, mesh.Dimension(), b1, b2),
74 fes_rt(&mesh, &fec_rt),
75 ess_rt_dofs(ess_rt_dofs_),
78 convert_map_type(fes_l2_.GetFE(0)->GetMapType() ==
FiniteElement::VALUE),
88 W_mix_coeff(W_mix_coeff_qf)
92 zero_l2_block = (L_const_coeff && L_const_coeff->constant == 0.0);
96 MFEM_VERIFY(!zero_l2_block,
97 "Mode::GRAD_DIV incompatible with zero coefficient.");
107 Dt.reset(D->Transpose());
134 if (convert_map_type)
138 det_J_qf = geom->detJ;
148 L_diag_unweighted.
SetSize(n_l2);
159 ess_rt_dofs_,
Mode::DARCY)
167 if (!zero_l2_block) { L_coeff.
Project(W_coeff_qf); }
172 else { W_mix_coeff_qf = 1.0; }
177 if (convert_map_type)
179 const int n = W_mix_coeff_qf.
Size();
180 const real_t *d_detJ = geom->detJ.Read();
183 const bool zero_l2 = zero_l2_block;
186 const real_t detJ = d_detJ[i];
187 if (!zero_l2) { d_w[i] *= detJ*detJ; }
217 const real_t *d_L_diag_unweighted = L_diag_unweighted.
Read();
219 MFEM_FORALL(i, L_diag.
Size(),
221 const real_t d = d_L_diag_unweighted[i];
236 const int *d_I = ess_rt_dofs.
Read();
238 MFEM_FORALL(i, ess_rt_dofs.
Size(), d_R_diag[d_I[i]] = 1.0;);
247 S.reset(
RAP(R_diag_inv.get(), Dt.get()));
251 std::unique_ptr<HypreParMatrix> D_Minv_Dt(
RAP(R_diag_inv.get(), Dt.get()));
253 S.reset(
ParAdd(D_Minv_Dt.get(), L_diag_inv.get()));
264 if (A_11) { A_block->SetBlock(0, 0, A_11.get()); }
265 A_block->SetBlock(0, 1, D.get());
266 A_block->SetBlock(1, 0, Dt.get());
267 A_block->SetBlock(1, 1, R.
Ptr(), -1.0);
270 D_prec->SetDiagonalBlock(0, &S_inv);
271 D_prec->SetDiagonalBlock(1, R_inv.get());
279 const int n_ess_dofs = ess_rt_dofs.
Size();
282 const int n_l2 = offsets[1];
283 const int n_rt = offsets[2]-offsets[1];
288 MFEM_VERIFY(x_bc.
Size() == n_rt || n_ess_dofs == 0,
"BCs not set");
294 const int *d_I = ess_rt_dofs.
Read();
297 MFEM_FORALL(i, n_ess_dofs,
299 const int j = d_I[i];
308 D_e->Mult(-1.0, w, 1.0, bE);
319 MFEM_FORALL(i, n_ess_dofs,
321 const int j = d_I[i];
337 Vector bE_prime(b_prime, offsets[0], offsets[1]-offsets[0]);
338 Vector bF_prime(b_prime, offsets[1], offsets[2]-offsets[1]);
340 const Vector bE(
const_cast<Vector&
>(
b), offsets[0], offsets[1]-offsets[0]);
341 const Vector bF(
const_cast<Vector&
>(
b), offsets[1], offsets[2]-offsets[1]);
347 L_inv->Mult(z, bE_prime);
357 minres.
Mult(b_prime, x_prime);
360 Vector xE_prime(x_prime, offsets[0], offsets[1]-offsets[0]);
361 Vector xF_prime(x_prime, offsets[1], offsets[2]-offsets[1]);
363 Vector xE(x, offsets[0], offsets[1]-offsets[0]);
364 Vector xF(x, offsets[1], offsets[2]-offsets[1]);
367 L_inv->Mult(xE_prime, z);
369 basis_l2.
Mult(z, xE);
370 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...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Mesh * GetMesh() const
Returns the mesh.
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.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetPrintLevel(int print_level)
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)
virtual void Mult(const Vector &b, Vector &x) const
Iterative solution of the linear system using the MINRES method.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans)
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
void GetElementTransformation(int i, IsoparametricTransformation *ElTr) const
Builds the transformation defining the i-th element in ElTr. ElTr must be allocated in advance and wi...
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.