26static int GetNFacesPerElement(
const Mesh &mesh)
 
   33      default: MFEM_ABORT(
"Invalid dimension.");
 
   40   const int ne = mesh.
GetNE();
 
   44   const int n_faces_per_el = GetNFacesPerElement(mesh);
 
   47   Vector emat(m * n * 2 * nf);
 
   60   const auto d_emat = 
Reshape(emat.
Read(), m, n, 2, nf);
 
   61   const int *d_dof_map = dof_map.
Read();
 
   72      const int i_lex = idx % m;
 
   73      const int j = (idx / m) % n;
 
   74      const int ie = (idx / m / n) % 2;
 
   75      const int f = idx / m / n / 2;
 
   77      const int e  = d_face_to_el(0, ie, 
f);
 
   78      const int fi = d_face_to_el(1, ie, 
f);
 
   84         const int i_s = d_dof_map[i_lex];
 
   85         const int i = (i_s >= 0) ? i_s : -1 - i_s;
 
   86         d_Ct_mat(i, j, fi, e) = d_emat(i_lex, j, ie, 
f);
 
 
   93template <
typename T, 
int SIZE>
 
   97   MFEM_HOST_DEVICE 
inline operator T *() 
const { 
return (T*)data; }
 
  101struct LocalMemory<T,0>
 
  103   MFEM_HOST_DEVICE 
inline operator T *() 
const { 
return (T*)
nullptr; }
 
  107template <
int MID, 
int MBD>
 
  111   const int ne = mesh.
GetNE();
 
  112   const int n_faces_per_el = GetNFacesPerElement(mesh);
 
  117   auto d_AhatInvCt = 
Reshape(AhatInvCt_mat.
Write(), m, n, n_faces_per_el, ne);
 
  123      MFEM_VERIFY(nidofs <= MID, 
"");
 
  124      MFEM_VERIFY(nbdofs <= MBD, 
"");
 
  150      static constexpr bool GLOBAL = (MID == 0 && MBD == 0);
 
  152      using internal::LocalMemory;
 
  156         constexpr int MD1D = DofQuadLimits::HDIV_MAX_D1D;
 
  157         constexpr int MAX_DOFS = 3*MD1D*(MD1D-1)*(MD1D-1);
 
  158         constexpr int MAX_IDOFS = (MID == 0 && MBD == 0) ? MAX_DOFS : MID;
 
  159         constexpr int MAX_BDOFS = (MID == 0 && MBD == 0) ? MAX_DOFS : MBD;
 
  161         LocalMemory<int,MAX_IDOFS> idofs_loc;
 
  162         LocalMemory<int,MAX_BDOFS> bdofs_loc;
 
  163         for (
int i = 0; i < nidofs; i++) { idofs_loc[i] = d_idofs[i]; }
 
  164         for (
int i = 0; i < nbdofs; i++) { bdofs_loc[i] = d_bdofs[i]; }
 
  166         LocalMemory<int,MAX_BDOFS> essdofs_loc;
 
  169         for (
int i = 0; i < nbdofs; i++)
 
  171            const int dof_idx = bdofs_loc[i];
 
  172            if (d_hat_dof_marker(dof_idx, e) == 
ESSENTIAL)
 
  174               essdofs_loc[nessdofs] = dof_idx;
 
  179               bdofs_loc[nbfdofs] = dof_idx;
 
  184         LocalMemory<real_t, MID*MID> A_ii_loc;
 
  185         LocalMemory<real_t, MBD*MID> A_bi_loc;
 
  186         LocalMemory<real_t, MID*MBD> A_ib_loc;
 
  187         LocalMemory<real_t, MBD*MBD> A_bb_loc;
 
  189         DeviceMatrix A_ii(GLOBAL ? &d_A_ii(0,0,e) : A_ii_loc, nidofs, nidofs);
 
  190         DeviceMatrix A_ib(GLOBAL ? &d_A_ib_all(0,e) : A_ib_loc, nidofs, nbfdofs);
 
  191         DeviceMatrix A_bi(GLOBAL ? &d_A_bi_all(0,e) : A_bi_loc, nbfdofs, nidofs);
 
  192         DeviceMatrix A_bb(GLOBAL ? &d_A_bb_all(0,e) : A_bb_loc, nbfdofs, nbfdofs);
 
  194         for (
int j = 0; j < nidofs; j++)
 
  196            const int jj = idofs_loc[j];
 
  197            for (
int i = 0; i < nidofs; i++)
 
  199               A_ii(i,j) = d_Ahat(idofs_loc[i], jj, e);
 
  201            for (
int i = 0; i < nbfdofs; i++)
 
  203               A_bi(i,j) = d_Ahat(bdofs_loc[i], jj, e);
 
  206         for (
int j = 0; j < nbfdofs; j++)
 
  208            const int jj = bdofs_loc[j];
 
  209            for (
int i = 0; i < nidofs; i++)
 
  211               A_ib(i,j) = d_Ahat(idofs_loc[i], jj, e);
 
  213            for (
int i = 0; i < nbfdofs; i++)
 
  215               A_bb(i,j) = d_Ahat(bdofs_loc[i], jj, e);
 
  219         LocalMemory<int,MID> ipiv_ii_loc;
 
  220         LocalMemory<int,MBD> ipiv_bb_loc;
 
  222         auto ipiv_ii = GLOBAL ? &d_ipiv_ii(0,e) : ipiv_ii_loc;
 
  223         auto ipiv_bb = GLOBAL ? &d_ipiv_ii(0,e) : ipiv_bb_loc;
 
  229         for (
int f = 0; 
f < n_faces_per_el; ++
f)
 
  231            for (
int j = 0; j < n; ++j)
 
  233               LocalMemory<real_t,MAX_BDOFS> Sb_inv_Cb_t;
 
  234               for (
int i = 0; i < nbfdofs; ++i)
 
  236                  Sb_inv_Cb_t[i] = d_Ct_mat(bdofs_loc[i], j, 
f, e);
 
  239               for (
int i = 0; i < nbfdofs; ++i)
 
  241                  const int b_i = bdofs_loc[i];
 
  242                  d_AhatInvCt(b_i, j, 
f, e) = Sb_inv_Cb_t[i];
 
  244               for (
int i = 0; i < nidofs; ++i)
 
  246                  d_AhatInvCt(idofs_loc[i], j, 
f, e) = 0.0;
 
  248               for (
int i = 0; i < nessdofs; ++i)
 
  250                  d_AhatInvCt(essdofs_loc[i], j, 
f, e) = 0.0;
 
  260            DeviceMatrix d_A_bb(&d_A_bb_all(0,e), nbfdofs, nbfdofs);
 
  262            for (
int j = 0; j < nidofs; j++)
 
  264               d_ipiv_ii(j,e) = ipiv_ii[j];
 
  265               for (
int i = 0; i < nidofs; i++)
 
  267                  d_A_ii(i,j,e) = A_ii(i,j);
 
  269               for (
int i = 0; i < nbfdofs; i++)
 
  271                  d_A_bi(i,j) = A_bi(i,j);
 
  274            for (
int j = 0; j < nbfdofs; j++)
 
  276               d_ipiv_bb(j,e) = ipiv_bb[j];
 
  277               for (
int i = 0; i < nidofs; i++)
 
  279                  d_A_ib(i,j) = A_ib(i,j);
 
  281               for (
int i = 0; i < nbfdofs; i++)
 
  283                  d_A_bb(i,j) = A_bb(i,j);
 
 
  294   const int ne = mesh.
GetNE();
 
  295   const int n_faces_per_el = GetNFacesPerElement(mesh);
 
  317   const auto d_AhatInvCt =
 
  318      Reshape(AhatInvCt_mat.
Read(), m, n, n_faces_per_el, ne);
 
  321   const int n_face_connections = 2*n_faces_per_el - 1;
 
  322   Array<int> face_to_face(nf * n_face_connections);
 
  329   auto d_CAhatInvCt = 
Reshape(CAhatInvCt.
Write(), n, n, n_face_connections, nf);
 
  330   auto d_face_to_face = 
Reshape(face_to_face.
Write(), n_face_connections, nf);
 
  332   mfem::forall(n*n*n_face_connections*nf, [=] MFEM_HOST_DEVICE (
int i)
 
  334      d_CAhatInvCt[i] = 0.0;
 
  340      for (
int ei = 0; ei < 2; ++ei)
 
  342         const int e = d_face_to_el(0, ei, fi);
 
  343         if (e < 0 || e >= ne) { 
continue; }
 
  344         for (
int fj_i = 0; fj_i < n_faces_per_el; ++fj_i)
 
  346            const int fj = d_el_to_face(fj_i, e);
 
  348            if (fj < 0) { 
continue; }
 
  353            for (
int i = 0; i < idx; ++i)
 
  355               if (d_face_to_face(i, fi) == fj)
 
  364               d_face_to_face(idx, fi) = fj;
 
  370      for (; idx < n_face_connections; ++idx)
 
  372         d_face_to_face(idx, fi) = -1;
 
  376   mfem::forall(nf*n_face_connections, [=] MFEM_HOST_DEVICE (
int idx)
 
  378      const int idx_j = idx % n_face_connections;
 
  379      const int fi = idx / n_face_connections;
 
  381      const int fj = d_face_to_face(idx_j, fi);
 
  382      if (fj < 0) { 
return; }
 
  384      for (
int ei = 0; ei < 2; ++ei)
 
  386         const int e = d_face_to_el(0, ei, fi);
 
  387         if (e < 0 || e >= ne) { 
continue; }
 
  388         const int fi_i = d_face_to_el(1, ei, fi);
 
  391         for (
int ej = 0; ej < 2; ++ej)
 
  393            if (d_face_to_el(0, ej, fj) == e)
 
  395               fj_i = d_face_to_el(1, ej, fj);
 
  401            const real_t *Ct_i = &d_Ct(0, 0, fi_i, e);
 
  402            const real_t *AhatInvCt_i = &d_AhatInvCt(0, 0, fj_i, e);
 
  403            real_t *CAhatInvCt_i = &d_CAhatInvCt(0, 0, idx_j, fi);
 
  416   h.
H->OverrideSize(ncdofs, ncdofs);
 
  418   h.
H->GetMemoryI().New(ncdofs + 1, 
h.
H->GetMemoryI().GetMemoryType());
 
  421      int *I = 
h.
H->WriteI();
 
  423      mfem::forall(ncdofs, [=] MFEM_HOST_DEVICE (
int i) { I[i] = 0; });
 
  427         const int i = idx_i % n;
 
  428         const int fi = idx_i / n;
 
  429         const int ii = c_gather_map(i, fi);
 
  431         for (
int idx = 0; idx < n_face_connections; ++idx)
 
  433            const int fj = d_face_to_face(idx, fi);
 
  434            if (fj < 0) { 
break; }
 
  435            for (
int j = 0; j < n; ++j)
 
  437               if (d_CAhatInvCt(i, j, idx, fi) != 0)
 
  453      int *I = 
h.
H->HostReadWriteI();
 
  454      int empty_row_count = 0;
 
  455      for (
int i = 0; i < ncdofs; i++)
 
  457         if (I[i] == 0) { empty_row_count++; }
 
  459      empty_rows.
SetSize(empty_row_count);
 
  461      int empty_row_idx = 0;
 
  463      for (
int i = 0; i < ncdofs; i++)
 
  468            empty_rows[empty_row_idx] = i;
 
  478   const int nnz = 
h.
H->HostReadI()[ncdofs];
 
  479   h.
H->GetMemoryJ().New(nnz, 
h.
H->GetMemoryJ().GetMemoryType());
 
  480   h.
H->GetMemoryData().New(nnz, 
h.
H->GetMemoryData().GetMemoryType());
 
  483      int *I = 
h.
H->ReadWriteI();
 
  484      int *J = 
h.
H->WriteJ();
 
  489         const int i = idx_i % n;
 
  490         const int fi = idx_i / n;
 
  491         const int ii = c_gather_map[i + fi*n];
 
  492         for (
int idx = 0; idx < n_face_connections; ++idx)
 
  494            const int fj = d_face_to_face(idx, fi);
 
  495            if (fj < 0) { 
break; }
 
  496            for (
int j = 0; j < n; ++j)
 
  498               const real_t val = d_CAhatInvCt(i, j, idx, fi);
 
  502                  const int jj = c_gather_map(j, fj);
 
  511      const int *d_empty_rows = empty_rows.
Read();
 
  514         const int i = d_empty_rows[idx];
 
  524      int *I = 
h.
H->HostReadWriteI();
 
  525      for (
int i = ncdofs - 1; i > 0; --i)
 
  537      pP.ConvertFrom(c_pfes->Dof_TrueDof_Matrix());
 
  539                             c_pfes->GetDofOffsets(), 
h.
H.get());
 
 
  549   const int ne = mesh.
GetNE();
 
  554   const int n_faces_per_el = GetNFacesPerElement(mesh);
 
  561   face_restr->
Mult(x, x_evec);
 
  566   const auto d_x_evec = 
Reshape(x_evec.
Read(), n_c_dof_per_face, nf);
 
  569   mfem::forall(ne * n_hat_dof_per_el, [=] MFEM_HOST_DEVICE (
int idx)
 
  571      const int e = idx / n_hat_dof_per_el;
 
  572      const int i = idx % n_hat_dof_per_el;
 
  574      for (
int fi = 0; fi < n_faces_per_el; ++fi)
 
  576         const int f = d_el_to_face[e*n_faces_per_el + fi];
 
  577         if (
f < 0) { 
continue; }
 
  578         for (
int j = 0; j < n_c_dof_per_face; ++j)
 
  580            d_y(i, e) += d_Ct(i, j, fi, e)*d_x_evec(j, 
f);
 
 
  589   const int ne = mesh.
GetNE();
 
  594   const int n_faces_per_el = GetNFacesPerElement(mesh);
 
  604   auto d_x = 
Reshape(x.
Read(), n_hat_dof_per_el, ne);
 
  605   auto d_y_evec = 
Reshape(y_evec.
Write(), n_c_dof_per_face, nf);
 
  607   mfem::forall(nf * n_c_dof_per_face, [=] MFEM_HOST_DEVICE (
int idx)
 
  609      const int f = idx / n_c_dof_per_face;
 
  610      const int j = idx % n_c_dof_per_face;
 
  611      d_y_evec(j, 
f) = 0.0;
 
  612      for (
int el_i = 0; el_i < 2; ++el_i)
 
  614         const int e = d_face_to_el(0, el_i, 
f);
 
  615         const int fi = d_face_to_el(1, el_i, 
f);
 
  618         if (e >= ne) { 
continue; }
 
  620         for (
int i = 0; i < n_hat_dof_per_el; ++i)
 
  622            d_y_evec(j, 
f) += d_Ct(i, j, fi, e)*d_x(i, e);
 
 
  633   const int n = elmat.
Width();
 
  636   const int offset = el*n*n;
 
  639      d_Ahat[offset + i] += d_elmat[i];
 
 
  662      Ordering::DofsToVDofs<Ordering::byNODES>(n/vdim, vdim, lvdofs);
 
  663      MFEM_ASSERT(lvdofs.
Size() == elmat.
Height(), 
"internal error");
 
  668      for (
int i = 0; i < lvdofs.
Size(); i++)
 
  674   const int offset = el*n*n;
 
  676   for (
int j = 0; j < n; ++j)
 
  678      const int j_f = e2f[j];
 
  679      if (j_f < 0) { 
continue; }
 
  680      for (
int i = 0; i < n; ++i)
 
  682         const int i_f = e2f[i];
 
  683         if (i_f < 0) { 
continue; }
 
  684         Ahat[offset + i + j*n] += B(i_f, j_f);
 
 
  695      d_Ahat[i] += d_elmats[i];
 
 
  709   MFEM_VERIFY(
dim == 2 || 
dim == 3, 
"");
 
  717      MFEM_VERIFY(tbe != 
nullptr, 
"");
 
  720      const int n_faces_per_el = GetNFacesPerElement(mesh);
 
  723      for (
int f = 0; 
f < n_faces_per_el; ++
f)
 
  727         all_face_dofs.
Append(face_map);
 
  732      for (
int i = 0; i < all_face_dofs.
Size(); ++i)
 
  734         const int j_s = all_face_dofs[i];
 
  735         const int j = (j_s >= 0) ? j_s : -1 - j_s;
 
  736         const int j_nat_s = dof_map[j];
 
  737         const int j_nat = (j_nat_s >= 0) ? j_nat_s : -1 - j_nat_s;
 
  738         b_marker[j_nat] = 
true;
 
  741      for (
int i = 0; i < ndof_per_el; ++i)
 
  749   const int n_faces_per_el = GetNFacesPerElement(mesh);
 
  763         el_to_face[el1 * n_faces_per_el + fi1] = face_idx;
 
  769            el_to_face[el2 * n_faces_per_el + fi2] = face_idx;
 
  788         d_hat_offsets[i] = i*ndof_per_el;
 
  810         int *d_free_tdof_marker = free_tdof_marker.
Write();
 
  813            d_free_tdof_marker[i] = 1;
 
  815         const int n_ess_dofs = ess_tdof_list.
Size();
 
  816         const int *d_ess_tdof_list = ess_tdof_list.
Read();
 
  819            d_free_tdof_marker[d_ess_tdof_list[i]] = 0;
 
  836         free_vdofs_marker.
MakeRef(free_tdof_marker);
 
  839      free_vdofs_marker.
MakeRef(free_tdof_marker);
 
  847         const int *gather_map = R->GatherMap().Read();
 
  848         const int *d_free_vdofs_marker = free_vdofs_marker.
Read();
 
  850                                       ndof_per_face, n_faces_per_el, ne);
 
  859            const int j_s = gather_map[i];
 
  860            const int j = (j_s >= 0) ? j_s : -1 - j_s;
 
  861            if (d_free_vdofs_marker[j])
 
  863               const int i_loc = i % ndof_per_el;
 
  864               const int e = i / ndof_per_el;
 
  866               for (
int f = 0; 
f < n_faces_per_el; ++
f)
 
  868                  for (
int k = 0; k < ndof_per_face; ++k)
 
  870                     if (d_Ct_mat(i_loc, k, 
f, e) != 0.0)
 
  891      const int *d_offsets = R->Offsets().Read();
 
  892      const int *d_indices = R->Indices().Read();
 
  896         d_hat_dof_gather_map[i] = -1;
 
  900         const int offset = d_offsets[i];
 
  901         const int j_s = d_indices[offset];
 
  902         const int hat_dof_index = (j_s >= 0) ? j_s : -1 - j_s;
 
  905         d_hat_dof_gather_map[hat_dof_index] = (j_s >= 0) ? i : (-2 - i);
 
 
  940      if (d_hat_dof_marker[i] == 
ESSENTIAL) { 
return; }
 
  942      const int j_s = gather_map[i];
 
  943      const int sgn = (j_s >= 0) ? 1 : -1;
 
  944      const int j = (j_s >= 0) ? j_s : -1 - j_s;
 
  946      d_lvec[j] = sgn*d_evec[i];
 
 
  974      const int j_s = d_hat_dof_gather_map[i];
 
  981         const int sgn = (j_s >= 0) ? 1 : -1;
 
  982         const int j = (j_s >= 0) ? j_s : -2 - j_s;
 
  983         d_b_hat[i] = sgn*d_b_lvec[j];
 
 
 1018      constexpr int MD1D = DofQuadLimits::HDIV_MAX_D1D;
 
 1019      constexpr int MAX_DOFS = 3*MD1D*(MD1D-1)*(MD1D-1);
 
 1020      internal::LocalMemory<int,MAX_DOFS> bdofs_loc;
 
 1023      for (
int i = 0; i < nbdofs; i++)
 
 1025         const int dof_idx = d_bdofs[i];
 
 1026         if (d_hat_dof_marker(dof_idx, e) != 
ESSENTIAL)
 
 1028            bdofs_loc[nbfdofs] = dof_idx;
 
 1033      for (
int i = 0; i < nidofs; ++i)
 
 1035         d_ivals(i, e) = d_x(d_idofs[i], e);
 
 1037      for (
int i = 0; i < nbfdofs; ++i)
 
 1039         d_bvals(i, e) = d_x(bdofs_loc[i], e);
 
 1046         kernels::LSolve(&d_A_ii(0,0,e), nidofs, &d_ipiv_ii(0,e), &d_ivals(0,e));
 
 1049            nidofs, nbfdofs, 1, &d_A_bi(0,e), &d_ivals(0,e), &d_bvals(0, e));
 
 1060            nbfdofs, nidofs, 1, &d_A_ib(0,e), &d_bvals(0,e), &d_ivals(0, e));
 
 1065      for (
int i = 0; i < nidofs; ++i)
 
 1067         d_x(d_idofs[i], e) = d_ivals(i, e);
 
 1069      for (
int i = 0; i < nbfdofs; ++i)
 
 1071         d_x(bdofs_loc[i], e) = d_bvals(i, e);
 
 
 1085         if (d_hat_dof_marker[i] == 
ESSENTIAL) { d_b_hat[i] = 0.0; }
 
 
 1115      P->
Mult(sol_r, sol_l);
 
 1128      if (d_hat_dof_marker[i] == 
ESSENTIAL) { d_tmp1[i] = 0.0; }
 
 
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
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 MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
int Append(const T &el)
Append element 'el' to array, resize if necessary.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
Data type dense matrix using column-major storage.
void AdjustDofDirection(Array< int > &dofs)
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
Rank 3 tensor (array of matrices)
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
A basic generic Tensor class, appropriate for use on the GPU.
Operator that converts FiniteElementSpace L-vectors to E-vectors.
const Array< int > & GatherMap() const
virtual MFEM_DEPRECATED int GetNFaces(int &nFaceVertices) const =0
virtual int GetNEdges() const =0
Base class for operators that extracts Face degrees of freedom.
void MultTranspose(const Vector &x, Vector &y) const override
Set the face degrees of freedom in the element degrees of freedom y to the values given in x.
virtual const Array< int > & GatherMap() const
Low-level access to the underlying gather map.
void Mult(const Vector &x, Vector &y) const override=0
Extract the face degrees of freedom from x into y.
void SubDofOrder(Geometry::Type Geom, int SDim, int Info, Array< int > &dofs) const
Get the local dofs for a given sub-manifold.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
static void AdjustVDofs(Array< int > &vdofs)
Remove the orientation information encoded into an array of dofs Some basis function types have a rel...
virtual const Operator * GetProlongationMatrix() const
virtual const Operator * GetRestrictionOperator() const
An abstract operator that performs the same action as GetRestrictionMatrix.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetNE() const
Returns number of elements in the mesh.
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
int GetVDim() const
Returns the vector dimension of the finite element space.
virtual const FaceRestriction * GetFaceRestriction(ElementDofOrdering f_ordering, FaceType, L2FaceValues mul=L2FaceValues::DoubleValued) const
Return an Operator that converts L-vectors to E-vectors on each face.
virtual void GetFaceMap(const int face_id, Array< int > &face_map) const
Return the mapping from lexicographic face DOFs to lexicographic element DOFs for the given local fac...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Vector Ct_mat
Constraint matrix (transposed) stored element-wise.
void ConstructC()
Construct the constraint matrix.
void Init(const Array< int > &ess_tdof_list)
Prepare for assembly; form the constraint matrix.
void FactorElementMatrices(Vector &AhatInvCt_mat)
void ReduceRHS(const Vector &b, Vector &b_r) const
Given a right-hand side on the original space, compute the corresponding right-hand side for the Lagr...
Array< int > hat_dof_gather_map
void ComputeSolution(const Vector &b, const Vector &sol_r, Vector &sol) const
Given Lagrange multipliers sol_r and the original right-hand side b, recover the solution sol on the ...
Array< DofType > hat_dof_marker
HybridizationExtension(class Hybridization &hybridization_)
Constructor.
Vector tmp2
Temporary vectors.
void ConstructH()
Form the Schur complement matrix .
void MultR(const Vector &b, Vector &b_hat) const
Apply the action of R mapping from "hat DOFs" to T-vector.
void MultC(const Vector &x, Vector &y) const
Compute the action of C x.
void MultAhatInv(Vector &x) const
Apply the elementwise A_hat^{-1}.
int num_hat_dofs
Number of Lagrange multipliers.
void AssembleMatrix(int el, const class DenseMatrix &elmat)
Assemble the element matrix A into the hybridized system matrix.
void MultCt(const Vector &x, Vector &y) const
Compute the action of C^t x.
class Hybridization & h
The associated Hybridization object.=.
void MultRt(const Vector &b, Vector &b_hat) const
Apply the action of R^t mapping into the "hat DOF" space.
void AssembleBdrMatrix(int bdr_el, const class DenseMatrix &elmat)
Assemble the boundary element matrix A into the hybridized system matrix.
void AssembleElementMatrices(const class DenseTensor &el_mats)
Invert and store the element matrices Ahat.
Auxiliary class Hybridization, used to implement BilinearForm hybridization.
FiniteElementSpace & c_fes
std::unique_ptr< SparseMatrix > H
The Schur complement system for the Lagrange multiplier.
FiniteElementSpace & fes
The finite element space.
std::unique_ptr< BilinearFormIntegrator > c_bfi
The constraint integrator.
Wrapper for hypre's ParCSR matrix class.
void BooleanMult(int alpha, const int *x, int beta, int *y)
The "Boolean" analog of y = alpha * A * x + beta * y, where elements in the sparsity pattern of the m...
bool Conforming() const
Return a bool indicating whether this mesh is conforming.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Geometry::Type GetElementGeometry(int i) const
virtual int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type, does not count master nonconforming face...
const Element * GetElement(int i) const
Return pointer to the i'th element object.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
FaceInformation GetFaceInformation(int f) const
void GetBdrElementAdjacentElement(int bdr_el, int &el, int &info) const
For the given boundary element, bdr_el, return its adjacent element and its info, i....
Pointer to an Operator of a specified type.
void MakePtAP(OperatorHandle &A, OperatorHandle &P)
Reset the OperatorHandle to hold the product P^t A P.
void MakeSquareBlockDiag(MPI_Comm comm, HYPRE_BigInt glob_size, HYPRE_BigInt *row_starts, SparseMatrix *diag)
Reset the OperatorHandle to hold a parallel square block-diagonal matrix using the currently set type...
Operator::Type Type() const
Get the currently set operator type id.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Abstract parallel finite element space.
const Array< int > & GetDofMap() const
Get an Array<int> that maps lexicographically ordered indices to the indices of the respective nodes/...
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
int Size() const
Returns the size of the vector.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
void SetSize(int s)
Resize the vector to size s.
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
MFEM_HOST_DEVICE void AddMultAtB(const int Aheight, const int Awidth, const int Bwidth, const TA *Adata, const TB *Bdata, TC *Cdata, const TB alpha, const TA beta)
Compute C = alpha*At*B + beta*C.
MFEM_HOST_DEVICE void LSolve(const real_t *data, const int m, const int *ipiv, real_t *x)
Assuming L.U = P.A factored matrix of size (m x m), compute X <- L^{-1} P X, for a vector X of length...
MFEM_HOST_DEVICE void USolve(const real_t *data, const int m, real_t *x)
Assuming L.U = P.A factored matrix of size (m x m), compute X <- U^{-1} X, for a vector X of length m...
MFEM_HOST_DEVICE void BlockFactor(const real_t *data, int m, const int *ipiv, int n, real_t *A12, real_t *A21, real_t *A22)
MFEM_HOST_DEVICE bool LUFactor(real_t *A, const int m, int *ipiv, const real_t tol=0.0)
Compute the LU factorization of the m x m matrix A.
MFEM_HOST_DEVICE void SubMult(const int m, const int n, const int r, const real_t *A21, const real_t *X1, real_t *X2)
Given an (n x m) matrix A21, compute X2 <- X2 - A21 X1, for matrices X1, and X2 of size (m x r) and (...
MFEM_HOST_DEVICE void LUSolve(const real_t *data, const int m, const int *ipiv, real_t *x)
Assuming L.U = P.A for a factored matrix (m x m),.
void add(const Vector &v1, const Vector &v2, Vector &v)
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
bool UsesTensorBasis(const FiniteElementSpace &fes)
Return true if the mesh contains only one topology and the elements are tensor elements.
@ SIZE
Number of host and device memory types.
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
@ NATIVE
Native ordering as defined by the FiniteElement.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void forall(int N, lambda &&body)