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;
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; }
570void 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_));
592void 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);
695void 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;
788void 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);
847void 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];
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);
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");
1044 Vector sc_real(
const_cast<Vector &
>(sc_sol),0, nrtdofs);
1045 Vector sc_imag(
const_cast<Vector &
>(sc_sol),nrtdofs, nrtdofs);
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);
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();
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);
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 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.
virtual void AddMult(const Vector &x, Vector &y, const real_t val=1.) const
Matrix-Vector Multiplication y = y + val*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.
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.
int owns_blocks
If owns_blocks the SparseMatrix objects Aij will be deallocated.
virtual void Finalize(int skip_zeros=1)
Finalize all the submatrices.
virtual void Mult(const Vector &x, Vector &y) const
Matrix-Vector Multiplication y = A*x.
virtual void MultTranspose(const Vector &x, Vector &y) const
MatrixTranspose-Vector Multiplication y = A'*x.
int NumRowBlocks() const
Return the number of row blocks.
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).
Operator & GetBlock(int i, int j)
Return a reference to block i,j.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
virtual void MultTranspose(const Vector &x, Vector &y) const
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...
virtual DenseMatrix & real()
Real or imaginary part accessor methods.
virtual DenseMatrix & imag()
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.
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)