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);
73 tr_fes.SetSize(nblocks);
74 tr_fec.SetSize(nblocks);
75 mesh = fes[0]->GetMesh();
78 const FiniteElementCollection * fec;
79 for (
int i = 0; i < nblocks; i++)
82 fec = fes[i]->FEColl();
84 (
dynamic_cast<const H1_Trace_FECollection*
>(fec) ||
85 dynamic_cast<const ND_Trace_FECollection*
>(fec) ||
86 dynamic_cast<const RT_Trace_FECollection*
>(fec));
90 pmesh =
dynamic_cast<ParMesh *
>(mesh);
92 nullptr : (IsTraceSpace[i]) ? fes[i] :
93 new ParFiniteElementSpace(pmesh, tr_fec[i] = fec->GetTraceCollection(),
95 fes[i]->GetOrdering());
100 nullptr : (IsTraceSpace[i]) ? fes[i] :
101 new FiniteElementSpace(mesh, tr_fec[i] = fec->GetTraceCollection(),
103 fes[i]->GetOrdering());
108 nullptr : (IsTraceSpace[i]) ? fes[i] :
109 new FiniteElementSpace(mesh, tr_fec[i] = fec->GetTraceCollection(),
111 fes[i]->GetOrdering());
113 if (tr_fes[i]) { rblocks++; }
117 ess_tdofs.SetSize(rblocks);
118 for (
int i = 0; i<rblocks; i++)
120 ess_tdofs[i] =
new Array<int>();
126void ComplexBlockStaticCondensation::ComputeOffsets()
128 dof_offsets.
SetSize(nblocks+1);
129 tdof_offsets.
SetSize(nblocks+1);
133 rdof_offsets.
SetSize(rblocks+1);
134 rtdof_offsets.
SetSize(rblocks+1);
136 rtdof_offsets[0] = 0;
139 for (
int i =0; i<nblocks; i++)
141 dof_offsets[i+1] = fes[i]->GetVSize();
142 tdof_offsets[i+1] = fes[i]->GetTrueVSize();
145 rdof_offsets[j+1] = tr_fes[i]->GetVSize();
146 rtdof_offsets[j+1] = tr_fes[i]->GetTrueVSize();
156void ComplexBlockStaticCondensation::Init()
158 lmat.SetSize(mesh->
GetNE());
159 lvec.SetSize(mesh->
GetNE());
160 for (
int i = 0; i < mesh->
GetNE(); i++)
168 S_r =
new BlockMatrix(rdof_offsets);
170 S_i =
new BlockMatrix(rdof_offsets);
175 int h = rdof_offsets[i+1] - rdof_offsets[i];
178 int w = rdof_offsets[j+1] - rdof_offsets[j];
179 S_r->
SetBlock(i,j,
new SparseMatrix(h, w));
180 S_i->
SetBlock(i,j,
new SparseMatrix(h, w));
184 y =
new Vector(2*rdof_offsets.Last());
186 y_r =
new BlockVector(*y, rdof_offsets);
187 y_i =
new BlockVector(*y, rdof_offsets.Last(), rdof_offsets);
190void ComplexBlockStaticCondensation::GetReduceElementIndicesAndOffsets(
int el,
191 Array<int> & trace_ldofs,
192 Array<int> & interior_ldofs,
193 Array<int> & offsets)
const
196 offsets.SetSize(tr_fes.Size()+1); offsets = 0;
198 Array<int> faces, ori;
213 MFEM_ABORT(
"ComplexBlockStaticCondensation::GetReduceElementIndicesAndOffsets: "
214 "dim > 3 not supported");
216 int numfaces = faces.Size();
218 trace_ldofs.SetSize(0);
219 interior_ldofs.SetSize(0);
224 for (
int i = 0; i<tr_fes.Size(); i++)
231 ndof = fes[i]->GetVDim()*fes[i]->GetFE(el)->GetDof();
234 else if (IsTraceSpace[i])
236 for (
int iface = 0; iface < numfaces; iface++)
238 td += fes[i]->GetVDim()*fes[i]->GetFaceElement(faces[iface])->GetDof();
244 Array<int> trace_dofs;
245 ndof = fes[i]->GetVDim()*fes[i]->GetFE(el)->GetDof();
246 tr_fes[i]->GetElementVDofs(el, trace_dofs);
247 td = trace_dofs.Size();
251 int_dofs.SetSize(ndof - td);
252 for (
int j = 0; j<td; j++)
254 tr_dofs[j] = skip + j;
256 for (
int j = 0; j<ndof-td; j++)
258 int_dofs[j] = skip + td + j;
262 trace_ldofs.Append(tr_dofs);
263 interior_ldofs.Append(int_dofs);
265 offsets.PartialSum();
269void ComplexBlockStaticCondensation::GetReduceElementVDofs(
int el,
270 Array<int> & rdofs)
const
272 Array<int> faces, ori;
288 MFEM_ABORT(
"ComplexBlockStaticCondensation::GetReduceElementVDofs: "
289 "dim > 3 not supported");
291 int numfaces = faces.Size();
294 for (
int i = 0; i<tr_fes.Size(); i++)
296 if (!tr_fes[i]) {
continue; }
300 Array<int> face_vdofs;
301 for (
int k = 0; k < numfaces; k++)
303 int iface = faces[k];
304 tr_fes[i]->GetFaceVDofs(iface, face_vdofs);
305 vdofs.Append(face_vdofs);
310 tr_fes[i]->GetElementVDofs(el, vdofs);
312 for (
int j=0; j<vdofs.Size(); j++)
314 vdofs[j] = (vdofs[j]>=0) ? vdofs[j]+rdof_offsets[skip] :
315 vdofs[j]-rdof_offsets[skip];
321void ComplexBlockStaticCondensation::GetElementVDofs(
int el,
322 Array<int> & vdofs)
const
324 Array<int> faces, ori;
340 MFEM_ABORT(
"ComplexBlockStaticCondensation::GetElementVDofs: "
341 "dim > 3 not supported");
343 int numfaces = faces.Size();
345 for (
int i = 0; i<tr_fes.Size(); i++)
350 Array<int> face_vdofs;
351 for (
int k = 0; k < numfaces; k++)
353 int iface = faces[k];
354 fes[i]->GetFaceVDofs(iface, face_vdofs);
355 dofs.Append(face_vdofs);
360 fes[i]->GetElementVDofs(el, dofs);
362 for (
int j=0; j<dofs.Size(); j++)
364 dofs[j] = (dofs[j]>=0) ? dofs[j]+dof_offsets[i] :
365 dofs[j]-dof_offsets[i];
372ComplexDenseMatrix * ComplexBlockStaticCondensation::GetLocalShurComplement(
374 const Array<int> & tr_idx,
const Array<int> & int_idx,
375 const ComplexDenseMatrix & elmat,
376 const Vector & elvect_real,
const Vector & elvect_imag,
377 Vector & rvect_real, Vector & rvect_imag)
379 int rdofs = tr_idx.Size();
380 int idofs = int_idx.Size();
381 MFEM_VERIFY(idofs != 0,
"Number of interior dofs is zero");
382 MFEM_VERIFY(rdofs != 0,
"Number of interface dofs is zero");
384 DenseMatrix A_tt_real, A_ti_real, A_it_real, A_ii_real;
385 DenseMatrix A_tt_imag, A_ti_imag, A_it_imag, A_ii_imag;
391 Vector yt_real(yt, 0,rdofs);
392 Vector yt_imag(yt, rdofs, rdofs);
394 Vector yi_real(yi, 0, idofs);
395 Vector yi_imag(yi,idofs, idofs);
398 elmat.real().GetSubMatrix(tr_idx,A_tt_real);
399 elmat.real().GetSubMatrix(tr_idx,int_idx, A_ti_real);
400 elmat.real().GetSubMatrix(int_idx, tr_idx, A_it_real);
401 elmat.real().GetSubMatrix(int_idx, A_ii_real);
403 elvect_real.GetSubVector(tr_idx, yt_real);
404 elvect_real.GetSubVector(int_idx, yi_real);
407 elmat.imag().GetSubMatrix(tr_idx,A_tt_imag);
408 elmat.imag().GetSubMatrix(tr_idx,int_idx, A_ti_imag);
409 elmat.imag().GetSubMatrix(int_idx, tr_idx, A_it_imag);
410 elmat.imag().GetSubMatrix(int_idx, A_ii_imag);
412 elvect_imag.GetSubVector(tr_idx, yt_imag);
413 elvect_imag.GetSubVector(int_idx, yi_imag);
416 ComplexDenseMatrix A_tt(&A_tt_real,&A_tt_imag,
false,
false);
417 ComplexDenseMatrix A_ti(&A_ti_real,&A_ti_imag,
false,
false);
418 ComplexDenseMatrix A_it(&A_it_real,&A_it_imag,
false,
false);
419 ComplexDenseMatrix A_ii(&A_ii_real,&A_ii_imag,
false,
false);
421 ComplexDenseMatrix * invA_ii = A_ii.ComputeInverse();
425 ComplexDenseMatrix * rmat =
mfem::Mult(A_ti,*lmat[el]);
428 rmat->real().Add(1., A_tt.real());
429 rmat->imag().Add(1., A_tt.imag());
432 lvec[el] =
new Vector(2*idofs);
433 invA_ii->Mult(yi,*lvec[el]);
436 Vector rvect(2*rdofs);
437 A_ti.Mult(*lvec[el], rvect);
438 rvect_real.SetSize(rdofs);
439 rvect_imag.SetSize(rdofs);
440 for (
int i = 0; i<rdofs; i++)
442 rvect_real(i) = yt_real(i) - rvect(i);
443 rvect_imag(i) = yt_imag(i) - rvect(i+rdofs);
457 GetReduceElementIndicesAndOffsets(el, tr_idx,int_idx, offsets);
460 Vector rvec_real, *rvecptr_real;
461 Vector rvec_imag, *rvecptr_imag;
463 if (int_idx.
Size()!=0)
465 rmat = GetLocalShurComplement(el,tr_idx,int_idx, elmat, elvect_r, elvect_i,
466 rvec_real,rvec_imag);
467 rvecptr_real = &rvec_real;
468 rvecptr_imag = &rvec_imag;
473 rvecptr_real = &elvect_r;
474 rvecptr_imag = &elvect_i;
496 MFEM_ABORT(
"ComplexBlockStaticCondensation::AssembleReducedSystem: "
497 "dim > 3 not supported");
499 int numfaces = faces.
Size();
502 for (
int i = 0; i<tr_fes.Size(); i++)
504 if (!tr_fes[i]) {
continue; }
510 for (
int k = 0; k < numfaces; k++)
512 int iface = faces[k];
513 tr_fes[i]->GetFaceVDofs(iface, face_vdofs);
514 vdofs_i.
Append(face_vdofs);
519 tr_fes[i]->GetElementVDofs(el, vdofs_i, doftrans_i);
522 for (
int j = 0; j<tr_fes.Size(); j++)
524 if (!tr_fes[j]) {
continue; }
531 for (
int k = 0; k < numfaces; k++)
533 int iface = faces[k];
534 tr_fes[j]->GetFaceVDofs(iface, face_vdofs);
535 vdofs_j.
Append(face_vdofs);
540 tr_fes[j]->GetElementVDofs(el, vdofs_j, doftrans_j);
545 offsets[j],offsets[j+1], Ae_r);
547 offsets[j],offsets[j+1], Ae_i);
556 Vector vec1_r(*rvecptr_real, offsets[i], offsets[i+1]-offsets[i]);
557 Vector vec1_i(*rvecptr_imag, offsets[i], offsets[i+1]-offsets[i]);
565 if (int_idx.
Size()!=0) {
delete rmat; }
568void ComplexBlockStaticCondensation::BuildProlongation()
575 for (
int i = 0; i<nblocks; i++)
577 if (!tr_fes[i]) {
continue; }
578 const SparseMatrix *P_ = tr_fes[i]->GetConformingProlongation();
581 const SparseMatrix *R_ = tr_fes[i]->GetRestrictionMatrix();
582 P->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(P_));
583 R->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(R_));
590void ComplexBlockStaticCondensation::BuildParallelProlongation()
592 MFEM_VERIFY(parallel,
"BuildParallelProlongation: wrong code path");
593 pP =
new BlockOperator(rdof_offsets, rtdof_offsets);
594 R =
new BlockMatrix(rtdof_offsets, rdof_offsets);
598 for (
int i = 0; i<nblocks; i++)
600 if (!tr_fes[i]) {
continue; }
601 const HypreParMatrix *P_ =
602 dynamic_cast<ParFiniteElementSpace *
>(tr_fes[i])->Dof_TrueDof_Matrix();
605 const SparseMatrix *R_ = tr_fes[i]->GetRestrictionMatrix();
606 pP->
SetBlock(skip,skip,
const_cast<HypreParMatrix*
>(P_));
607 R->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(R_));
617 if (!pP) { BuildParallelProlongation(); }
634 for (
int i = 0; i<nblocks; i++)
636 if (!tr_fes[i]) {
continue; }
640 for (
int j = 0; j<nblocks; j++)
642 if (!tr_fes[j]) {
continue; }
644 if (skip_i == skip_j)
649 PtAP_r =
RAP(A_r,Pi);
656 PtAP_i =
RAP(A_i,Pi);
668 PtAP_r =
RAP(Pi,A_r,Pj);
676 PtAP_i =
RAP(Pi,A_i,Pj);
682 pS_r->
SetBlock(skip_i,skip_j,PtAP_r);
683 pS_i->
SetBlock(skip_i,skip_j,PtAP_i);
693void ComplexBlockStaticCondensation::ConformingAssemble(
int skip_zeros)
696 if (!P) { BuildProlongation(); }
705 BlockMatrix *PtAe_r =
mfem::Mult(*Pt, *S_e_r);
706 BlockMatrix *PtAe_i =
mfem::Mult(*Pt, *S_e_i);
720 BlockMatrix *PtAeP_r =
mfem::Mult(*S_e_r, *P);
721 BlockMatrix *PtAeP_i =
mfem::Mult(*S_e_i, *P);
726 width = 2*S_r->
Width();
751 bool conforming =
true;
752 for (
int i = 0; i<nblocks; i++)
754 if (!tr_fes[i]) {
continue; }
755 const SparseMatrix *P_ = tr_fes[i]->GetConformingProlongation();
762 if (!conforming) { ConformingAssemble(0); }
763 const int remove_zeros = 0;
771 FillEssTdofLists(ess_rtdof_list);
774 const int remove_zeros = 0;
777 delete S_r; S_r=
nullptr;
778 delete S_i; S_i=
nullptr;
779 delete S_e_r; S_e_r =
nullptr;
780 delete S_e_i; S_e_i =
nullptr;
786void ComplexBlockStaticCondensation::ConvertMarkerToReducedTrueDofs(
796 for (
int i = 0; i<nblocks; i++)
798 tdof_marker0.
MakeRef(&tdof_marker[tdof_offsets[i]],
799 tdof_offsets[i+1]-tdof_offsets[i]);
800 const SparseMatrix * R_ = fes[i]->GetRestrictionMatrix();
803 dof_marker0.
MakeRef(tdof_marker0);
807 dof_marker0.
SetSize(fes[i]->GetVSize());
810 dof_marker.
Append(dof_marker0);
813 int rdofs = rdof_edof.
Size();
814 Array<int> rdof_marker(rdofs);
816 for (
int i = 0; i < rdofs; i++)
818 rdof_marker[i] = dof_marker[rdof_edof[i]];
822 Array<int> rtdof_marker0;
823 Array<int> rdof_marker0;
825 for (
int i = 0; i<nblocks; i++)
827 if (!tr_fes[i]) {
continue; }
828 rdof_marker0.
MakeRef(&rdof_marker[rdof_offsets[k]],
829 rdof_offsets[k+1]-rdof_offsets[k]);
830 const SparseMatrix *tr_R = tr_fes[i]->GetRestrictionMatrix();
833 rtdof_marker0.MakeRef(rdof_marker0);
838 tr_R->BooleanMult(rdof_marker0, rtdof_marker0);
840 rtdof_marker.
Append(rtdof_marker0);
845void ComplexBlockStaticCondensation::FillEssTdofLists(
const Array<int> &
852 for (j = 0; j < rblocks; j++)
854 if (rtdof_offsets[j+1] > tdof) {
break; }
856 ess_tdofs[j]->Append(tdof-rtdof_offsets[j]);
866 ConvertMarkerToReducedTrueDofs(tdof_marker, rtdof_marker);
875 MFEM_VERIFY(!parallel,
"EliminateReducedTrueDofs::Wrong code path");
881 offsets.
MakeRef( (P) ? rtdof_offsets : rdof_offsets);
889 int h = offsets[i+1] - offsets[i];
892 int w = offsets[j+1] - offsets[j];
906 MFEM_ASSERT(
sol.Size() == 2*dof_offsets.
Last(),
"'sol' has incorrect size");
907 const int nrdofs = rdof_offsets.Last();
915 sol_r_real.
MakeRef(sc_sol, 0, nrdofs);
916 sol_r_imag.
MakeRef(sc_sol, nrdofs, nrdofs);
923 for (
int i = 0; i < nrdofs; i++)
925 sol_r_real(i) =
sol(rdof_edof[i]);
926 sol_r_imag(i) =
sol(rdof_edof[i] + dof_offsets.
Last());
933 Vector sc_real(sc_sol, 0, n);
934 Vector sc_imag(sc_sol, n, n);
939 R->
Mult(blsol_r_real, sc_real);
940 R->
Mult(blsol_r_imag, sc_imag);
946 int copy_interior)
const
962 S_r->
PartMult(ess_rtdof_list,X_r,*y_r);
963 S_r->
PartMult(ess_rtdof_list,X_i,*y_i);
979 S_r->
PartMult(ess_rtdof_list,X_r,B_r);
980 S_r->
PartMult(ess_rtdof_list,X_i,B_i);
995 pS_e_r->
Mult(X_r,tmp); B_r-=tmp;
996 pS_e_i->
Mult(X_i,tmp); B_r+=tmp;
998 pS_e_i->
Mult(X_r,tmp); B_i-=tmp;
999 pS_e_r->
Mult(X_i,tmp); B_i-=tmp;
1001 for (
int j = 0; j<rblocks; j++)
1003 if (!ess_tdofs[j]->Size()) {
continue; }
1004 for (
int i = 0; i < ess_tdofs[j]->Size(); i++)
1006 int tdof = (*ess_tdofs[j])[i];
1007 int gdof = tdof + rtdof_offsets[j];
1008 B_r(gdof) = X_r(gdof);
1009 B_i(gdof) = X_i(gdof);
1026 const int nrdofs = rdof_offsets.Last();
1027 const int nrtdofs = rtdof_offsets.
Last();
1028 MFEM_VERIFY(sc_sol.
Size() == 2*nrtdofs,
"'sc_sol' has incorrect size");
1042 Vector sc_real(
const_cast<Vector &
>(sc_sol),0, nrtdofs);
1043 Vector sc_imag(
const_cast<Vector &
>(sc_sol),nrtdofs, nrtdofs);
1046 P->
Mult(sc_real, sol_r_real);
1047 P->
Mult(sc_imag, sol_r_imag);
1053 Vector sc_real(
const_cast<Vector &
>(sc_sol),0, nrtdofs);
1054 Vector sc_imag(
const_cast<Vector &
>(sc_sol),nrtdofs, nrtdofs);
1057 pP->
Mult(sc_real, sol_r_real);
1058 pP->
Mult(sc_imag, sol_r_imag);
1062 sol.SetSize(2*dof_offsets.
Last());
1066 if (rdof_offsets.Last() == dof_offsets.
Last())
1068 sol_real = sol_r_real;
1069 sol_imag = sol_r_imag;
1080 const int NE = mesh->
GetNE();
1088 for (
int iel = 0; iel < NE; iel++)
1090 GetReduceElementVDofs(iel, trace_vdofs);
1092 int n = trace_vdofs.
Size();
1100 int m = lmat[iel]->Height()/2;
1104 lmat[iel]->Mult(lsr,lsi);
1109 GetReduceElementIndicesAndOffsets(iel,tr_idx, int_idx, idx_offs);
1112 int k = (lmat[iel]->Width() + lmat[iel]->Height())/2;
1114 lsol_real.
MakeRef(lsol, 0, k);
1115 lsol_imag.
MakeRef(lsol, k, k);
1122 GetElementVDofs(iel, vdofs);
1132 delete S_e_r; S_e_r =
nullptr;
1133 delete S_e_i; S_e_i =
nullptr;
1134 delete S_r; S_r =
nullptr;
1135 delete S_i; S_i =
nullptr;
1136 delete S; S=
nullptr;
1137 delete y_r; y_r=
nullptr;
1138 delete y_i; y_i=
nullptr;
1139 delete y; y=
nullptr;
1141 if (P) {
delete P; } P=
nullptr;
1142 if (R) {
delete R; } R=
nullptr;
1148 delete pS_e_r; pS_e_r=
nullptr;
1149 delete pS_e_i; pS_e_i=
nullptr;
1150 delete pS_r; pS_r=
nullptr;
1151 delete pS_i; pS_i=
nullptr;
1152 for (
int i = 0; i<rblocks; i++)
1154 delete ess_tdofs[i];
1156 delete pP; pP =
nullptr;
1160 for (
int i=0; i<lmat.Size(); i++)
1162 delete lmat[i]; lmat[i] =
nullptr;
1163 delete lvec[i]; lvec[i] =
nullptr;
1166 for (
int i = 0; i<tr_fes.Size(); i++)
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 PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
T & Last()
Return the last element in the array.
void MultTranspose(const Vector &x, Vector &y) const override
MatrixTranspose-Vector Multiplication y = A'*x.
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....
void SetBlock(int i, int j, SparseMatrix *mat)
Set A(i,j) = mat.
void Mult(const Vector &x, Vector &y) const override
Matrix-Vector Multiplication y = A*x.
int NumColBlocks() const
Return the number of column blocks.
int IsZeroBlock(int i, int j) const
Check if block (i,j) is a zero block.
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...
SparseMatrix & GetBlock(int i, int j)
Return a reference to block (i,j). Reference may be invalid if Aij(i,j) == NULL.
void AddMult(const Vector &x, Vector &y, const real_t val=1.) const override
Matrix-Vector Multiplication y = y + val*A*x.
int owns_blocks
If owns_blocks the SparseMatrix objects Aij will be deallocated.
void Finalize(int skip_zeros=1) override
Finalize all the submatrices.
int NumRowBlocks() const
Return the number of row blocks.
A class to handle Block systems in a matrix-free implementation.
void Mult(const Vector &x, Vector &y) const override
Operator application.
void SetBlock(int iRow, int iCol, Operator *op, real_t c=1.0)
Add a block op in the block-entry (iblock, jblock).
Operator & GetBlock(int i, int j)
Return a reference to block i,j.
void MultTranspose(const Vector &x, Vector &y) const override
Action of the transpose operator.
A class to handle Vectors in a block fashion.
Vector & GetBlock(int i)
Get the i-th vector in the block.
void EliminateReducedTrueDofs(const Array< int > &ess_rtdof_list, Matrix::DiagonalPolicy dpolicy)
Eliminate the given reduced true dofs from the Schur complement matrix S.
ComplexBlockStaticCondensation(Array< FiniteElementSpace * > &fes_)
void ParallelAssemble(BlockMatrix *m_r, BlockMatrix *m_i)
void Finalize(int skip_zeros=0)
Finalize the construction of the Schur complement matrix.
void AssembleReducedSystem(int el, ComplexDenseMatrix &elmat, Vector &elvect_r, Vector &elvect_i)
void FormSystemMatrix(Operator::DiagonalPolicy diag_policy)
void SetEssentialTrueDofs(const Array< int > &ess_tdof_list)
Determine and save internally essential reduced true dofs.
void ComputeSolution(const Vector &sc_sol, Vector &sol) const
~ComplexBlockStaticCondensation()
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....
void ReduceSolution(const Vector &sol, Vector &sc_sol) const
Specialization of the ComplexOperator built from a pair of Dense Matrices. The purpose of this specia...
DenseMatrix & imag() override
DenseMatrix & real() override
Real or imaginary part accessor methods.
Data type dense matrix using column-major storage.
void GetSubMatrix(const Array< int > &idx, DenseMatrix &A) const
@ DISCONTINUOUS
Field is discontinuous across element interfaces.
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...
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
Wrapper for hypre's ParCSR matrix class.
void EliminateRows(const Array< int > &rows)
Eliminate rows from the diagonal and off-diagonal blocks of the matrix.
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
HypreParMatrix * EliminateCols(const Array< int > &cols)
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
void GetElementFaces(int i, Array< int > &faces, Array< int > &ori) const
Return the indices and the orientations of all faces of element i.
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
@ DIAG_ZERO
Set the diagonal value to zero.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Abstract parallel finite element space.
HYPRE_BigInt GlobalVSize() const
HYPRE_BigInt * GetDofOffsets() const
Class for parallel meshes.
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void Neg()
(*this) = -(*this)
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...
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
void SetSubVectorComplement(const Array< int > &dofs, const real_t val)
Set all vector entries NOT in the dofs Array to the given val.
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.
const int * ess_tdof_list
int GetVDim(const FieldDescriptor &f)
Get the vdim of a field descriptor.
int GetTrueVSize(const FieldDescriptor &f)
Get the true dof size of a field descriptor.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void TransformDual(const DofTransformation &ran_dof_trans, const DofTransformation &dom_dof_trans, DenseMatrix &elmat)
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
real_t sol(const Vector &x)