23 :
Solver(fes_orig.GetTrueVSize()),
24 fec(fes_orig.GetMaxElementOrder(),
25 fes_orig.
GetMesh()->Dimension(),
27 fes_orig.GetFE(0)->GetMapType()),
33 const int btype_orig =
36 if (btype_orig == btype)
97 MFEM_ABORT(
"SetOperator not supported with DGMassInverse.")
118template<
int DIM,
int D1D,
int Q1D>
121 using namespace internal;
127 const int ND =
static_cast<int>(pow(d1d,
DIM));
142 const bool CHANGE_BASIS = (
d2q !=
nullptr);
150 const real_t *b_orig =
nullptr;
151 const real_t *d2q_B =
nullptr;
152 const real_t *q2d_B =
nullptr;
153 const real_t *q2d_Bt =
nullptr;
169 static constexpr int NB = Q1D ? Q1D : 1;
177 DGMassBasis<DIM,D1D>(e, NE, q2d_Bt, b_orig, b2, d1d);
181 DGMassBasis<DIM,D1D>(e, NE, d2q_B,
u,
u, d1d);
185 const int tid = MFEM_THREAD_ID(x) + NB*MFEM_THREAD_ID(y);
190 DGMassApply<DIM,D1D,Q1D>(e, NE, B, Bt, pa_data,
u, r, d1d, q1d);
191 DGMassAxpy(e, NE, ND, 1.0,
b, -1.0, r, r);
196 const int BX = MFEM_THREAD_SIZE(x);
197 const int BY = MFEM_THREAD_SIZE(y);
198 const int bxy = BX*BY;
202 for (
int i = tid; i < ND; i += bxy)
210 DGMassPreconditioner(e, NE, ND, dinv, r, z);
211 DGMassAxpy(e, NE, ND, 1.0, z, 0.0, z, d);
213 real_t nom = DGMassDot<NB>(e, NE, ND, d, r);
214 if (nom < 0.0) {
return; }
215 real_t r0 = fmax(nom*RELTOL*RELTOL, ABSTOL*ABSTOL);
216 if (nom <= r0) {
return; }
218 DGMassApply<DIM,D1D,Q1D>(e, NE, B, Bt, pa_data, d, z, d1d, q1d);
219 real_t den = DGMassDot<NB>(e, NE, ND, z, d);
222 DGMassDot<NB>(e, NE, ND, d, d);
224 if (den == 0.0) {
return; }
232 DGMassAxpy(e, NE, ND, 1.0,
u,
alpha, d,
u);
233 DGMassAxpy(e, NE, ND, 1.0, r, -
alpha, z, r);
235 DGMassPreconditioner(e, NE, ND, dinv, r, z);
237 real_t betanom = DGMassDot<NB>(e, NE, ND, r, z);
238 if (betanom < 0.0) {
return; }
239 if (betanom <= r0) {
break; }
241 if (++i > MAXIT) {
break; }
244 DGMassAxpy(e, NE, ND, 1.0, z,
beta, d, d);
245 DGMassApply<DIM,D1D,Q1D>(e, NE, B, Bt, pa_data, d, z, d1d, q1d);
246 den = DGMassDot<NB>(e, NE, ND, d, z);
249 DGMassDot<NB>(e, NE, ND, d, d);
251 if (den == 0.0) {
break; }
258 DGMassBasis<DIM,D1D>(e, NE, q2d_B,
u,
u, d1d);
270 const int id = (d1d << 4) | q1d;
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
Solver for the discontinuous Galerkin mass matrix.
Vector diag_inv
Jacobi preconditioner.
class BilinearForm * M
Mass bilinear form, owned.
class MassIntegrator * m
Mass integrator, owned by the form M.
real_t rel_tol
Relative CG tolerance.
int max_iter
Maximum number of CG iterations;.
void SetOperator(const Operator &op)
Not implemented. Aborts.
Array< real_t > B_
Inverse of change of basis.
real_t abs_tol
Absolute CG tolerance.
void Mult(const Vector &b, Vector &u) const
Solve the system M b = u.
DGMassInverse(FiniteElementSpace &fes_, Coefficient *coeff, const IntegrationRule *ir, int btype)
Protected constructor, used internally.
Array< real_t > Bt_
Inverse of change of basis, transposed.
void Update()
Recompute operator and preconditioner (when coefficient or mesh changes).
void DGMassCGIteration(const Vector &b_, Vector &u_) const
Solve the system M b = u. Not part of the public interface.
void SetRelTol(const real_t rel_tol_)
Set the relative tolerance.
void SetMaxIter(const real_t max_iter_)
Set the maximum number of iterations.
FiniteElementSpace fes
FE space in requested basis.
const DofToQuad * d2q
Change of basis. Not owned.
void SetAbsTol(const real_t abs_tol_)
Set the absolute tolerance.
Data type dense matrix using column-major storage.
void Transpose()
(*this) = (*this)^t
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Array< real_t > B
Basis functions evaluated at quadrature points.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
Array< real_t > Bt
Transpose of B.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetNE() const
Returns number of elements in the mesh.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Class for an integration rule - an Array of IntegrationPoint.
Arbitrary order "L2-conforming" discontinuous finite elements.
virtual void GetInverseMatrix(int m, real_t *X) const
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
virtual bool Factor(int m, real_t TOL=0.0)
Compute the LU factorization of the current matrix.
const DofToQuad * maps
Not owned.
int Dimension() const
Dimension of the reference space used within the elements.
int height
Dimension of the output / number of rows in the matrix.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
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 SetSize(int s)
Resize the vector to size s.
void Reciprocal()
(*this)(i) = 1.0 / (*this)(i)
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
real_t u(const Vector &xvec)
DeviceTensor< 2, real_t > DeviceMatrix
DeviceTensor< 2, const real_t > ConstDeviceMatrix
void forall_2D(int N, int X, int Y, lambda &&body)