26 for (
int k = 0; k<nblocks; k++)
28 if (!tr_fes[k]) {
continue; }
29 rdof_edof0.
SetSize(tr_fes[k]->GetVSize());
30 for (
int i = 0; i < mesh->
GetNE(); i++)
32 fes[k]->GetElementVDofs(i, vdofs);
33 tr_fes[k]->GetElementVDofs(i, rvdofs);
34 const int vdim = fes[k]->GetVDim();
35 const int nsd = vdofs.
Size()/vdim;
36 const int nsrd = rvdofs.
Size()/vdim;
37 for (
int vd = 0; vd < vdim; vd++)
39 for (
int j = 0; j < nsrd; j++)
41 int rvdof = rvdofs[j+nsrd*vd];
42 int vdof = vdofs[j+nsd*vd];
48 MFEM_ASSERT(vdof >= 0,
"incompatible volume and trace FE spaces");
49 rdof_edof0[rvdof] = vdof + dof_offsets[k];
53 rdof_edof.
Append(rdof_edof0);
63 if (dynamic_cast<ParFiniteElementSpace *>(fes_[0]))
74 mesh = fes[0]->GetMesh();
77 const FiniteElementCollection * fec;
78 for (
int i = 0; i < nblocks; i++)
80 fec = fes[i]->FEColl();
82 (
dynamic_cast<const H1_Trace_FECollection*
>(fec) ||
83 dynamic_cast<const ND_Trace_FECollection*>(fec) ||
84 dynamic_cast<const RT_Trace_FECollection*
>(fec));
88 pmesh =
dynamic_cast<ParMesh *
>(mesh);
90 nullptr : (IsTraceSpace[i]) ? fes[i] :
91 new ParFiniteElementSpace(pmesh, fec->GetTraceCollection(), fes[i]->GetVDim(),
92 fes[i]->GetOrdering());
97 nullptr : (IsTraceSpace[i]) ? fes[i] :
98 new FiniteElementSpace(mesh, fec->GetTraceCollection(), fes[i]->GetVDim(),
99 fes[i]->GetOrdering());
104 nullptr : (IsTraceSpace[i]) ? fes[i] :
105 new FiniteElementSpace(mesh, fec->GetTraceCollection(), fes[i]->GetVDim(),
106 fes[i]->GetOrdering());
108 if (tr_fes[i]) { rblocks++; }
112 ess_tdofs.SetSize(rblocks);
113 for (
int i = 0; i<rblocks; i++)
115 ess_tdofs[i] =
new Array<int>();
121 void ComplexBlockStaticCondensation::ComputeOffsets()
123 dof_offsets.
SetSize(nblocks+1);
124 tdof_offsets.
SetSize(nblocks+1);
128 rdof_offsets.
SetSize(rblocks+1);
129 rtdof_offsets.
SetSize(rblocks+1);
131 rtdof_offsets[0] = 0;
134 for (
int i =0; i<nblocks; i++)
136 dof_offsets[i+1] = fes[i]->GetVSize();
137 tdof_offsets[i+1] = fes[i]->GetTrueVSize();
140 rdof_offsets[j+1] = tr_fes[i]->GetVSize();
141 rtdof_offsets[j+1] = tr_fes[i]->GetTrueVSize();
151 void ComplexBlockStaticCondensation::Init()
153 lmat.SetSize(mesh->
GetNE());
154 lvec.SetSize(mesh->
GetNE());
155 for (
int i = 0; i < mesh->
GetNE(); i++)
163 S_r =
new BlockMatrix(rdof_offsets);
165 S_i =
new BlockMatrix(rdof_offsets);
170 int h = rdof_offsets[i+1] - rdof_offsets[i];
173 int w = rdof_offsets[j+1] - rdof_offsets[j];
174 S_r->
SetBlock(i,j,
new SparseMatrix(h, w));
175 S_i->
SetBlock(i,j,
new SparseMatrix(h, w));
179 y =
new Vector(2*rdof_offsets.Last());
181 y_r =
new BlockVector(*y, rdof_offsets);
182 y_i =
new BlockVector(*y, rdof_offsets.Last(), rdof_offsets);
185 void ComplexBlockStaticCondensation::GetReduceElementIndicesAndOffsets(
int el,
186 Array<int> & trace_ldofs,
187 Array<int> & interior_ldofs,
188 Array<int> & offsets)
const 191 offsets.SetSize(tr_fes.
Size()+1); offsets = 0;
193 Array<int> faces, ori;
208 MFEM_ABORT(
"ComplexBlockStaticCondensation::GetReduceElementIndicesAndOffsets: " 209 "dim > 3 not supported");
211 int numfaces = faces.Size();
213 trace_ldofs.SetSize(0);
214 interior_ldofs.SetSize(0);
219 for (
int i = 0; i<tr_fes.
Size(); i++)
226 ndof = fes[i]->GetVDim()*fes[i]->GetFE(el)->GetDof();
229 else if (IsTraceSpace[i])
231 for (
int iface = 0; iface < numfaces; iface++)
233 td += fes[i]->GetVDim()*fes[i]->GetFaceElement(faces[iface])->GetDof();
239 Array<int> trace_dofs;
240 ndof = fes[i]->GetVDim()*fes[i]->GetFE(el)->GetDof();
241 tr_fes[i]->GetElementVDofs(el, trace_dofs);
242 td = trace_dofs.
Size();
246 int_dofs.SetSize(ndof - td);
247 for (
int j = 0; j<td; j++)
249 tr_dofs[j] = skip + j;
251 for (
int j = 0; j<ndof-td; j++)
253 int_dofs[j] = skip + td + j;
257 trace_ldofs.Append(tr_dofs);
258 interior_ldofs.Append(int_dofs);
260 offsets.PartialSum();
264 void ComplexBlockStaticCondensation::GetReduceElementVDofs(
int el,
265 Array<int> & rdofs)
const 267 Array<int> faces, ori;
283 MFEM_ABORT(
"ComplexBlockStaticCondensation::GetReduceElementVDofs: " 284 "dim > 3 not supported");
286 int numfaces = faces.Size();
289 for (
int i = 0; i<tr_fes.
Size(); i++)
291 if (!tr_fes[i]) {
continue; }
295 Array<int> face_vdofs;
296 for (
int k = 0; k < numfaces; k++)
298 int iface = faces[k];
299 tr_fes[i]->GetFaceVDofs(iface, face_vdofs);
305 tr_fes[i]->GetElementVDofs(el, vdofs);
307 for (
int j=0; j<vdofs.Size(); j++)
309 vdofs[j] = (vdofs[j]>=0) ? vdofs[j]+rdof_offsets[skip] :
310 vdofs[j]-rdof_offsets[skip];
316 void ComplexBlockStaticCondensation::GetElementVDofs(
int el,
317 Array<int> & vdofs)
const 319 Array<int> faces, ori;
335 MFEM_ABORT(
"ComplexBlockStaticCondensation::GetElementVDofs: " 336 "dim > 3 not supported");
338 int numfaces = faces.Size();
340 for (
int i = 0; i<tr_fes.
Size(); i++)
345 Array<int> face_vdofs;
346 for (
int k = 0; k < numfaces; k++)
348 int iface = faces[k];
349 fes[i]->GetFaceVDofs(iface, face_vdofs);
355 fes[i]->GetElementVDofs(el, dofs);
357 for (
int j=0; j<dofs.Size(); j++)
359 dofs[j] = (dofs[j]>=0) ? dofs[j]+dof_offsets[i] :
360 dofs[j]-dof_offsets[i];
367 ComplexDenseMatrix * ComplexBlockStaticCondensation::GetLocalShurComplement(
369 const Array<int> & tr_idx,
const Array<int> & int_idx,
370 const ComplexDenseMatrix & elmat,
371 const Vector & elvect_real,
const Vector & elvect_imag,
372 Vector & rvect_real, Vector & rvect_imag)
374 int rdofs = tr_idx.Size();
375 int idofs = int_idx.Size();
376 MFEM_VERIFY(idofs != 0,
"Number of interior dofs is zero");
377 MFEM_VERIFY(rdofs != 0,
"Number of interface dofs is zero");
379 DenseMatrix A_tt_real, A_ti_real, A_it_real, A_ii_real;
380 DenseMatrix A_tt_imag, A_ti_imag, A_it_imag, A_ii_imag;
386 Vector yt_real(yt, 0,rdofs);
387 Vector yt_imag(yt, rdofs, rdofs);
389 Vector yi_real(yi, 0, idofs);
390 Vector yi_imag(yi,idofs, idofs);
393 elmat.real().GetSubMatrix(tr_idx,A_tt_real);
394 elmat.real().GetSubMatrix(tr_idx,int_idx, A_ti_real);
395 elmat.real().GetSubMatrix(int_idx, tr_idx, A_it_real);
396 elmat.real().GetSubMatrix(int_idx, A_ii_real);
398 elvect_real.GetSubVector(tr_idx, yt_real);
399 elvect_real.GetSubVector(int_idx, yi_real);
402 elmat.imag().GetSubMatrix(tr_idx,A_tt_imag);
403 elmat.imag().GetSubMatrix(tr_idx,int_idx, A_ti_imag);
404 elmat.imag().GetSubMatrix(int_idx, tr_idx, A_it_imag);
405 elmat.imag().GetSubMatrix(int_idx, A_ii_imag);
407 elvect_imag.GetSubVector(tr_idx, yt_imag);
408 elvect_imag.GetSubVector(int_idx, yi_imag);
411 ComplexDenseMatrix A_tt(&A_tt_real,&A_tt_imag,
false,
false);
412 ComplexDenseMatrix A_ti(&A_ti_real,&A_ti_imag,
false,
false);
413 ComplexDenseMatrix A_it(&A_it_real,&A_it_imag,
false,
false);
414 ComplexDenseMatrix A_ii(&A_ii_real,&A_ii_imag,
false,
false);
416 ComplexDenseMatrix * invA_ii = A_ii.ComputeInverse();
420 ComplexDenseMatrix * rmat =
mfem::Mult(A_ti,*lmat[el]);
423 rmat->real().Add(1., A_tt.real());
424 rmat->imag().Add(1., A_tt.imag());
427 lvec[el] =
new Vector(2*idofs);
428 invA_ii->Mult(yi,*lvec[el]);
431 Vector rvect(2*rdofs);
432 A_ti.Mult(*lvec[el], rvect);
433 rvect_real.SetSize(rdofs);
434 rvect_imag.SetSize(rdofs);
435 for (
int i = 0; i<rdofs; i++)
437 rvect_real(i) = yt_real(i) - rvect(i);
438 rvect_imag(i) = yt_imag(i) - rvect(i+rdofs);
452 GetReduceElementIndicesAndOffsets(el, tr_idx,int_idx, offsets);
455 Vector rvec_real, *rvecptr_real;
456 Vector rvec_imag, *rvecptr_imag;
458 if (int_idx.
Size()!=0)
460 rmat = GetLocalShurComplement(el,tr_idx,int_idx, elmat, elvect_r, elvect_i,
461 rvec_real,rvec_imag);
462 rvecptr_real = &rvec_real;
463 rvecptr_imag = &rvec_imag;
468 rvecptr_real = &elvect_r;
469 rvecptr_imag = &elvect_i;
492 MFEM_ABORT(
"ComplexBlockStaticCondensation::AssembleReducedSystem: " 493 "dim > 3 not supported");
495 int numfaces = faces.
Size();
498 for (
int i = 0; i<tr_fes.
Size(); i++)
500 if (!tr_fes[i]) {
continue; }
502 doftrans_i =
nullptr;
506 for (
int k = 0; k < numfaces; k++)
508 int iface = faces[k];
509 tr_fes[i]->GetFaceVDofs(iface, face_vdofs);
510 vdofs_i.
Append(face_vdofs);
515 doftrans_i = tr_fes[i]->GetElementVDofs(el, vdofs_i);
518 for (
int j = 0; j<tr_fes.
Size(); j++)
520 if (!tr_fes[j]) {
continue; }
522 doftrans_j =
nullptr;
527 for (
int k = 0; k < numfaces; k++)
529 int iface = faces[k];
530 tr_fes[j]->GetFaceVDofs(iface, face_vdofs);
531 vdofs_j.
Append(face_vdofs);
536 doftrans_j = tr_fes[j]->GetElementVDofs(el, vdofs_j);
541 offsets[j],offsets[j+1], Ae_r);
543 offsets[j],offsets[j+1], Ae_i);
544 if (doftrans_i || doftrans_j)
555 Vector vec1_r(*rvecptr_real, offsets[i], offsets[i+1]-offsets[i]);
556 Vector vec1_i(*rvecptr_imag, offsets[i], offsets[i+1]-offsets[i]);
567 if (int_idx.
Size()!=0) {
delete rmat; }
570 void ComplexBlockStaticCondensation::BuildProlongation()
577 for (
int i = 0; i<nblocks; i++)
579 if (!tr_fes[i]) {
continue; }
580 const SparseMatrix *P_ = tr_fes[i]->GetConformingProlongation();
583 const SparseMatrix *R_ = tr_fes[i]->GetRestrictionMatrix();
584 P->
SetBlock(skip,skip,const_cast<SparseMatrix*>(P_));
585 R->
SetBlock(skip,skip,const_cast<SparseMatrix*>(R_));
592 void ComplexBlockStaticCondensation::BuildParallelProlongation()
594 MFEM_VERIFY(parallel,
"BuildParallelProlongation: wrong code path");
595 pP =
new BlockOperator(rdof_offsets, rtdof_offsets);
596 R =
new BlockMatrix(rtdof_offsets, rdof_offsets);
600 for (
int i = 0; i<nblocks; i++)
602 if (!tr_fes[i]) {
continue; }
603 const HypreParMatrix *P_ =
604 dynamic_cast<ParFiniteElementSpace *
>(tr_fes[i])->Dof_TrueDof_Matrix();
607 const SparseMatrix *R_ = tr_fes[i]->GetRestrictionMatrix();
608 pP->
SetBlock(skip,skip,const_cast<HypreParMatrix*>(P_));
609 R->
SetBlock(skip,skip,const_cast<SparseMatrix*>(R_));
619 if (!pP) { BuildParallelProlongation(); }
636 for (
int i = 0; i<nblocks; i++)
638 if (!tr_fes[i]) {
continue; }
642 for (
int j = 0; j<nblocks; j++)
644 if (!tr_fes[j]) {
continue; }
646 if (skip_i == skip_j)
651 PtAP_r =
RAP(A_r,Pi);
658 PtAP_i =
RAP(A_i,Pi);
670 PtAP_r =
RAP(Pi,A_r,Pj);
678 PtAP_i =
RAP(Pi,A_i,Pj);
684 pS_r->
SetBlock(skip_i,skip_j,PtAP_r);
685 pS_i->
SetBlock(skip_i,skip_j,PtAP_i);
695 void ComplexBlockStaticCondensation::ConformingAssemble(
int skip_zeros)
698 if (!P) { BuildProlongation(); }
707 BlockMatrix *PtAe_r =
mfem::Mult(*Pt, *S_e_r);
708 BlockMatrix *PtAe_i =
mfem::Mult(*Pt, *S_e_i);
722 BlockMatrix *PtAeP_r =
mfem::Mult(*S_e_r, *P);
723 BlockMatrix *PtAeP_i =
mfem::Mult(*S_e_i, *P);
728 width = 2*S_r->
Width();
753 bool conforming =
true;
754 for (
int i = 0; i<nblocks; i++)
756 if (!tr_fes[i]) {
continue; }
757 const SparseMatrix *P_ = tr_fes[i]->GetConformingProlongation();
764 if (!conforming) { ConformingAssemble(0); }
765 const int remove_zeros = 0;
773 FillEssTdofLists(ess_rtdof_list);
776 const int remove_zeros = 0;
779 delete S_r; S_r=
nullptr;
780 delete S_i; S_i=
nullptr;
781 delete S_e_r; S_e_r =
nullptr;
782 delete S_e_i; S_e_i =
nullptr;
788 void ComplexBlockStaticCondensation::ConvertMarkerToReducedTrueDofs(
798 for (
int i = 0; i<nblocks; i++)
800 tdof_marker0.
MakeRef(&tdof_marker[tdof_offsets[i]],
801 tdof_offsets[i+1]-tdof_offsets[i]);
802 const SparseMatrix * R_ = fes[i]->GetRestrictionMatrix();
805 dof_marker0.
MakeRef(tdof_marker0);
809 dof_marker0.
SetSize(fes[i]->GetVSize());
812 dof_marker.
Append(dof_marker0);
815 int rdofs = rdof_edof.
Size();
816 Array<int> rdof_marker(rdofs);
818 for (
int i = 0; i < rdofs; i++)
820 rdof_marker[i] = dof_marker[rdof_edof[i]];
824 Array<int> rtdof_marker0;
825 Array<int> rdof_marker0;
827 for (
int i = 0; i<nblocks; i++)
829 if (!tr_fes[i]) {
continue; }
830 rdof_marker0.
MakeRef(&rdof_marker[rdof_offsets[k]],
831 rdof_offsets[k+1]-rdof_offsets[k]);
832 const SparseMatrix *tr_R = tr_fes[i]->GetRestrictionMatrix();
835 rtdof_marker0.
MakeRef(rdof_marker0);
839 rtdof_marker0.SetSize(tr_fes[i]->GetTrueVSize());
840 tr_R->BooleanMult(rdof_marker0, rtdof_marker0);
842 rtdof_marker.
Append(rtdof_marker0);
847 void ComplexBlockStaticCondensation::FillEssTdofLists(
const Array<int> &
851 for (
int i = 0; i<ess_tdof_list.Size(); i++)
853 int tdof = ess_tdof_list[i];
854 for (j = 0; j < rblocks; j++)
856 if (rtdof_offsets[j+1] > tdof) {
break; }
858 ess_tdofs[j]->Append(tdof-rtdof_offsets[j]);
868 ConvertMarkerToReducedTrueDofs(tdof_marker, rtdof_marker);
877 MFEM_VERIFY(!parallel,
"EliminateReducedTrueDofs::Wrong code path");
883 offsets.
MakeRef( (P) ? rtdof_offsets : rdof_offsets);
891 int h = offsets[i+1] - offsets[i];
894 int w = offsets[j+1] - offsets[j];
902 Operator::DiagonalPolicy::DIAG_ZERO);
908 MFEM_ASSERT(sol.
Size() == 2*dof_offsets.
Last(),
"'sol' has incorrect size");
909 const int nrdofs = rdof_offsets.Last();
917 sol_r_real.
MakeRef(sc_sol, 0, nrdofs);
918 sol_r_imag.
MakeRef(sc_sol, nrdofs, nrdofs);
925 for (
int i = 0; i < nrdofs; i++)
927 sol_r_real(i) = sol(rdof_edof[i]);
928 sol_r_imag(i) = sol(rdof_edof[i] + dof_offsets.
Last());
935 Vector sc_real(sc_sol, 0, n);
936 Vector sc_imag(sc_sol, n, n);
941 R->
Mult(blsol_r_real, sc_real);
942 R->
Mult(blsol_r_imag, sc_imag);
948 int copy_interior)
const 964 S_r->
PartMult(ess_rtdof_list,X_r,*y_r);
965 S_r->
PartMult(ess_rtdof_list,X_i,*y_i);
981 S_r->
PartMult(ess_rtdof_list,X_r,B_r);
982 S_r->
PartMult(ess_rtdof_list,X_i,B_i);
997 pS_e_r->
Mult(X_r,tmp); B_r-=tmp;
998 pS_e_i->
Mult(X_i,tmp); B_r+=tmp;
1000 pS_e_i->
Mult(X_r,tmp); B_i-=tmp;
1001 pS_e_r->
Mult(X_i,tmp); B_i-=tmp;
1003 for (
int j = 0; j<rblocks; j++)
1005 if (!ess_tdofs[j]->Size()) {
continue; }
1006 for (
int i = 0; i < ess_tdofs[j]->Size(); i++)
1008 int tdof = (*ess_tdofs[j])[i];
1009 int gdof = tdof + rtdof_offsets[j];
1010 B_r(gdof) = X_r(gdof);
1011 B_i(gdof) = X_i(gdof);
1018 X_r.SetSubVectorComplement(ess_rtdof_list, 0.0);
1019 X_i.SetSubVectorComplement(ess_rtdof_list, 0.0);
1028 const int nrdofs = rdof_offsets.Last();
1029 const int nrtdofs = rtdof_offsets.
Last();
1030 MFEM_VERIFY(sc_sol.
Size() == 2*nrtdofs,
"'sc_sol' has incorrect size");
1038 sol_r_real.
MakeRef(const_cast<Vector &>(sc_sol), 0, sc_sol.
Size()/2);
1039 sol_r_imag.
MakeRef(const_cast<Vector &>(sc_sol), sc_sol.
Size()/2,
1044 Vector sc_real(const_cast<Vector &>(sc_sol),0, nrtdofs);
1045 Vector sc_imag(const_cast<Vector &>(sc_sol),nrtdofs, nrtdofs);
1046 sol_r_real.SetSize(nrdofs);
1048 P->
Mult(sc_real, sol_r_real);
1049 P->
Mult(sc_imag, sol_r_imag);
1055 Vector sc_real(const_cast<Vector &>(sc_sol),0, nrtdofs);
1056 Vector sc_imag(const_cast<Vector &>(sc_sol),nrtdofs, nrtdofs);
1057 sol_r_real.SetSize(nrdofs);
1059 pP->
Mult(sc_real, sol_r_real);
1060 pP->
Mult(sc_imag, sol_r_imag);
1068 if (rdof_offsets.Last() == dof_offsets.
Last())
1070 sol_real = sol_r_real;
1071 sol_imag = sol_r_imag;
1082 const int NE = mesh->
GetNE();
1090 for (
int iel = 0; iel < NE; iel++)
1092 GetReduceElementVDofs(iel, trace_vdofs);
1094 int n = trace_vdofs.
Size();
1098 sol_r_real.GetSubVector(trace_vdofs, lsr_real);
1102 int m = lmat[iel]->Height()/2;
1106 lmat[iel]->Mult(lsr,lsi);
1111 GetReduceElementIndicesAndOffsets(iel,tr_idx, int_idx, idx_offs);
1114 int k = (lmat[iel]->Width() + lmat[iel]->Height())/2;
1116 lsol_real.
MakeRef(lsol, 0, k);
1117 lsol_imag.
MakeRef(lsol, k, k);
1124 GetElementVDofs(iel, vdofs);
1127 sol_real.SetSubVector(vdofs,lsol_real);
1128 sol_imag.SetSubVector(vdofs,lsol_imag);
1134 delete S_e_r; S_e_r =
nullptr;
1135 delete S_e_i; S_e_i =
nullptr;
1136 delete S_r; S_r =
nullptr;
1137 delete S_i; S_i =
nullptr;
1138 delete S; S=
nullptr;
1139 delete y_r; y_r=
nullptr;
1140 delete y_i; y_i=
nullptr;
1141 delete y; y=
nullptr;
1143 if (P) {
delete P; } P=
nullptr;
1144 if (R) {
delete R; } R=
nullptr;
1150 delete pS_e_r; pS_e_r=
nullptr;
1151 delete pS_e_i; pS_e_i=
nullptr;
1152 delete pS_r; pS_r=
nullptr;
1153 delete pS_i; pS_i=
nullptr;
1154 for (
int i = 0; i<rblocks; i++)
1156 delete ess_tdofs[i];
1158 delete pP; pP =
nullptr;
1162 for (
int i=0; i<lmat.Size(); i++)
1164 delete lmat[i]; lmat[i] =
nullptr;
1165 delete lvec[i]; lvec[i] =
nullptr;
void SetEssentialTrueDofs(const Array< int > &ess_tdof_list)
Determine and save internally essential reduced true dofs.
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
A class to handle Vectors in a block fashion.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
Partial matrix vector multiplication of (*this) with x involving only the rows given by rows...
virtual DenseMatrix & real()
Real or imaginary part accessor methods.
Field is discontinuous across element interfaces.
int Dimension() const
Dimension of the reference space used within the elements.
int owns_blocks
If owns_blocks the SparseMatrix objects Aij will be deallocated.
void SetSize(int s)
Resize the vector to size s.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
int Size() const
Returns the size of the vector.
void ParallelAssemble(BlockMatrix *m_r, BlockMatrix *m_i)
Data type dense matrix using column-major storage.
Abstract parallel finite element space.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
ComplexBlockStaticCondensation(Array< FiniteElementSpace *> &fes_)
Operator & GetBlock(int i, int j)
Return a reference to block i,j.
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
void SetBlock(int i, int j, SparseMatrix *mat)
Set A(i,j) = mat.
int NumRowBlocks() const
Return the number of row blocks.
virtual void Finalize(int skip_zeros=1)
Finalize all the submatrices.
void GetElementFaces(int i, Array< int > &faces, Array< int > &ori) const
Return the indices and the orientations of all faces of element i.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void ReduceSystem(Vector &x, Vector &X, Vector &B, int copy_interior=0) const
Set the reduced solution X and r.h.s B vectors from the full linear system solution x and r...
virtual void MultTranspose(const Vector &x, Vector &y) const
MatrixTranspose-Vector Multiplication y = A'*x.
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
int NumColBlocks() const
Return the number of column blocks.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
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 ReduceSolution(const Vector &sol, Vector &sc_sol) const
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator.
HypreParMatrix * EliminateCols(const Array< int > &cols)
void ComputeSolution(const Vector &sc_sol, Vector &sol) const
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
HYPRE_BigInt GlobalVSize() const
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
void AssembleReducedSystem(int el, ComplexDenseMatrix &elmat, Vector &elvect_r, Vector &elvect_i)
virtual void Mult(const Vector &x, Vector &y) const
Matrix-Vector Multiplication y = A*x.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
HYPRE_BigInt * GetDofOffsets() const
int GetNE() const
Returns number of elements.
void EliminateRows(const Array< int > &rows)
Eliminate rows from the diagonal and off-diagonal blocks of the matrix.
void GetSubMatrix(const Array< int > &idx, DenseMatrix &A) const
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
SparseMatrix & GetBlock(int i, int j)
Return a reference to block (i,j). Reference may be invalid if Aij(i,j) == NULL.
void Finalize(int skip_zeros=0)
Finalize the construction of the Schur complement matrix.
virtual void AddMult(const Vector &x, Vector &y, const double val=1.) const
Matrix-Vector Multiplication y = y + val*A*x.
int Size() const
Return the logical size of the array.
T & Last()
Return the last element in the array.
static void ListToMarker(const Array< int > &list, int marker_size, Array< int > &marker, int mark_val=-1)
Convert an array of indices (list) to a Boolean marker array where all indices in the list are marked...
void EliminateReducedTrueDofs(const Array< int > &ess_rtdof_list, Matrix::DiagonalPolicy dpolicy)
Eliminate the given reduced true dofs from the Schur complement matrix S.
void MakeRef(T *, int)
Make this Array a reference to a pointer.
void FormSystemMatrix(Operator::DiagonalPolicy diag_policy)
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
~ComplexBlockStaticCondensation()
void TransformDual(const DofTransformation *ran_dof_trans, const DofTransformation *dom_dof_trans, DenseMatrix &elmat)
Wrapper for hypre's ParCSR matrix class.
A class to handle Block systems in a matrix-free implementation.
virtual DenseMatrix & imag()
Class for parallel meshes.
void EliminateRowCols(const Array< int > &vdofs, BlockMatrix *Ae, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate the rows and columns corresponding to the entries in vdofs + save the eliminated entries in...
Specialization of the ComplexOperator built from a pair of Dense Matrices. The purpose of this specia...
void SetBlock(int iRow, int iCol, Operator *op, double c=1.0)
Add a block op in the block-entry (iblock, jblock).
int IsZeroBlock(int i, int j) const
Check if block (i,j) is a zero block.
Vector & GetBlock(int i)
Get the i-th vector in the block.
void Neg()
(*this) = -(*this)
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).