28template <>
void Ordering::
29DofsToVDofs<Ordering::byNODES>(
int ndofs,
int vdim,
Array<int> &dofs)
32 int size = dofs.
Size();
34 for (
int vd = 1; vd < vdim; vd++)
36 for (
int i = 0; i < size; i++)
38 dofs[i+size*vd] = Map<byNODES>(ndofs, vdim, dofs[i], vd);
43template <>
void Ordering::
44DofsToVDofs<Ordering::byVDIM>(
int ndofs,
int vdim,
Array<int> &dofs)
47 int size = dofs.
Size();
49 for (
int vd = vdim-1; vd >= 0; vd--)
51 for (
int i = 0; i < size; i++)
53 dofs[i+size*vd] = Map<byVDIM>(ndofs, vdim, dofs[i], vd);
61 ndofs(0), nvdofs(0), nedofs(0), nfdofs(0), nbdofs(0),
63 elem_dof(NULL), elem_fos(NULL), bdr_elem_dof(NULL), bdr_elem_fos(NULL),
65 NURBSext(NULL), own_ext(false),
68 sequence(0), mesh_sequence(0), orders_changed(false), relaxed_hp(false)
75 mesh_ = mesh_ ? mesh_ : orig.
mesh;
76 fec_ = fec_ ? fec_ : orig.
fec;
101 MFEM_VERIFY(
cP == NULL,
"");
102 MFEM_VERIFY(
cR == NULL,
"");
110 int n = perm->
Size();
112 for (
int i=0; i<n; ++i)
116 perm_mat->
Set(i, j,
s);
128 else if (perm != NULL)
139 else if (perm != NULL)
141 cR.reset(perm_mat_tr);
152 "Space has not been Updated() after a Mesh change.");
153 MFEM_VERIFY(i >= 0 && i <
GetNE(),
"Invalid element index");
154 MFEM_VERIFY(
p >= 0 &&
p <=
MaxVarOrder,
"Order out of range");
179 "Space has not been Updated() after a Mesh change.");
180 MFEM_VERIFY(i >= 0 && i <
GetNE(),
"Invalid element index");
195 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
199 for (
int i = 0; i < dofs.
Size(); i++)
201 dofs[i] = Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, i, vd);
206 for (
int i = 0; i < dofs.
Size(); i++)
208 dofs[i] = Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, i, vd);
215 if (
vdim == 1) {
return; }
216 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
220 Ordering::DofsToVDofs<Ordering::byNODES>(ndofs_,
vdim, dofs);
224 Ordering::DofsToVDofs<Ordering::byVDIM>(ndofs_,
vdim, dofs);
230 if (
vdim == 1) {
return; }
231 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
235 for (
int i = 0; i < dofs.
Size(); i++)
237 dofs[i] = Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, dofs[i], vd);
242 for (
int i = 0; i < dofs.
Size(); i++)
244 dofs[i] = Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, dofs[i], vd);
251 if (
vdim == 1) {
return dof; }
252 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
256 return Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, dof, vd);
260 return Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, dof, vd);
267 int n = vdofs.
Size(), *vdof = vdofs;
268 for (
int i = 0; i < n; i++)
271 if ((j = vdof[i]) < 0)
356 if (el_fos) { el_fos -> MakeI (
mesh ->
GetNE()); }
357 for (
int i = 0; i <
mesh ->
GetNE(); i++)
360 el_dof -> AddColumnsInRow (i, dofs.
Size());
365 el_fos -> AddColumnsInRow (i, Fo.
Size());
369 if (el_fos) { el_fos -> MakeJ(); }
370 for (
int i = 0; i <
mesh ->
GetNE(); i++)
373 el_dof -> AddConnections (i, (
int *)dofs, dofs.
Size());
378 el_fos -> AddConnections (i, (
int *)Fo, Fo.
Size());
381 el_dof -> ShiftUpI();
382 if (el_fos) { el_fos -> ShiftUpI(); }
408 if (bel_fos) { bel_fos->
MakeJ(); }
421 if (bel_fos) { bel_fos->
ShiftUpI(); }
437 for (
int i = 0; i < fc_dof->
Size(); i++)
443 for (
int i = 0; i < fc_dof->
Size(); i++)
468 for (
int k = 0, dof_counter = 0; k < nnz; k++)
470 const int sdof = J[k];
471 const int dof = (sdof < 0) ? -1-sdof : sdof;
472 int new_dof = dof_marker[dof];
475 dof_marker[dof] = new_dof = dof_counter++;
477 J[k] = (sdof < 0) ? -1-new_dof : new_dof;
490 for (
int i = 0; i <
mesh ->
GetNE(); i++)
492 const int *dofs =
elem_dof -> GetRow(i);
493 const int n =
elem_dof -> RowSize(i);
494 for (
int j = 0; j < n; j++)
510 mark_array[d >= 0 ? d : -1 - d] = -1;
521 for (
int i = 0; i <
GetNBE(); i++)
533 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
546 for (
auto v : bdr_verts)
555 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
559 for (
auto e : bdr_edges)
568 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
572 for (
auto f : bdr_faces)
581 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
608 std::string error_msg =
"failed dof: ";
609 auto ess_tdofs_ = ess_tdofs.
HostRead();
610 auto ess_tdofs2_ = ess_tdofs2.
HostRead();
611 for (
int i = 0; i < ess_tdofs2.
Size(); ++i)
613 if (
bool(ess_tdofs_[i]) !=
bool(ess_tdofs2_[i]))
615 error_msg += std::to_string(i) +=
"(R ";
616 error_msg += std::to_string(
bool(ess_tdofs_[i])) +=
" P^T ";
617 error_msg += std::to_string(
bool(ess_tdofs2_[i])) +=
") ";
624 MFEM_ASSERT(R->
Width() == ess_vdofs.
Size(),
"!");
625 MFEM_VERIFY(counter == 0,
"internal MFEM error: counter = " << counter
626 <<
' ' << error_msg);
653 for (
int i = 0; i < marker.
Size(); i++)
655 if (marker[i]) { num_marked++; }
659 list.Reserve(num_marked);
660 for (
int i = 0; i < marker.
Size(); i++)
662 if (marker[i]) { list.Append(i); }
674 for (
int i = 0; i < list.Size(); i++)
676 marker[list[i]] = mark_val;
684 if (
cP) {
cP->BooleanMultTranspose(dofs, cdofs); }
685 else { dofs.
Copy(cdofs); }
692 if (
cR) {
cR->BooleanMultTranspose(cdofs, dofs); }
693 else { cdofs.
Copy(dofs); }
711 if (d_vdofs.
Size() != c_vdofs.
Size())
713 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
717 for (j = 0; j < d_vdofs.
Size(); j++)
719 R -> Set (c_vdofs[j], d_vdofs[j], 1.0);
743 if (c_dofs.
Size() != 1)
745 "D2Const_GlobalRestrictionMatrix (...)");
748 for (j = 0; j < d_dofs.
Size(); j++)
750 R -> Set (c_dofs[0], d_dofs[j], 1.0);
774 for (
int i = 0; i <
mesh ->
GetNE(); i++)
781 if (geom != cached_geom)
783 h_fe =
this ->
GetFE (i);
784 l_fe = lfes ->
GetFE (i);
786 h_fe->
Project(*l_fe, T, loc_restr);
790 for (
int vd = 0; vd < lvdim; vd++)
792 l_dofs.
Copy(l_vdofs);
795 h_dofs.
Copy(h_vdofs);
798 R -> SetSubMatrix (l_vdofs, h_vdofs, loc_restr, 1);
811 for (
int i = skipfirst; i < slave_dofs.
Size(); i++)
813 int sdof = slave_dofs[i];
816 for (
int j = 0; j < master_dofs.
Size(); j++)
819 if (std::abs(coef) > 1e-12)
821 int mdof = master_dofs[j];
822 if (mdof != sdof && mdof != (-1-sdof))
824 deps.
Add(sdof, mdof, coef);
847 MFEM_ASSERT(V.
Size() == E.
Size(),
"");
854 for (
int i = 0; i < E.
Size(); i++)
856 int a = i,
b = (i+1) % V.
Size();
857 if (V[
a] > V[
b]) { std::swap(
a,
b); }
864 for (
int j = 0; j < 2; j++)
866 edge_pm(j, 0) = (*pm)(j,
a);
867 edge_pm(j, 1) = (*pm)(j,
b);
868 mid[j] = 0.5*((*pm)(j,
a) + (*pm)(j,
b));
873 if (mid[0] > eps && mid[0] < 1-eps &&
874 mid[1] > eps && mid[1] < 1-eps)
893 for (
int i = 0; i < ndep; i++)
895 if (!finalized[dep[i]]) {
return false; }
922 if (!dofs.
Size()) {
return 0; }
927 for (
int i = 0; i < nv; i++)
930 dofs[nv+i] = edof[nv+i];
934 for (
int i = 0; i < ne; i++)
936 dofs[face_vert*nv + i] = edof[2*nv + i];
989 "This method should not be used with a ParFiniteElementSpace!");
1004 Array<int> master_dofs, slave_dofs, highest_dofs;
1021 for (
int entity = 2; entity >= 1; entity--)
1024 if (!list.masters.Size()) {
continue; }
1031 int p =
GetEntityDofs(entity, master.index, master_dofs, master_geom);
1032 if (!master_dofs.
Size()) {
continue; }
1035 if (!master_fe) {
continue; }
1037 switch (master_geom)
1042 default: MFEM_ABORT(
"unsupported geometry");
1045 for (
int si = master.slaves_begin; si < master.slaves_end; si++)
1050 if (!slave_dofs.
Size()) {
break; }
1069 const auto *pm = list.point_matrices[master_geom][slave.
matrix];
1071 slave_dofs, slave.
index, pm);
1083 master_geom, nvar-1);
1084 const auto *highest_fe =
fec->
GetFE(master_geom, q);
1104 MFEM_ASSERT(ent_dofs.
Size() == num_ent+1,
"");
1108 for (
int i = 0; i < num_ent; i++)
1110 if (ent_dofs.
RowSize(i) <= 1) {
continue; }
1115 if (geom != last_geom)
1123 const auto *master_fe =
fec->
GetFE(geom,
p);
1124 if (!master_fe) {
break; }
1127 for (
int variant = 1; ; variant++)
1129 int q =
GetEntityDofs(entity, i, slave_dofs, geom, variant);
1130 if (q < 0) {
break; }
1132 const auto *slave_fe =
fec->
GetFE(geom, q);
1145 int n_true_dofs = 0;
1146 for (
int i = 0; i <
ndofs; i++)
1148 if (!deps.
RowSize(i)) { n_true_dofs++; }
1152 if (n_true_dofs ==
ndofs)
1170 for (
int i = 0; i < n_true_dofs; i++)
1175 cR_I[n_true_dofs] = n_true_dofs;
1197 for (
int i = 0, true_dof = 0; i <
ndofs; i++)
1201 cP->
Add(i, true_dof, 1.0);
1203 finalized[i] =
true;
1209 inv_deps.
GetRow(i, cols, srow);
1210 cR_hp->AddRow(true_dof, cols, srow);
1214 cR_hp->Add(true_dof, i, 1.0);
1230 int n_finalized = n_true_dofs;
1234 for (
int dof = 0; dof <
ndofs; dof++)
1240 int n_dep = deps.
RowSize(dof);
1242 for (
int j = 0; j < n_dep; j++)
1244 cP->GetRow(dep_col[j], cols, srow);
1245 srow *= dep_coef[j];
1246 cP->AddRow(dof, cols, srow);
1249 finalized[dof] =
true;
1259 MFEM_VERIFY(n_finalized ==
ndofs,
1260 "Error creating cP matrix: n_finalized = "
1261 << n_finalized <<
", ndofs = " <<
ndofs);
1276 if (
vdim == 1) {
return; }
1278 int height = mat.
Height();
1279 int width = mat.
Width();
1285 for (
int i = 0; i < height; i++)
1287 mat.
GetRow(i, dofs, srow);
1288 for (
int vd = 0; vd <
vdim; vd++)
1375 key_face key = std::make_tuple(is_dg_space, f_ordering, type, m);
1376 auto itr =
L2F.find(key);
1377 if (itr !=
L2F.end())
1407 for (
int i = 0; i <
E2Q_array.Size(); i++)
1410 if (qi->
IntRule == &ir) {
return qi; }
1421 for (
int i = 0; i <
E2Q_array.Size(); i++)
1424 if (qi->
qspace == &qs) {
return qi; }
1441 if (qi->
IntRule == &ir) {
return qi; }
1454 if (qi->
IntRule == &ir) {
return qi; }
1465 const int coarse_ndofs,
const Table &coarse_elem_dof,
1478 if (elem_geoms.
Size() == 1)
1480 const int coarse_ldof = localP[elem_geoms[0]].
SizeJ();
1498 const int fine_ldof = localP[geom].
SizeI();
1503 for (
int vd = 0; vd <
vdim; vd++)
1505 coarse_dofs.
Copy(coarse_vdofs);
1508 for (
int i = 0; i < fine_ldof; i++)
1511 int m = (r >= 0) ? r : (-1 - r);
1516 P->
SetRow(r, coarse_vdofs, row);
1523 MFEM_ASSERT(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
1536 int nmat = pmats.
SizeK();
1543 localP.
SetSize(ldof, ldof, nmat);
1544 for (
int i = 0; i < nmat; i++)
1552 const Table* old_elem_dof,
1553 const Table* old_elem_fos)
1555 MFEM_VERIFY(
GetNE() >= old_elem_dof->
Size(),
1556 "Previous mesh is not coarser.");
1561 for (
int i = 0; i < elem_geoms.
Size(); i++)
1574 old_elem_dof(old_elem_dof),
1575 old_elem_fos(old_elem_fos)
1577 MFEM_VERIFY(fespace->
GetNE() >= old_elem_dof->
Size(),
1578 "Previous mesh is not coarser.");
1585 for (
int i = 0; i < elem_geoms.
Size(); i++)
1590 ConstructDoFTransArray();
1596 fespace(fespace), old_elem_dof(NULL), old_elem_fos(NULL)
1600 for (
int i = 0; i < elem_geoms.
Size(); i++)
1603 localP[elem_geoms[i]]);
1615 ConstructDoFTransArray();
1620 delete old_elem_dof;
1621 delete old_elem_fos;
1622 for (
int i=0; i<old_DoFTransArray.Size(); i++)
1624 delete old_DoFTransArray[i];
1628void FiniteElementSpace::RefinementOperator::ConstructDoFTransArray()
1631 for (
int i=0; i<old_DoFTransArray.Size(); i++)
1633 old_DoFTransArray[i] = NULL;
1647 const FiniteElement *nd_tet =
1652 new ND_TetDofTransformation(nd_tet->GetOrder());
1655 const FiniteElement *nd_pri =
1660 new ND_WedgeDofTransformation(nd_pri->GetOrder());
1668 Mesh* mesh_ref = fespace->GetMesh();
1672 Array<int> dofs, vdofs, old_dofs, old_vdofs, old_Fo;
1674 int rvdim = fespace->GetVDim();
1675 int old_ndofs = width / rvdim;
1679 for (
int k = 0; k < mesh_ref->
GetNE(); k++)
1688 old_elem_dof->GetRow(emb.
parent, old_dofs);
1692 for (
int vd = 0; vd < rvdim; vd++)
1695 fespace->DofsToVDofs(vd, vdofs);
1696 old_dofs.
Copy(old_vdofs);
1697 fespace->DofsToVDofs(vd, old_vdofs, old_ndofs);
1700 lP.
Mult(subX, subY);
1706 old_elem_fos->GetRow(emb.
parent, old_Fo);
1707 old_DoFTrans.SetDofTransformation(*old_DoFTransArray[geom]);
1708 old_DoFTrans.SetFaceOrientations(old_Fo);
1711 for (
int vd = 0; vd < rvdim; vd++)
1714 fespace->DofsToVDofs(vd, vdofs);
1715 old_dofs.
Copy(old_vdofs);
1716 fespace->DofsToVDofs(vd, old_vdofs, old_ndofs);
1719 old_DoFTrans.InvTransformPrimal(subX);
1720 lP.
Mult(subX, subY);
1724 doftrans->
SetVDim(rvdim, fespace->GetOrdering());
1734 Mesh* mesh_ref = fespace->GetMesh();
1741 Array<int> f_dofs, c_dofs, f_vdofs, c_vdofs, old_Fo;
1743 int rvdim = fespace->GetVDim();
1744 int old_ndofs = width / rvdim;
1746 Vector subY, subX, subYt;
1748 for (
int k = 0; k < mesh_ref->
GetNE(); k++)
1755 old_elem_dof->GetRow(emb.
parent, c_dofs);
1761 for (
int vd = 0; vd < rvdim; vd++)
1763 f_dofs.
Copy(f_vdofs);
1764 fespace->DofsToVDofs(vd, f_vdofs);
1765 c_dofs.
Copy(c_vdofs);
1766 fespace->DofsToVDofs(vd, c_vdofs, old_ndofs);
1769 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1784 old_elem_fos->GetRow(emb.
parent, old_Fo);
1785 old_DoFTrans.SetDofTransformation(*old_DoFTransArray[geom]);
1786 old_DoFTrans.SetFaceOrientations(old_Fo);
1788 doftrans->SetVDim();
1789 for (
int vd = 0; vd < rvdim; vd++)
1791 f_dofs.
Copy(f_vdofs);
1792 fespace->DofsToVDofs(vd, f_vdofs);
1793 c_dofs.
Copy(c_vdofs);
1794 fespace->DofsToVDofs(vd, c_vdofs, old_ndofs);
1797 doftrans->InvTransformDual(subX);
1798 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1806 old_DoFTrans.TransformDual(subYt);
1809 doftrans->SetVDim(rvdim, fespace->GetOrdering());
1812 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1830 : geom(g), num_children(n), children(c) { }
1832 bool operator<(
const RefType &other)
const
1834 if (geom < other.geom) {
return true; }
1835 if (geom > other.geom) {
return false; }
1836 if (num_children < other.num_children) {
return true; }
1837 if (num_children > other.num_children) {
return false; }
1838 for (
int i = 0; i < num_children; i++)
1840 if (children[i].one < other.children[i].one) {
return true; }
1841 if (children[i].one > other.children[i].one) {
return false; }
1847void GetCoarseToFineMap(
const CoarseFineTransformations &cft,
1849 Table &coarse_to_fine,
1850 Array<int> &coarse_to_ref_type,
1851 Table &ref_type_to_matrix,
1852 Array<Geometry::Type> &ref_type_to_geom)
1854 const int fine_ne = cft.embeddings.Size();
1856 for (
int i = 0; i < fine_ne; i++)
1858 coarse_ne = std::max(coarse_ne, cft.embeddings[i].parent);
1862 coarse_to_ref_type.SetSize(coarse_ne);
1863 coarse_to_fine.SetDims(coarse_ne, fine_ne);
1865 Array<int> cf_i(coarse_to_fine.GetI(), coarse_ne+1);
1866 Array<Pair<int,int> > cf_j(fine_ne);
1868 for (
int i = 0; i < fine_ne; i++)
1870 cf_i[cft.embeddings[i].parent+1]++;
1873 MFEM_ASSERT(cf_i.Last() == cf_j.Size(),
"internal error");
1874 for (
int i = 0; i < fine_ne; i++)
1876 const Embedding &e = cft.embeddings[i];
1877 cf_j[cf_i[e.parent]].one = e.matrix;
1878 cf_j[cf_i[e.parent]].two = i;
1881 std::copy_backward(cf_i.begin(), cf_i.end()-1, cf_i.end());
1883 for (
int i = 0; i < coarse_ne; i++)
1885 std::sort(&cf_j[cf_i[i]], cf_j.GetData() + cf_i[i+1]);
1887 for (
int i = 0; i < fine_ne; i++)
1889 coarse_to_fine.GetJ()[i] = cf_j[i].two;
1895 map<RefType,int> ref_type_map;
1896 for (
int i = 0; i < coarse_ne; i++)
1898 const int num_children = cf_i[i+1]-cf_i[i];
1899 MFEM_ASSERT(num_children > 0,
"");
1900 const int fine_el = cf_j[cf_i[i]].two;
1903 const RefType ref_type(geom, num_children, &cf_j[cf_i[i]]);
1904 pair<map<RefType,int>::iterator,
bool> res =
1905 ref_type_map.insert(
1906 pair<const RefType,int>(ref_type, (
int)ref_type_map.size()));
1907 coarse_to_ref_type[i] = res.first->second;
1910 ref_type_to_matrix.MakeI((
int)ref_type_map.size());
1911 ref_type_to_geom.SetSize((
int)ref_type_map.size());
1912 for (map<RefType,int>::iterator it = ref_type_map.begin();
1913 it != ref_type_map.end(); ++it)
1915 ref_type_to_matrix.AddColumnsInRow(it->second, it->first.num_children);
1916 ref_type_to_geom[it->second] = it->first.geom;
1919 ref_type_to_matrix.MakeJ();
1920 for (map<RefType,int>::iterator it = ref_type_map.begin();
1921 it != ref_type_map.end(); ++it)
1923 const RefType &rt = it->first;
1924 for (
int j = 0; j < rt.num_children; j++)
1926 ref_type_to_matrix.AddConnection(it->second, rt.children[j].one);
1929 ref_type_to_matrix.ShiftUpI();
1944 "incompatible coarse and fine FE spaces");
1952 for (
int gi = 0; gi < elem_geoms.
Size(); gi++)
1955 DenseTensor &lP = localP[geom], &lM = localM[geom];
1965 for (
int i = 0; i < pmats.
SizeK(); i++)
1975 Table ref_type_to_matrix;
1976 internal::GetCoarseToFineMap(rtrans, *f_mesh, coarse_to_fine,
1977 coarse_to_ref_type, ref_type_to_matrix,
1979 MFEM_ASSERT(coarse_to_fine.Size() == c_fes->
GetNE(),
"");
1981 const int total_ref_types = ref_type_to_geom.Size();
1983 Array<int> ref_type_to_coarse_elem_offset(total_ref_types);
1984 ref_type_to_fine_elem_offset.
SetSize(total_ref_types);
1987 for (
int i = 0; i < total_ref_types; i++)
1990 ref_type_to_coarse_elem_offset[i] = num_ref_types[g];
1991 ref_type_to_fine_elem_offset[i] = num_fine_elems[g];
1993 num_fine_elems[g] += ref_type_to_matrix.
RowSize(i);
1998 if (num_ref_types[g] == 0) {
continue; }
1999 const int fine_dofs = localP[g].
SizeI();
2000 const int coarse_dofs = localP[g].
SizeJ();
2001 localPtMP[g].
SetSize(coarse_dofs, coarse_dofs, num_ref_types[g]);
2002 localR[g].
SetSize(coarse_dofs, fine_dofs, num_fine_elems[g]);
2004 for (
int i = 0; i < total_ref_types; i++)
2007 DenseMatrix &lPtMP = localPtMP[g](ref_type_to_coarse_elem_offset[i]);
2008 int lR_offset = ref_type_to_fine_elem_offset[i];
2009 const int *mi = ref_type_to_matrix.
GetRow(i);
2010 const int nm = ref_type_to_matrix.
RowSize(i);
2012 for (
int s = 0;
s < nm;
s++)
2021 for (
int s = 0;
s < nm;
s++)
2034 delete coarse_elem_dof;
2043 const int fine_vdim = fine_fes->GetVDim();
2044 const int coarse_ndofs = height/fine_vdim;
2045 for (
int coarse_el = 0; coarse_el < coarse_to_fine.Size(); coarse_el++)
2047 coarse_elem_dof->
GetRow(coarse_el, c_vdofs);
2048 fine_fes->DofsToVDofs(c_vdofs, coarse_ndofs);
2053 const int ref_type = coarse_to_ref_type[coarse_el];
2055 const int *fine_elems = coarse_to_fine.GetRow(coarse_el);
2056 const int num_fine_elems = coarse_to_fine.RowSize(coarse_el);
2057 const int lR_offset = ref_type_to_fine_elem_offset[ref_type];
2058 for (
int s = 0;
s < num_fine_elems;
s++)
2061 fine_fes->GetElementVDofs(fine_elems[
s], f_vdofs);
2080 const int nmat = pmats.
SizeK();
2081 const int ldof = fe->
GetDof();
2087 localR.
SetSize(ldof, ldof, nmat);
2088 for (
int i = 0; i < nmat; i++)
2096 const Table* old_elem_dof,
2097 const Table* old_elem_fos)
2101 MFEM_VERIFY(
Nonconforming(),
"Not implemented for conforming meshes.");
2102 MFEM_VERIFY(old_ndofs,
"Missing previous (finer) space.");
2103 MFEM_VERIFY(
ndofs <= old_ndofs,
"Previous space is not finer.");
2111 for (
int i = 0; i < elem_geoms.
Size(); i++)
2124 MFEM_ASSERT(dtrans.
embeddings.Size() == old_elem_dof->
Size(),
"");
2128 for (
int k = 0; k < dtrans.
embeddings.Size(); k++)
2135 old_elem_dof->
GetRow(k, old_dofs);
2137 for (
int vd = 0; vd <
vdim; vd++)
2139 old_dofs.
Copy(old_vdofs);
2142 for (
int i = 0; i < lR.
Height(); i++)
2144 if (!std::isfinite(lR(i, 0))) {
continue; }
2147 int m = (r >= 0) ? r : (-1 - r);
2149 if (is_dg || !mark[m])
2152 R->
SetRow(r, old_vdofs, row);
2163 MFEM_VERIFY(num_marked == R->
Height(),
2164 "internal error: not all rows of R were set.");
2184 int nmat = pmats.
SizeK();
2191 for (
int i = 0; i < nmat; i++)
2200 int vdim_,
int ordering_)
2221 MFEM_VERIFY(mesh_->
NURBSext,
"NURBS FE space requires a NURBS mesh.");
2223 if (NURBSext_ == NULL)
2294 mfem_error(
"FiniteElementSpace::StealNURBSext");
2303 MFEM_VERIFY(
NURBSext,
"NURBSExt not defined.");
2347 if (
b == -1) {
continue; }
2357 for (
int i = 0; i < nv; i++)
2359 MFEM_VERIFY(fv[i] == bv[i],
2360 "non-matching face and boundary elements detected!");
2365 for (
int i = 0; i < row.
Size(); i++)
2368 face_dof_list.
Append(conn);
2377 MFEM_VERIFY(!
NURBSext,
"internal error");
2382 "Variable order space requires a nonconforming mesh.");
2405 "Mesh was not correctly finalized.");
2416 else if (mixed_faces)
2505 MFEM_ASSERT(bits != 0,
"invalid bit mask");
2506 for (
int order = 0; bits != 0; order++, bits >>= 1)
2508 if (bits & 1) {
return order; }
2534 for (
int j = 0; j < E.
Size(); j++)
2536 edge_orders[E[j]] |= mask;
2542 for (
int j = 0; j < F.
Size(); j++)
2544 face_orders[F[j]] |= mask;
2570 for (
int i = master.slaves_begin; i < master.slaves_end; i++)
2572 slave_orders |= edge_orders[edge_list.
slaves[i].index];
2575 int min_order =
MinOrder(slave_orders);
2576 if (min_order <
MinOrder(edge_orders[master.index]))
2578 edge_orders[master.index] |= (
VarOrderBits(1) << min_order);
2588 for (
int i = master.slaves_begin; i < master.slaves_end; i++)
2591 if (slave.
index >= 0)
2593 slave_orders |= face_orders[slave.
index];
2596 for (
int j = 0; j < E.
Size(); j++)
2598 slave_orders |= edge_orders[E[j]];
2604 slave_orders |= edge_orders[-1 - slave.
index];
2608 int min_order =
MinOrder(slave_orders);
2609 if (min_order <
MinOrder(face_orders[master.index]))
2611 face_orders[master.index] |= (
VarOrderBits(1) << min_order);
2620 for (
int j = 0; j < E.
Size(); j++)
2622 edge_orders[E[j]] |= face_orders[i];
2644 int num_ent = entity_orders.
Size();
2653 var_ent_order->
Reserve(num_ent);
2657 for (
int i = 0; i < num_ent; i++)
2662 for (
int order = 0; bits != 0; order++, bits >>= 1)
2669 if (var_ent_order) { var_ent_order->
Append(order); }
2675 list.Append(
Connection(num_ent, total_dofs));
2683 int row,
int ndof)
const
2685 const int *beg = var_dof_table.
GetRow(row);
2686 const int *end = var_dof_table.
GetRow(row + 1);
2691 if ((beg[1] - beg[0]) == ndof) {
return beg[0]; }
2695 MFEM_ABORT(
"DOFs not found for ndof = " << ndof);
2705 if (variant >= end - beg) {
return -1; }
2721 if (variant >= end - beg) {
return -1; }
2735static const char* msg_orders_changed =
2736 "Element orders changed, you need to Update() the space first.";
2776 for (
int i = 0; i < F.
Size(); i++)
2794 for (
int i = 0; i < V.
Size(); i++)
2796 for (
int j = 0; j < nv; j++)
2798 dofs.
Append(V[i]*nv + j);
2805 for (
int i = 0; i < E.
Size(); i++)
2810 for (
int j = 0; j < ne; j++)
2819 for (
int i = 0; i < F.
Size(); i++)
2827 for (
int j = 0; j < nf; j++)
2839 for (
int j = 0; j < nb; j++)
2915 for (
int i = 0; i < V.
Size(); i++)
2917 for (
int j = 0; j < nv; j++)
2919 dofs.
Append(V[i]*nv + j);
2926 for (
int i = 0; i < E.
Size(); i++)
2931 for (
int j = 0; j < ne; j++)
2943 for (
int j = 0; j < nf; j++)
2972 int order, nf, fbase;
2980 if (variant >= end - beg) {
return -1; }
2982 fbase = beg[variant];
2983 nf = beg[variant+1] - fbase;
2989 std::stringstream msg;
2990 msg <<
"fec->GetNumDof(" << (fgeom == Geometry::SQUARE ?
"square" :
"triangle")
2991 <<
", " << order <<
") = " << fec->GetNumDof(fgeom, order) <<
" nf " << nf;
2992 msg <<
" face " << face <<
" variant " << variant << std::endl;
2998 if (variant > 0) {
return -1; }
3017 for (
int i = 0; i < V.
Size(); i++)
3019 for (
int j = 0; j < nv; j++)
3021 dofs.
Append(V[i]*nv + j);
3027 for (
int i = 0; i < E.
Size(); i++)
3032 for (
int j = 0; j < ne; j++)
3038 for (
int j = 0; j < nf; j++)
3051 int order, ne, base;
3056 if (variant >= end - beg) {
return -1; }
3058 base = beg[variant];
3059 ne = beg[variant+1] - base;
3066 if (variant > 0) {
return -1; }
3079 for (
int i = 0; i < 2; i++)
3081 for (
int j = 0; j < nv; j++)
3083 dofs.
Append(V[i]*nv + j);
3086 for (
int j = 0; j < ne; j++)
3098 for (
int j = 0; j < nv; j++)
3113 for (
int j = 0; j < nb; j++)
3143 for (
int j = 0; j < nf; j++)
3155 for (
int j = 0, k =
nvdofs+i*ne; j < ne; j++, k++)
3164 "FiniteElementSpace::GetPatchDofs needs a NURBSExtension");
3174 MFEM_ABORT(
"Empty MPI partitions are not permitted!");
3176 MFEM_ABORT(
"Invalid element id:" << i <<
"; minimum allowed:" << 0 <<
3177 ", maximum allowed:" <<
mesh->
GetNE()-1);
3195 "internal error: " <<
3260 "NURBS mesh: only boundary faces are supported!");
3270 MFEM_ASSERT(
mesh->
Dimension() > 1,
"No edges with mesh dimension < 2");
3296 for (
int i = 0; i <
E2Q_array.Size(); i++)
3359 for (
int i = 0; i < elem_geoms.
Size(); i++)
3362 localP[elem_geoms[i]]);
3398 if (RP_case == 0) {
return; }
3411 cR.get(), T.
Ptr(), coarse_P,
false, owner,
false));
3433 MFEM_ABORT(
"not implemented yet");
3449 MFEM_ABORT(
"Error in update sequence. Space needs to be updated after "
3450 "each mesh modification.");
3457 MFEM_ABORT(
"Updating space after both mesh change and element order "
3458 "change is not supported. Please update separately after "
3469 Table* old_elem_dof = NULL;
3470 Table* old_elem_fos = NULL;
3496 MFEM_VERIFY(!old_orders_changed,
"Interpolation for element order change "
3497 "is not implemented yet, sorry.");
3507 old_elem_fos, old_ndofs));
3510 old_elem_dof = NULL;
3511 old_elem_fos = NULL;
3530 false,
false,
true));
3539 delete old_elem_dof;
3540 delete old_elem_fos;
3551 int fes_format = 90;
3552 bool nurbs_unit_weights =
false;
3563 MFEM_VERIFY(nurbs_fec,
"invalid FE collection");
3565 const real_t eps = 5e-14;
3576 os << (fes_format == 90 ?
3577 "FiniteElementSpace\n" :
"MFEM FiniteElementSpace v1.0\n")
3578 <<
"FiniteElementCollection: " <<
fec->
Name() <<
'\n'
3579 <<
"VDim: " <<
vdim <<
'\n'
3580 <<
"Ordering: " <<
ordering <<
'\n';
3582 if (fes_format == 100)
3596 os <<
"NURBS_orders\n";
3603 os <<
"NURBS_periodic\n";
3608 if (!nurbs_unit_weights)
3610 os <<
"NURBS_weights\n";
3614 os <<
"End: MFEM FiniteElementSpace v1.0\n";
3621 int fes_format = 0, ord;
3627 getline(input, buff);
3629 if (buff ==
"FiniteElementSpace") { fes_format = 90; }
3630 else if (buff ==
"MFEM FiniteElementSpace v1.0") { fes_format = 100; }
3631 else { MFEM_ABORT(
"input stream is not a FiniteElementSpace!"); }
3632 getline(input, buff,
' ');
3634 getline(input, buff);
3637 getline(input, buff,
' ');
3639 getline(input, buff,
' ');
3644 if (fes_format == 90)
3648 MFEM_VERIFY(m->
NURBSext,
"NURBS FE collection requires a NURBS mesh!");
3649 const int order = nurbs_fec->
GetOrder();
3657 else if (fes_format == 100)
3662 MFEM_VERIFY(input.good(),
"error reading FiniteElementSpace v1.0");
3663 getline(input, buff);
3665 if (buff ==
"NURBS_order" || buff ==
"NURBS_orders")
3667 MFEM_VERIFY(nurbs_fec,
3668 buff <<
": NURBS FE collection is required!");
3669 MFEM_VERIFY(m->
NURBSext, buff <<
": NURBS mesh is required!");
3670 MFEM_VERIFY(!nurbs_ext, buff <<
": order redefinition!");
3671 if (buff ==
"NURBS_order")
3684 else if (buff ==
"NURBS_periodic")
3691 else if (buff ==
"NURBS_weights")
3693 MFEM_VERIFY(nurbs_ext,
"NURBS_weights: NURBS_orders have to be "
3694 "specified before NURBS_weights!");
3697 else if (buff ==
"element_orders")
3699 MFEM_VERIFY(!nurbs_fec,
"section element_orders cannot be used "
3700 "with a NURBS FE collection");
3701 MFEM_ABORT(
"element_orders: not implemented yet!");
3703 else if (buff ==
"End: MFEM FiniteElementSpace v1.0")
3709 MFEM_ABORT(
"unknown section: " << buff);
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
T Sum()
Return the sum of all the array entries using the '+'' operator for class 'T'.
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.
void DeleteAll()
Delete the whole array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void Save(std::ostream &out, int fmt=0) const
Save the Array to the stream out using the format fmt. The format fmt can be:
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication with the inverse of dense matrix.
Data type dense matrix using column-major storage.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
void UseExternalData(real_t *d, int h, int w)
Change the data array and the size of the DenseMatrix.
void GetRow(int r, Vector &row) const
Rank 3 tensor (array of matrices)
void SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
Abstract base class that defines an interface for element restrictions.
Operator that converts FiniteElementSpace L-vectors to E-vectors.
Abstract data type element.
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
virtual int GetNVertices() const =0
A class that performs interpolation from a face E-vector to quadrature point values and/or derivative...
const IntegrationRule * IntRule
Not owned.
Base class for operators that extracts Face degrees of freedom.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
static FiniteElementCollection * New(const char *name)
Factory method: return a newly allocated FiniteElementCollection according to the given name.
@ DISCONTINUOUS
Field is discontinuous across element interfaces.
const int * GetDofOrdering(Geometry::Type geom, int p, int ori) const
Variable order version of DofOrderForOrientation().
int GetOrder() const
Return the order (polynomial degree) of the FE collection, corresponding to the order/degree returned...
virtual int GetContType() const =0
int HasFaceDofs(Geometry::Type geom, int p) const
virtual int DofForGeometry(Geometry::Type GeomType) const =0
int GetNumDof(Geometry::Type geom, int p) const
Variable order version of DofForGeometry().
virtual const FiniteElement * TraceFiniteElementForGeometry(Geometry::Type GeomType) const
virtual const char * Name() const
const FiniteElement * GetFE(Geometry::Type geom, int p) const
Variable order version of FiniteElementForGeometry().
virtual const FiniteElement * FiniteElementForGeometry(Geometry::Type GeomType) const =0
virtual ~DerefinementOperator()
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
DerefinementOperator(const FiniteElementSpace *f_fes, const FiniteElementSpace *c_fes, BilinearFormIntegrator *mass_integ)
TODO: Implement DofTransformation support.
GridFunction interpolation operator applicable after mesh refinement.
virtual ~RefinementOperator()
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 ...
RefinementOperator(const FiniteElementSpace *fespace, Table *old_elem_dof, Table *old_elem_fos, int old_ndofs)
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
void Save(std::ostream &out) const
Save finite element space to output stream out.
void DestroyDoFTransArray()
int GetEntityVDofs(int entity, int index, Array< int > &dofs, Geometry::Type master_geom=Geometry::INVALID, int variant=0) const
Helper to get vertex, edge or face VDOFs (entity=0,1,2 resp.).
void GetVDofs(int vd, Array< int > &dofs, int ndofs=-1) const
Returns the indices of all of the VDofs for the specified dimension 'vd'.
DofTransformation DoFTrans
static int EncodeDof(int entity_base, int idx)
Helper to encode a sign flip into a DOF index (for Hcurl/Hdiv shapes).
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
void ReorderElementToDofTable()
Reorder the scalar DOFs based on the element ordering.
Array< char > var_face_orders
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
void BuildNURBSFaceToDofTable() const
Generates partial face_dof table for a NURBS space.
static void AddDependencies(SparseMatrix &deps, Array< int > &master_dofs, Array< int > &slave_dofs, DenseMatrix &I, int skipfirst=0)
const Table & GetElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each mesh element,...
Array< int > dof_ldof_array
Array< StatelessDofTransformation * > DoFTransArray
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const
Compute the full set of vdofs corresponding to each entry in dofs.
void GetEdgeInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified edge.
Array< FaceQuadratureInterpolator * > E2BFQ_array
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
Array< FaceQuadratureInterpolator * > E2IFQ_array
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...
int GetNumElementInteriorDofs(int i) const
Returns the number of degrees of freedom associated with the interior of the specified element.
void GetEdgeVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the specified edge, including the DOFs for the vert...
NURBSExtension * NURBSext
virtual int GetFaceDofs(int face, Array< int > &dofs, int variant=0) const
Returns the indices of the degrees of freedom for the specified face, including the DOFs for the edge...
virtual void GetTrueTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
Construct and return an Operator that can be used to transfer true-dof data from coarse_fes,...
static void AdjustVDofs(Array< int > &vdofs)
Remove the orientation information encoded into an array of dofs Some basis function types have a rel...
int GetEdgeOrder(int edge, int variant=0) const
bool Nonconforming() const
void GetVertexVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the specified vertices.
void GetVertexDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the specified vertices.
void BuildFaceToDofTable() const
int GetFaceOrder(int face, int variant=0) const
Returns the polynomial degree of the i'th face finite element.
int GetNumBorderDofs(Geometry::Type geom, int order) const
FiniteElementSpace()
Default constructor: the object is invalid until initialized using the method Load().
Array< int > dof_elem_array
int FindFaceDof(int face, int ndof) const
Similar to FindEdgeDof, but used for mixed meshes too.
static int MinOrder(VarOrderBits bits)
Return the minimum order (least significant bit set) in the bit mask.
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...
MFEM_DEPRECATED void RebuildElementToDofTable()
(
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
bool orders_changed
True if at least one element order changed (variable-order space only).
SparseMatrix * DerefinementMatrix(int old_ndofs, const Table *old_elem_dof, const Table *old_elem_fos)
Calculate GridFunction restriction matrix after mesh derefinement.
void GetLocalRefinementMatrices(Geometry::Type geom, DenseTensor &localP) const
void GetEdgeInteriorVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the interior of the specified edge.
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,...
SparseMatrix * D2C_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
Generate the global restriction matrix from a discontinuous FE space to the continuous FE space of th...
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
int GetNBE() const
Returns number of boundary elements in the mesh.
virtual void UpdateMeshPointer(Mesh *new_mesh)
int GetDegenerateFaceDofs(int index, Array< int > &dofs, Geometry::Type master_geom, int variant) const
const QuadratureInterpolator * GetQuadratureInterpolator(const IntegrationRule &ir) const
Return a QuadratureInterpolator that interpolates E-vectors to quadrature point values and/or derivat...
int GetBdrAttribute(int i) const
int GetEntityDofs(int entity, int index, Array< int > &dofs, Geometry::Type master_geom=Geometry::INVALID, int variant=0) const
Helper to get vertex, edge or face DOFs (entity=0,1,2 resp.).
virtual const Operator * GetRestrictionOperator() const
An abstract operator that performs the same action as GetRestrictionMatrix.
static constexpr int MaxVarOrder
virtual void CopyProlongationAndRestriction(const FiniteElementSpace &fes, const Array< int > *perm)
Copies the prolongation and restriction matrices from fes.
Array< char > var_edge_orders
std::unique_ptr< Operator > R_transpose
Operator computing the action of the transpose of the restriction.
void UpdateElementOrders()
Resize the elem_order array on mesh change.
void MakeVDimMatrix(SparseMatrix &mat) const
Replicate 'mat' in the vector dimension, according to vdim ordering mode.
int GetNF() const
Returns number of faces (i.e. co-dimension 1 entities) in the mesh.
SparseMatrix * H2L_GlobalRestrictionMatrix(FiniteElementSpace *lfes)
Construct the restriction matrix from the FE space given by (*this) to the lower degree FE space give...
SparseMatrix * D2Const_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
Generate the global restriction matrix from a discontinuous FE space to the piecewise constant FE spa...
const FiniteElementCollection * fec
Associated FE collection (not owned).
FiniteElementCollection * Load(Mesh *m, std::istream &input)
Read a FiniteElementSpace from a stream. The returned FiniteElementCollection is owned by the caller.
void BuildBdrElementToDofTable() const
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
Array< QuadratureInterpolator * > E2Q_array
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Ordering::Type GetOrdering() const
Return the ordering method.
NURBSExtension * StealNURBSext()
void BuildDofToArrays()
Initialize internal data that enables the use of the methods GetElementForDof() and GetLocalDofForDof...
void GetPatchDofs(int patch, Array< int > &dofs) const
Returns indices of degrees of freedom for NURBS patch index patch. Cartesian ordering is used,...
const Operator * GetRestrictionTransposeOperator() const
Return an operator that performs the transpose of GetRestrictionOperator.
static bool DofFinalizable(int dof, const Array< bool > &finalized, const SparseMatrix &deps)
void GetLocalDerefinementMatrices(Geometry::Type geom, DenseTensor &localR) const
void BuildConformingInterpolation() const
Calculate the cP and cR matrices for a nonconforming mesh.
int GetNE() const
Returns number of elements in the mesh.
int vdim
Vector dimension (number of unknowns per degree of freedom).
Table var_face_dofs
NOTE: also used for spaces with mixed faces.
OperatorHandle L2E_nat
The element restriction operators, see GetElementRestriction().
int * bdofs
internal DOFs of elements if mixed/var-order; NULL otherwise
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
const FiniteElement * GetEdgeElement(int i, int variant=0) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th edge in the ...
int GetEdgeDofs(int edge, Array< int > &dofs, int variant=0) const
Returns the indices of the degrees of freedom for the specified edge, including the DOFs for the vert...
std::tuple< bool, ElementDofOrdering, FaceType, L2FaceValues > key_face
The face restriction operators, see GetFaceRestriction().
std::unique_ptr< SparseMatrix > cR
Conforming restriction matrix such that cR.cP=I.
void ConstructDoFTransArray()
void GetElementInteriorVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the interior of the specified element.
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the specified face, including the DOFs for the edge...
virtual void Update(bool want_transform=true)
Reflect changes in the mesh: update number of DOFs, etc. Also, calculate GridFunction transformation ...
OperatorHandle Th
Transformation to apply to GridFunctions after space Update().
void CalcEdgeFaceVarOrders(Array< VarOrderBits > &edge_orders, Array< VarOrderBits > &face_orders) const
SparseMatrix * RefinementMatrix(int old_ndofs, const Table *old_elem_dof, const Table *old_elem_fos)
std::uint64_t VarOrderBits
Bit-mask representing a set of orders needed by an edge/face.
SparseMatrix * RefinementMatrix_main(const int coarse_ndofs, const Table &coarse_elem_dof, const Table *coarse_elem_fos, const DenseTensor localP[]) const
int ndofs
Number of degrees of freedom. Number of unknowns is ndofs * vdim.
std::unique_ptr< SparseMatrix > cP
void AddEdgeFaceDependencies(SparseMatrix &deps, Array< int > &master_dofs, const FiniteElement *master_fe, Array< int > &slave_dofs, int slave_face, const DenseMatrix *pm) const
const FiniteElement * GetTraceElement(int i, Geometry::Type geom_type) const
Return the trace element from element 'i' to the given 'geom_type'.
int MakeDofTable(int ent_dim, const Array< int > &entity_orders, Table &entity_dofs, Array< char > *var_ent_order)
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
Mesh * mesh
The mesh that FE space lives on (not owned).
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
void ConvertToConformingVDofs(const Array< int > &dofs, Array< int > &cdofs)
For a partially conforming FE space, convert a marker array (nonzero entries are true) on the partial...
void SetElementOrder(int i, int p)
Sets the order of the i'th finite element.
const SparseMatrix * GetHpConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
int GetElementOrderImpl(int i) const
Return element order: internal version of GetElementOrder without checks.
int GetNVariants(int entity, int index) const
Return number of possible DOF variants for edge/face (var. order spaces).
virtual ~FiniteElementSpace()
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
const Table * GetElementToFaceOrientationTable() const
DofTransformation * GetBdrElementDofs(int bel, Array< int > &dofs) const
Returns indices of degrees of freedom for boundary element 'bel'. The returned indices are offsets in...
void GetBoundaryTrueDofs(Array< int > &boundary_dofs, int component=-1)
Get a list of all boundary true dofs, boundary_dofs. For spaces with 'vdim' > 1, the 'component' para...
int GetVDim() const
Returns vector dimension.
const FaceQuadratureInterpolator * GetFaceQuadratureInterpolator(const IntegrationRule &ir, FaceType type) const
Return a FaceQuadratureInterpolator that interpolates E-vectors to quadrature point values and/or der...
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
void GetFaceInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified face.
int GetNConformingDofs() const
static int DecodeDof(int dof)
Helper to return the DOF associated with a sign encoded DOF.
void GetElementInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified element.
void Constructor(Mesh *mesh, NURBSExtension *ext, const FiniteElementCollection *fec, int vdim=1, int ordering=Ordering::byNODES)
Help function for constructors + Load().
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for i'th boundary element. The returned indices are offsets int...
void ConvertFromConformingVDofs(const Array< int > &cdofs, Array< int > &dofs)
For a partially conforming FE space, convert a marker array (nonzero entries are true) on the conform...
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_vdofs, int component=-1) const
Mark degrees of freedom associated with boundary elements with the specified boundary attributes (mar...
int DofToVDof(int dof, int vd, int ndofs=-1) const
Compute a single vdof corresponding to the index dof and the vector index vd.
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.
int FindEdgeDof(int edge, int ndof) const
void GetPatchVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom in vdofs for NURBS patch i.
void BuildElementToDofTable() const
std::unique_ptr< SparseMatrix > cR_hp
A version of the conforming restriction matrix for variable-order spaces.
int FindDofs(const Table &var_dof_table, int row, int ndof) const
Search row of a DOF table for a DOF set of size 'ndof', return first DOF.
Abstract class for all finite elements.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
int GetDim() const
Returns the reference space dimension for the finite element.
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 GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs.
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
static const int NumVerts[NumGeom]
Class for an integration rule - an Array of IntegrationPoint.
Operator that converts L2 FiniteElementSpace L-vectors to E-vectors.
Operator that extracts Face degrees of freedom for L2 spaces.
Class used by MFEM to store pointers to host and/or device memory.
List of mesh geometries stored as Array<Geometry::Type>.
void GetFaceEdges(int i, Array< int > &edges, Array< int > &o) const
Operation GetLastOperation() const
Return type of last modification of the mesh.
int GetNEdges() const
Return the number of edges.
void GetBdrElementFace(int i, int *f, int *o) const
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
Geometry::Type GetFaceGeometry(int i) const
Return the Geometry::Type associated with face i.
Geometry::Type GetElementGeometry(int i) const
Geometry::Type GetBdrElementGeometry(int i) const
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
int GetBdrElementFaceIndex(int be_idx) const
Return the local face (codimension-1) index for the given boundary element index.
int GetNFaces() const
Return the number of faces in a 3D mesh.
const CoarseFineTransformations & GetRefinementTransforms() const
int GetNE() const
Returns number of elements.
const Element * GetFace(int i) const
Return pointer to the i'th face element object.
int Dimension() const
Dimension of the reference space used within the elements.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
void GetBdrElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of bdr element i.
void GetElementFaces(int i, Array< int > &faces, Array< int > &ori) const
Return the indices and the orientations of all faces of element i.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
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....
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
int GetNBE() const
Returns number of boundary elements.
NCMesh * ncmesh
Optional nonconforming mesh extension.
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
Geometry::Type GetElementBaseGeometry(int i) const
Operator that extracts face degrees of freedom for L2 nonconforming spaces.
const NCList & GetNCList(int entity)
Return vertex/edge/face list (entity = 0/1/2, respectively).
const CoarseFineTransformations & GetDerefinementTransforms() const
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
virtual void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges, Array< int > &bdr_faces)
Get a list of vertices (2D/3D), edges (3D) and faces (3D) that coincide with boundary elements with t...
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
Arbitrary order H(curl)-conforming Nedelec finite elements.
const Vector & GetWeights() const
const Array< int > & GetSlave() const
void LoadBE(int i, const FiniteElement *BE) const
Table * GetElementDofTable()
const Array< int > & GetMaster() const
void LoadFE(int i, const FiniteElement *FE) const
void GetPatchDofs(const int patch, Array< int > &dofs)
Table * GetBdrElementDofTable()
int GetOrder() const
If all orders are identical, return that number. Otherwise, return NURBSFECollection::VariableOrder.
const Array< int > & GetOrders() const
Read-only access to the orders of all knot vectors.
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
int GetOrder() const
Get the order of the NURBS collection: either a positive number, when using fixed order,...
void SetOrder(int Order) const
Set the order and the name, based on the given Order: either a positive number for fixed order,...
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().
bool OwnsOperator() const
Return true if the OperatorHandle owns the held Operator.
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
Operator * Ptr() const
Access the underlying Operator pointer.
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
OpType * Is() const
Return the Operator pointer dynamically cast to a specified OpType.
Operator::Type Type() const
Get the currently set operator type id.
int width
Dimension of the input / number of columns in the matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Type
Enumeration defining IDs for some classes derived from Operator.
@ ANY_TYPE
ID for the base class Operator, i.e. any type.
@ MFEM_SPARSEMAT
ID for class SparseMatrix.
The ordering method used when the number of unknowns per mesh node (vector dimension) is bigger than ...
Abstract parallel finite element space.
General product operator: x -> (A*B)(x) = A(B(x)).
A class that performs interpolation from an E-vector to quadrature point values and/or derivatives (Q...
const IntegrationRule * IntRule
Not owned.
const QuadratureSpace * qspace
Not owned.
Class representing the storage layout of a QuadratureFunction.
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const
Extract all column indices and values from a given row.
void Add(const int i, const int j, const real_t val)
void Swap(SparseMatrix &other)
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
int RowSize(const int i) const
Returns the number of elements in row i.
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR.
real_t * GetRowEntries(const int row)
Return a pointer to the entries in a row.
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
void Set(const int i, const int j, const real_t val)
void AddConnections(int r, const int *c, int nc)
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void AddConnection(int r, int c)
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
int Size() const
Returns the number of TYPE I elements.
int Size_of_connections() const
void AddColumnsInRow(int r, int ncol)
void MakeFromList(int nrows, const Array< Connection > &list)
void AddAColumnInRow(int r)
The transpose of a given operator. Switches the roles of the methods Mult() and MultTranspose().
General triple product operator x -> A*B*C*x, with ownership of the factors.
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
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...
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
real_t Max() const
Returns the maximal element of the vector.
void SetSize(int s)
Resize the vector to size s.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
real_t Min() const
Returns the minimal element of the vector.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
int index(int i, int j, int nx, int ny)
void RemoveBasisAndRestriction(const mfem::FiniteElementSpace *fes)
Remove from ceed_basis_map and ceed_restr_map the entries associated with the given fes.
Linear1DFiniteElement SegmentFE
void Swap(Array< T > &, Array< T > &)
void mfem_error(const char *msg)
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.
void filter_dos(std::string &line)
Check for, and remove, a trailing '\r' from and std::string.
bool UsesTensorBasis(const FiniteElementSpace &fes)
Return true if the mesh contains only one topology and the elements are tensor elements.
BiLinear2DFiniteElement QuadrilateralFE
@ byNODES
NQPT x VDIM x NE (values) / NQPT x VDIM x DIM x NE (grads)
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
ElementDofOrdering GetEVectorOrdering(const FiniteElementSpace &fes)
Return LEXICOGRAPHIC if mesh contains only one topology and the elements are tensor elements,...
void MarkDofs(const Array< int > &dofs, Array< int > &mark_array)
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
@ LEXICOGRAPHIC
Lexicographic ordering for tensor-product FiniteElements.
@ NATIVE
Native ordering as defined by the FiniteElement.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
MFEM_EXPORT Linear2DFiniteElement TriangleFE
void skip_comment_lines(std::istream &is, const char comment_char)
Check if the stream starts with comment_char. If so skip it.
real_t p(const Vector &x, real_t t)
bool operator<(const Data &d1, const Data &d2)
Helper struct for defining a connectivity table, see Table::MakeFromList.
Defines the position of a fine element within a coarse element.
int parent
Coarse Element index in the coarse mesh.
Geometry::Type Geom() const
Lists all edges/faces in the nonconforming mesh.
Array< Slave > slaves
All MeshIds corresponding to slave faces.
Array< Master > masters
All MeshIds corresponding to master faces.
Nonconforming edge/face within a bigger edge/face.
unsigned matrix
index into NCList::point_matrices[geom]