14 #include "../../general/forall.hpp" 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();
43 const double *d_diag = diag.
Read();
44 MFEM_FORALL(i, n+1, I[i] = i;);
54 HypreParMatrix D(MPI_COMM_WORLD, global_size, row_starts, &diag_spmat);
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);
94 if (mode == Mode::GRAD_DIV)
96 MFEM_VERIFY(!zero_l2_block,
97 "Mode::GRAD_DIV incompatible with zero coefficient.");
107 Dt.reset(D->Transpose());
129 if (mode == Mode::DARCY && !zero_l2_block)
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); }
171 if (mode == Mode::GRAD_DIV) { W_mix_coeff_qf = 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 double *d_detJ = geom->detJ.Read();
181 double *d_w_mix = W_mix_coeff_qf.
ReadWrite();
183 const bool zero_l2 = zero_l2_block;
186 const double detJ = d_detJ[i];
187 if (!zero_l2) { d_w[i] *= detJ*detJ; }
217 const double *d_L_diag_unweighted = L_diag_unweighted.
Read();
219 MFEM_FORALL(i, L_diag.
Size(),
221 const double 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();
295 const double *d_x_bc = x_bc.
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);
317 const double *d_w = w.
Read();
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);
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Abstract class for all finite elements.
void EliminateBC(Vector &) const
Eliminates the BCs (called internally, not public interface).
Class for an integration rule - an Array of IntegrationPoint.
A coefficient that is constant across space and time.
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.
void SetSize(int s)
Resize the vector to size s.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
void MultInverse(const Vector &x, Vector &y) const
int Size() const
Returns the size of the vector.
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 ...
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Abstract parallel finite element space.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void Mult(const Vector &x, Vector &y) const override
Operator application: y=A(x).
Memory< double > & GetMemoryData()
Memory< int > & GetMemoryI()
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Memory< int > & GetMemoryJ()
void Setup()
Build the linear operator and solver. Must be called when the coefficients change.
void Mult(const Vector &b, Vector &x) const override
Solve the linear system for L2 (scalar) and RT (flux) unknowns.
Quadrature function coefficient which requires that the quadrature rules used for this coefficient be...
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
A class to handle Block diagonal preconditioners in a matrix-free implementation. ...
Jacobi smoothing for a given bilinear form (no matrix necessary).
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
void SetPrintLevel(int print_level)
ParMesh * GetParMesh() const
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans)
void SetMaxIter(int max_it)
The operator x -> R*A*P*x constructed through the actions of R^T, A and P.
int * WriteI(bool on_dev=true)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
long long ReduceInt(int value) const override
Utility function: sum integers from all processors (Allreduce).
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
HYPRE_BigInt GlobalTrueVSize() const
Mesh * GetMesh() const
Returns the mesh.
void SetAbsTol(double atol)
void SetRelTol(double rtol)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
Mode
Which type of saddle-point problem is being solved?
const IntegrationRule & GetMassIntRule(FiniteElementSpace &fes_l2)
Solve the H(div) saddle-point system using MINRES with matrix-free block-diagonal preconditioning...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
const IntegrationRule & GetIntRule(int idx) const
Return the IntegrationRule associated with entity idx.
HypreParMatrix * ParAdd(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A + B.
int * WriteJ(bool on_dev=true)
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
HypreParMatrix * MakeDiagonalMatrix(Vector &diag, const ParFiniteElementSpace &fes)
Return a new HypreParMatrix with given diagonal entries.
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
HypreParMatrix * FormDiscreteDivergenceMatrix(ParFiniteElementSpace &fes_rt, ParFiniteElementSpace &fes_l2, const Array< int > &ess_dofs)
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 Reciprocal(Vector &x)
Replace x[i] with 1.0/x[i] for all i.
void OverrideSize(int height_, int width_)
Sets the height and width of the matrix.
Operator * Ptr() const
Access the underlying Operator pointer.
virtual void Project(QuadratureFunction &qf)
Fill the QuadratureFunction qf by evaluating the coefficient at the quadrature points.
int Size() const
Return the logical size of the array.
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.
Wrapper for hypre's ParCSR matrix class.
A class to handle Block systems in a matrix-free implementation.
Class for parallel meshes.
HYPRE_BigInt * GetTrueDofOffsets() const
Represents values or vectors of values at quadrature points on a mesh.
Settings for the output behavior of the IterativeSolver.
Solver for the discontinuous Galerkin mass matrix.
double * WriteData(bool on_dev=true)