23 :
Solver(fes_orig.GetTrueVSize()),
24 fec(fes_orig.GetMaxElementOrder(),
25 fes_orig.
GetMesh()->Dimension(),
27 fes_orig.GetTypicalFE()->GetMapType()),
33 const int btype_orig =
36 if (btype_orig == btype)
99 MFEM_ABORT(
"SetOperator not supported with DGMassInverse.")
120template<
int DIM,
int D1D,
int Q1D>
123 using namespace internal;
129 const int ND =
static_cast<int>(pow(d1d,
DIM));
144 const bool CHANGE_BASIS = (
d2q !=
nullptr);
152 const real_t *b_orig =
nullptr;
153 const real_t *d2q_B =
nullptr;
154 const real_t *q2d_B =
nullptr;
155 const real_t *q2d_Bt =
nullptr;
171 static constexpr int NB = Q1D ? Q1D : 1;
179 DGMassBasis<DIM,D1D>(e, NE, q2d_Bt, b_orig, b2, d1d);
183 DGMassBasis<DIM,D1D>(e, NE, d2q_B,
u,
u, d1d);
187 const int tid = MFEM_THREAD_ID(x) + NB*MFEM_THREAD_ID(y);
192 DGMassApply<DIM,D1D,Q1D>(e, NE, B, Bt, pa_data,
u, r, d1d, q1d);
193 DGMassAxpy(e, NE, ND, 1.0,
b, -1.0, r, r);
198 const int BX = MFEM_THREAD_SIZE(x);
199 const int BY = MFEM_THREAD_SIZE(y);
200 const int bxy = BX*BY;
204 for (
int i = tid; i < ND; i += bxy)
212 DGMassPreconditioner(e, NE, ND, dinv, r, z);
213 DGMassAxpy(e, NE, ND, 1.0, z, 0.0, z, d);
215 real_t nom = DGMassDot<NB>(e, NE, ND, d, r);
216 if (nom < 0.0) {
return; }
217 real_t r0 = fmax(nom*RELTOL*RELTOL, ABSTOL*ABSTOL);
218 if (nom <= r0) {
return; }
220 DGMassApply<DIM,D1D,Q1D>(e, NE, B, Bt, pa_data, d, z, d1d, q1d);
221 real_t den = DGMassDot<NB>(e, NE, ND, z, d);
224 DGMassDot<NB>(e, NE, ND, d, d);
226 if (den == 0.0) {
return; }
234 DGMassAxpy(e, NE, ND, 1.0,
u,
alpha, d,
u);
235 DGMassAxpy(e, NE, ND, 1.0, r, -
alpha, z, r);
237 DGMassPreconditioner(e, NE, ND, dinv, r, z);
239 real_t betanom = DGMassDot<NB>(e, NE, ND, r, z);
240 if (betanom < 0.0) {
return; }
241 if (betanom <= r0) {
break; }
243 if (++i > MAXIT) {
break; }
246 DGMassAxpy(e, NE, ND, 1.0, z,
beta, d, d);
247 DGMassApply<DIM,D1D,Q1D>(e, NE, B, Bt, pa_data, d, z, d1d, q1d);
248 den = DGMassDot<NB>(e, NE, ND, d, z);
251 DGMassDot<NB>(e, NE, ND, d, d);
253 if (den == 0.0) {
break; }
260 DGMassBasis<DIM,D1D>(e, NE, q2d_B,
u,
u, d1d);
272 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.
void SetMaxIter(const int max_iter_)
Set the maximum number of iterations.
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.
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.
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)
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.
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.
bool Factor(int m, real_t TOL=0.0) override
Compute the LU factorization of the current matrix.
void GetInverseMatrix(int m, real_t *X) const override
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
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)