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");
66 const int RP_case = bool(out_cR) + 2*bool(in_cP);
83 out_cR, &oper, in_cP,
false,
false,
false));
89 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
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);
549 std::unique_ptr<SparseMatrix> R_mat, M_LH_mat;
562 R_mat.reset(
RAP(*P_lor, *R_mat, *P_ho));
563 M_LH_mat.reset(
RAP(*P_lor, *M_LH_mat, *P_ho));
573 M_LH_mat.reset(
mfem::Mult(*P_lor, *M_LH_mat));
582 R = std::move(R_mat);
583 M_LH = std::move(M_LH_mat);
593 pcg(pfes_ho.GetComm())
620 std::unique_ptr<HypreParMatrix> R_T(R_mat->
Transpose());
627 M_LH.reset(M_LH_mat);
641 pcg.SetPrintLevel(0);
643 pcg.SetMaxIter(1000);
645 pcg.SetRelTol(1e-13);
646 pcg.SetAbsTol(1e-13);
647 pcg.SetPreconditioner(*precon);
648 pcg.SetOperator(*RTxM_LH);
654 Vector X(fes_ho.GetTrueVSize());
657 Vector Y_dim(R->Height());
658 Vector Y(fes_lor.GetTrueVSize());
662 GetTDofs(fes_ho, x, X);
664 for (
int d = 0; d < fes_ho.GetVDim(); ++d)
666 TDofsListByVDim(fes_ho, d, vdofs_list);
668 R->Mult(X_dim, Y_dim);
669 TDofsListByVDim(fes_lor, d, vdofs_list);
673 SetFromTDofs(fes_lor, Y, y);
679 Vector X(fes_lor.GetTrueVSize());
680 Vector X_dim(R->Height());
683 Vector Y(fes_ho.GetTrueVSize());
687 GetTDofsTranspose(fes_lor, x, X);
689 for (
int d = 0; d < fes_ho.GetVDim(); ++d)
691 TDofsListByVDim(fes_lor, d, vdofs_list);
693 R->MultTranspose(X_dim, Y_dim);
694 TDofsListByVDim(fes_ho, d, vdofs_list);
698 SetFromTDofsTranspose(fes_ho, Y, y);
704 Vector X(fes_lor.GetTrueVSize());
705 Vector X_dim(M_LH->Height());
708 Vector Y_dim(pcg.Height());
709 Vector Y(fes_ho.GetTrueVSize());
713 GetTDofs(fes_lor, x, X);
715 for (
int d = 0; d < fes_ho.GetVDim(); ++d)
717 TDofsListByVDim(fes_lor, d, vdofs_list);
720 M_LH->MultTranspose(X_dim, Xbar);
722 pcg.Mult(Xbar, Y_dim);
723 TDofsListByVDim(fes_ho, d, vdofs_list);
727 SetFromTDofs(fes_ho, Y, y);
733 Vector X(fes_ho.GetTrueVSize());
734 Vector X_dim(pcg.Width());
735 Vector Xbar(pcg.Height());
737 Vector Y_dim(M_LH->Height());
738 Vector Y(fes_lor.GetTrueVSize());
742 GetTDofsTranspose(fes_ho, x, X);
744 for (
int d = 0; d < fes_ho.GetVDim(); ++d)
746 TDofsListByVDim(fes_ho, d, vdofs_list);
750 pcg.Mult(X_dim, Xbar);
751 M_LH->Mult(Xbar, Y_dim);
752 TDofsListByVDim(fes_lor, d, vdofs_list);
756 SetFromTDofsTranspose(fes_lor, Y, y);
761 pcg.SetRelTol(p_rtol_);
766 pcg.SetAbsTol(p_atol_);
770std::unique_ptr<SparseMatrix>,
771std::unique_ptr<SparseMatrix>>
774 std::pair<std::unique_ptr<SparseMatrix>,
775 std::unique_ptr<SparseMatrix>> r_and_mlh;
777 Mesh* mesh_ho = fes_ho.GetMesh();
778 Mesh* mesh_lor = fes_lor.GetMesh();
779 int nel_ho = mesh_ho->
GetNE();
780 int nel_lor = mesh_lor->
GetNE();
781 int ndof_lor = fes_lor.GetNDofs();
786 return std::make_pair(
797 for (
int ig = 0; ig < geoms.
Size(); ++ig)
803 BuildHo2Lor(nel_ho, nel_lor, cf_tr);
812 for (
int iho = 0; iho < nel_ho; ++iho)
815 ho2lor.GetRow(iho, lor_els);
816 int nref = ho2lor.RowSize(iho);
820 int nedof_lor = fe_lor.
GetDof();
825 Vector shape_lor(nedof_lor);
828 for (
int iref = 0; iref < nref; ++iref)
830 int ilor = lor_els[iref];
841 ML_el += (shape_lor *= (el_tr->
Weight() * ip_lor.
weight));
843 fes_lor.GetElementDofs(ilor, dofs_lor);
848 LumpedMassInverse(ML_inv);
851 r_and_mlh.first = AllocR();
856 for (
int icol = 0; icol < r_and_mlh.first->Height() + 1; ++icol)
858 I[icol] = r_and_mlh.first->GetI()[icol];
861 for (
int jcol = 0; jcol < r_and_mlh.first->NumNonZeroElems(); ++jcol)
863 J[jcol] = r_and_mlh.first->GetJ()[jcol];
865 r_and_mlh.second = std::unique_ptr<SparseMatrix>(
867 r_and_mlh.first->Width(),
true,
true,
true));
873 for (
int iho = 0; iho < nel_ho; ++iho)
876 ho2lor.GetRow(iho, lor_els);
877 int nref = ho2lor.RowSize(iho);
886 int nedof_ho = fe_ho.
GetDof();
887 int nedof_lor = fe_lor.
GetDof();
891 for (
int iref = 0; iref < nref; ++iref)
893 int ilor = lor_els[iref];
900 ElemMixedMass(geom, fe_ho, fe_lor, el_tr, ip_tr, M_LH_el);
903 fes_lor.GetElementDofs(ilor, dofs_lor);
905 for (
int i = 0; i < nedof_lor; ++i)
908 R_el.
SetRow(i, R_row.
Set(ML_inv[dofs_lor[i]], R_row));
911 fes_ho.GetElementDofs(iho, dofs_ho);
912 r_and_mlh.second->AddSubMatrix(dofs_lor, dofs_ho, M_LH_el);
913 r_and_mlh.first->AddSubMatrix(dofs_lor, dofs_ho, R_el);
987 R_mat->
BooleanMult(x_vdofs_marker, X_vdofs_marker);
1000 Vector ML_inv_full(fes_lor.GetVSize());
1003 fes_lor.GetVDofs(0, vdofs_list);
1006 Vector ML_inv_true(fes_lor.GetTrueVSize());
1007 const Operator *P = fes_lor.GetProlongationMatrix();
1009 else { ML_inv_true = ML_inv_full; }
1011 for (
int i = 0; i < ML_inv_true.
Size(); ++i)
1013 ML_inv_true[i] = 1.0 / ML_inv_true[i];
1016 if (P) { P->
Mult(ML_inv_true, ML_inv_full); }
1017 else { ML_inv_full = ML_inv_true; }
1022std::unique_ptr<SparseMatrix>
1025 const Table& elem_dof_ho = fes_ho.GetElementToDofTable();
1026 const Table& elem_dof_lor = fes_lor.GetElementToDofTable();
1027 const int ndof_ho = fes_ho.GetNDofs();
1028 const int ndof_lor = fes_lor.GetNDofs();
1031 Transpose(elem_dof_lor, dof_elem_lor, ndof_lor);
1033 Mesh* mesh_lor = fes_lor.GetMesh();
1037 const int* elem_dof_hoI = elem_dof_ho.
GetI();
1038 const int* elem_dof_hoJ = elem_dof_ho.
GetJ();
1039 const int* dof_elem_lorI = dof_elem_lor.
GetI();
1040 const int* dof_elem_lorJ = dof_elem_lor.
GetJ();
1046 dof_used_ho.
SetSize(ndof_ho, -1);
1049 for (
int ilor = 0; ilor < ndof_lor; ++ilor)
1051 for (
int jlor = dof_elem_lorI[ilor]; jlor < dof_elem_lorI[ilor + 1]; ++jlor)
1053 int el_lor = dof_elem_lorJ[jlor];
1055 for (
int jho = elem_dof_hoI[iho]; jho < elem_dof_hoI[iho + 1]; ++jho)
1057 int dof_ho = elem_dof_hoJ[jho];
1058 if (dof_used_ho[dof_ho] != ilor)
1060 dof_used_ho[dof_ho] = ilor;
1068 Table dof_lor_dof_ho;
1069 dof_lor_dof_ho.
SetDims(ndof_lor, sizeJ);
1071 for (
int i = 0; i < ndof_ho; ++i)
1073 dof_used_ho[i] = -1;
1077 int* dof_dofI = dof_lor_dof_ho.
GetI();
1078 int* dof_dofJ = dof_lor_dof_ho.
GetJ();
1080 for (
int ilor = 0; ilor < ndof_lor; ++ilor)
1082 dof_dofI[ilor] = sizeJ;
1083 for (
int jlor = dof_elem_lorI[ilor]; jlor < dof_elem_lorI[ilor + 1]; ++jlor)
1085 int el_lor = dof_elem_lorJ[jlor];
1087 for (
int jho = elem_dof_hoI[iho]; jho < elem_dof_hoI[iho + 1]; ++jho)
1089 int dof_ho = elem_dof_hoJ[jho];
1090 if (dof_used_ho[dof_ho] != ilor)
1092 dof_used_ho[dof_ho] = ilor;
1093 dof_dofJ[sizeJ] = dof_ho;
1103 std::unique_ptr<SparseMatrix> R_local(
new SparseMatrix(
1104 dof_dofI, dof_dofJ, data, ndof_lor,
1105 ndof_ho,
true,
true,
true));
1121 if (!
F) { BuildF(); }
1129 if (!
F) { BuildF(); }
1135void L2ProjectionGridTransfer::BuildF()
1151 F =
new L2ProjectionH1Space(dom_pfes, ran_pfes);
1169 :
Operator(hFESpace_.GetVSize(), lFESpace_.GetVSize())
1172 if (lFESpace_.
FEColl() == hFESpace_.
FEColl() && !isvar_order)
1214 :
Operator(hFESpace_.GetVSize(), lFESpace_.GetVSize()), lFESpace(lFESpace_),
1234 int vdim = lFESpace.
GetVDim();
1236 for (
int i = 0; i < mesh->
GetNE(); i++)
1242 if (geom != cached_geom || isvar_order)
1244 h_fe = hFESpace.
GetFE(i);
1245 l_fe = lFESpace.
GetFE(i);
1252 for (
int vd = 0; vd < vdim; vd++)
1254 l_dofs.
Copy(l_vdofs);
1256 h_dofs.
Copy(h_vdofs);
1263 loc_prol.
Mult(subX, subY);
1291 int vdim = lFESpace.
GetVDim();
1293 for (
int i = 0; i < mesh->
GetNE(); i++)
1299 if (geom != cached_geom || isvar_order)
1301 h_fe = hFESpace.
GetFE(i);
1302 l_fe = lFESpace.
GetFE(i);
1310 for (
int vd = 0; vd < vdim; vd++)
1312 l_dofs.
Copy(l_vdofs);
1314 h_dofs.
Copy(h_vdofs);
1322 for (
int p = 0;
p < h_dofs.
Size(); ++
p)
1324 if (processed[lFESpace.
DecodeDof(h_dofs[
p])])
1330 loc_prol.
Mult(subX, subY);
1338 for (
int p = 0;
p < h_dofs.
Size(); ++
p)
1340 processed[lFESpace.
DecodeDof(h_dofs[
p])] = 1;
1350 :
Operator(hFESpace_.GetVSize(), lFESpace_.GetVSize()), lFESpace(lFESpace_),
1356 if (mesh->
GetNE() == 0)
1364 MFEM_VERIFY(ltel,
"Low order FE space must be tensor product space");
1368 MFEM_VERIFY(htel,
"High order FE space must be tensor product space");
1378 int j = hdofmap[i] >=0 ? hdofmap[i] : -1 - hdofmap[i];
1382 NE = lFESpace.
GetNE();
1390 elem_restrict_lex_l =
1393 MFEM_VERIFY(elem_restrict_lex_l,
1394 "Low order ElementRestriction not available");
1396 elem_restrict_lex_h =
1399 MFEM_VERIFY(elem_restrict_lex_h,
1400 "High order ElementRestriction not available");
1408 "High order element restriction is of unsupported type");
1412 ->BooleanMask(mask);
1416namespace TransferKernels
1429 for (
int qy = 0; qy < Q1D; ++qy)
1431 for (
int qx = 0; qx < Q1D; ++qx)
1433 y_(qx, qy, e) = 0.0;
1437 for (
int dy = 0; dy < D1D; ++dy)
1439 real_t sol_x[DofQuadLimits::MAX_Q1D];
1440 for (
int qy = 0; qy < Q1D; ++qy)
1444 for (
int dx = 0; dx < D1D; ++dx)
1446 const real_t s = x_(dx, dy, e);
1447 for (
int qx = 0; qx < Q1D; ++qx)
1449 sol_x[qx] += B_(qx, dx) *
s;
1452 for (
int qy = 0; qy < Q1D; ++qy)
1454 const real_t d2q = B_(qy, dy);
1455 for (
int qx = 0; qx < Q1D; ++qx)
1457 y_(qx, qy, e) += d2q * sol_x[qx];
1461 for (
int qy = 0; qy < Q1D; ++qy)
1463 for (
int qx = 0; qx < Q1D; ++qx)
1465 y_(qx, qy, e) *= m_(qx, qy, e);
1475 auto x_ =
Reshape(localL.
Read(), D1D, D1D, D1D, NE);
1478 auto m_ =
Reshape(mask.
Read(), Q1D, Q1D, Q1D, NE);
1482 for (
int qz = 0; qz < Q1D; ++qz)
1484 for (
int qy = 0; qy < Q1D; ++qy)
1486 for (
int qx = 0; qx < Q1D; ++qx)
1488 y_(qx, qy, qz, e) = 0.0;
1493 for (
int dz = 0; dz < D1D; ++dz)
1495 real_t sol_xy[DofQuadLimits::MAX_Q1D][DofQuadLimits::MAX_Q1D];
1496 for (
int qy = 0; qy < Q1D; ++qy)
1498 for (
int qx = 0; qx < Q1D; ++qx)
1500 sol_xy[qy][qx] = 0.0;
1503 for (
int dy = 0; dy < D1D; ++dy)
1505 real_t sol_x[DofQuadLimits::MAX_Q1D];
1506 for (
int qx = 0; qx < Q1D; ++qx)
1510 for (
int dx = 0; dx < D1D; ++dx)
1512 const real_t s = x_(dx, dy, dz, e);
1513 for (
int qx = 0; qx < Q1D; ++qx)
1515 sol_x[qx] += B_(qx, dx) *
s;
1518 for (
int qy = 0; qy < Q1D; ++qy)
1520 const real_t wy = B_(qy, dy);
1521 for (
int qx = 0; qx < Q1D; ++qx)
1523 sol_xy[qy][qx] += wy * sol_x[qx];
1527 for (
int qz = 0; qz < Q1D; ++qz)
1529 const real_t wz = B_(qz, dz);
1530 for (
int qy = 0; qy < Q1D; ++qy)
1532 for (
int qx = 0; qx < Q1D; ++qx)
1534 y_(qx, qy, qz, e) += wz * sol_xy[qy][qx];
1539 for (
int qz = 0; qz < Q1D; ++qz)
1541 for (
int qy = 0; qy < Q1D; ++qy)
1543 for (
int qx = 0; qx < Q1D; ++qx)
1545 y_(qx, qy, qz, e) *= m_(qx, qy, qz, e);
1563 for (
int dy = 0; dy < D1D; ++dy)
1565 for (
int dx = 0; dx < D1D; ++dx)
1567 y_(dx, dy, e) = 0.0;
1571 for (
int qy = 0; qy < Q1D; ++qy)
1573 real_t sol_x[DofQuadLimits::MAX_D1D];
1574 for (
int dx = 0; dx < D1D; ++dx)
1578 for (
int qx = 0; qx < Q1D; ++qx)
1580 const real_t s = m_(qx, qy, e) * x_(qx, qy, e);
1581 for (
int dx = 0; dx < D1D; ++dx)
1583 sol_x[dx] += Bt_(dx, qx) *
s;
1586 for (
int dy = 0; dy < D1D; ++dy)
1588 const real_t q2d = Bt_(dy, qy);
1589 for (
int dx = 0; dx < D1D; ++dx)
1591 y_(dx, dy, e) += q2d * sol_x[dx];
1601 auto x_ =
Reshape(localH.
Read(), Q1D, Q1D, Q1D, NE);
1604 auto m_ =
Reshape(mask.
Read(), Q1D, Q1D, Q1D, NE);
1608 for (
int dz = 0; dz < D1D; ++dz)
1610 for (
int dy = 0; dy < D1D; ++dy)
1612 for (
int dx = 0; dx < D1D; ++dx)
1614 y_(dx, dy, dz, e) = 0.0;
1619 for (
int qz = 0; qz < Q1D; ++qz)
1621 real_t sol_xy[DofQuadLimits::MAX_D1D][DofQuadLimits::MAX_D1D];
1622 for (
int dy = 0; dy < D1D; ++dy)
1624 for (
int dx = 0; dx < D1D; ++dx)
1629 for (
int qy = 0; qy < Q1D; ++qy)
1631 real_t sol_x[DofQuadLimits::MAX_D1D];
1632 for (
int dx = 0; dx < D1D; ++dx)
1636 for (
int qx = 0; qx < Q1D; ++qx)
1638 const real_t s = m_(qx, qy, qz, e) * x_(qx, qy, qz, e);
1639 for (
int dx = 0; dx < D1D; ++dx)
1641 sol_x[dx] += Bt_(dx, qx) *
s;
1644 for (
int dy = 0; dy < D1D; ++dy)
1646 const real_t wy = Bt_(dy, qy);
1647 for (
int dx = 0; dx < D1D; ++dx)
1649 sol_xy[dy][dx] += wy * sol_x[dx];
1653 for (
int dz = 0; dz < D1D; ++dz)
1655 const real_t wz = Bt_(dz, qz);
1656 for (
int dy = 0; dy < D1D; ++dy)
1658 for (
int dx = 0; dx < D1D; ++dx)
1660 y_(dx, dy, dz, e) += wz * sol_xy[dy][dx];
1683 elem_restrict_lex_l->
Mult(x, localL);
1694 MFEM_ABORT(
"TensorProductPRefinementTransferOperator::Mult not "
1695 "implemented for dim = "
1709 elem_restrict_lex_h->
Mult(x, localH);
1720 MFEM_ABORT(
"TensorProductPRefinementTransferOperator::MultTranspose not "
1721 "implemented for dim = "
1730 :
Operator(hFESpace_.GetTrueVSize(), lFESpace_.GetTrueVSize()),
1731 lFESpace(lFESpace_),
1743 if (P) { MFEM_VERIFY(R,
"Both P and R have to be not NULL") }
1759 delete localTransferOperator;
1767 localTransferOperator->
Mult(tmpL, tmpH);
1772 localTransferOperator->
Mult(x, tmpH);
1777 localTransferOperator->
Mult(x, y);
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 Copy(Array ©) const
Create a copy of the internal array to the provided copy.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Data type for scaled Jacobi-type smoother of sparse matrix.
void Factor()
Factor the current DenseMatrix, *a.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication with the inverse of dense matrix.
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
Data type dense matrix using column-major storage.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
void Transpose()
(*this) = (*this)^t
void SetRow(int r, const real_t *row)
real_t * GetData() const
Returns the matrix data array.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
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.
void GetRow(int r, Vector &row) const
Rank 3 tensor (array of matrices)
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
Structure representing the matrices/tensors needed to evaluate (in reference space) the values,...
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Array< real_t > B
Basis functions evaluated at quadrature points.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Array< real_t > Bt
Transpose of B.
Operator that converts FiniteElementSpace L-vectors to E-vectors.
@ DISCONTINUOUS
Field is discontinuous across element interfaces.
@ CONTINUOUS
Field is continuous across element interfaces.
virtual int GetContType() const =0
Derefinement operator, used by the friend class InterpolationGridTransfer.
GridFunction interpolation operator applicable after mesh refinement.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
void GetVDofs(int vd, Array< int > &dofs, int ndofs=-1) const
Returns the indices of all of the VDofs for the specified dimension 'vd'.
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
const Table & GetElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each mesh element,...
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const
Compute the full set of vdofs corresponding to each entry in dofs.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element 'elem'. The returned indices are offsets into an ldo...
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
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...
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
void GetLocalRefinementMatrices(Geometry::Type geom, DenseTensor &localP) const
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 const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
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.
SparseMatrix * RefinementMatrix_main(const int coarse_ndofs, const Table &coarse_elem_dof, const Table *coarse_elem_fos, const DenseTensor localP[]) const
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
const Table * GetElementToFaceOrientationTable() const
int GetVDim() const
Returns vector dimension.
virtual const SparseMatrix * GetHpRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
static int DecodeDof(int dof)
Helper to return the DOF associated with a sign encoded DOF.
Abstract class for all finite elements.
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...
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
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...
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
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...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
FiniteElementSpace & dom_fes
Domain FE space.
FiniteElementSpace & ran_fes
Range FE space.
Operator::Type oper_type
Desired Operator::Type for the construction of all operators defined by the underlying transfer algor...
const Operator & MakeTrueOperator(FiniteElementSpace &fes_in, FiniteElementSpace &fes_out, const Operator &oper, OperatorHandle &t_oper)
GridTransfer(FiniteElementSpace &dom_fes_, FiniteElementSpace &ran_fes_)
The BoomerAMG solver in hypre.
void SetPrintLevel(int print_level)
Wrapper for hypre's ParCSR matrix class.
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...
HypreParMatrix * Transpose() const
Returns the transpose of *this.
Class for integration point with weight.
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
virtual ~InterpolationGridTransfer()
BilinearFormIntegrator * mass_integ
Ownership depends on own_mass_integ.
OperatorHandle F
Forward, coarse-to-fine, operator.
bool own_mass_integ
Ownership flag for mass_integ.
virtual const Operator & BackwardOperator()
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
OperatorHandle B
Backward, fine-to-coarse, operator.
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,...
virtual const Operator & ForwardOperator()
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
void SetFromTDofsTranspose(const FiniteElementSpace &fes, const Vector &X, Vector &x) const
Sets dual field coefficients given a vector of dual field coefficients on the tdofs and a finite elem...
virtual void Prolongate(const Vector &x, Vector &y) const
void TDofsListByVDim(const FiniteElementSpace &fes, int vdim, Array< int > &vdofs_list) const
Fills the vdofs_list array with a list of vdofs for a given vdim and a given finite element space.
std::unique_ptr< Solver > precon
void SetupPCG()
Sets up the PCG solver (sets parameters, operator, and preconditioner)
virtual void ProlongateTranspose(const Vector &x, Vector &y) const
void GetTDofs(const FiniteElementSpace &fes, const Vector &x, Vector &X) const
Recovers vector of tdofs given a vector of dofs and a finite element space.
void SetFromTDofs(const FiniteElementSpace &fes, const Vector &X, Vector &x) const
Sets dof values given a vector of tdofs and a finite element space.
virtual void SetAbsTol(real_t p_atol_)
Sets absolute tolerance in preconditioned conjugate gradient solver.
std::unique_ptr< Operator > RTxM_LH
L2ProjectionH1Space(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_)
void GetTDofsTranspose(const FiniteElementSpace &fes, const Vector &x, Vector &X) const
Recovers a vector of dual field coefficients on the tdofs given a vector of dual coefficients and a f...
virtual void Mult(const Vector &x, Vector &y) const
std::unique_ptr< SparseMatrix > AllocR()
Computes sparsity pattern and initializes R matrix.
std::unique_ptr< Operator > M_LH
void LumpedMassInverse(Vector &ML_inv) const
Returns the inverse of an on-rank lumped mass matrix.
std::pair< std::unique_ptr< SparseMatrix >, std::unique_ptr< SparseMatrix > > ComputeSparseRAndM_LH()
Computes on-rank R and M_LH matrices.
std::unique_ptr< Operator > R
virtual void MultTranspose(const Vector &x, Vector &y) const
virtual void SetRelTol(real_t p_rtol_)
Sets relative tolerance in preconditioned conjugate gradient solver.
L2ProjectionL2Space(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_)
virtual void Prolongate(const Vector &x, Vector &y) const
virtual void MultTranspose(const Vector &x, Vector &y) const
virtual void Mult(const Vector &x, Vector &y) const
virtual void ProlongateTranspose(const Vector &x, Vector &y) const
void BuildHo2Lor(int nel_ho, int nel_lor, const CoarseFineTransformations &cf_tr)
const FiniteElementSpace & fes_ho
const FiniteElementSpace & fes_lor
void ElemMixedMass(Geometry::Type geom, const FiniteElement &fe_ho, const FiniteElement &fe_lor, ElementTransformation *el_tr, IntegrationPointTransformation &ip_tr, DenseMatrix &M_mixed_el) const
L2Projection(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_)
L2Projection * F
Forward, coarse-to-fine, operator.
virtual bool SupportsBackwardsOperator() const
virtual const Operator & ForwardOperator()
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
L2Prolongation * B
Backward, fine-to-coarse, operator.
virtual ~L2ProjectionGridTransfer()
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)
Class used by MFEM to store pointers to host and/or device memory.
List of mesh geometries stored as Array<Geometry::Type>.
void GetGeometries(int dim, Array< Geometry::Type > &el_geoms) const
Return all element geometries of the given dimension present in the mesh.
const CoarseFineTransformations & GetRefinementTransforms() const
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
Geometry::Type GetElementBaseGeometry(int i) const
Pointer to an Operator of a specified type.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
Operator * Ptr() const
Access the underlying Operator pointer.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
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).
@ ANY_TYPE
ID for the base class Operator, i.e. any type.
@ MFEM_SPARSEMAT
ID for class SparseMatrix.
@ Hypre_ParCSR
ID for class HypreParMatrix.
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 ...
Matrix-free transfer operator between finite element spaces on the same mesh.
PRefinementTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_)
Constructs a transfer operator from lFESpace to hFESpace which have different FE collections.
virtual ~PRefinementTransferOperator()
Destructor.
virtual void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
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...
Abstract parallel finite element space.
HYPRE_BigInt * GetTrueDofOffsets() const
HYPRE_BigInt GlobalVSize() const
HYPRE_BigInt * GetDofOffsets() const
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
ParMesh * GetParMesh() const
General product operator: x -> (A*B)(x) = A(B(x)).
virtual void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
void LoseData()
Call this if data has been stolen.
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void SortRows()
Sort the column (TYPE II) indices in each row.
void SetDims(int rows, int nnz)
const Array< int > & GetDofMap() const
Get an Array<int> that maps lexicographically ordered indices to the indices of the respective nodes/...
Matrix-free transfer operator between finite element spaces on the same mesh exploiting the tensor pr...
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...
TensorProductPRefinementTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_)
Constructs a transfer operator from lFESpace to hFESpace which have different FE collections.
virtual ~TensorProductPRefinementTransferOperator()
Destructor.
virtual void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
Matrix-free transfer operator between finite element spaces.
virtual ~TransferOperator()
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 MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
TransferOperator(const FiniteElementSpace &lFESpace, const FiniteElementSpace &hFESpace)
Constructs a transfer operator from lFESpace to hFESpace.
General triple product operator x -> A*B*C*x, with ownership of the factors.
~TrueTransferOperator()
Destructor.
virtual void MultTranspose(const Vector &x, Vector &y) const override
Restriction by applying the transpose of the Mult method.
TrueTransferOperator(const FiniteElementSpace &lFESpace_, const FiniteElementSpace &hFESpace_)
Constructs a transfer operator working on true degrees of freedom from lFESpace to hFESpace.
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.
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
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...
Vector & Set(const real_t a, const Vector &x)
(*this) = a * x
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.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void Prolongation2D(const int NE, const int D1D, const int Q1D, const Vector &localL, Vector &localH, const Array< real_t > &B, const Vector &mask)
void Restriction3D(const int NE, const int D1D, const int Q1D, const Vector &localH, Vector &localL, const Array< real_t > &Bt, const Vector &mask)
void Restriction2D(const int NE, const int D1D, const int Q1D, const Vector &localH, Vector &localL, const Array< real_t > &Bt, const Vector &mask)
void Prolongation3D(const int NE, const int D1D, const int Q1D, const Vector &localL, Vector &localH, const Array< real_t > &B, const Vector &mask)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B, bool own_matrix)
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
@ LEXICOGRAPHIC
Lexicographic ordering for tensor-product FiniteElements.
SparseMatrix * TransposeMult(const SparseMatrix &A, const SparseMatrix &B)
C = A^T B.
void forall(int N, lambda &&body)
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
real_t p(const Vector &x, real_t t)