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.
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.
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)