12 #include "transfer.hpp" 14 #include "../general/forall.hpp" 21 : dom_fes(dom_fes_), ran_fes(ran_fes_),
23 fw_t_oper(), bw_t_oper()
28 MFEM_VERIFY(par_dom == par_ran,
"the domain and range FE spaces must both" 29 " be either serial or parallel");
50 MFEM_VERIFY(mat != NULL,
"Operator is not a SparseMatrix");
53 t_oper.
Reset(const_cast<SparseMatrix*>(mat),
false);
66 const int RP_case = bool(out_cR) + 2*bool(in_cP);
70 t_oper.
Reset(const_cast<Operator*>(&oper),
false);
83 out_cR, &oper, in_cP,
false,
false,
false));
89 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
111 else if ((hy_mat = dynamic_cast<const HypreParMatrix *>(&oper)))
120 MFEM_ABORT(
"unknown Operator type");
128 false,
false,
false));
132 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
137 return *t_oper.
Ptr();
172 for (
int i = 0; i < elem_geoms.Size(); i++)
175 localP[elem_geoms[i]]);
183 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
213 MFEM_ABORT(
"unknown type of FE space");
224 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
233 :
Operator(fes_lor_.GetVSize(), fes_ho_.GetVSize()),
243 ho2lor.MakeI(nel_ho);
244 for (
int ilor = 0; ilor < nel_lor; ++ilor)
247 ho2lor.AddAColumnInRow(iho);
250 for (
int ilor = 0; ilor < nel_lor; ++ilor)
253 ho2lor.AddConnection(iho, ilor);
291 int nel_ho = mesh_ho->
GetNE();
292 int nel_lor = mesh_lor->
GetNE();
299 if (nel_ho == 0) {
return; }
306 for (
int ig = 0; ig < geoms.
Size(); ++ig)
316 for (
int iho = 0; iho < nel_ho; ++iho)
321 offsets[iho+1] = offsets[iho] + fe_ho.
GetDof()*fe_lor.
GetDof()*nref;
335 for (
int iho = 0; iho < nel_ho; ++iho)
344 int ndof_ho = fe_ho.
GetDof();
345 int ndof_lor = fe_lor.
GetDof();
350 DenseMatrix R_iho(&R[offsets[iho]], ndof_lor*nref, ndof_ho);
352 DenseMatrix Minv_lor(ndof_lor*nref, ndof_lor*nref);
368 for (
int iref = 0; iref < nref; ++iref)
371 int ilor = lor_els[iref];
374 M_lor.
CopyMN(M_lor_el, iref*ndof_lor, iref*ndof_lor);
378 Minv_lor.
CopyMN(M_lor_el, iref*ndof_lor, iref*ndof_lor);
388 ElemMixedMass(geom, fe_ho, fe_lor, el_tr, ip_tr, M_mixed_el);
390 M_mixed.
CopyMN(M_mixed_el, iref*ndof_lor, 0);
396 DenseMatrix P_iho(&P[offsets[iho]], ndof_ho, ndof_lor*nref);
401 RtMlorR_inv.
Mult(RtMlor, P_iho);
409 int vdim = fes_ho.GetVDim();
412 for (
int iho = 0; iho < fes_ho.GetNE(); ++iho)
414 int nref = ho2lor.RowSize(iho);
415 int ndof_ho = fes_ho.GetFE(iho)->GetDof();
416 int ndof_lor = fes_lor.GetFE(ho2lor.GetRow(iho)[0])->GetDof();
417 xel_mat.
SetSize(ndof_ho, vdim);
418 yel_mat.
SetSize(ndof_lor*nref, vdim);
419 DenseMatrix R_iho(&R[offsets[iho]], ndof_lor*nref, ndof_ho);
421 fes_ho.GetElementVDofs(iho, vdofs);
425 for (
int iref = 0; iref < nref; ++iref)
427 int ilor = ho2lor.GetRow(iho)[iref];
428 for (
int vd=0; vd<vdim; ++vd)
430 fes_lor.GetElementDofs(ilor, vdofs);
431 fes_lor.DofsToVDofs(vd, vdofs);
441 int vdim = fes_ho.GetVDim();
445 for (
int iho = 0; iho < fes_ho.GetNE(); ++iho)
447 int nref = ho2lor.RowSize(iho);
448 int ndof_ho = fes_ho.GetFE(iho)->GetDof();
449 int ndof_lor = fes_lor.GetFE(ho2lor.GetRow(iho)[0])->GetDof();
450 xel_mat.
SetSize(ndof_lor*nref, vdim);
451 yel_mat.
SetSize(ndof_ho, vdim);
452 DenseMatrix R_iho(&R[offsets[iho]], ndof_lor*nref, ndof_ho);
455 for (
int iref=0; iref<nref; ++iref)
457 int ilor = ho2lor.GetRow(iho)[iref];
458 for (
int vd=0; vd<vdim; ++vd)
460 fes_lor.GetElementDofs(ilor, vdofs);
461 fes_lor.DofsToVDofs(vd, vdofs);
468 fes_ho.GetElementVDofs(iho, vdofs);
476 if (fes_ho.GetNE() == 0) {
return; }
477 MFEM_VERIFY(P.Size() > 0,
"Prolongation not supported for these spaces.")
478 int vdim = fes_ho.GetVDim();
482 for (
int iho = 0; iho < fes_ho.GetNE(); ++iho)
484 int nref = ho2lor.RowSize(iho);
485 int ndof_ho = fes_ho.GetFE(iho)->GetDof();
486 int ndof_lor = fes_lor.GetFE(ho2lor.GetRow(iho)[0])->GetDof();
487 xel_mat.
SetSize(ndof_lor*nref, vdim);
488 yel_mat.
SetSize(ndof_ho, vdim);
489 DenseMatrix P_iho(&P[offsets[iho]], ndof_ho, ndof_lor*nref);
492 for (
int iref = 0; iref < nref; ++iref)
494 int ilor = ho2lor.GetRow(iho)[iref];
495 for (
int vd = 0; vd < vdim; ++vd)
497 fes_lor.GetElementDofs(ilor, vdofs);
498 fes_lor.DofsToVDofs(vd, vdofs);
505 fes_ho.GetElementVDofs(iho, vdofs);
513 if (fes_ho.GetNE() == 0) {
return; }
514 MFEM_VERIFY(P.Size() > 0,
"Prolongation not supported for these spaces.")
515 int vdim = fes_ho.GetVDim();
518 for (
int iho = 0; iho < fes_ho.GetNE(); ++iho)
520 int nref = ho2lor.RowSize(iho);
521 int ndof_ho = fes_ho.GetFE(iho)->GetDof();
522 int ndof_lor = fes_lor.GetFE(ho2lor.GetRow(iho)[0])->GetDof();
523 xel_mat.
SetSize(ndof_ho, vdim);
524 yel_mat.
SetSize(ndof_lor*nref, vdim);
525 DenseMatrix P_iho(&P[offsets[iho]], ndof_ho, ndof_lor*nref);
527 fes_ho.GetElementVDofs(iho, vdofs);
532 for (
int iref = 0; iref < nref; ++iref)
534 int ilor = ho2lor.GetRow(iho)[iref];
535 for (
int vd=0; vd<vdim; ++vd)
537 fes_lor.GetElementDofs(ilor, vdofs);
538 fes_lor.DofsToVDofs(vd, vdofs);
551 int nel_ho = mesh_ho->
GetNE();
552 int nel_lor = mesh_lor->
GetNE();
556 if (nel_ho == 0) {
return; }
563 for (
int ig = 0; ig < geoms.
Size(); ++ig)
578 for (
int iho = 0; iho < nel_ho; ++iho)
586 int nedof_lor = fe_lor.
GetDof();
591 Vector shape_lor(nedof_lor);
594 for (
int iref = 0; iref < nref; ++iref)
596 int ilor = lor_els[iref];
607 ML_el += (shape_lor *= (el_tr->
Weight() * ip_lor.
weight));
614 for (
int i = 0; i < ndof_lor; ++i)
616 ML_inv[i] = 1.0 / ML_inv[i];
631 for (
int iho = 0; iho < nel_ho; ++iho)
644 int nedof_ho = fe_ho.
GetDof();
645 int nedof_lor = fe_lor.
GetDof();
649 for (
int iref = 0; iref < nref; ++iref)
651 int ilor = lor_els[iref];
663 for (
int i = 0; i < nedof_lor; ++i)
666 R_el.
SetRow(i, R_row.
Set(ML_inv[dofs_lor[i]], R_row));
695 int vdim = fes_ho.GetVDim();
696 const int ndof_ho = fes_ho.GetNDofs();
697 const int ndof_lor = fes_lor.GetNDofs();
703 for (
int d = 0; d < vdim; ++d)
705 fes_ho.GetVDofs(d, dofs_ho);
706 fes_lor.GetVDofs(d, dofs_lor);
708 R.Mult(x_dim, y_dim);
716 int vdim = fes_ho.GetVDim();
717 const int ndof_ho = fes_ho.GetNDofs();
718 const int ndof_lor = fes_lor.GetNDofs();
724 for (
int d = 0; d < vdim; ++d)
726 fes_ho.GetVDofs(d, dofs_ho);
727 fes_lor.GetVDofs(d, dofs_lor);
729 R.MultTranspose(x_dim, y_dim);
737 int vdim = fes_ho.GetVDim();
738 const int ndof_ho = fes_ho.GetNDofs();
739 const int ndof_lor = fes_lor.GetNDofs();
746 for (
int d = 0; d < vdim; ++d)
748 fes_lor.GetVDofs(d, dofs_lor);
751 M_LH.MultTranspose(x_dim, xbar);
753 pcg.Mult(xbar, y_dim);
754 fes_ho.GetVDofs(d, dofs_ho);
762 int vdim = fes_ho.GetVDim();
763 const int ndof_ho = fes_ho.GetNDofs();
764 const int ndof_lor = fes_lor.GetNDofs();
771 for (
int d = 0; d < vdim; ++d)
773 fes_ho.GetVDofs(d, dofs_ho);
777 pcg.Mult(x_dim, xbar);
778 M_LH.Mult(xbar, y_dim);
779 fes_lor.GetVDofs(d, dofs_lor);
786 pcg.SetRelTol(p_rtol_);
791 pcg.SetAbsTol(p_atol_);
794 void L2ProjectionGridTransfer::L2ProjectionH1Space::AllocR()
796 const Table& elem_dof_ho = fes_ho.GetElementToDofTable();
797 const Table& elem_dof_lor = fes_lor.GetElementToDofTable();
798 const int ndof_ho = fes_ho.GetNDofs();
799 const int ndof_lor = fes_lor.GetNDofs();
802 Transpose(elem_dof_lor, dof_elem_lor, ndof_lor);
804 Mesh* mesh_lor = fes_lor.GetMesh();
808 const int* elem_dof_hoI = elem_dof_ho.
GetI();
809 const int* elem_dof_hoJ = elem_dof_ho.
GetJ();
810 const int* dof_elem_lorI = dof_elem_lor.
GetI();
811 const int* dof_elem_lorJ = dof_elem_lor.
GetJ();
817 dof_used_ho.
SetSize(ndof_ho, -1);
820 for (
int ilor = 0; ilor < ndof_lor; ++ilor)
822 for (
int jlor = dof_elem_lorI[ilor]; jlor < dof_elem_lorI[ilor + 1]; ++jlor)
824 int el_lor = dof_elem_lorJ[jlor];
826 for (
int jho = elem_dof_hoI[iho]; jho < elem_dof_hoI[iho + 1]; ++jho)
828 int dof_ho = elem_dof_hoJ[jho];
829 if (dof_used_ho[dof_ho] != ilor)
831 dof_used_ho[dof_ho] = ilor;
839 Table dof_lor_dof_ho;
840 dof_lor_dof_ho.SetDims(ndof_lor, sizeJ);
842 for (
int i = 0; i < ndof_ho; ++i)
848 int* dof_dofI = dof_lor_dof_ho.GetI();
849 int* dof_dofJ = dof_lor_dof_ho.GetJ();
851 for (
int ilor = 0; ilor < ndof_lor; ++ilor)
853 dof_dofI[ilor] = sizeJ;
854 for (
int jlor = dof_elem_lorI[ilor]; jlor < dof_elem_lorI[ilor + 1]; ++jlor)
856 int el_lor = dof_elem_lorJ[jlor];
858 for (
int jho = elem_dof_hoI[iho]; jho < elem_dof_hoI[iho + 1]; ++jho)
860 int dof_ho = elem_dof_hoJ[jho];
861 if (dof_used_ho[dof_ho] != ilor)
863 dof_used_ho[dof_ho] = ilor;
864 dof_dofJ[sizeJ] = dof_ho;
871 dof_lor_dof_ho.SortRows();
872 double* data = Memory<double>(dof_dofI[ndof_lor]);
874 R = SparseMatrix(dof_dofI, dof_dofJ, data, ndof_lor, ndof_ho,
878 dof_lor_dof_ho.LoseData();
889 if (!
F) { BuildF(); }
897 if (!
F) { BuildF(); }
903 void L2ProjectionGridTransfer::BuildF()
924 :
Operator(hFESpace_.GetVSize(), lFESpace_.GetVSize())
927 if (lFESpace_.
FEColl() == hFESpace_.
FEColl() && !isvar_order)
939 && dynamic_cast<const TensorBasisElement*>(hFESpace_.
GetFE(0))
969 :
Operator(hFESpace_.GetVSize(), lFESpace_.GetVSize()), lFESpace(lFESpace_),
991 for (
int i = 0; i < mesh->
GetNE(); i++)
997 if (geom != cached_geom || isvar_order)
999 h_fe = hFESpace.
GetFE(i);
1000 l_fe = lFESpace.
GetFE(i);
1007 for (
int vd = 0; vd < vdim; vd++)
1009 l_dofs.
Copy(l_vdofs);
1011 h_dofs.
Copy(h_vdofs);
1018 loc_prol.
Mult(subX, subY);
1046 int vdim = lFESpace.
GetVDim();
1048 for (
int i = 0; i < mesh->
GetNE(); i++)
1054 if (geom != cached_geom || isvar_order)
1056 h_fe = hFESpace.
GetFE(i);
1057 l_fe = lFESpace.
GetFE(i);
1065 for (
int vd = 0; vd < vdim; vd++)
1067 l_dofs.
Copy(l_vdofs);
1069 h_dofs.
Copy(h_vdofs);
1077 for (
int p = 0;
p < h_dofs.
Size(); ++
p)
1079 if (processed[lFESpace.
DecodeDof(h_dofs[
p])])
1085 loc_prol.
Mult(subX, subY);
1093 for (
int p = 0;
p < h_dofs.
Size(); ++
p)
1095 processed[lFESpace.
DecodeDof(h_dofs[
p])] = 1;
1105 :
Operator(hFESpace_.GetVSize(), lFESpace_.GetVSize()), lFESpace(lFESpace_),
1111 if (mesh->
GetNE() == 0)
1119 MFEM_VERIFY(ltel,
"Low order FE space must be tensor product space");
1123 MFEM_VERIFY(htel,
"High order FE space must be tensor product space");
1133 int j = hdofmap[i] >=0 ? hdofmap[i] : -1 - hdofmap[i];
1137 NE = lFESpace.
GetNE();
1145 elem_restrict_lex_l =
1148 MFEM_VERIFY(elem_restrict_lex_l,
1149 "Low order ElementRestriction not available");
1151 elem_restrict_lex_h =
1154 MFEM_VERIFY(elem_restrict_lex_h,
1155 "High order ElementRestriction not available");
1162 MFEM_VERIFY(dynamic_cast<const ElementRestriction*>(elem_restrict_lex_h),
1163 "High order element restriction is of unsupported type");
1167 ->BooleanMask(mask);
1171 namespace TransferKernels
1186 for (
int dy = 0; dy < D1D; ++dy)
1189 for (
int qy = 0; qy < Q1D; ++qy)
1193 for (
int dx = 0; dx < D1D; ++dx)
1195 const double s = x_(dx, dy, e);
1196 for (
int qx = 0; qx < Q1D; ++qx)
1198 sol_x[qx] += B_(qx, dx) *
s;
1201 for (
int qy = 0; qy < Q1D; ++qy)
1203 const double d2q = B_(qy, dy);
1204 for (
int qx = 0; qx < Q1D; ++qx)
1206 y_(qx, qy, e) += d2q * sol_x[qx];
1210 for (
int qy = 0; qy < Q1D; ++qy)
1212 for (
int qx = 0; qx < Q1D; ++qx)
1214 y_(qx, qy, e) *= m_(qx, qy, e);
1224 auto x_ =
Reshape(localL.
Read(), D1D, D1D, D1D, NE);
1227 auto m_ =
Reshape(mask.
Read(), Q1D, Q1D, Q1D, NE);
1233 for (
int dz = 0; dz < D1D; ++dz)
1236 for (
int qy = 0; qy < Q1D; ++qy)
1238 for (
int qx = 0; qx < Q1D; ++qx)
1240 sol_xy[qy][qx] = 0.0;
1243 for (
int dy = 0; dy < D1D; ++dy)
1246 for (
int qx = 0; qx < Q1D; ++qx)
1250 for (
int dx = 0; dx < D1D; ++dx)
1252 const double s = x_(dx, dy, dz, e);
1253 for (
int qx = 0; qx < Q1D; ++qx)
1255 sol_x[qx] += B_(qx, dx) *
s;
1258 for (
int qy = 0; qy < Q1D; ++qy)
1260 const double wy = B_(qy, dy);
1261 for (
int qx = 0; qx < Q1D; ++qx)
1263 sol_xy[qy][qx] += wy * sol_x[qx];
1267 for (
int qz = 0; qz < Q1D; ++qz)
1269 const double wz = B_(qz, dz);
1270 for (
int qy = 0; qy < Q1D; ++qy)
1272 for (
int qx = 0; qx < Q1D; ++qx)
1274 y_(qx, qy, qz, e) += wz * sol_xy[qy][qx];
1279 for (
int qz = 0; qz < Q1D; ++qz)
1281 for (
int qy = 0; qy < Q1D; ++qy)
1283 for (
int qx = 0; qx < Q1D; ++qx)
1285 y_(qx, qy, qz, e) *= m_(qx, qy, qz, e);
1305 for (
int qy = 0; qy < Q1D; ++qy)
1308 for (
int dx = 0; dx < D1D; ++dx)
1312 for (
int qx = 0; qx < Q1D; ++qx)
1314 const double s = m_(qx, qy, e) * x_(qx, qy, e);
1315 for (
int dx = 0; dx < D1D; ++dx)
1317 sol_x[dx] += Bt_(dx, qx) *
s;
1320 for (
int dy = 0; dy < D1D; ++dy)
1322 const double q2d = Bt_(dy, qy);
1323 for (
int dx = 0; dx < D1D; ++dx)
1325 y_(dx, dy, e) += q2d * sol_x[dx];
1335 auto x_ =
Reshape(localH.
Read(), Q1D, Q1D, Q1D, NE);
1338 auto m_ =
Reshape(mask.
Read(), Q1D, Q1D, Q1D, NE);
1344 for (
int qz = 0; qz < Q1D; ++qz)
1347 for (
int dy = 0; dy < D1D; ++dy)
1349 for (
int dx = 0; dx < D1D; ++dx)
1354 for (
int qy = 0; qy < Q1D; ++qy)
1357 for (
int dx = 0; dx < D1D; ++dx)
1361 for (
int qx = 0; qx < Q1D; ++qx)
1363 const double s = m_(qx, qy, qz, e) * x_(qx, qy, qz, e);
1364 for (
int dx = 0; dx < D1D; ++dx)
1366 sol_x[dx] += Bt_(dx, qx) *
s;
1369 for (
int dy = 0; dy < D1D; ++dy)
1371 const double wy = Bt_(dy, qy);
1372 for (
int dx = 0; dx < D1D; ++dx)
1374 sol_xy[dy][dx] += wy * sol_x[dx];
1378 for (
int dz = 0; dz < D1D; ++dz)
1380 const double wz = Bt_(dz, qz);
1381 for (
int dy = 0; dy < D1D; ++dy)
1383 for (
int dx = 0; dx < D1D; ++dx)
1385 y_(dx, dy, dz, e) += wz * sol_xy[dy][dx];
1408 elem_restrict_lex_l->
Mult(x, localL);
1419 MFEM_ABORT(
"TensorProductPRefinementTransferOperator::Mult not " 1420 "implemented for dim = " 1434 elem_restrict_lex_h->
Mult(x, localH);
1445 MFEM_ABORT(
"TensorProductPRefinementTransferOperator::MultTranspose not " 1446 "implemented for dim = " 1455 :
Operator(hFESpace_.GetTrueVSize(), lFESpace_.GetTrueVSize()),
1456 lFESpace(lFESpace_),
1468 if (P) { MFEM_VERIFY(R,
"Both P and R have to be not NULL") }
1484 delete localTransferOperator;
1492 localTransferOperator->
Mult(tmpL, tmpH);
1497 localTransferOperator->
Mult(x, tmpH);
1502 localTransferOperator->
Mult(x, y);
1510 R->MultTranspose(x, tmpH);
1516 R->MultTranspose(x, tmpH);
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Abstract class for all finite elements.
virtual ~InterpolationGridTransfer()
const Operator & MakeTrueOperator(FiniteElementSpace &fes_in, FiniteElementSpace &fes_out, const Operator &oper, OperatorHandle &t_oper)
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 ...
virtual void Prolongate(const Vector &x, Vector &y) const
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
int GetNPoints() const
Returns the number of the points in the integration rule.
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
Class for an integration rule - an Array of IntegrationPoint.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
virtual void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
Data type for scaled Jacobi-type smoother of sparse matrix.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
BilinearFormIntegrator * mass_integ
Ownership depends on own_mass_integ.
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
L2ProjectionH1Space(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_)
void SetRow(int r, const double *row)
virtual ~TensorProductPRefinementTransferOperator()
Destructor.
Geometry::Type GetElementBaseGeometry(int i) const
Field is discontinuous across element interfaces.
virtual void Mult(const Vector &x, Vector &y) const
FiniteElementSpace & dom_fes
Domain FE space.
virtual int GetContType() const =0
Matrix-free transfer operator between finite element spaces on the same mesh.
void Mult(const double *x, double *y) const
Matrix vector multiplication with the inverse of dense matrix.
void SetSize(int s)
Resize the vector to size s.
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
static int DecodeDof(int dof)
Helpers to remove encoded sign from a DOF.
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Pointer to an Operator of a specified type.
int * GetJ()
Return the array J.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
virtual void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
int Size() const
Returns the size of the vector.
virtual const Operator * GetRestrictionOperator() const
An abstract operator that performs the same action as GetRestrictionMatrix.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Data type dense matrix using column-major storage.
virtual ~TransferOperator()
Destructor.
Operator::Type oper_type
Desired Operator::Type for the construction of all operators defined by the underlying transfer algor...
int GetNDofs() const
Returns number of degrees of freedom.
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
int * GetI()
Return the array I.
~TrueTransferOperator()
Destructor.
virtual void Mult(const Vector &x, Vector &y) const override
Interpolation or prolongation of a vector x corresponding to the coarse space to the vector y corresp...
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Abstract parallel finite element space.
virtual const Operator & ForwardOperator()
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
void Factor()
Factor the current DenseMatrix, *a.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
virtual void Prolongate(const Vector &x, Vector &y) const
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B, bool own_matrix)
virtual void ProlongateTranspose(const Vector &x, Vector &y) const
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
void BuildHo2Lor(int nel_ho, int nel_lor, const CoarseFineTransformations &cf_tr)
virtual ~PRefinementTransferOperator()
Destructor.
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
const Array< int > & GetDofMap() const
Get an Array<int> that maps lexicographically ordered indices to the indices of the respective nodes/...
Derefinement operator, used by the friend class InterpolationGridTransfer.
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
FiniteElementSpace & ran_fes
Range FE space.
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
ID for class SparseMatrix.
const Table * GetElementToFaceOrientationTable() const
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
const FiniteElementSpace & fes_ho
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
virtual const Operator & BackwardOperator()
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
General product operator: x -> (A*B)(x) = A(B(x)).
ID for the base class Operator, i.e. any type.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
virtual void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
double * GetData() const
Returns the matrix data array.
void ElemMixedMass(Geometry::Type geom, const FiniteElement &fe_ho, const FiniteElement &fe_lor, ElementTransformation *el_tr, IntegrationPointTransformation &ip_tr, DenseMatrix &M_mixed_el) const
const FiniteElementCollection * FEColl() const
OperatorHandle F
Forward, coarse-to-fine, operator.
GridTransfer(FiniteElementSpace &dom_fes_, FiniteElementSpace &ran_fes_)
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
void SetMaxIter(int max_it)
TensorProductPRefinementTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_)
Constructs a transfer operator from lFESpace to hFESpace which have different FE collections.
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
HypreParMatrix * LeftDiagMult(const SparseMatrix &D, HYPRE_BigInt *row_starts=NULL) const
Multiply the HypreParMatrix on the left by a block-diagonal parallel matrix D and return the result a...
void Restriction2D(const int NE, const int D1D, const int Q1D, const Vector &localH, Vector &localL, const Array< double > &Bt, const Vector &mask)
virtual void SetAbsTol(double p_atol_)
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
L2Projection(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_)
virtual void GetTransferMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
Return interpolation matrix, I, which maps dofs from a coarse element, fe, to the fine dofs on this f...
virtual void Mult(const Vector &x, Vector &y) const
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void Mult(const double *x, double *y) const
Matrix vector multiplication.
int GetNE() const
Returns number of elements in the mesh.
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...
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
OperatorHandle B
Backward, fine-to-coarse, operator.
List of mesh geometries stored as Array<Geometry::Type>.
int GetVDim() const
Returns vector dimension.
virtual const Operator & BackwardOperator()
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
void SetMassIntegrator(BilinearFormIntegrator *mass_integ_, bool own_mass_integ_=true)
Assign a mass integrator to be used in the construction of the backward, fine-to-coarse, transfer operator.
Array< double > Bt
Transpose of B.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Mesh * GetMesh() const
Returns the mesh.
double p(const Vector &x, double t)
virtual void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
void Transpose()
(*this) = (*this)^t
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
Matrix-free transfer operator between finite element spaces.
Operator that converts FiniteElementSpace L-vectors to E-vectors.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
SparseMatrix * RefinementMatrix_main(const int coarse_ndofs, const Table &coarse_elem_dof, const Table *coarse_elem_fos, const DenseTensor localP[]) const
Matrix-free transfer operator between finite element spaces on the same mesh exploiting the tensor pr...
void GetRow(int r, Vector &row) const
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
virtual void Mult(const Vector &x, Vector &y) const override
Interpolation or prolongation of a vector x corresponding to the coarse space to the vector y corresp...
L2Prolongation * B
Backward, fine-to-coarse, operator.
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
void Restriction3D(const int NE, const int D1D, const int Q1D, const Vector &localH, Vector &localL, const Array< double > &Bt, const Vector &mask)
int GetDof() const
Returns the number of degrees of freedom in the finite element.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Structure representing the matrices/tensors needed to evaluate (in reference space) the values...
virtual DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element 'elem'.
bool own_mass_integ
Ownership flag for mass_integ.
const CoarseFineTransformations & GetRefinementTransforms()
Vector & Set(const double a, const Vector &x)
(*this) = a * x
void GetGeometries(int dim, Array< Geometry::Type > &el_geoms) const
Return all element geometries of the given dimension present in the mesh.
virtual void MultTranspose(const Vector &x, Vector &y) const
L2Projection * F
Forward, coarse-to-fine, operator.
Array< double > B
Basis functions evaluated at quadrature points.
int GetNE() const
Returns number of elements.
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
virtual const Operator & ForwardOperator()
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Class for integration point with weight.
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
GridFunction interpolation operator applicable after mesh refinement.
virtual void Mult(const Vector &x, Vector &y) const override
Interpolation or prolongation of a vector x corresponding to the coarse space to the vector y corresp...
SparseMatrix * TransposeMult(const SparseMatrix &A, const SparseMatrix &B)
C = A^T B.
const FiniteElementSpace & fes_lor
General triple product operator x -> A*B*C*x, with ownership of the factors.
PRefinementTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_)
Constructs a transfer operator from lFESpace to hFESpace which have different FE collections.
TrueTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_)
Constructs a transfer operator working on true degrees of freedom from lFESpace to hFESpace...
virtual ~L2ProjectionH1Space()
virtual void Mult(const Vector &x, Vector &y) const override
Interpolation or prolongation of a true dof vector x to a true dof vector y.
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
Lexicographic ordering for tensor-product FiniteElements.
Operator * Ptr() const
Access the underlying Operator pointer.
int Size() const
Return the logical size of the array.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual ~L2ProjectionGridTransfer()
ID for class HypreParMatrix.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
virtual void ProlongateTranspose(const Vector &x, Vector &y) const
void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco)
Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this.
Field is continuous across element interfaces.
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Wrapper for hypre's ParCSR matrix class.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Rank 3 tensor (array of matrices)
L2ProjectionL2Space(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_)
HYPRE_BigInt * GetTrueDofOffsets() const
void Prolongation2D(const int NE, const int D1D, const int Q1D, const Vector &localL, Vector &localH, const Array< double > &B, const Vector &mask)
const Table & GetElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each mesh element...
virtual const SparseMatrix * GetHpRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
void GetLocalRefinementMatrices(Geometry::Type geom, DenseTensor &localP) const
virtual void SetRelTol(double p_rtol_)
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
virtual bool SupportsBackwardsOperator() const
TransferOperator(const FiniteElementSpace &lFESpace, const FiniteElementSpace &hFESpace)
Constructs a transfer operator from lFESpace to hFESpace.
void GetTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
Construct and return an Operator that can be used to transfer GridFunction data from coarse_fes...
virtual void MultTranspose(const Vector &x, Vector &y) const
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
void Prolongation3D(const int NE, const int D1D, const int Q1D, const Vector &localL, Vector &localH, const Array< double > &B, const Vector &mask)
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.