23 #ifdef MFEM_DEBUG_HYBRIDIZATION_CP
32 : fes(fespace), c_fes(c_fespace), c_bfi(NULL), Ct(NULL),
33 Af_data(NULL), Af_ipiv(NULL)
65 for (
int i = 0; i < NE; i++)
68 num_hat_dofs += vdofs.
Size();
77 "parallel non-conforming AMR meshes are not supported yet");
84 const int skip_zeros = 1;
89 for (
int i = 0; i < num_faces; i++)
92 if (!FTr) {
continue; }
99 for (
int j = 0; j < s1; j++)
103 for (
int j = 0; j < s2; j++)
105 vdofs[s1+j] = o2 + j;
114 Ct->AddSubMatrix(vdofs, c_vdofs, elmat, skip_zeros);
121 for (
int i = 0; i < num_shared_faces; i++)
125 MFEM_ASSERT(FTr->
Elem2No < 0,
"");
130 for (
int j = 0; j < s1; j++)
137 *fe, *fe, *FTr, elmat);
140 Ct->AddSubMatrix(vdofs, c_vdofs, elmat, skip_zeros);
144 Ct->Finalize(skip_zeros);
149 MFEM_ABORT(
"TODO: algebraic definition of C");
152 #ifdef MFEM_DEBUG_HYBRIDIZATION_CP
155 std::ofstream C_file(
"C_matrix.txt");
163 std::ofstream P_file(
"P_matrix.txt");
181 free_tdof_marker = 1;
182 for (
int i = 0; i < ess_tdof_list.
Size(); i++)
184 free_tdof_marker[ess_tdof_list[i]] = 0;
193 free_vdofs_marker.
MakeRef(free_tdof_marker);
198 cP->
BooleanMult(free_tdof_marker, free_vdofs_marker);
205 P->
BooleanMult(1, free_tdof_marker, 0, free_vdofs_marker);
211 free_vdofs_marker.
MakeRef(free_tdof_marker);
216 cP->
BooleanMult(free_tdof_marker, free_vdofs_marker);
219 for (
int i = 0; i < NE; i++)
223 for (
int j = 0; j < vdofs.
Size(); j++)
237 for (
int i = 0; i < num_hat_dofs; i++)
254 #ifdef MFEM_DEBUG_HERE
257 for (
int i = 0; i < NE; i++)
263 #ifdef MFEM_DEBUG_HERE
271 #ifdef MFEM_DEBUG_HERE
275 int myid = pmesh ? pmesh->
GetMyRank() : 0;
278 int e_size = num_hat_dofs - (i_size + b_size);
279 std::cout <<
"\nHybridization::Init:"
280 <<
" [" << myid <<
"] hat dofs - \"internal\": " << i_size
281 <<
", \"boundary\": " << b_size
282 <<
", \"essential\": " << e_size <<
'\n' << std::endl;
283 #undef MFEM_DEBUG_HERE
295 for (
int i = 0; i < NE; i++)
299 for (
int j = 0; j < vdofs.
Size(); j++)
303 vdof_marker[vdofs[j]] = 1;
307 for (
int tdof = 0; tdof < R->
Height(); tdof++)
309 if (free_tdof_marker[tdof]) {
continue; }
311 const int ncols = R->
RowSize(tdof);
314 for (
int j = 0; j < ncols; j++)
316 if (std::abs(vals[j]) != 0.0 && vdof_marker[cols[j]] == 0)
318 MFEM_ABORT(
"Ref != 0");
336 for (
int i = h_start; i < h_end; i++)
339 if (mark == 0) { i_dofs.
Append(i-h_start); }
340 else if (mark == -1) { b_dofs.
Append(i-h_start); }
358 for (
int j = 0; j < i_dofs.
Size(); j++)
360 int j_dof = i_dofs[j];
361 for (
int i = 0; i < i_dofs.
Size(); i++)
363 A_ii(i,j) = A(i_dofs[i],j_dof);
365 for (
int i = 0; i < b_dofs.
Size(); i++)
367 A_bi(i,j) = A(b_dofs[i],j_dof);
370 for (
int j = 0; j < b_dofs.
Size(); j++)
372 int j_dof = b_dofs[j];
373 for (
int i = 0; i < i_dofs.
Size(); i++)
375 A_ib(i,j) = A(i_dofs[i],j_dof);
377 for (
int i = 0; i < b_dofs.
Size(); i++)
379 A_bb(i,j) = A(b_dofs[i],j_dof);
387 LU_ii.BlockFactor(i_dofs.
Size(), b_dofs.
Size(),
388 A_ib.Data(), A_bi.Data(), A_bb.Data());
389 LU_bb.Factor(b_dofs.
Size());
392 std::map<int,int> Cb_g2l;
393 for (
int i = 0; i < b_dofs.
Size(); i++)
398 for (
int j = 0; j < ncols; j++)
400 const std::pair<const int,int> p(cols[j], (
int)Cb_g2l.size());
405 for (std::map<int, int>::iterator it = Cb_g2l.begin();
406 it != Cb_g2l.end(); ++it)
408 c_dofs[it->second] = it->first;
411 for (
int i = 0; i < b_dofs.
Size(); i++)
417 for (
int j = 0; j < ncols; j++)
419 Cb_t(i,Cb_g2l[cols[j]]) = vals[j];
425 LU_bb.Solve(Cb_t.Height(), Cb_t.Width(), Sb_inv_Cb_t.
Data());
427 MultAtB(Cb_t, Sb_inv_Cb_t, Hb);
430 const int skip_zeros = 1;
443 if (!c_pfes) {
return; }
474 Vector el_vals, bf_i, i_vals, b_vals;
499 for (
int i = 0; i < NE; i++)
503 for (
int j = 0; j < vdofs.
Size(); j++)
506 if (vdof < 0) { vdof = -1 - vdof; }
507 if (vdof_marker[vdof]) { el_vals(j) = 0.0; }
508 else { vdof_marker[vdof] =
true; }
520 double *U_ib = LU_ii.
data + i_dofs.
Size()*i_dofs.
Size();
521 double *L_bi = U_ib + i_dofs.
Size()*b_dofs.
Size();
589 for (
int i = 0; i < NE; i++)
595 int vdof = vdofs[j-hat_offsets[i]];
596 if (vdof >= 0) { s(vdof) = bf(j); }
597 else { s(-1-vdof) = -bf(j); }
Abstract class for Finite Elements.
int Size() const
Logical size of the array.
int RowSize(const int i) const
Returns the number of elements in row i.
Class for grid function - Vector with associated FE space.
FiniteElementSpace * c_fes
Array< int > Af_f_offsets
HYPRE_Int MultTranspose(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A^t * x + beta * y.
void SetSize(int s)
Resizes the vector if the new size is different.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, but treat all elements as booleans (zero=false, nonzero=true).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols.
int GetNSharedFaces() const
Return the number of shared faces (3D), edges (2D), vertices (1D)
void BlockBackSolve(int m, int n, int r, const double *U12, const double *X2, double *Y1) const
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
HYPRE_Int * GetDofOffsets()
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
int GetNE() const
Returns number of elements.
Abstract parallel finite element space.
const FiniteElement * GetFaceElement(int i) const
FaceElementTransformations * GetInteriorFaceTransformations(int FaceNo)
double * GetRowEntries(const int row)
Return a pointer to the entries in a row.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
void DeleteAll()
Delete whole array.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
int GetNE() const
Returns number of elements in the mesh.
void Finalize()
Finalize the construction of the hybridized matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
int Append(const T &el)
Append element to array, resize if necessary.
Mesh * GetMesh() const
Returns the mesh.
int GetSharedFace(int sface) const
Return the local face index for the given shared face.
void ComputeSolution(const Vector &b, const Vector &sol_r, Vector &sol) const
void BlockForwSolve(int m, int n, int r, const double *L21, double *B1, double *B2) const
HypreParMatrix * RAP(HypreParMatrix *A, HypreParMatrix *P)
Returns the matrix P^t * A * P.
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
const SparseMatrix * GetConformingProlongation()
virtual void Finalize(int skip_zeros=1)
virtual const SparseMatrix * GetRestrictionMatrix()
void BooleanMult(int alpha, int *x, int beta, int *y)
void MultAfInv(const Vector &b, const Vector &lambda, Vector &bf, int mode) const
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void Threshold(double eps)
Replace small entries, abs(a_ij) <= eps, with zero.
BilinearFormIntegrator * c_bfi
HypreParMatrix * Dof_TrueDof_Matrix()
The true dof-to-dof interpolation matrix.
double MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
double * Data() const
Returns vector of the elements.
void AssembleMatrix(int el, const DenseMatrix &A)
Assemble the element matrix A into the hybridized system matrix.
Abstract finite element space.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
void GetIBDofs(int el, Array< int > &i_dofs, Array< int > &b_dofs) const
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void PrintMatlab(std::ostream &out=std::cout) const
Prints matrix in matlab format.
void SetSubVector(const Array< int > &dofs, const Vector &elemvect)
~Hybridization()
Destructor.
void SetDataAndSize(double *d, int s)
void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i'th element.
Array< int > hat_dofs_marker
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th face element (2D and 3D).
void MakeRef(T *, int)
Make this Array a reference to a pointer.
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
void ReduceRHS(const Vector &b, Vector &b_r) const
void Init(const Array< int > &ess_tdof_list)
Prepare the Hybridization object for assembly.
Wrapper for hypre's ParCSR matrix class.
Hybridization(FiniteElementSpace *fespace, FiniteElementSpace *c_fespace)
Constructor.
Class for parallel meshes.
static void AdjustVDofs(Array< int > &vdofs)