14 #include "../general/text.hpp" 15 #include "../general/forall.hpp" 16 #include "../mesh/mesh_headers.hpp" 28 template <>
void Ordering::
29 DofsToVDofs<Ordering::byNODES>(
int ndofs,
int vdim,
Array<int> &dofs)
32 int size = dofs.Size();
33 dofs.SetSize(size*vdim);
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);
43 template <>
void Ordering::
44 DofsToVDofs<Ordering::byVDIM>(
int ndofs,
int vdim,
Array<int> &dofs)
47 int size = dofs.Size();
48 dofs.SetSize(size*vdim);
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);
59 FiniteElementSpace::FiniteElementSpace()
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),
66 DoFTrans(0), VDoFTrans(vdim, ordering),
69 sequence(0), mesh_sequence(0), orders_changed(false), relaxed_hp(false)
75 : VDoFTrans(orig.vdim, orig.ordering)
77 mesh_ = mesh_ ? mesh_ : orig.
mesh;
78 fec_ = fec_ ? fec_ : orig.
fec;
103 MFEM_VERIFY(
cP == NULL,
"");
104 MFEM_VERIFY(
cR == NULL,
"");
112 int n = perm->
Size();
114 for (
int i=0; i<n; ++i)
118 perm_mat->
Set(i, j,
s);
130 else if (perm != NULL)
141 else if (perm != NULL)
143 cR.reset(perm_mat_tr);
154 "Space has not been Updated() after a Mesh change.");
155 MFEM_VERIFY(i >= 0 && i <
GetNE(),
"Invalid element index");
156 MFEM_VERIFY(
p >= 0 &&
p <=
MaxVarOrder,
"Order out of range");
181 "Space has not been Updated() after a Mesh change.");
182 MFEM_VERIFY(i >= 0 && i <
GetNE(),
"Invalid element index");
197 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
201 for (
int i = 0; i < dofs.
Size(); i++)
203 dofs[i] = Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, i, vd);
208 for (
int i = 0; i < dofs.
Size(); i++)
210 dofs[i] = Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, i, vd);
217 if (
vdim == 1) {
return; }
218 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
222 Ordering::DofsToVDofs<Ordering::byNODES>(ndofs_,
vdim, dofs);
226 Ordering::DofsToVDofs<Ordering::byVDIM>(ndofs_,
vdim, dofs);
232 if (
vdim == 1) {
return; }
233 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
237 for (
int i = 0; i < dofs.
Size(); i++)
239 dofs[i] = Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, dofs[i], vd);
244 for (
int i = 0; i < dofs.
Size(); i++)
246 dofs[i] = Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, dofs[i], vd);
253 if (
vdim == 1) {
return dof; }
254 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
258 return Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, dof, vd);
262 return Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, dof, vd);
269 int n = vdofs.
Size(), *vdof = vdofs;
270 for (
int i = 0; i < n; i++)
273 if ((j = vdof[i]) < 0)
285 if (
vdim == 1 || doftrans == NULL)
301 if (
vdim == 1 || doftrans == NULL)
358 if (el_fos) { el_fos -> MakeI (
mesh ->
GetNE()); }
359 for (
int i = 0; i <
mesh ->
GetNE(); i++)
362 el_dof -> AddColumnsInRow (i, dofs.
Size());
367 el_fos -> AddColumnsInRow (i, Fo.
Size());
371 if (el_fos) { el_fos -> MakeJ(); }
372 for (
int i = 0; i <
mesh ->
GetNE(); i++)
375 el_dof -> AddConnections (i, (
int *)dofs, dofs.
Size());
380 el_fos -> AddConnections (i, (
int *)Fo, Fo.
Size());
383 el_dof -> ShiftUpI();
384 if (el_fos) { el_fos -> ShiftUpI(); }
410 if (bel_fos) { bel_fos->
MakeJ(); }
423 if (bel_fos) { bel_fos->
ShiftUpI(); }
439 for (
int i = 0; i < fc_dof->
Size(); i++)
445 for (
int i = 0; i < fc_dof->
Size(); i++)
470 for (
int k = 0, dof_counter = 0; k < nnz; k++)
472 const int sdof = J[k];
473 const int dof = (sdof < 0) ? -1-sdof : sdof;
474 int new_dof = dof_marker[dof];
477 dof_marker[dof] = new_dof = dof_counter++;
479 J[k] = (sdof < 0) ? -1-new_dof : new_dof;
492 for (
int i = 0; i <
mesh ->
GetNE(); i++)
494 const int *dofs =
elem_dof -> GetRow(i);
495 const int n =
elem_dof -> RowSize(i);
496 for (
int j = 0; j < n; j++)
510 for (
int i = 0; i < dofs.
Size(); i++)
513 if (k < 0) { k = -1 - k; }
527 for (
int i = 0; i <
GetNBE(); i++)
535 mark_dofs(vdofs, ess_vdofs);
540 for (
int d = 0; d < dofs.
Size(); d++)
541 { dofs[d] =
DofToVDof(dofs[d], component); }
542 mark_dofs(dofs, ess_vdofs);
554 for (
int i = 0; i < bdr_verts.
Size(); i++)
559 mark_dofs(vdofs, ess_vdofs);
564 for (
int d = 0; d < dofs.
Size(); d++)
565 { dofs[d] =
DofToVDof(dofs[d], component); }
566 mark_dofs(dofs, ess_vdofs);
569 for (
int i = 0; i < bdr_edges.
Size(); i++)
574 mark_dofs(vdofs, ess_vdofs);
579 for (
int d = 0; d < dofs.
Size(); d++)
580 { dofs[d] =
DofToVDof(dofs[d], component); }
581 mark_dofs(dofs, ess_vdofs);
626 for (
int i = 0; i < marker.
Size(); i++)
628 if (marker[i]) { num_marked++; }
633 for (
int i = 0; i < marker.
Size(); i++)
635 if (marker[i]) { list.
Append(i); }
647 for (
int i = 0; i < list.
Size(); i++)
649 marker[list[i]] = mark_val;
657 if (
cP) {
cP->BooleanMultTranspose(dofs, cdofs); }
658 else { dofs.
Copy(cdofs); }
665 if (
cR) {
cR->BooleanMultTranspose(cdofs, dofs); }
666 else { cdofs.
Copy(dofs); }
684 if (d_vdofs.
Size() != c_vdofs.
Size())
686 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
690 for (j = 0; j < d_vdofs.
Size(); j++)
692 R ->
Set (c_vdofs[j], d_vdofs[j], 1.0);
716 if (c_dofs.
Size() != 1)
718 "D2Const_GlobalRestrictionMatrix (...)");
721 for (j = 0; j < d_dofs.
Size(); j++)
723 R ->
Set (c_dofs[0], d_dofs[j], 1.0);
747 for (
int i = 0; i <
mesh ->
GetNE(); i++)
754 if (geom != cached_geom)
756 h_fe =
this ->
GetFE (i);
757 l_fe = lfes ->
GetFE (i);
759 h_fe->
Project(*l_fe, T, loc_restr);
763 for (
int vd = 0; vd < lvdim; vd++)
765 l_dofs.
Copy(l_vdofs);
768 h_dofs.
Copy(h_vdofs);
771 R -> SetSubMatrix (l_vdofs, h_vdofs, loc_restr, 1);
784 for (
int i = skipfirst; i < slave_dofs.
Size(); i++)
786 int sdof = slave_dofs[i];
789 for (
int j = 0; j < master_dofs.
Size(); j++)
791 double coef = I(i, j);
792 if (std::abs(coef) > 1e-12)
794 int mdof = master_dofs[j];
795 if (mdof != sdof && mdof != (-1-sdof))
797 deps.
Add(sdof, mdof, coef);
820 mesh->GetFaceVertices(slave_face, V);
821 mesh->GetFaceEdges(slave_face, E, Eo);
822 MFEM_ASSERT(V.
Size() == E.
Size(),
"");
829 for (
int i = 0; i < E.
Size(); i++)
831 int a = i,
b = (i+1) % V.
Size();
832 if (V[
a] > V[
b]) { std::swap(
a,
b); }
839 for (
int j = 0; j < 2; j++)
841 edge_pm(j, 0) = (*pm)(j,
a);
842 edge_pm(j, 1) = (*pm)(j,
b);
843 mid[j] = 0.5*((*pm)(j,
a) + (*pm)(j,
b));
847 const double eps = 1e-14;
848 if (mid[0] > eps && mid[0] < 1-eps &&
849 mid[1] > eps && mid[1] < 1-eps)
851 int order = GetEdgeDofs(E[i], slave_dofs, 0);
854 edge_fe->GetTransferMatrix(*master_fe, edge_T, I);
856 AddDependencies(deps, master_dofs, slave_dofs, I, 0);
868 for (
int i = 0; i < ndep; i++)
870 if (!finalized[dep[i]]) {
return false; }
897 if (!dofs.
Size()) {
return 0; }
902 for (
int i = 0; i < nv; i++)
905 dofs[nv+i] = edof[nv+i];
909 for (
int i = 0; i < ne; i++)
911 dofs[face_vert*nv + i] = edof[2*nv + i];
954 MFEM_VERIFY(dynamic_cast<const ParFiniteElementSpace*>(
this) == NULL,
955 "This method should not be used with a ParFiniteElementSpace!");
970 Array<int> master_dofs, slave_dofs, highest_dofs;
987 for (
int entity = 2; entity >= 1; entity--)
990 if (!list.
masters.Size()) {
continue; }
998 if (!master_dofs.
Size()) {
continue; }
1001 if (!master_fe) {
continue; }
1003 switch (master_geom)
1008 default: MFEM_ABORT(
"unsupported geometry");
1016 if (!slave_dofs.
Size()) {
break; }
1037 slave_dofs, slave.
index, pm);
1049 master_geom, nvar-1);
1050 const auto *highest_fe =
fec->
GetFE(master_geom, q);
1052 T.SetIdentityTransformation(master_geom);
1070 MFEM_ASSERT(ent_dofs.
Size() == num_ent+1,
"");
1074 for (
int i = 0; i < num_ent; i++)
1076 if (ent_dofs.
RowSize(i) <= 1) {
continue; }
1081 if (geom != last_geom)
1083 T.SetIdentityTransformation(geom);
1089 const auto *master_fe =
fec->
GetFE(geom,
p);
1090 if (!master_fe) {
break; }
1093 for (
int variant = 1; ; variant++)
1095 int q =
GetEntityDofs(entity, i, slave_dofs, geom, variant);
1096 if (q < 0) {
break; }
1098 const auto *slave_fe =
fec->
GetFE(geom, q);
1111 int n_true_dofs = 0;
1112 for (
int i = 0; i <
ndofs; i++)
1114 if (!deps.
RowSize(i)) { n_true_dofs++; }
1118 if (n_true_dofs ==
ndofs)
1136 for (
int i = 0; i < n_true_dofs; i++)
1141 cR_I[n_true_dofs] = n_true_dofs;
1163 for (
int i = 0, true_dof = 0; i <
ndofs; i++)
1167 cP->Add(i, true_dof, 1.0);
1169 finalized[i] =
true;
1175 inv_deps.
GetRow(i, cols, srow);
1176 cR_hp->AddRow(true_dof, cols, srow);
1180 cR_hp->Add(true_dof, i, 1.0);
1196 int n_finalized = n_true_dofs;
1200 for (
int dof = 0; dof <
ndofs; dof++)
1206 int n_dep = deps.
RowSize(dof);
1208 for (
int j = 0; j < n_dep; j++)
1210 cP->GetRow(dep_col[j], cols, srow);
1211 srow *= dep_coef[j];
1212 cP->AddRow(dof, cols, srow);
1215 finalized[dof] =
true;
1225 MFEM_VERIFY(n_finalized ==
ndofs,
1226 "Error creating cP matrix: n_finalized = " 1227 << n_finalized <<
", ndofs = " <<
ndofs);
1242 if (
vdim == 1) {
return; }
1244 int height = mat.
Height();
1245 int width = mat.
Width();
1251 for (
int i = 0; i < height; i++)
1253 mat.
GetRow(i, dofs, srow);
1254 for (
int vd = 0; vd <
vdim; vd++)
1341 key_face key = std::make_tuple(is_dg_space, f_ordering, type, m);
1342 auto itr =
L2F.find(key);
1343 if (itr !=
L2F.end())
1373 for (
int i = 0; i <
E2Q_array.Size(); i++)
1376 if (qi->
IntRule == &ir) {
return qi; }
1387 for (
int i = 0; i <
E2Q_array.Size(); i++)
1390 if (qi->
qspace == &qs) {
return qi; }
1407 if (qi->
IntRule == &ir) {
return qi; }
1420 if (qi->
IntRule == &ir) {
return qi; }
1431 const int coarse_ndofs,
const Table &coarse_elem_dof,
1444 if (elem_geoms.
Size() == 1)
1446 const int coarse_ldof = localP[elem_geoms[0]].
SizeJ();
1464 const int fine_ldof = localP[geom].
SizeI();
1469 for (
int vd = 0; vd <
vdim; vd++)
1471 coarse_dofs.Copy(coarse_vdofs);
1474 for (
int i = 0; i < fine_ldof; i++)
1477 int m = (r >= 0) ? r : (-1 - r);
1482 P->
SetRow(r, coarse_vdofs, row);
1489 MFEM_ASSERT(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
1502 int nmat = pmats.
SizeK();
1509 localP.
SetSize(ldof, ldof, nmat);
1510 for (
int i = 0; i < nmat; i++)
1518 const Table* old_elem_dof,
1519 const Table* old_elem_fos)
1521 MFEM_VERIFY(
GetNE() >= old_elem_dof->
Size(),
1522 "Previous mesh is not coarser.");
1527 for (
int i = 0; i < elem_geoms.Size(); i++)
1540 , old_elem_dof(old_elem_dof)
1541 , old_elem_fos(old_elem_fos)
1543 MFEM_VERIFY(fespace->
GetNE() >= old_elem_dof->
Size(),
1544 "Previous mesh is not coarser.");
1546 width = old_ndofs * fespace->
GetVDim();
1551 for (
int i = 0; i < elem_geoms.Size(); i++)
1556 ConstructDoFTrans();
1561 :
Operator(fespace->GetVSize(), coarse_fes->GetVSize()),
1562 fespace(fespace), old_elem_dof(NULL), old_elem_fos(NULL)
1566 for (
int i = 0; i < elem_geoms.Size(); i++)
1569 localP[elem_geoms[i]]);
1581 ConstructDoFTrans();
1586 delete old_elem_dof;
1587 delete old_elem_fos;
1588 for (
int i=0; i<old_DoFTrans.Size(); i++)
1590 delete old_DoFTrans[i];
1594 void FiniteElementSpace::RefinementOperator
1595 ::ConstructDoFTrans()
1598 for (
int i=0; i<old_DoFTrans.Size(); i++)
1600 old_DoFTrans[i] = NULL;
1604 if (dynamic_cast<const ND_FECollection*>(fec_ref))
1614 const FiniteElement * nd_tet =
1619 new ND_TetDofTransformation(nd_tet->GetOrder());
1622 const FiniteElement * nd_pri =
1627 new ND_WedgeDofTransformation(nd_pri->GetOrder());
1639 Array<int> dofs, vdofs, old_dofs, old_vdofs, old_Fo;
1641 int rvdim = fespace->
GetVDim();
1642 int old_ndofs = width / rvdim;
1646 for (
int k = 0; k < mesh_ref->
GetNE(); k++)
1659 for (
int vd = 0; vd < rvdim; vd++)
1663 old_dofs.
Copy(old_vdofs);
1666 lP.
Mult(subX, subY);
1673 old_DoFTrans[geom]->SetFaceOrientations(old_Fo);
1680 new_doftrans = doftrans;
1684 for (
int vd = 0; vd < rvdim; vd++)
1688 old_dofs.
Copy(old_vdofs);
1691 old_DoFTrans[geom]->InvTransformPrimal(subX);
1692 lP.
Mult(subX, subY);
1699 doftrans = new_doftrans;
1717 Array<int> f_dofs, c_dofs, f_vdofs, c_vdofs, old_Fo;
1719 int rvdim = fespace->
GetVDim();
1720 int old_ndofs = width / rvdim;
1722 Vector subY, subX, subYt;
1724 for (
int k = 0; k < mesh_ref->
GetNE(); k++)
1737 for (
int vd = 0; vd < rvdim; vd++)
1739 f_dofs.
Copy(f_vdofs);
1741 c_dofs.
Copy(c_vdofs);
1746 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1763 old_DoFTrans[geom]->SetFaceOrientations(old_Fo);
1770 new_doftrans = doftrans;
1774 for (
int vd = 0; vd < rvdim; vd++)
1776 f_dofs.
Copy(f_vdofs);
1778 c_dofs.
Copy(c_vdofs);
1782 doftrans->InvTransformDual(subX);
1783 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1792 old_DoFTrans[geom]->TransformDual(subYt);
1798 doftrans = new_doftrans;
1802 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1820 : geom(g), num_children(n), children(c) { }
1822 bool operator<(
const RefType &other)
const 1824 if (geom < other.geom) {
return true; }
1825 if (geom > other.geom) {
return false; }
1826 if (num_children < other.num_children) {
return true; }
1827 if (num_children > other.num_children) {
return false; }
1828 for (
int i = 0; i < num_children; i++)
1830 if (children[i].one < other.children[i].one) {
return true; }
1831 if (children[i].one > other.children[i].one) {
return false; }
1837 void GetCoarseToFineMap(
const CoarseFineTransformations &cft,
1839 Table &coarse_to_fine,
1840 Array<int> &coarse_to_ref_type,
1841 Table &ref_type_to_matrix,
1842 Array<Geometry::Type> &ref_type_to_geom)
1844 const int fine_ne = cft.embeddings.Size();
1846 for (
int i = 0; i < fine_ne; i++)
1848 coarse_ne = std::max(coarse_ne, cft.embeddings[i].parent);
1852 coarse_to_ref_type.SetSize(coarse_ne);
1853 coarse_to_fine.SetDims(coarse_ne, fine_ne);
1855 Array<int> cf_i(coarse_to_fine.GetI(), coarse_ne+1);
1856 Array<Pair<int,int> > cf_j(fine_ne);
1858 for (
int i = 0; i < fine_ne; i++)
1860 cf_i[cft.embeddings[i].parent+1]++;
1863 MFEM_ASSERT(cf_i.Last() == cf_j.Size(),
"internal error");
1864 for (
int i = 0; i < fine_ne; i++)
1866 const Embedding &e = cft.embeddings[i];
1867 cf_j[cf_i[e.parent]].one = e.matrix;
1868 cf_j[cf_i[e.parent]].two = i;
1871 std::copy_backward(cf_i.begin(), cf_i.end()-1, cf_i.end());
1873 for (
int i = 0; i < coarse_ne; i++)
1875 std::sort(&cf_j[cf_i[i]], cf_j.GetData() + cf_i[i+1]);
1877 for (
int i = 0; i < fine_ne; i++)
1879 coarse_to_fine.GetJ()[i] = cf_j[i].two;
1885 map<RefType,int> ref_type_map;
1886 for (
int i = 0; i < coarse_ne; i++)
1888 const int num_children = cf_i[i+1]-cf_i[i];
1889 MFEM_ASSERT(num_children > 0,
"");
1890 const int fine_el = cf_j[cf_i[i]].two;
1893 const RefType ref_type(geom, num_children, &cf_j[cf_i[i]]);
1894 pair<map<RefType,int>::iterator,
bool> res =
1895 ref_type_map.insert(
1896 pair<const RefType,int>(ref_type, (
int)ref_type_map.size()));
1897 coarse_to_ref_type[i] = res.first->second;
1900 ref_type_to_matrix.MakeI((
int)ref_type_map.size());
1901 ref_type_to_geom.SetSize((
int)ref_type_map.size());
1902 for (map<RefType,int>::iterator it = ref_type_map.begin();
1903 it != ref_type_map.end(); ++it)
1905 ref_type_to_matrix.AddColumnsInRow(it->second, it->first.num_children);
1906 ref_type_to_geom[it->second] = it->first.geom;
1909 ref_type_to_matrix.MakeJ();
1910 for (map<RefType,int>::iterator it = ref_type_map.begin();
1911 it != ref_type_map.end(); ++it)
1913 const RefType &rt = it->first;
1914 for (
int j = 0; j < rt.num_children; j++)
1916 ref_type_to_matrix.AddConnection(it->second, rt.children[j].one);
1919 ref_type_to_matrix.ShiftUpI();
1934 "incompatible coarse and fine FE spaces");
1942 for (
int gi = 0; gi < elem_geoms.
Size(); gi++)
1945 DenseTensor &lP = localP[geom], &lM = localM[geom];
1954 emb_tr.SetIdentityTransformation(geom);
1955 for (
int i = 0; i < pmats.
SizeK(); i++)
1957 emb_tr.SetPointMat(pmats(i));
1965 Table ref_type_to_matrix;
1966 internal::GetCoarseToFineMap(rtrans, *f_mesh, coarse_to_fine,
1967 coarse_to_ref_type, ref_type_to_matrix,
1969 MFEM_ASSERT(coarse_to_fine.Size() == c_fes->
GetNE(),
"");
1971 const int total_ref_types = ref_type_to_geom.Size();
1973 Array<int> ref_type_to_coarse_elem_offset(total_ref_types);
1974 ref_type_to_fine_elem_offset.
SetSize(total_ref_types);
1977 for (
int i = 0; i < total_ref_types; i++)
1980 ref_type_to_coarse_elem_offset[i] = num_ref_types[g];
1981 ref_type_to_fine_elem_offset[i] = num_fine_elems[g];
1983 num_fine_elems[g] += ref_type_to_matrix.
RowSize(i);
1988 if (num_ref_types[g] == 0) {
continue; }
1989 const int fine_dofs = localP[g].
SizeI();
1990 const int coarse_dofs = localP[g].
SizeJ();
1991 localPtMP[g].
SetSize(coarse_dofs, coarse_dofs, num_ref_types[g]);
1992 localR[g].
SetSize(coarse_dofs, fine_dofs, num_fine_elems[g]);
1994 for (
int i = 0; i < total_ref_types; i++)
1997 DenseMatrix &lPtMP = localPtMP[g](ref_type_to_coarse_elem_offset[i]);
1998 int lR_offset = ref_type_to_fine_elem_offset[i];
1999 const int *mi = ref_type_to_matrix.
GetRow(i);
2000 const int nm = ref_type_to_matrix.
RowSize(i);
2002 for (
int s = 0;
s < nm;
s++)
2011 for (
int s = 0;
s < nm;
s++)
2024 delete coarse_elem_dof;
2033 const int fine_vdim = fine_fes->GetVDim();
2034 const int coarse_ndofs = height/fine_vdim;
2035 for (
int coarse_el = 0; coarse_el < coarse_to_fine.Size(); coarse_el++)
2037 coarse_elem_dof->
GetRow(coarse_el, c_vdofs);
2038 fine_fes->DofsToVDofs(c_vdofs, coarse_ndofs);
2043 const int ref_type = coarse_to_ref_type[coarse_el];
2045 const int *fine_elems = coarse_to_fine.GetRow(coarse_el);
2046 const int num_fine_elems = coarse_to_fine.RowSize(coarse_el);
2047 const int lR_offset = ref_type_to_fine_elem_offset[ref_type];
2048 for (
int s = 0;
s < num_fine_elems;
s++)
2051 fine_fes->GetElementVDofs(fine_elems[
s], f_vdofs);
2070 const int nmat = pmats.
SizeK();
2071 const int ldof = fe->
GetDof();
2077 localR.
SetSize(ldof, ldof, nmat);
2078 for (
int i = 0; i < nmat; i++)
2086 const Table* old_elem_dof,
2087 const Table* old_elem_fos)
2091 MFEM_VERIFY(
Nonconforming(),
"Not implemented for conforming meshes.");
2092 MFEM_VERIFY(old_ndofs,
"Missing previous (finer) space.");
2093 MFEM_VERIFY(
ndofs <= old_ndofs,
"Previous space is not finer.");
2101 for (
int i = 0; i < elem_geoms.
Size(); i++)
2114 MFEM_ASSERT(dtrans.
embeddings.Size() == old_elem_dof->
Size(),
"");
2118 for (
int k = 0; k < dtrans.
embeddings.Size(); k++)
2125 old_elem_dof->
GetRow(k, old_dofs);
2127 for (
int vd = 0; vd <
vdim; vd++)
2129 old_dofs.
Copy(old_vdofs);
2132 for (
int i = 0; i < lR.
Height(); i++)
2134 if (!std::isfinite(lR(i, 0))) {
continue; }
2137 int m = (r >= 0) ? r : (-1 - r);
2139 if (is_dg || !mark[m])
2142 R->
SetRow(r, old_vdofs, row);
2153 MFEM_VERIFY(num_marked == R->
Height(),
2154 "internal error: not all rows of R were set.");
2174 int nmat = pmats.
SizeK();
2181 for (
int i = 0; i < nmat; i++)
2190 int vdim_,
int ordering_)
2211 MFEM_VERIFY(mesh_->
NURBSext,
"NURBS FE space requires a NURBS mesh.");
2213 if (NURBSext_ == NULL)
2248 for (
int i=0; i<
DoFTrans.Size(); i++)
2253 if (dynamic_cast<const ND_FECollection*>(
fec))
2285 mfem_error(
"FiniteElementSpace::StealNURBSext");
2294 MFEM_VERIFY(
NURBSext,
"NURBSExt not defined.");
2338 if (
b == -1) {
continue; }
2348 for (
int i = 0; i < nv; i++)
2350 MFEM_VERIFY(fv[i] == bv[i],
2351 "non-matching face and boundary elements detected!");
2356 for (
int i = 0; i < row.
Size(); i++)
2359 face_dof_list.
Append(conn);
2368 MFEM_VERIFY(!
NURBSext,
"internal error");
2373 "Variable order space requires a nonconforming mesh.");
2396 "Mesh was not correctly finalized.");
2407 else if (mixed_faces)
2494 MFEM_ASSERT(bits != 0,
"invalid bit mask");
2495 for (
int order = 0; bits != 0; order++, bits >>= 1)
2497 if (bits & 1) {
return order; }
2524 for (
int j = 0; j < E.
Size(); j++)
2526 edge_orders[E[j]] |= mask;
2532 for (
int j = 0; j < F.
Size(); j++)
2534 face_orders[F[j]] |= mask;
2562 slave_orders |= edge_orders[edge_list.
slaves[i].index];
2565 int min_order =
MinOrder(slave_orders);
2581 if (slave.
index >= 0)
2583 slave_orders |= face_orders[slave.
index];
2586 for (
int j = 0; j < E.
Size(); j++)
2588 slave_orders |= edge_orders[E[j]];
2594 slave_orders |= edge_orders[-1 - slave.
index];
2598 int min_order =
MinOrder(slave_orders);
2610 for (
int j = 0; j < E.
Size(); j++)
2612 edge_orders[E[j]] |= face_orders[i];
2634 int num_ent = entity_orders.
Size();
2643 var_ent_order->
Reserve(num_ent);
2647 for (
int i = 0; i < num_ent; i++)
2652 for (
int order = 0; bits != 0; order++, bits >>= 1)
2660 if (var_ent_order) { var_ent_order->
Append(order); }
2675 int row,
int ndof)
const 2677 const int *beg = var_dof_table.
GetRow(row);
2678 const int *end = var_dof_table.
GetRow(row + 1);
2683 if ((beg[1] - beg[0]) == ndof) {
return beg[0]; }
2687 MFEM_ABORT(
"DOFs not found for ndof = " << ndof);
2697 if (variant >= end - beg) {
return -1; }
2713 if (variant >= end - beg) {
return -1; }
2727 static const char* msg_orders_changed =
2728 "Element orders changed, you need to Update() the space first.";
2765 for (
int i = 0; i < F.
Size(); i++)
2772 -> SetFaceOrientations(Fo);
2781 for (
int i = 0; i < V.
Size(); i++)
2783 for (
int j = 0; j < nv; j++)
2785 dofs.
Append(V[i]*nv + j);
2792 for (
int i = 0; i < E.
Size(); i++)
2797 for (
int j = 0; j < ne; j++)
2806 for (
int i = 0; i < F.
Size(); i++)
2814 for (
int j = 0; j < nf; j++)
2826 for (
int j = 0; j < nb; j++)
2837 "FiniteElementSpace::GetPatchDofs needs a NURBSExtension");
2847 MFEM_ABORT(
"Empty MPI partitions are not permitted!");
2849 MFEM_ABORT(
"Invalid element id:" << i <<
"; minimum allowed:" << 0 <<
2850 ", maximum allowed:" <<
mesh->
GetNE()-1);
2868 "internal error: " <<
2891 SetFaceOrientations(Fo);
2924 SetFaceOrientations(Fo);
2933 for (
int i = 0; i < V.
Size(); i++)
2935 for (
int j = 0; j < nv; j++)
2937 dofs.
Append(V[i]*nv + j);
2944 for (
int i = 0; i < E.
Size(); i++)
2949 for (
int j = 0; j < ne; j++)
2961 for (
int j = 0; j < nf; j++)
2984 int order, nf, fbase;
2992 if (variant >= end - beg) {
return -1; }
2994 fbase = beg[variant];
2995 nf = beg[variant+1] - fbase;
3003 if (variant > 0) {
return -1; }
3022 for (
int i = 0; i < V.
Size(); i++)
3024 for (
int j = 0; j < nv; j++)
3026 dofs.
Append(V[i]*nv + j);
3032 for (
int i = 0; i < E.
Size(); i++)
3037 for (
int j = 0; j < ne; j++)
3043 for (
int j = 0; j < nf; j++)
3056 int order, ne, base;
3061 if (variant >= end - beg) {
return -1; }
3063 base = beg[variant];
3064 ne = beg[variant+1] - base;
3071 if (variant > 0) {
return -1; }
3084 for (
int i = 0; i < 2; i++)
3086 for (
int j = 0; j < nv; j++)
3088 dofs.
Append(V[i]*nv + j);
3091 for (
int j = 0; j < ne; j++)
3103 for (
int j = 0; j < nv; j++)
3118 for (
int j = 0; j < nb; j++)
3136 for (
int j = 0, k =
nvdofs+i*ne; j < ne; j++, k++)
3160 for (
int j = 0; j < nf; j++)
3222 "NURBS mesh: only boundary faces are supported!");
3232 MFEM_ASSERT(
mesh->
Dimension() > 1,
"No edges with mesh dimension < 2");
3258 for (
int i = 0; i <
E2Q_array.Size(); i++)
3305 for (
int i = 0; i <
DoFTrans.Size(); i++)
3322 for (
int i = 0; i < elem_geoms.
Size(); i++)
3325 localP[elem_geoms[i]]);
3361 if (RP_case == 0) {
return; }
3362 const bool owner = T.OwnsOperator();
3363 T.SetOperatorOwner(
false);
3374 cR.get(), T.Ptr(), coarse_P,
false, owner,
false));
3396 MFEM_ABORT(
"not implemented yet");
3412 MFEM_ABORT(
"Error in update sequence. Space needs to be updated after " 3413 "each mesh modification.");
3420 MFEM_ABORT(
"Updating space after both mesh change and element order " 3421 "change is not supported. Please update separately after " 3432 Table* old_elem_dof = NULL;
3433 Table* old_elem_fos = NULL;
3459 MFEM_VERIFY(!old_orders_changed,
"Interpolation for element order change " 3460 "is not implemented yet, sorry.");
3470 old_elem_fos, old_ndofs));
3473 old_elem_dof = NULL;
3474 old_elem_fos = NULL;
3493 false,
false,
true));
3502 delete old_elem_dof;
3503 delete old_elem_fos;
3514 int fes_format = 90;
3515 bool nurbs_unit_weights =
false;
3526 MFEM_VERIFY(nurbs_fec,
"invalid FE collection");
3528 const double eps = 5e-14;
3539 os << (fes_format == 90 ?
3540 "FiniteElementSpace\n" :
"MFEM FiniteElementSpace v1.0\n")
3541 <<
"FiniteElementCollection: " <<
fec->
Name() <<
'\n' 3542 <<
"VDim: " <<
vdim <<
'\n' 3543 <<
"Ordering: " <<
ordering <<
'\n';
3545 if (fes_format == 100)
3559 os <<
"NURBS_orders\n";
3566 os <<
"NURBS_periodic\n";
3571 if (!nurbs_unit_weights)
3573 os <<
"NURBS_weights\n";
3577 os <<
"End: MFEM FiniteElementSpace v1.0\n";
3584 int fes_format = 0, ord;
3590 getline(input, buff);
3592 if (buff ==
"FiniteElementSpace") { fes_format = 90; }
3593 else if (buff ==
"MFEM FiniteElementSpace v1.0") { fes_format = 100; }
3594 else { MFEM_ABORT(
"input stream is not a FiniteElementSpace!"); }
3595 getline(input, buff,
' ');
3597 getline(input, buff);
3600 getline(input, buff,
' ');
3602 getline(input, buff,
' ');
3607 if (fes_format == 90)
3611 MFEM_VERIFY(m->
NURBSext,
"NURBS FE collection requires a NURBS mesh!");
3612 const int order = nurbs_fec->
GetOrder();
3620 else if (fes_format == 100)
3625 MFEM_VERIFY(input.good(),
"error reading FiniteElementSpace v1.0");
3626 getline(input, buff);
3628 if (buff ==
"NURBS_order" || buff ==
"NURBS_orders")
3630 MFEM_VERIFY(nurbs_fec,
3631 buff <<
": NURBS FE collection is required!");
3632 MFEM_VERIFY(m->
NURBSext, buff <<
": NURBS mesh is required!");
3633 MFEM_VERIFY(!nurbs_ext, buff <<
": order redefinition!");
3634 if (buff ==
"NURBS_order")
3647 else if (buff ==
"NURBS_periodic")
3654 else if (buff ==
"NURBS_weights")
3656 MFEM_VERIFY(nurbs_ext,
"NURBS_weights: NURBS_orders have to be " 3657 "specified before NURBS_weights!");
3660 else if (buff ==
"element_orders")
3662 MFEM_VERIFY(!nurbs_fec,
"section element_orders cannot be used " 3663 "with a NURBS FE collection");
3664 MFEM_ABORT(
"element_orders: not implemented yet!");
3666 else if (buff ==
"End: MFEM FiniteElementSpace v1.0")
3672 MFEM_ABORT(
"unknown section: " << buff);
SparseMatrix * RefinementMatrix(int old_ndofs, const Table *old_elem_dof, const Table *old_elem_fos)
Abstract class for all finite elements.
VDofTransformation VDoFTrans
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
void GetEdgeInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified edge.
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
BiLinear2DFiniteElement QuadrilateralFE
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
int ndofs
Number of degrees of freedom. Number of unknowns is ndofs * vdim.
Class for an integration rule - an Array of IntegrationPoint.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
int * bdofs
internal DOFs of elements if mixed/var-order; NULL otherwise
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
static void AddDependencies(SparseMatrix &deps, Array< int > &master_dofs, Array< int > &slave_dofs, DenseMatrix &I, int skipfirst=0)
const CoarseFineTransformations & GetDerefinementTransforms()
virtual void Update(bool want_transform=true)
Reflect changes in the mesh: update number of DOFs, etc. Also, calculate GridFunction transformation ...
void SetSize(int dim, int connections_per_row)
Set the size and the number of connections for the table.
SparseMatrix * DerefinementMatrix(int old_ndofs, const Table *old_elem_dof, const Table *old_elem_fos)
Calculate GridFunction restriction matrix after mesh derefinement.
void AddColumnsInRow(int r, int ncol)
void OrientedPointMatrix(const Slave &slave, DenseMatrix &oriented_matrix) const
Return the point matrix oriented according to the master and slave edges.
int MakeDofTable(int ent_dim, const Array< int > &entity_orders, Table &entity_dofs, Array< char > *var_ent_order)
Linear1DFiniteElement SegmentFE
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
std::unique_ptr< SparseMatrix > cP
DerefinementOperator(const FiniteElementSpace *f_fes, const FiniteElementSpace *c_fes, BilinearFormIntegrator *mass_integ)
TODO: Implement DofTransformation support.
Geometry::Type GetElementBaseGeometry(int i) const
int GetBdrElementEdgeIndex(int i) const
Field is discontinuous across element interfaces.
void LoadFE(int i, const FiniteElement *FE) const
bool Nonconforming() const
int Dimension() const
Dimension of the reference space used within the elements.
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
virtual int GetContType() const =0
void Mult(const double *x, double *y) const
Matrix vector multiplication with the inverse of dense matrix.
const FiniteElement * GetFE(Geometry::Type geom, int p) const
Variable order version of FiniteElementForGeometry().
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void SetSize(int s)
Resize the vector to size s.
void GetEdgeInteriorVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the interior of the specified edge.
void GetVertexVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the specified vertices.
void SetElementOrder(int i, int p)
Sets the order of the i'th finite 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...
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
static int DecodeDof(int dof)
Helper to return the DOF associated with a sign encoded DOF.
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
int RowSize(const int i) const
Returns the number of elements in row i.
Lists all edges/faces in the nonconforming mesh.
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...
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
static int MinOrder(VarOrderBits bits)
Return the minimum order (least significant bit set) in the bit mask.
int GetOrder() const
Return the order (polynomial degree) of the FE collection, corresponding to the order/degree returned...
Geometry::Type GetFaceGeometry(int i) const
Return the Geometry::Type associated with face i.
const Array< int > & GetSlave() const
Pointer to an Operator of a specified type.
OpType * Is() const
Return the Operator pointer dynamically cast to a specified OpType.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
virtual const FiniteElement * FiniteElementForGeometry(Geometry::Type GeomType) const =0
virtual DofTransformation * GetBdrElementDofs(int bel, Array< int > &dofs) const
Returns indices of degrees of freedom for boundary element 'bel'. The returned indices are offsets in...
static constexpr int MaxVarOrder
virtual ~DerefinementOperator()
std::unique_ptr< SparseMatrix > cR_hp
A version of the conforming restriction matrix for variable-order spaces.
unsigned matrix
index into NCList::point_matrices[geom]
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.
void AddEdgeFaceDependencies(SparseMatrix &deps, Array< int > &master_dofs, const FiniteElement *master_fe, Array< int > &slave_dofs, int slave_face, const DenseMatrix *pm) const
virtual const Operator * GetRestrictionOperator() const
An abstract operator that performs the same action as GetRestrictionMatrix.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Data type dense matrix using column-major storage.
void GetPatchDofs(const int patch, Array< int > &dofs)
int vdim
Vector dimension (number of unknowns per degree of freedom).
int GetDegenerateFaceDofs(int index, Array< int > &dofs, Geometry::Type master_geom, int variant) const
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
Operator that extracts face degrees of freedom for L2 nonconforming spaces.
void BuildBdrElementToDofTable() const
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
const FiniteElement * GetTraceElement(int i, Geometry::Type geom_type) const
Return the trace element from element 'i' to the given 'geom_type'.
Geometry::Type Geom() const
const Vector & GetWeights() const
int GetNEdges() const
Return the number of edges.
const Operator * GetRestrictionTransposeOperator() const
Return an operator that performs the transpose of GetRestrictionOperator.
T Sum()
Return the sum of all the array entries using the '+'' operator for class 'T'.
MFEM_DEPRECATED void RebuildElementToDofTable()
(
void CalcEdgeFaceVarOrders(Array< VarOrderBits > &edge_orders, Array< VarOrderBits > &face_orders) const
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const
Extract all column indices and values from a given row.
bool operator<(const Pair< A, B > &p, const Pair< A, B > &q)
Comparison operator for class Pair, based on the first element only.
void BuildConformingInterpolation() const
Calculate the cP and cR matrices for a nonconforming mesh.
FiniteElementCollection * Load(Mesh *m, std::istream &input)
Read a FiniteElementSpace from a stream. The returned FiniteElementCollection is owned by the caller...
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
void GetVDofs(int vd, Array< int > &dofs, int ndofs=-1) const
Returns the indices of all of the VDofs for the specified dimension 'vd'.
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
double * GetRowEntries(const int row)
Return a pointer to the entries in a row.
virtual void CopyProlongationAndRestriction(const FiniteElementSpace &fes, const Array< int > *perm)
Copies the prolongation and restriction matrices from fes.
const FiniteElementCollection * fec
Associated FE collection (not owned).
OperatorHandle Th
Transformation to apply to GridFunctions after space Update().
void GetVertexDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the specified vertices.
const SparseMatrix * GetHpConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
int GetNBE() const
Returns number of boundary elements.
void skip_comment_lines(std::istream &is, const char comment_char)
Check if the stream starts with comment_char. If so skip it.
void DeleteAll()
Delete the whole array.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
void AddConnections(int r, const int *c, int nc)
std::uint64_t VarOrderBits
Bit-mask representing a set of orders needed by an edge/face.
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
int FindFaceDof(int face, int ndof) const
Similar to FindEdgeDof, but used for mixed meshes too.
Array< int > dof_elem_array
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
const Array< int > & GetMaster() const
virtual int DofForGeometry(Geometry::Type GeomType) const =0
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
std::function< double(const Vector &)> f(double mass_coeff)
virtual void UpdateMeshPointer(Mesh *new_mesh)
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
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...
const IntegrationRule * IntRule
Not owned.
void GetElementInteriorVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the interior of the specified element.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
void GetPatchVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom in vdofs for NURBS patch i.
int uni_fdof
of single face DOFs if all faces uniform; -1 otherwise
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
ID for class SparseMatrix.
void BuildFaceToDofTable() const
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
void Set(const int i, const int j, const double val)
const Table * GetElementToFaceOrientationTable() const
void GetBdrElementFace(int i, int *f, int *o) const
Return the index and the orientation of the face of bdr element i. (3D)
General product operator: x -> (A*B)(x) = A(B(x)).
ID for the base class Operator, i.e. any type.
void GetElementFaces(int i, Array< int > &faces, Array< int > &ori) const
Return the indices and the orientations of all faces of element i.
void BuildElementToDofTable() const
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:
Array< DofTransformation * > DoFTrans
const int * GetDofOrdering(Geometry::Type geom, int p, int ori) const
Variable order version of DofOrderForOrientation().
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
void MakeFromList(int nrows, const Array< Connection > &list)
bool orders_changed
True if at least one element order changed (variable-order space only).
std::unique_ptr< Operator > R_transpose
Operator computing the action of the transpose of the restriction.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
int GetOrder() const
If all orders are identical, return that number. Otherwise, return NURBSFECollection::VariableOrder.
const FiniteElementCollection * FEColl() const
Operator that extracts Face degrees of freedom for L2 spaces.
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
A class that performs interpolation from an E-vector to quadrature point values and/or derivatives (Q...
const Array< int > & GetOrders() const
Read-only access to the orders of all knot vectors.
const IntegrationRule * IntRule
Not owned.
SparseMatrix * D2Const_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
Generate the global restriction matrix from a discontinuous FE space to the piecewise constant FE spa...
static const int NumVerts[NumGeom]
SparseMatrix * D2C_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
Generate the global restriction matrix from a discontinuous FE space to the continuous FE space of th...
void AddConnection(int r, int c)
int GetNumBorderDofs(Geometry::Type geom, int order) const
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
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...
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
NURBSExtension * StealNURBSext()
Array< DenseMatrix * > point_matrices[Geometry::NumGeom]
List of unique point matrices for each slave geometry.
virtual const char * Name() const
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
virtual ~RefinementOperator()
const FaceQuadratureInterpolator * GetFaceQuadratureInterpolator(const IntegrationRule &ir, FaceType type) const
Return a FaceQuadratureInterpolator that interpolates E-vectors to quadrature point values and/or der...
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Array< int > dof_ldof_array
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 SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
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 FindEdgeDof(int edge, int ndof) const
static int EncodeDof(int entity_base, int idx)
Helper to encode a sign flip into a DOF index (for Hcurl/Hdiv shapes).
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void Mult(const double *x, double *y) const
Matrix vector multiplication.
int GetNE() const
Returns number of elements in the mesh.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void GetFaceInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified face.
virtual void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges)
Array< QuadratureInterpolator * > E2Q_array
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...
A class that performs interpolation from a face E-vector to quadrature point values and/or derivative...
void Add(const int i, const int j, const double val)
Abstract base class that defines an interface for element restrictions.
OperatorHandle L2E_nat
The element restriction operators, see GetElementRestriction().
int slaves_end
slave faces
double * GetData() const
Return a pointer to the beginning of the Vector data.
List of mesh geometries stored as Array<Geometry::Type>.
int GetVDim() const
Returns vector dimension.
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 ...
Geometry::Type GetElementGeometry(int i) const
int GetNF() const
Returns number of faces (i.e. co-dimension 1 entities) in the mesh.
Type
Enumeration defining IDs for some classes derived from Operator.
Mesh * GetMesh() const
Returns the mesh.
void Swap(Array< T > &, Array< T > &)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
double p(const Vector &x, double t)
int GetDim() const
Returns the reference space dimension for the finite element.
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
Operator that converts FiniteElementSpace L-vectors to E-vectors.
void LoadBE(int i, const FiniteElement *BE) const
Nonconforming edge/face within a bigger edge/face.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
SparseMatrix * RefinementMatrix_main(const int coarse_ndofs, const Table &coarse_elem_dof, const Table *coarse_elem_fos, const DenseTensor localP[]) const
virtual ~FiniteElementSpace()
int GetNumDof(Geometry::Type geom, int p) const
Variable order version of DofForGeometry().
void GetRow(int r, Vector &row) const
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
SparseMatrix * H2L_GlobalRestrictionMatrix(FiniteElementSpace *lfes)
Construct the restriction matrix from the FE space given by (*this) to the lower degree FE space give...
int GetNumElementInteriorDofs(int i) const
Returns the number of degrees of freedom associated with the interior of the specified element...
double Min() const
Returns the minimal element of the vector.
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...
void GetPatchDofs(int patch, Array< int > &dofs) const
Returns indices of degrees of freedom for NURBS patch index patch. Cartesian ordering is used...
void AddAColumnInRow(int r)
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
virtual const FiniteElement * TraceFiniteElementForGeometry(Geometry::Type GeomType) const
int GetEdgeOrder(int edge, int variant=0) const
void RemoveBasisAndRestriction(const mfem::FiniteElementSpace *fes)
Remove from ceed_basis_map and ceed_restr_map the entries associated with the given fes...
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
RefinementOperator(const FiniteElementSpace *fespace, Table *old_elem_dof, Table *old_elem_fos, int old_ndofs)
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...
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.
Array< char > var_face_orders
int GetFaceOrder(int face, int variant=0) const
Returns the polynomial degree of the i'th face finite element.
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged...
Helper struct for defining a connectivity table, see Table::MakeFromList.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Table * GetElementDofTable()
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Table * GetBdrElementDofTable()
The transpose of a given operator. Switches the roles of the methods Mult() and MultTranspose().
virtual 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...
double Max() const
Returns the maximal element of the vector.
The ordering method used when the number of unknowns per mesh node (vector dimension) is bigger than ...
MFEM_EXPORT Linear2DFiniteElement TriangleFE
const CoarseFineTransformations & GetRefinementTransforms()
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
Geometry::Type GetBdrElementGeometry(int i) const
std::unique_ptr< SparseMatrix > cR
Conforming restriction matrix such that cR.cP=I.
static FiniteElementCollection * New(const char *name)
Factory method: return a newly allocated FiniteElementCollection according to the given name...
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, defined on a coarse mesh, to this FE space, defined on a refined mesh.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
int GetNE() const
Returns number of elements.
void GetFaceEdges(int i, Array< int > &edges, Array< int > &o) const
NURBSExtension * NURBSext
Optional NURBS mesh extension.
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...
Operator::Type Type() const
Get the currently set operator type id.
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
const QuadratureInterpolator * GetQuadratureInterpolator(const IntegrationRule &ir) const
Return a QuadratureInterpolator that interpolates E-vectors to quadrature point values and/or derivat...
int HasFaceDofs(Geometry::Type geom, int p) const
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
int GetOrder() const
Get the order of the NURBS collection: either a positive number, when using fixed order...
Mesh * mesh
The mesh that FE space lives on (not owned).
void ReorderElementToDofTable()
Reorder the scalar DOFs based on the element ordering.
GridFunction interpolation operator applicable after mesh refinement.
const NCList & GetNCList(int entity)
Return vertex/edge/face list (entity = 0/1/2, respectively).
Array< FaceQuadratureInterpolator * > E2BFQ_array
int Size() const
Returns the number of TYPE I elements.
int GetBdrAttribute(int i) const
int GetElementOrderImpl(int i) const
Return element order: internal version of GetElementOrder without checks.
Ordering::Type GetOrdering() const
Return the ordering method.
const Element * GetFace(int i) const
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...
Table var_face_dofs
NOTE: also used for spaces with mixed faces.
void Save(std::ostream &out) const
Save finite element space to output stream out.
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
General triple product operator x -> A*B*C*x, with ownership of the factors.
Array< FaceQuadratureInterpolator * > E2IFQ_array
void UpdateElementOrders()
Resize the elem_order array on mesh change.
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.).
void GetLocalDerefinementMatrices(Geometry::Type geom, DenseTensor &localR) const
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...
int GetNBE() const
Returns number of boundary elements in the mesh.
void MakeVDimMatrix(SparseMatrix &mat) const
Replicate 'mat' in the vector dimension, according to vdim ordering mode.
int index(int i, int j, int nx, int ny)
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Array< char > var_edge_orders
Lexicographic ordering for tensor-product FiniteElements.
virtual int GetNVertices() const =0
int parent
Coarse Element index in the coarse mesh.
FiniteElementSpace()
Default constructor: the object is invalid until initialized using the method Load().
void Constructor(Mesh *mesh, NURBSExtension *ext, const FiniteElementCollection *fec, int vdim=1, int ordering=Ordering::byNODES)
Help function for constructors + Load().
Operator * Ptr() const
Access the underlying Operator pointer.
int Size_of_connections() const
NCMesh * ncmesh
Optional nonconforming mesh extension.
int Size() const
Return the logical size of the array.
NQPT x VDIM x NE (values) / NQPT x VDIM x DIM x NE (grads)
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
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...
void filter_dos(std::string &line)
Check for, and remove, a trailing '\r' from and std::string.
MFEM_HOST_DEVICE void Set(const int height, const int width, const double alpha, const TA *Adata, TB *Bdata)
Compute B = alpha*A, where the matrices A and B are of size height x width with data Adata and Bdata...
void MakeRef(T *, int)
Make this Array a reference to a pointer.
void BuildNURBSFaceToDofTable() const
Generates partial face_dof table for a NURBS space.
int DofToVDof(int dof, int vd, int ndofs=-1) const
Compute a single vdof corresponding to the index dof and the vector index vd.
int GetNFaces() const
Return the number of faces in a 3D mesh.
std::tuple< bool, ElementDofOrdering, FaceType, L2FaceValues > key_face
The face restriction operators, see GetFaceRestriction().
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
void GetElementInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified element.
static bool DofFinalizable(int dof, const Array< bool > &finalized, const SparseMatrix &deps)
Class representing the storage layout of a QuadratureFunction.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
void UseExternalData(double *d, int h, int w)
Change the data array and the size of the DenseMatrix.
NURBSExtension * NURBSext
const FiniteElement * GetEdgeElement(int i, int variant=0) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th edge in the ...
Operation GetLastOperation() const
Return type of last modification of the mesh.
int GetNVariants(int entity, int index) const
Return number of possible DOF variants for edge/face (var. order spaces).
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Base class for operators that extracts Face degrees of freedom.
virtual void GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs. ...
void Swap(SparseMatrix &other)
int GetNConformingDofs() const
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...
Rank 3 tensor (array of matrices)
void SetOrder(int Order) const
Set the order and the name, based on the given Order: either a positive number for fixed order...
Geometry::Type GetBdrElementBaseGeometry(int i) const
Abstract data type element.
void BuildDofToArrays()
Initialize internal data that enables the use of the methods GetElementForDof() and GetLocalDofForDof...
const Table & GetElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each mesh element...
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
void GetLocalRefinementMatrices(Geometry::Type geom, DenseTensor &localP) const
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const
Compute the full set of vdofs corresponding to each entry in dofs.
Operator that converts L2 FiniteElementSpace L-vectors to E-vectors.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
static void AdjustVDofs(Array< int > &vdofs)
Remove the orientation information encoded into an array of dofs Some basis function types have a rel...
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
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...
Defines the position of a fine element within a coarse element.
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 Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
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 ...
const QuadratureSpace * qspace
Not owned.