13 #include "../../general/forall.hpp" 14 #include "../../fem/pbilinearform.hpp" 24 if (dynamic_cast<const ND_FECollection*>(fec))
28 else if (dynamic_cast<const RT_FECollection*>(fec))
34 MFEM_ABORT(
"Bad finite element type.")
41 const int op1 = o + 1;
42 const int nedge =
static_cast<int>(
dim*o*pow(op1,
dim-1));
47 for (
int c=0; c<
dim; ++c)
49 const int nx = (c == 0) ? o : op1;
50 for (
int i2=0; i2<op1; ++i2)
52 for (
int i1=0; i1<o; ++i1)
54 const int ix = (c == 0) ? i1 : i2;
55 const int iy = (c == 0) ? i2 : i1;
57 const int iedge = ix + iy*nx + c*o*op1;
59 const int ix1 = (c == 0) ? ix + 1 : ix;
60 const int iy1 = (c == 1) ? iy + 1 : iy;
62 const int iv0 = ix + iy*op1;
63 const int iv1 = ix1 + iy1*op1;
75 const int op1 = o + 1;
76 const int nedge =
static_cast<int>(
dim*o*pow(op1,
dim-1));
81 for (
int c=0; c<
dim; ++c)
83 const int nx = (c == 0) ? op1 : o;
84 for (
int i=0; i<o*op1; ++i)
89 const int iedge = ix + iy*nx + c*o*op1;
91 const int ix1 = (c == 0) ? ix : ix + 1;
92 const int iy1 = (c == 1) ? iy : iy + 1;
94 const int iv0 = ix + iy*op1;
95 const int iv1 = ix1 + iy1*op1;
99 e2v(0, iedge) = (c == 1) ? iv0 : iv1;
100 e2v(1, iedge) = (c == 1) ? iv1 : iv0;
108 const int op1 = o + 1;
109 const int nedge =
static_cast<int>(
dim*o*pow(op1,
dim-1));
114 for (
int c=0; c<
dim; ++c)
116 const int nx = (c == 0) ? o : op1;
117 const int ny = (c == 1) ? o : op1;
118 for (
int i=0; i<o*op1*op1; ++i)
121 const int iy = (i/nx)%ny;
122 const int iz = i/nx/ny;
124 const int iedge = ix + iy*nx + iz*nx*ny + c*o*op1*op1;
126 const int ix1 = (c == 0) ? ix + 1 : ix;
127 const int iy1 = (c == 1) ? iy + 1 : iy;
128 const int iz1 = (c == 2) ? iz + 1 : iz;
130 const int iv0 = ix + iy*op1 + iz*op1*op1;
131 const int iv1 = ix1 + iy1*op1 + iz1*op1*op1;
153 const int nnz = 2*nedge_dof;
154 auto I = G_local.
WriteI();
155 mfem::forall(nedge_dof+1, [=] MFEM_HOST_DEVICE (
int i) { I[i] = 2*i; });
170 MFEM_VERIFY(R_v != NULL && R_e != NULL,
"");
173 const int nedge_per_el =
static_cast<int>(
dim*
order*pow(
order + 1,
dim - 1));
174 const int nvert_per_el =
static_cast<int>(pow(
order + 1,
dim));
176 const auto offsets_e = R_e->Offsets().Read();
177 const auto indices_e = R_e->Indices().Read();
178 const auto gather_v =
Reshape(R_v->GatherMap().Read(), nvert_per_el, nel_ho);
180 const auto e2v =
Reshape(edge2vertex.Read(), 2, nedge_per_el);
186 auto J = G_local.
WriteJ();
192 const int sj = indices_e[offsets_e[i]];
193 const int j = (sj >= 0) ? sj : -1 - sj;
194 const int sgn = (sj >= 0) ? 1 : -1;
195 const int j_loc = j%nedge_per_el;
196 const int j_el = j/nedge_per_el;
198 const int jv0_loc = e2v(0, j_loc);
199 const int jv1_loc = e2v(1, j_loc);
201 J[i*2 + 0] = gather_v(jv0_loc, j_el);
202 J[i*2 + 1] = gather_v(jv1_loc, j_el);
221 G_diag.SetOperatorOwner(
false);
242 template <
typename T>
243 static inline const T *HypreRead(
const Memory<T> &mem)
248 template <
typename T>
249 static inline T *HypreWrite(Memory<T> &mem)
272 MFEM_VERIFY(el_restr != NULL,
"");
276 const int ndp1 =
order + 1;
277 const int ndof_per_el =
static_cast<int>(pow(ndp1,
dim));
278 const int sdim =
dim;
279 const int ntdofs = R->
Height();
289 const auto d_offsets = HypreRead(el_restr->Offsets().GetMemory());
290 const auto d_indices = HypreRead(el_restr->Indices().GetMemory());
291 const auto ltdof_ldof = HypreRead(R->
GetMemoryJ());
294 MFEM_HYPRE_FORALL(i, ntdofs,
296 const int j = d_offsets[ltdof_ldof[i]];
297 for (
int c = 0; c < sdim; ++c)
299 const int idx_j = d_indices[j];
300 xyz_tv(i,c) = xyz_e(c, idx_j%ndof_per_el, idx_j/ndof_per_el);
308 double *d_x_ptr = xyz_tv + 0*ntdofs;
310 double *d_y_ptr = xyz_tv + 1*ntdofs;
314 double *d_z_ptr = xyz_tv + 2*ntdofs;
359 : edge_fes(pfes_ho_),
360 dim(edge_fes.GetParMesh()->Dimension()),
361 order(edge_fes.GetMaxElementOrder()),
362 vert_fec(order,
dim),
363 vert_fes(edge_fes.GetParMesh(), &vert_fec)
376 batched_lor.
Assemble(a_ho, ess_tdof_list, A);
380 lor_ams.StealGradientMatrix(),
381 lor_ams.StealXCoordinate(),
382 lor_ams.StealYCoordinate(),
383 lor_ams.StealZCoordinate());
const T * Read(MemoryClass mc, int size) const
Get read-only access to the memory with the given MemoryClass.
Create and assemble a low-order refined version of a ParBilinearForm.
HypreParVector * StealZCoordinate()
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
The Auxiliary-space Maxwell Solver in hypre.
BatchedLOR_AMS(ParFiniteElementSpace &pfes_ho_, const Vector &X_vert)
Construct the BatchedLOR_AMS object associated with the Nedelec space (or RT in 2D) pfes_ho_...
ParFiniteElementSpace & edge_fes
The Nedelec space.
Device memory; using CUDA or HIP *Malloc and *Free.
Efficient batched assembly of LOR discretizations on device.
Pointer to an Operator of a specified type.
void Form2DEdgeToVertex_ND(Array< int > &edge2vert)
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Abstract parallel finite element space.
void FormGradientMatrix()
Construct the discrete gradient matrix (not part of the public API).
virtual const SparseMatrix * GetRestrictionMatrix() const
Get the R matrix which restricts a local dof vector to true dof vector.
Memory< double > & GetMemoryData()
Memory< double > & GetMemory()
Return a reference to the Memory object used by the Vector.
static bool FormIsSupported(BilinearForm &a)
Returns true if the form a supports batched assembly, false otherwise.
Memory< int > & GetMemoryI()
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
Memory< int > & GetMemoryJ()
const OperatorHandle & GetAssembledSystem() const
Returns the assembled LOR system (const version).
ParFiniteElementSpace vert_fes
The corresponding H1 space.
void HypreStealOwnership(HypreParMatrix &A_hyp, SparseMatrix &A_diag)
Make A_hyp steal ownership of its diagonal part A_diag.
Vector * StealCoordinateVector()
Vector * xyz_tvec
Mesh vertex coordinates in true-vector format.
const FiniteElementCollection * FEColl() const
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
void Form2DEdgeToVertex(Array< int > &edge2vert)
HypreParMatrix * G
Discrete gradient matrix.
const int dim
Spatial dimension.
void Form3DEdgeToVertex(Array< int > &edge2vert)
int * WriteI(bool on_dev=true)
void FormCoordinateVectors(const Vector &X_vert)
Construct the mesh coordinate vectors (not part of the public API).
int Capacity() const
Return the size of the allocated memory.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
void SetOperator(const Operator &op)
Set/update the solver for the given operator.
int GetNE() const
Returns number of elements in the mesh.
HypreParVector * StealYCoordinate()
HYPRE_BigInt GlobalTrueVSize() const
void MakeRectangularBlockDiag(MPI_Comm comm, HYPRE_BigInt glob_num_rows, HYPRE_BigInt glob_num_cols, HYPRE_BigInt *row_starts, HYPRE_BigInt *col_starts, SparseMatrix *diag)
Reset the OperatorHandle to hold a parallel rectangular block-diagonal matrix using the currently set...
Wrapper for hypre's parallel vector class.
const Vector & GetLORVertexCoordinates()
Return the vertices of the LOR mesh in E-vector format.
bool IsIdentityProlongation(const Operator *P)
SolverType & GetSolver()
Access the underlying solver.
void forall(int N, lambda &&body)
Operator that converts FiniteElementSpace L-vectors to E-vectors.
HYPRE_BigInt GlobalVSize() const
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void Assemble(BilinearForm &a, const Array< int > ess_dofs, OperatorHandle &A)
Assemble the given form as a matrix and place the result in A.
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
const int order
Polynomial degree.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
int * WriteJ(bool on_dev=true)
HYPRE_BigInt * GetDofOffsets() const
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
constexpr MemoryClass GetHypreMemoryClass()
The MemoryClass used by Hypre objects.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
HypreParVector * StealXCoordinate()
void Form2DEdgeToVertex_RT(Array< int > &edge2vert)
void OverrideSize(int height_, int width_)
Sets the height and width of the matrix.
Class used by MFEM to store pointers to host and/or device memory.
LORSolver(BilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Create a solver of type SolverType, formed using the assembled SparseMatrix of the LOR version of a_h...
Lexicographic ordering for tensor-product FiniteElements.
Operator * Ptr() const
Access the underlying Operator pointer.
ID for class HypreParMatrix.
T * StealPointer(T *&ptr)
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
Wrapper for hypre's ParCSR matrix class.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
HypreParMatrix * StealGradientMatrix()
HYPRE_BigInt * GetTrueDofOffsets() const
MemoryClass
Memory classes identify sets of memory types.
int width
Dimension of the input / number of columns in the matrix.
double * WriteData(bool on_dev=true)