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);
243static inline const T *HypreRead(
const Memory<T> &mem)
249static 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));
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());
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 real_t *d_x_ptr = xyz_tv + 0*ntdofs;
310 real_t *d_y_ptr = xyz_tv + 1*ntdofs;
314 real_t *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);
394 width = solver->Width();
395 height = solver->Height();
400 solver->SetOperator(op);
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
Efficient batched assembly of LOR discretizations on device.
const Vector & GetLORVertexCoordinates()
Return the vertices of the LOR mesh in E-vector format.
static bool FormIsSupported(BilinearForm &a)
Returns true if the form a supports batched assembly, false otherwise.
void Assemble(BilinearForm &a, const Array< int > ess_dofs, OperatorHandle &A)
Assemble the given form as a matrix and place the result in A.
HypreParVector * StealZCoordinate()
HypreParVector * StealYCoordinate()
HypreParMatrix * StealGradientMatrix()
const int order
Polynomial degree.
Vector * StealCoordinateVector()
void FormGradientMatrix()
Construct the discrete gradient matrix (not part of the public API).
HypreParVector * StealXCoordinate()
HypreParMatrix * G
Discrete gradient matrix.
void Form2DEdgeToVertex_RT(Array< int > &edge2vert)
ParFiniteElementSpace & edge_fes
The Nedelec space.
const int dim
Spatial dimension.
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_.
Vector * xyz_tvec
Mesh vertex coordinates in true-vector format.
ParFiniteElementSpace vert_fes
The corresponding H1 space.
void FormCoordinateVectors(const Vector &X_vert)
Construct the mesh coordinate vectors (not part of the public API).
void Form2DEdgeToVertex(Array< int > &edge2vert)
void Form3DEdgeToVertex(Array< int > &edge2vert)
void Form2DEdgeToVertex_ND(Array< int > &edge2vert)
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
Operator that converts FiniteElementSpace L-vectors to E-vectors.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
int GetNE() const
Returns number of elements in the mesh.
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
The Auxiliary-space Maxwell Solver in hypre.
Wrapper for hypre's ParCSR matrix class.
Wrapper for hypre's parallel vector class.
const OperatorHandle & GetAssembledSystem() const
Returns the assembled LOR system (const version).
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void SetOperator(const Operator &op)
Set/update the solver for the given operator.
SolverType & GetSolver()
Access the underlying solver.
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...
Class used by MFEM to store pointers to host and/or device memory.
int Capacity() const
Return the size of the allocated memory.
const T * Read(MemoryClass mc, int size) const
Get read-only access to the memory with the given MemoryClass.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
int SpaceDimension() const
Dimension of the physical space containing the mesh.
Arbitrary order H(curl)-conforming Nedelec finite elements.
Pointer to an Operator of a specified type.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
Operator * Ptr() const
Access the underlying Operator pointer.
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...
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
@ Hypre_ParCSR
ID for class HypreParMatrix.
Abstract parallel finite element space.
HYPRE_BigInt * GetTrueDofOffsets() const
HYPRE_BigInt GlobalVSize() const
HYPRE_BigInt GlobalTrueVSize() const
HYPRE_BigInt * GetDofOffsets() const
const Operator * GetProlongationMatrix() const override
The returned Operator is owned by the FiniteElementSpace.
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
const SparseMatrix * GetRestrictionMatrix() const override
Get the R matrix which restricts a local dof vector to true dof vector.
Create and assemble a low-order refined version of a ParBilinearForm.
ParFiniteElementSpace & GetParFESpace() const
Return the LOR ParFiniteElementSpace.
HypreParMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a HypreParMatrix.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
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)
Memory< real_t > & GetMemory()
Return a reference to the Memory object used by the Vector.
T * StealPointer(T *&ptr)
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
MemoryClass
Memory classes identify sets of memory types.
MemoryClass GetHypreMemoryClass()
The MemoryClass used by Hypre objects.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
bool IsIdentityProlongation(const Operator *P)
void HypreStealOwnership(HypreParMatrix &A_hyp, SparseMatrix &A_diag)
Make A_hyp steal ownership of its diagonal part A_diag.
void hypre_forall(int N, lambda &&body)
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
@ LEXICOGRAPHIC
Lexicographic ordering for tensor-product FiniteElements.
void forall(int N, lambda &&body)