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 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>();
121void 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();
151void 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);
185void 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();
264void 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);
300 vdofs.Append(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];
316void 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);
350 dofs.Append(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];
367ComplexDenseMatrix * 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;
491 MFEM_ABORT(
"ComplexBlockStaticCondensation::AssembleReducedSystem: "
492 "dim > 3 not supported");
494 int numfaces = faces.
Size();
497 for (
int i = 0; i<tr_fes.Size(); i++)
499 if (!tr_fes[i]) {
continue; }
505 for (
int k = 0; k < numfaces; k++)
507 int iface = faces[k];
508 tr_fes[i]->GetFaceVDofs(iface, face_vdofs);
509 vdofs_i.
Append(face_vdofs);
514 tr_fes[i]->GetElementVDofs(el, vdofs_i, doftrans_i);
517 for (
int j = 0; j<tr_fes.Size(); j++)
519 if (!tr_fes[j]) {
continue; }
526 for (
int k = 0; k < numfaces; k++)
528 int iface = faces[k];
529 tr_fes[j]->GetFaceVDofs(iface, face_vdofs);
530 vdofs_j.
Append(face_vdofs);
535 tr_fes[j]->GetElementVDofs(el, vdofs_j, doftrans_j);
540 offsets[j],offsets[j+1], Ae_r);
542 offsets[j],offsets[j+1], Ae_i);
551 Vector vec1_r(*rvecptr_real, offsets[i], offsets[i+1]-offsets[i]);
552 Vector vec1_i(*rvecptr_imag, offsets[i], offsets[i+1]-offsets[i]);
560 if (int_idx.
Size()!=0) {
delete rmat; }
563void ComplexBlockStaticCondensation::BuildProlongation()
570 for (
int i = 0; i<nblocks; i++)
572 if (!tr_fes[i]) {
continue; }
573 const SparseMatrix *P_ = tr_fes[i]->GetConformingProlongation();
576 const SparseMatrix *R_ = tr_fes[i]->GetRestrictionMatrix();
577 P->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(P_));
578 R->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(R_));
585void ComplexBlockStaticCondensation::BuildParallelProlongation()
587 MFEM_VERIFY(parallel,
"BuildParallelProlongation: wrong code path");
588 pP =
new BlockOperator(rdof_offsets, rtdof_offsets);
589 R =
new BlockMatrix(rtdof_offsets, rdof_offsets);
593 for (
int i = 0; i<nblocks; i++)
595 if (!tr_fes[i]) {
continue; }
596 const HypreParMatrix *P_ =
597 dynamic_cast<ParFiniteElementSpace *
>(tr_fes[i])->Dof_TrueDof_Matrix();
600 const SparseMatrix *R_ = tr_fes[i]->GetRestrictionMatrix();
601 pP->
SetBlock(skip,skip,
const_cast<HypreParMatrix*
>(P_));
602 R->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(R_));
612 if (!pP) { BuildParallelProlongation(); }
629 for (
int i = 0; i<nblocks; i++)
631 if (!tr_fes[i]) {
continue; }
635 for (
int j = 0; j<nblocks; j++)
637 if (!tr_fes[j]) {
continue; }
639 if (skip_i == skip_j)
644 PtAP_r =
RAP(A_r,Pi);
651 PtAP_i =
RAP(A_i,Pi);
663 PtAP_r =
RAP(Pi,A_r,Pj);
671 PtAP_i =
RAP(Pi,A_i,Pj);
677 pS_r->
SetBlock(skip_i,skip_j,PtAP_r);
678 pS_i->
SetBlock(skip_i,skip_j,PtAP_i);
688void ComplexBlockStaticCondensation::ConformingAssemble(
int skip_zeros)
691 if (!P) { BuildProlongation(); }
700 BlockMatrix *PtAe_r =
mfem::Mult(*Pt, *S_e_r);
701 BlockMatrix *PtAe_i =
mfem::Mult(*Pt, *S_e_i);
715 BlockMatrix *PtAeP_r =
mfem::Mult(*S_e_r, *P);
716 BlockMatrix *PtAeP_i =
mfem::Mult(*S_e_i, *P);
721 width = 2*S_r->
Width();
746 bool conforming =
true;
747 for (
int i = 0; i<nblocks; i++)
749 if (!tr_fes[i]) {
continue; }
750 const SparseMatrix *P_ = tr_fes[i]->GetConformingProlongation();
757 if (!conforming) { ConformingAssemble(0); }
758 const int remove_zeros = 0;
766 FillEssTdofLists(ess_rtdof_list);
769 const int remove_zeros = 0;
772 delete S_r; S_r=
nullptr;
773 delete S_i; S_i=
nullptr;
774 delete S_e_r; S_e_r =
nullptr;
775 delete S_e_i; S_e_i =
nullptr;
781void ComplexBlockStaticCondensation::ConvertMarkerToReducedTrueDofs(
791 for (
int i = 0; i<nblocks; i++)
793 tdof_marker0.
MakeRef(&tdof_marker[tdof_offsets[i]],
794 tdof_offsets[i+1]-tdof_offsets[i]);
795 const SparseMatrix * R_ = fes[i]->GetRestrictionMatrix();
798 dof_marker0.
MakeRef(tdof_marker0);
802 dof_marker0.
SetSize(fes[i]->GetVSize());
805 dof_marker.
Append(dof_marker0);
808 int rdofs = rdof_edof.
Size();
809 Array<int> rdof_marker(rdofs);
811 for (
int i = 0; i < rdofs; i++)
813 rdof_marker[i] = dof_marker[rdof_edof[i]];
817 Array<int> rtdof_marker0;
818 Array<int> rdof_marker0;
820 for (
int i = 0; i<nblocks; i++)
822 if (!tr_fes[i]) {
continue; }
823 rdof_marker0.
MakeRef(&rdof_marker[rdof_offsets[k]],
824 rdof_offsets[k+1]-rdof_offsets[k]);
825 const SparseMatrix *tr_R = tr_fes[i]->GetRestrictionMatrix();
828 rtdof_marker0.MakeRef(rdof_marker0);
833 tr_R->BooleanMult(rdof_marker0, rtdof_marker0);
835 rtdof_marker.
Append(rtdof_marker0);
840void ComplexBlockStaticCondensation::FillEssTdofLists(
const Array<int> &
844 for (
int i = 0; i<ess_tdof_list.Size(); i++)
846 int tdof = ess_tdof_list[i];
847 for (j = 0; j < rblocks; j++)
849 if (rtdof_offsets[j+1] > tdof) {
break; }
851 ess_tdofs[j]->Append(tdof-rtdof_offsets[j]);
861 ConvertMarkerToReducedTrueDofs(tdof_marker, rtdof_marker);
870 MFEM_VERIFY(!parallel,
"EliminateReducedTrueDofs::Wrong code path");
876 offsets.
MakeRef( (P) ? rtdof_offsets : rdof_offsets);
884 int h = offsets[i+1] - offsets[i];
887 int w = offsets[j+1] - offsets[j];
901 MFEM_ASSERT(sol.
Size() == 2*dof_offsets.
Last(),
"'sol' has incorrect size");
902 const int nrdofs = rdof_offsets.Last();
910 sol_r_real.
MakeRef(sc_sol, 0, nrdofs);
911 sol_r_imag.
MakeRef(sc_sol, nrdofs, nrdofs);
918 for (
int i = 0; i < nrdofs; i++)
920 sol_r_real(i) = sol(rdof_edof[i]);
921 sol_r_imag(i) = sol(rdof_edof[i] + dof_offsets.
Last());
928 Vector sc_real(sc_sol, 0, n);
929 Vector sc_imag(sc_sol, n, n);
934 R->
Mult(blsol_r_real, sc_real);
935 R->
Mult(blsol_r_imag, sc_imag);
941 int copy_interior)
const
957 S_r->
PartMult(ess_rtdof_list,X_r,*y_r);
958 S_r->
PartMult(ess_rtdof_list,X_i,*y_i);
974 S_r->
PartMult(ess_rtdof_list,X_r,B_r);
975 S_r->
PartMult(ess_rtdof_list,X_i,B_i);
990 pS_e_r->
Mult(X_r,tmp); B_r-=tmp;
991 pS_e_i->
Mult(X_i,tmp); B_r+=tmp;
993 pS_e_i->
Mult(X_r,tmp); B_i-=tmp;
994 pS_e_r->
Mult(X_i,tmp); B_i-=tmp;
996 for (
int j = 0; j<rblocks; j++)
998 if (!ess_tdofs[j]->Size()) {
continue; }
999 for (
int i = 0; i < ess_tdofs[j]->Size(); i++)
1001 int tdof = (*ess_tdofs[j])[i];
1002 int gdof = tdof + rtdof_offsets[j];
1003 B_r(gdof) = X_r(gdof);
1004 B_i(gdof) = X_i(gdof);
1021 const int nrdofs = rdof_offsets.Last();
1022 const int nrtdofs = rtdof_offsets.
Last();
1023 MFEM_VERIFY(sc_sol.
Size() == 2*nrtdofs,
"'sc_sol' has incorrect size");
1037 Vector sc_real(
const_cast<Vector &
>(sc_sol),0, nrtdofs);
1038 Vector sc_imag(
const_cast<Vector &
>(sc_sol),nrtdofs, nrtdofs);
1041 P->
Mult(sc_real, sol_r_real);
1042 P->
Mult(sc_imag, sol_r_imag);
1048 Vector sc_real(
const_cast<Vector &
>(sc_sol),0, nrtdofs);
1049 Vector sc_imag(
const_cast<Vector &
>(sc_sol),nrtdofs, nrtdofs);
1052 pP->
Mult(sc_real, sol_r_real);
1053 pP->
Mult(sc_imag, sol_r_imag);
1061 if (rdof_offsets.Last() == dof_offsets.
Last())
1063 sol_real = sol_r_real;
1064 sol_imag = sol_r_imag;
1075 const int NE = mesh->
GetNE();
1083 for (
int iel = 0; iel < NE; iel++)
1085 GetReduceElementVDofs(iel, trace_vdofs);
1087 int n = trace_vdofs.
Size();
1095 int m = lmat[iel]->Height()/2;
1099 lmat[iel]->Mult(lsr,lsi);
1104 GetReduceElementIndicesAndOffsets(iel,tr_idx, int_idx, idx_offs);
1107 int k = (lmat[iel]->Width() + lmat[iel]->Height())/2;
1109 lsol_real.
MakeRef(lsol, 0, k);
1110 lsol_imag.
MakeRef(lsol, k, k);
1117 GetElementVDofs(iel, vdofs);
1127 delete S_e_r; S_e_r =
nullptr;
1128 delete S_e_i; S_e_i =
nullptr;
1129 delete S_r; S_r =
nullptr;
1130 delete S_i; S_i =
nullptr;
1131 delete S; S=
nullptr;
1132 delete y_r; y_r=
nullptr;
1133 delete y_i; y_i=
nullptr;
1134 delete y; y=
nullptr;
1136 if (P) {
delete P; } P=
nullptr;
1137 if (R) {
delete R; } R=
nullptr;
1143 delete pS_e_r; pS_e_r=
nullptr;
1144 delete pS_e_i; pS_e_i=
nullptr;
1145 delete pS_r; pS_r=
nullptr;
1146 delete pS_i; pS_i=
nullptr;
1147 for (
int i = 0; i<rblocks; i++)
1149 delete ess_tdofs[i];
1151 delete pP; pP =
nullptr;
1155 for (
int i=0; i<lmat.Size(); i++)
1157 delete lmat[i]; lmat[i] =
nullptr;
1158 delete lvec[i]; lvec[i] =
nullptr;
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.
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)