27 MFEM_VERIFY(!
Serial(),
"internal MFEM error");
32 real_t loc_energy, glob_energy;
38 MFEM_ABORT(
"TODO: add energy contribution from shared faces");
67 for (
int i = 0; i < n_shared_faces; i++)
70 int Elem2NbrNo = tr->Elem2No - pmesh->
GetNE();
72 fe1 = pfes->
GetFE(tr->Elem1No);
82 for (
int k = 0; k <
fnfi.Size(); k++)
84 fnfi[k]->AssembleFaceVector(*fe1, *fe2, *tr, el_x, el_y);
95 mfem::forall(N, [=] MFEM_HOST_DEVICE (
int i) { Y_RW[idx[i]] = 0.0; });
101 "this method is not supported yet with partial assembly");
109 int skip_zeros)
const
116 Vector el_x, nbr_x, face_x;
123 for (
int i = 0; i < nfaces; i++)
138 vdofs1.
Copy(vdofs_all);
139 for (
int j = 0; j < vdofs2.
Size(); j++)
151 for (
int k = 0; k <
fnfi.Size(); k++)
155 *T, face_x, elemmat);
172 const int skip_zeros = 0;
194 for (
int i = 0; i < glob_J.
Size(); i++)
198 glob_J[i] = J[i] + ldof_offset;
202 glob_J[i] = face_nbr_glob_ldof[J[i] - lvsize];
258 for (
int s1=0; s1<
fes.Size(); ++s1)
260 for (
int s2=0; s2<
fes.Size(); ++s2)
268 for (
int s=0; s<pf.
Size(); s++)
277 for (
int s1=0; s1<
fes.Size(); ++s1)
279 for (
int s2=0; s2<
fes.Size(); ++s2)
305 for (
int s = 0; s <
fes.Size(); ++s)
309 rhs[s]->SetSubVector(*
ess_tdofs[s], 0.0);
322 for (
int s = 0; s <
fes.Size(); ++s)
326 rhs[s]->SetSubVector(*
ess_tdofs[s], 0.0);
337 for (
int s = 0; s <
fes.Size(); ++s)
359 for (
int s=0; s<
fes.Size(); ++s)
361 fes[s]->GetProlongationMatrix()->Mult(
381 for (
int s=0; s<
fes.Size(); ++s)
383 el_x_const[s] = el_x[s] =
new Vector();
389 pgfs[s]->ExchangeFaceNbrData();
393 for (
int i = 0; i < n_shared_faces; i++)
396 int Elem2NbrNo = tr->Elem2No - pmesh->
GetNE();
398 for (
int s=0; s<
fes.Size(); ++s)
401 fe[s] = pfes->
GetFE(tr->Elem1No);
407 el_x[s]->
SetSize(vdofs[s]->Size() + vdofs2[s]->Size());
409 pgfs[s]->FaceNbrData().GetSubVector(*(vdofs2[s]),
410 el_x[s]->GetData() + vdofs[s]->Size());
413 for (
int k = 0; k <
fnfi.Size(); ++k)
415 fnfi[k]->AssembleFaceVector(fe, fe2, *tr, el_x_const, el_y);
417 for (
int s=0; s<
fes.Size(); ++s)
419 if (el_y[s]->Size() == 0) {
continue; }
425 for (
int s=0; s<
fes.Size(); ++s)
435 for (
int s=0; s<
fes.Size(); ++s)
437 fes[s]->GetProlongationMatrix()->MultTranspose(
455 for (
int s=0; s<
fes.Size(); ++s)
457 fes[s]->GetProlongationMatrix()->Mult(
467 for (
int i = 0; i <
fes.Size(); ++i)
469 for (
int j = 0; j <
fes.Size(); ++j)
480 for (
int s1=0; s1<
fes.Size(); ++s1)
482 for (
int s2=0; s2<
fes.Size(); ++s2)
490 int skip_zeros)
const
506 for (
int s1=0; s1<
fes.Size(); ++s1)
508 el_x_const[s1] = el_x[s1] =
new Vector();
515 pgfs[s1]->ExchangeFaceNbrData();
516 for (
int s2=0; s2<
fes.Size(); ++s2)
523 for (
int i = 0; i < n_shared_faces; i++)
526 int Elem2NbrNo = tr->Elem2No - pmesh->
GetNE();
528 for (
int s=0; s<
fes.Size(); ++s)
531 fe[s] = pfes->
GetFE(tr->Elem1No);
537 el_x[s]->
SetSize(vdofs[s]->Size() + vdofs2[s]->Size());
539 pgfs[s]->FaceNbrData().GetSubVector(*(vdofs2[s]),
540 el_x[s]->GetData() + vdofs[s]->Size());
542 vdofs[s]->
Copy(*vdofs_all[s]);
544 const int lvsize = pfes->
GetVSize();
545 for (
int j = 0; j < vdofs2[s]->
Size(); j++)
547 if ((*vdofs2[s])[j] >= 0)
549 (*vdofs2[s])[j] += lvsize;
553 (*vdofs2[s])[j] -= lvsize;
556 vdofs_all[s]->
Append(*(vdofs2[s]));
559 for (
int k = 0; k <
fnfi.Size(); ++k)
561 fnfi[k]->AssembleFaceGrad(fe, fe2, *tr, el_x_const, elmats);
563 for (
int s1=0; s1<
fes.Size(); ++s1)
565 for (
int s2=0; s2<
fes.Size(); ++s2)
567 if (elmats(s1,s2)->Height() == 0) {
continue; }
568 Grads(s1,s2)->AddSubMatrix(*vdofs[s1], *vdofs_all[s2],
569 *elmats(s1,s2), skip_zeros);
575 for (
int s1=0; s1<
fes.Size(); ++s1)
578 delete vdofs_all[s1];
582 for (
int s2=0; s2<
fes.Size(); ++s2)
584 delete elmats(s1,s2);
598 for (
int s1=0; s1<
fes.Size(); ++s1)
602 for (
int s2=0; s2<
fes.Size(); ++s2)
612 for (
int s=0; s<
fes.Size(); ++s)
614 fes[s]->GetProlongationMatrix()->Mult(
620 const int skip_zeros = 0;
622 for (
int s=0; s<
fes.Size(); ++s)
627 for (
int s1=0; s1<
fes.Size(); ++s1)
629 for (
int s2=0; s2<
fes.Size(); ++s2)
631 if (
Grads(s1,s2) == NULL)
633 int nbr_size = pfes[s2]->GetFaceNbrVSize();
635 pfes[s2]->GetVSize() + nbr_size);
646 for (
int s1=0; s1<
fes.Size(); ++s1)
647 for (
int s2=0; s2<
fes.Size(); ++s2)
649 Grads(s1,s2)->Finalize(skip_zeros);
652 for (
int s1=0; s1<
fes.Size(); ++s1)
654 for (
int s2=0; s2<
fes.Size(); ++s2)
662 int lvsize = pfes[s2]->GetVSize();
668 int *J =
Grads(s1,s2)->GetJ();
669 for (
int i = 0; i < glob_J.
Size(); i++)
673 glob_J[i] = J[i] + ldof_offset;
677 glob_J[i] = face_nbr_glob_ldof[J[i] - lvsize];
684 pfes[s1]->GlobalVSize(), pfes[s2]->GlobalVSize(),
685 Grads(s1,s2)->GetI(), glob_J,
Grads(s1,s2)->GetData(),
686 pfes[s1]->GetDofOffsets(), pfes[s2]->GetDofOffsets()));
694 Ph.ConvertFrom(pfes[s1]->Dof_TrueDof_Matrix());
703 Ph.ConvertFrom(pfes[s2]->Dof_TrueDof_Matrix());
720 for (
int s1=0; s1<
fes.Size(); ++s1)
722 for (
int s2=0; s2<
fes.Size(); ++s2)
730 dA.MakeSquareBlockDiag(pfes[s1]->GetComm(), pfes[s1]->GlobalVSize(),
731 pfes[s1]->GetDofOffsets(),
Grads(s1,s1));
732 Ph.ConvertFrom(pfes[s1]->Dof_TrueDof_Matrix());
740 dA.MakeRectangularBlockDiag(pfes[s1]->GetComm(),
741 pfes[s1]->GlobalVSize(),
742 pfes[s2]->GlobalVSize(),
743 pfes[s1]->GetDofOffsets(),
744 pfes[s2]->GetDofOffsets(),
747 Ph.ConvertFrom(pfes[s2]->Dof_TrueDof_Matrix());
766 for (
int s1=0; s1<
fes.Size(); ++s1)
768 for (
int s2=0; s2<
fes.Size(); ++s2)
Dynamic 2D array using row-major layout.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
void DeleteAll()
Delete the whole array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
A class to handle Block systems in a matrix-free implementation.
void SetBlock(int iRow, int iCol, Operator *op, real_t c=1.0)
Add a block op in the block-entry (iblock, jblock).
A class to handle Vectors in a block fashion.
void Update(real_t *data, const Array< int > &bOffsets)
Update method.
void SyncFromBlocks() const
Synchronize the memory location flags (i.e. the memory validity flags) of the big/monolithic block-ve...
Vector & GetBlock(int i)
Get the i-th vector in the block.
Data type dense matrix using column-major storage.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Abstract class for all finite elements.
Wrapper for hypre's ParCSR matrix class.
int GetNE() const
Returns number of elements.
Pointer to an Operator of a specified type.
void EliminateRowsCols(OperatorHandle &A, const Array< int > &ess_dof_list)
Reset the OperatorHandle to be the eliminated part of A after elimination of the essential dofs ess_d...
void ConvertFrom(OperatorHandle &A)
Convert the given OperatorHandle A to the currently set type id.
void MakePtAP(OperatorHandle &A, OperatorHandle &P)
Reset the OperatorHandle to hold the product P^t A P.
Operator * Ptr() const
Access the underlying Operator pointer.
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
Operator::Type Type() const
Get the currently set operator type id.
int height
Dimension of the output / number of rows in the matrix.
Type
Enumeration defining IDs for some classes derived from Operator.
@ Hypre_ParCSR
ID for class HypreParMatrix.
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Abstract parallel finite element space.
HYPRE_BigInt GlobalVSize() const
void ExchangeFaceNbrData()
const FiniteElement * GetFaceNbrFE(int i, int ndofs=0) const
HYPRE_BigInt GetMyDofOffset() const
HYPRE_BigInt * GetDofOffsets() const
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
void GetFaceNbrElementVDofs(int i, Array< int > &vdofs, DofTransformation &doftrans) const
const HYPRE_BigInt * GetFaceNbrGlobalDofMap()
int GetFaceNbrVSize() const
ParMesh * GetParMesh() const
const FiniteElement * GetFE(int i) const override
Class for parallel grid function.
void ExchangeFaceNbrData()
void MakeRef(FiniteElementSpace *f, real_t *v) override
Make the ParGridFunction reference external data on a new FiniteElementSpace.
Class for parallel meshes.
int GetNSharedFaces() const
Return the number of shared faces (3D), edges (2D), vertices (1D)
FaceElementTransformations * GetSharedFaceTransformations(int sf, bool fill2=true)
Get the FaceElementTransformations for the given shared face (edge 2D) using the shared face index sf...
int NumNonZeroElems() const override
Returns the number of the nonzero elements in the matrix.
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
real_t * GetData()
Return the element data, i.e. the array A.
void Finalize(int skip_zeros=1) override
Finalize the matrix initialization, switching the storage format from LIL to CSR.
int * GetJ()
Return the array J.
int * GetI()
Return the array I.
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add elements of the elemvect Vector to the entries listed in dofs. Negative dof values cause the -dof...
void SyncMemory(const Vector &v) const
Update the memory location of the vector to match v.
void SetSize(int s)
Resize the vector to size s.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
void forall(int N, lambda &&body)
Helper struct to convert a C++ type to an MPI type.