25   for (
int k = 0; k<nblocks; k++)
 
   27      if (!tr_fes[k]) { 
continue; }
 
   28      rdof_edof0.
SetSize(tr_fes[k]->GetVSize());
 
   29      for (
int i = 0; i < mesh->
GetNE(); i++)
 
   31         fes[k]->GetElementVDofs(i, vdofs);
 
   32         tr_fes[k]->GetElementVDofs(i, rvdofs);
 
   33         const int vdim = fes[k]->GetVDim();
 
   34         const int nsd = vdofs.
Size()/vdim;
 
   35         const int nsrd = rvdofs.
Size()/vdim;
 
   36         for (
int vd = 0; vd < vdim; vd++)
 
   38            for (
int j = 0; j < nsrd; j++)
 
   40               int rvdof = rvdofs[j+nsrd*vd];
 
   41               int vdof = vdofs[j+nsd*vd];
 
   47               MFEM_ASSERT(vdof >= 0, 
"incompatible volume and trace FE spaces");
 
   48               rdof_edof0[rvdof] = vdof + dof_offsets[k];
 
   52      rdof_edof.
Append(rdof_edof0);
 
 
   71   tr_fes.SetSize(nblocks);
 
   72   mesh = fes[0]->GetMesh();
 
   75   const FiniteElementCollection * fec;
 
   76   for (
int i = 0; i < nblocks; i++)
 
   78      fec = fes[i]->FEColl();
 
   80         (
dynamic_cast<const H1_Trace_FECollection*
>(fec) ||
 
   81          dynamic_cast<const ND_Trace_FECollection*
>(fec) ||
 
   82          dynamic_cast<const RT_Trace_FECollection*
>(fec));
 
   86         pmesh = 
dynamic_cast<ParMesh *
>(mesh);
 
   88                     nullptr : (IsTraceSpace[i]) ? fes[i] :
 
   89                     new ParFiniteElementSpace(pmesh, fec->GetTraceCollection(), fes[i]->GetVDim(),
 
   90                                               fes[i]->GetOrdering());
 
   95                     nullptr : (IsTraceSpace[i]) ? fes[i] :
 
   96                     new FiniteElementSpace(mesh, fec->GetTraceCollection(), fes[i]->GetVDim(),
 
   97                                            fes[i]->GetOrdering());
 
  102                  nullptr : (IsTraceSpace[i]) ? fes[i] :
 
  103                  new FiniteElementSpace(mesh, fec->GetTraceCollection(), fes[i]->GetVDim(),
 
  104                                         fes[i]->GetOrdering());
 
  106      if (tr_fes[i]) { rblocks++; }
 
  110      ess_tdofs.SetSize(rblocks);
 
  111      for (
int i = 0; i<rblocks; i++)
 
  113         ess_tdofs[i] = 
new Array<int>();
 
  119void BlockStaticCondensation::ComputeOffsets()
 
  121   dof_offsets.
SetSize(nblocks+1);
 
  122   tdof_offsets.
SetSize(nblocks+1);
 
  126   rdof_offsets.
SetSize(rblocks+1);
 
  127   rtdof_offsets.
SetSize(rblocks+1);
 
  129   rtdof_offsets[0] = 0;
 
  132   for (
int i =0; i<nblocks; i++)
 
  134      dof_offsets[i+1] = fes[i]->GetVSize();
 
  135      tdof_offsets[i+1] = fes[i]->GetTrueVSize();
 
  138         rdof_offsets[j+1] = tr_fes[i]->GetVSize();
 
  139         rtdof_offsets[j+1] = tr_fes[i]->GetTrueVSize();
 
  150void BlockStaticCondensation::Init()
 
  152   lmat.SetSize(mesh->
GetNE());
 
  153   lvec.SetSize(mesh->
GetNE());
 
  154   for (
int i = 0; i < mesh->
GetNE(); i++)
 
  162   S = 
new BlockMatrix(rdof_offsets);
 
  167      int h = rdof_offsets[i+1] - rdof_offsets[i];
 
  170         int w = rdof_offsets[j+1] - rdof_offsets[j];
 
  171         S->
SetBlock(i,j,
new SparseMatrix(h, w));
 
  174   y = 
new BlockVector(rdof_offsets);
 
  178void BlockStaticCondensation::GetReducedElementIndicesAndOffsets(
int el,
 
  179                                                                 Array<int> & trace_ldofs,
 
  180                                                                 Array<int> & interior_ldofs,
 
  181                                                                 Array<int> & offsets)
 const 
  184   offsets.SetSize(tr_fes.Size()+1); offsets = 0;
 
  186   Array<int> faces, ori;
 
  201      MFEM_ABORT(
"BlockStaticCondensation::GetReducedElementIndicesAndOffsets: " 
  202                 "dim > 3 not supported");
 
  204   int numfaces = faces.Size();
 
  206   trace_ldofs.SetSize(0);
 
  207   interior_ldofs.SetSize(0);
 
  212   for (
int i = 0; i<tr_fes.Size(); i++)
 
  219         ndof = fes[i]->GetVDim()*fes[i]->GetFE(el)->GetDof();
 
  222      else if (IsTraceSpace[i])
 
  224         for (
int iface = 0; iface < numfaces; iface++)
 
  226            td += fes[i]->GetVDim()*fes[i]->GetFaceElement(faces[iface])->GetDof();
 
  232         Array<int> trace_dofs;
 
  233         ndof = fes[i]->GetVDim()*fes[i]->GetFE(el)->GetDof();
 
  234         tr_fes[i]->GetElementVDofs(el, trace_dofs);
 
  235         td = trace_dofs.Size(); 
 
  239      int_dofs.SetSize(ndof - td);
 
  240      for (
int j = 0; j<td; j++)
 
  242         tr_dofs[j] = skip + j;
 
  244      for (
int j = 0; j<ndof-td; j++)
 
  246         int_dofs[j] = skip + td + j;
 
  250      trace_ldofs.Append(tr_dofs);
 
  251      interior_ldofs.Append(int_dofs);
 
  253   offsets.PartialSum();
 
  257void BlockStaticCondensation::GetReducedElementVDofs(
int el,
 
  258                                                     Array<int> & rdofs)
 const 
  260   Array<int> faces, ori;
 
  276      MFEM_ABORT(
"BlockStaticCondensation::GetReducedElementVDofs: " 
  277                 "dim > 3 not supported");
 
  279   int numfaces = faces.Size();
 
  282   for (
int i = 0; i<tr_fes.Size(); i++)
 
  284      if (!tr_fes[i]) { 
continue; }
 
  288         Array<int> face_vdofs;
 
  289         for (
int k = 0; k < numfaces; k++)
 
  291            int iface = faces[k];
 
  292            tr_fes[i]->GetFaceVDofs(iface, face_vdofs);
 
  293            vdofs.Append(face_vdofs);
 
  298         tr_fes[i]->GetElementVDofs(el, vdofs);
 
  300      for (
int j=0; j<vdofs.Size(); j++)
 
  302         vdofs[j] = (vdofs[j]>=0) ? vdofs[j]+rdof_offsets[skip] :
 
  303                    vdofs[j]-rdof_offsets[skip];
 
  310void BlockStaticCondensation::GetElementVDofs(
int el, Array<int> & vdofs)
 const 
  312   Array<int> faces, ori;
 
  328      MFEM_ABORT(
"BlockStaticCondensation::GetElementVDofs: " 
  329                 "dim > 3 not supported");
 
  331   int numfaces = faces.Size();
 
  333   for (
int i = 0; i<tr_fes.Size(); i++)
 
  338         Array<int> face_vdofs;
 
  339         for (
int k = 0; k < numfaces; k++)
 
  341            int iface = faces[k];
 
  342            fes[i]->GetFaceVDofs(iface, face_vdofs);
 
  343            dofs.Append(face_vdofs);
 
  348         fes[i]->GetElementVDofs(el, dofs);
 
  350      for (
int j=0; j<dofs.Size(); j++)
 
  352         dofs[j] = (dofs[j]>=0) ? dofs[j]+dof_offsets[i] :
 
  353                   dofs[j]-dof_offsets[i];
 
  360void BlockStaticCondensation::GetLocalSchurComplement(
int el,
 
  361                                                      const Array<int> & tr_idx,
 
  362                                                      const Array<int> & int_idx,
 
  363                                                      const DenseMatrix & elmat,
 
  364                                                      const Vector & elvect,
 
  368   int rdofs = tr_idx.Size();
 
  369   int idofs = int_idx.Size();
 
  370   MFEM_VERIFY(idofs != 0, 
"Number of interior dofs is zero");
 
  371   MFEM_VERIFY(rdofs != 0, 
"Number of interface dofs is zero");
 
  374   rvect.SetSize(rdofs);
 
  376   DenseMatrix A_tt, A_ti, A_it, A_ii;
 
  379   elmat.GetSubMatrix(tr_idx,A_tt);
 
  380   elmat.GetSubMatrix(tr_idx,int_idx, A_ti);
 
  381   elmat.GetSubMatrix(int_idx, tr_idx, A_it);
 
  382   elmat.GetSubMatrix(int_idx, A_ii);
 
  384   elvect.GetSubVector(tr_idx, y_t);
 
  385   elvect.GetSubVector(int_idx, y_i);
 
  387   DenseMatrixInverse lu(A_ii);
 
  389   lmat[el] = 
new DenseMatrix(idofs,rdofs);
 
  390   lvec[el] = 
new Vector(idofs);
 
  392   lu.Mult(A_it,*lmat[el]);
 
  393   lu.Mult(y_i,*lvec[el]);
 
  402   A_ti.Mult(*lvec[el], rvect);
 
  416   GetReducedElementIndicesAndOffsets(el, tr_idx,int_idx, offsets);
 
  421   if (int_idx.
Size()!=0)
 
  423      GetLocalSchurComplement(el,tr_idx,int_idx, elmat, elvect, rmat, rvec);
 
  452      MFEM_ABORT(
"BlockStaticCondensation::AssembleReducedSystem: " 
  453                 "dim > 3 not supported");
 
  455   int numfaces = faces.
Size();
 
  458   for (
int i = 0; i<tr_fes.Size(); i++)
 
  460      if (!tr_fes[i]) { 
continue; }
 
  462      doftrans_i = 
nullptr;
 
  466         for (
int k = 0; k < numfaces; k++)
 
  468            int iface = faces[k];
 
  469            tr_fes[i]->GetFaceVDofs(iface, face_vdofs);
 
  470            vdofs_i.
Append(face_vdofs);
 
  475         doftrans_i = tr_fes[i]->GetElementVDofs(el, vdofs_i);
 
  478      for (
int j = 0; j<tr_fes.Size(); j++)
 
  480         if (!tr_fes[j]) { 
continue; }
 
  482         doftrans_j = 
nullptr;
 
  487            for (
int k = 0; k < numfaces; k++)
 
  489               int iface = faces[k];
 
  490               tr_fes[j]->GetFaceVDofs(iface, face_vdofs);
 
  491               vdofs_j.
Append(face_vdofs);
 
  496            doftrans_j = tr_fes[j]->GetElementVDofs(el, vdofs_j);
 
  501                               offsets[j],offsets[j+1], Ae);
 
  502         if (doftrans_i || doftrans_j)
 
  515                          offsets[i+1]-offsets[i]);
 
 
  525void BlockStaticCondensation::BuildProlongation()
 
  532   for (
int i = 0; i<nblocks; i++)
 
  534      if (!tr_fes[i]) { 
continue; }
 
  535      const SparseMatrix *P_ = tr_fes[i]->GetConformingProlongation();
 
  538         const SparseMatrix *R_ = tr_fes[i]->GetRestrictionMatrix();
 
  539         P->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(P_));
 
  540         R->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(R_));
 
  547void BlockStaticCondensation::BuildParallelProlongation()
 
  549   MFEM_VERIFY(parallel, 
"BuildParallelProlongation: wrong code path");
 
  550   pP = 
new BlockOperator(rdof_offsets, rtdof_offsets);
 
  551   R = 
new BlockMatrix(rtdof_offsets, rdof_offsets);
 
  555   for (
int i = 0; i<nblocks; i++)
 
  557      if (!tr_fes[i]) { 
continue; }
 
  558      const HypreParMatrix *P_ =
 
  559         dynamic_cast<ParFiniteElementSpace *
>(tr_fes[i])->Dof_TrueDof_Matrix();
 
  562         const SparseMatrix *R_ = tr_fes[i]->GetRestrictionMatrix();
 
  563         pP->
SetBlock(skip,skip,
const_cast<HypreParMatrix*
>(P_));
 
  564         R->
SetBlock(skip,skip,
const_cast<SparseMatrix*
>(R_));
 
  572   if (!pP) { BuildParallelProlongation(); }
 
  583   for (
int i = 0; i<nblocks; i++)
 
  585      if (!tr_fes[i]) { 
continue; }
 
  589      for (
int j = 0; j<nblocks; j++)
 
  591         if (!tr_fes[j]) { 
continue; }
 
  593         if (skip_i == skip_j)
 
 
  624void BlockStaticCondensation::ConformingAssemble(
int skip_zeros)
 
  627   if (!P) { BuildProlongation(); }
 
  654   if (S_e) { S_e->
Finalize(skip_zeros); }
 
 
  664         bool conforming = 
true;
 
  665         for (
int i = 0; i<nblocks; i++)
 
  667            if (!tr_fes[i]) { 
continue; }
 
  668            const SparseMatrix *P_ = tr_fes[i]->GetConformingProlongation();
 
  675         if (!conforming) { ConformingAssemble(0); }
 
  676         const int remove_zeros = 0;
 
  684      FillEssTdofLists(ess_rtdof_list);
 
  687         const int remove_zeros = 0;
 
  691         delete S_e; S_e = 
nullptr;
 
 
  698void BlockStaticCondensation::ConvertMarkerToReducedTrueDofs(
 
  707   int * data = tdof_marker.
GetData();
 
  708   for (
int i = 0; i<nblocks; i++)
 
  710      tdof_marker0.
MakeRef(&data[tdof_offsets[i]],tdof_offsets[i+1]-tdof_offsets[i]);
 
  711      const SparseMatrix * R_ = fes[i]->GetRestrictionMatrix();
 
  714         dof_marker0.
MakeRef(tdof_marker0);
 
  718         dof_marker0.
SetSize(fes[i]->GetVSize());
 
  721      dof_marker.
Append(dof_marker0);
 
  724   int rdofs = rdof_edof.
Size();
 
  725   Array<int> rdof_marker(rdofs);
 
  727   for (
int i = 0; i < rdofs; i++)
 
  729      rdof_marker[i] = dof_marker[rdof_edof[i]];
 
  733   Array<int> rtdof_marker0;
 
  734   Array<int> rdof_marker0;
 
  735   int * rdata = rdof_marker.
GetData();
 
  737   for (
int i = 0; i<nblocks; i++)
 
  739      if (!tr_fes[i]) { 
continue; }
 
  740      rdof_marker0.MakeRef(&rdata[rdof_offsets[k]],rdof_offsets[k+1]-rdof_offsets[k]);
 
  741      const SparseMatrix *tr_R = tr_fes[i]->GetRestrictionMatrix();
 
  744         rtdof_marker0.MakeRef(rdof_marker0);
 
  748         rtdof_marker0.SetSize(tr_fes[i]->GetTrueVSize());
 
  749         tr_R->BooleanMult(rdof_marker0, rtdof_marker0);
 
  751      rtdof_marker.
Append(rtdof_marker0);
 
  756void BlockStaticCondensation::FillEssTdofLists(
const Array<int> & ess_tdof_list)
 
  759   for (
int i = 0; i<ess_tdof_list.Size(); i++)
 
  761      int tdof = ess_tdof_list[i];
 
  762      for (j = 0; j < rblocks; j++)
 
  764         if (rtdof_offsets[j+1] > tdof) { 
break; }
 
  766      ess_tdofs[j]->Append(tdof-rtdof_offsets[j]);
 
  776   ConvertMarkerToReducedTrueDofs(tdof_marker, rtdof_marker);
 
 
  784   MFEM_VERIFY(!parallel, 
"EliminateReducedTrueDofs::Wrong Code path");
 
  790      offsets.
MakeRef( (P) ? rtdof_offsets : rdof_offsets);
 
  796         int h = offsets[i+1] - offsets[i];
 
  799            int w = offsets[j+1] - offsets[j];
 
 
  810   MFEM_ASSERT(sol.
Size() == dof_offsets.
Last(), 
"'sol' has incorrect size");
 
  811   const int nrdofs = rdof_offsets.Last();
 
  822   for (
int i = 0; i < nrdofs; i++)
 
  824      sol_r(i) = sol(rdof_edof[i]);
 
  831      R->
Mult(blsol_r, sc_sol);
 
 
  837                                           int copy_interior)
 const 
  865      for (
int j = 0; j<rblocks; j++)
 
  867         if (!ess_tdofs[j]->Size()) { 
continue; }
 
  871         for (
int i = 0; i < ess_tdofs[j]->Size(); i++)
 
  873            int tdof = (*ess_tdofs[j])[i];
 
  874            int gdof = tdof + rtdof_offsets[j];
 
  875            B(gdof) = diag(tdof)*X(gdof);
 
 
  888   const int nrdofs = rdof_offsets.Last();
 
  889   const int nrtdofs = rtdof_offsets.
Last();
 
  890   MFEM_VERIFY(sc_sol.
Size() == nrtdofs, 
"'sc_sol' has incorrect size");
 
  902         P->
Mult(sc_sol, sol_r);
 
  909      pP->
Mult(sc_sol, sol_r);
 
  913   if (rdof_offsets.Last() == dof_offsets.
Last())
 
  925   const int NE = mesh->
GetNE();
 
  931   for (
int iel = 0; iel < NE; iel++)
 
  933      lsol.
SetSize(lmat[iel]->Width() + lmat[iel]->Height());
 
  934      GetReducedElementVDofs(iel, trace_vdofs);
 
  940      lsi.
SetSize(lmat[iel]->Height());
 
  941      lmat[iel]->Mult(lsr,lsi);
 
  946      GetReducedElementIndicesAndOffsets(iel,tr_idx, int_idx, idx_offs);
 
  951      GetElementVDofs(iel, vdofs);
 
 
  960   delete S_e; S_e = 
nullptr;
 
  964   if (P) { 
delete P; } P=
nullptr;
 
  965   if (R) { 
delete R; } R=
nullptr;
 
  970      delete pS; pS=
nullptr;
 
  971      delete pS_e; pS_e=
nullptr;
 
  972      for (
int i = 0; i<rblocks; i++)
 
  976      delete pP; pP=
nullptr;
 
  980   for (
int i=0; i<lmat.Size(); i++)
 
  982      delete lmat[i]; lmat[i] = 
nullptr;
 
  983      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 * GetData()
Returns the data.
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.
~BlockStaticCondensation()
void FormSystemMatrix(Operator::DiagonalPolicy diag_policy)
void EliminateReducedTrueDofs(const Array< int > &ess_rtdof_list, Matrix::DiagonalPolicy dpolicy)
Eliminate the given reduced true dofs from the Schur complement matrix S.
void SetEssentialTrueDofs(const Array< int > &ess_tdof_list)
Determine and save internally essential reduced true dofs.
BlockStaticCondensation(Array< FiniteElementSpace * > &fes_)
void ParallelAssemble(BlockMatrix *m)
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 ComputeSolution(const Vector &sc_sol, Vector &sol) const
void ReduceSolution(const Vector &sol, Vector &sc_sol) const
void Finalize(int skip_zeros=0)
Finalize the construction of the Schur complement matrix.
void AssembleReducedSystem(int el, DenseMatrix &elmat, Vector &elvect)
A class to handle Vectors in a block fashion.
Vector & GetBlock(int i)
Get the i-th vector in the block.
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 GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
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.
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 SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
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.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
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)