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),
67 cP(NULL), cR(NULL), cR_hp(NULL), cP_is_set(false),
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)
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)
352 if (el_fos) { el_fos -> MakeI (
mesh ->
GetNE()); }
353 for (
int i = 0; i <
mesh ->
GetNE(); i++)
356 el_dof -> AddColumnsInRow (i, dofs.
Size());
361 el_fos -> AddColumnsInRow (i, Fo.
Size());
365 if (el_fos) { el_fos -> MakeJ(); }
366 for (
int i = 0; i <
mesh ->
GetNE(); i++)
369 el_dof -> AddConnections (i, (
int *)dofs, dofs.
Size());
374 el_fos -> AddConnections (i, (
int *)Fo, Fo.
Size());
377 el_dof -> ShiftUpI();
378 if (el_fos) { el_fos -> ShiftUpI(); }
416 for (
int i = 0; i < fc_dof->
Size(); i++)
422 for (
int i = 0; i < fc_dof->
Size(); i++)
447 for (
int k = 0, dof_counter = 0; k < nnz; k++)
449 const int sdof = J[k];
450 const int dof = (sdof < 0) ? -1-sdof : sdof;
451 int new_dof = dof_marker[dof];
454 dof_marker[dof] = new_dof = dof_counter++;
456 J[k] = (sdof < 0) ? -1-new_dof : new_dof;
469 for (
int i = 0; i <
mesh ->
GetNE(); i++)
471 const int *dofs =
elem_dof -> GetRow(i);
472 const int n =
elem_dof -> RowSize(i);
473 for (
int j = 0; j < n; j++)
487 for (
int i = 0; i < dofs.
Size(); i++)
490 if (k < 0) { k = -1 - k; }
504 for (
int i = 0; i <
GetNBE(); i++)
512 mark_dofs(vdofs, ess_vdofs);
517 for (
int d = 0; d < dofs.
Size(); d++)
518 { dofs[d] =
DofToVDof(dofs[d], component); }
519 mark_dofs(dofs, ess_vdofs);
531 for (
int i = 0; i < bdr_verts.
Size(); i++)
536 mark_dofs(vdofs, ess_vdofs);
541 for (
int d = 0; d < dofs.
Size(); d++)
542 { dofs[d] =
DofToVDof(dofs[d], component); }
543 mark_dofs(dofs, ess_vdofs);
546 for (
int i = 0; i < bdr_edges.
Size(); i++)
551 mark_dofs(vdofs, ess_vdofs);
556 for (
int d = 0; d < dofs.
Size(); d++)
557 { dofs[d] =
DofToVDof(dofs[d], component); }
558 mark_dofs(dofs, ess_vdofs);
603 for (
int i = 0; i < marker.
Size(); i++)
605 if (marker[i]) { num_marked++; }
610 for (
int i = 0; i < marker.
Size(); i++)
612 if (marker[i]) { list.
Append(i); }
624 for (
int i = 0; i < list.
Size(); i++)
626 marker[list[i]] = mark_val;
635 else { dofs.
Copy(cdofs); }
643 else { cdofs.
Copy(dofs); }
661 if (d_vdofs.
Size() != c_vdofs.
Size())
663 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
667 for (j = 0; j < d_vdofs.
Size(); j++)
669 R ->
Set (c_vdofs[j], d_vdofs[j], 1.0);
693 if (c_dofs.
Size() != 1)
695 "D2Const_GlobalRestrictionMatrix (...)");
698 for (j = 0; j < d_dofs.
Size(); j++)
700 R ->
Set (c_dofs[0], d_dofs[j], 1.0);
724 for (
int i = 0; i <
mesh ->
GetNE(); i++)
731 if (geom != cached_geom)
733 h_fe =
this ->
GetFE (i);
734 l_fe = lfes ->
GetFE (i);
736 h_fe->
Project(*l_fe, T, loc_restr);
740 for (
int vd = 0; vd < lvdim; vd++)
742 l_dofs.
Copy(l_vdofs);
745 h_dofs.
Copy(h_vdofs);
748 R -> SetSubMatrix (l_vdofs, h_vdofs, loc_restr, 1);
761 for (
int i = skipfirst; i < slave_dofs.
Size(); i++)
763 int sdof = slave_dofs[i];
766 for (
int j = 0; j < master_dofs.
Size(); j++)
768 double coef = I(i, j);
769 if (std::abs(coef) > 1e-12)
771 int mdof = master_dofs[j];
772 if (mdof != sdof && mdof != (-1-sdof))
774 deps.
Add(sdof, mdof, coef);
797 mesh->GetFaceVertices(slave_face, V);
798 mesh->GetFaceEdges(slave_face, E, Eo);
799 MFEM_ASSERT(V.
Size() == E.
Size(),
"");
806 for (
int i = 0; i < E.
Size(); i++)
808 int a = i,
b = (i+1) % V.
Size();
809 if (V[
a] > V[
b]) { std::swap(
a,
b); }
816 for (
int j = 0; j < 2; j++)
818 edge_pm(j, 0) = (*pm)(j,
a);
819 edge_pm(j, 1) = (*pm)(j,
b);
820 mid[j] = 0.5*((*pm)(j,
a) + (*pm)(j,
b));
824 const double eps = 1e-14;
825 if (mid[0] > eps && mid[0] < 1-eps &&
826 mid[1] > eps && mid[1] < 1-eps)
828 int order = GetEdgeDofs(E[i], slave_dofs, 0);
831 edge_fe->GetTransferMatrix(*master_fe, edge_T, I);
833 AddDependencies(deps, master_dofs, slave_dofs, I, 0);
845 for (
int i = 0; i < ndep; i++)
847 if (!finalized[dep[i]]) {
return false; }
874 if (!dofs.
Size()) {
return 0; }
879 for (
int i = 0; i < nv; i++)
882 dofs[nv+i] = edof[nv+i];
886 for (
int i = 0; i < ne; i++)
888 dofs[face_vert*nv + i] = edof[2*nv + i];
931 MFEM_VERIFY(dynamic_cast<const ParFiniteElementSpace*>(
this) == NULL,
932 "This method should not be used with a ParFiniteElementSpace!");
944 Array<int> master_dofs, slave_dofs, highest_dofs;
961 for (
int entity = 2; entity >= 1; entity--)
964 if (!list.
masters.Size()) {
continue; }
972 if (!master_dofs.
Size()) {
continue; }
975 if (!master_fe) {
continue; }
982 default: MFEM_ABORT(
"unsupported geometry");
990 if (!slave_dofs.
Size()) {
break; }
1011 slave_dofs, slave.
index, pm);
1023 master_geom, nvar-1);
1024 const auto *highest_fe =
fec->
GetFE(master_geom, q);
1026 T.SetIdentityTransformation(master_geom);
1044 MFEM_ASSERT(ent_dofs.
Size() == num_ent+1,
"");
1048 for (
int i = 0; i < num_ent; i++)
1050 if (ent_dofs.
RowSize(i) <= 1) {
continue; }
1055 if (geom != last_geom)
1057 T.SetIdentityTransformation(geom);
1063 const auto *master_fe =
fec->
GetFE(geom,
p);
1064 if (!master_fe) {
break; }
1067 for (
int variant = 1; ; variant++)
1069 int q =
GetEntityDofs(entity, i, slave_dofs, geom, variant);
1070 if (q < 0) {
break; }
1072 const auto *slave_fe =
fec->
GetFE(geom, q);
1085 int n_true_dofs = 0;
1086 for (
int i = 0; i <
ndofs; i++)
1088 if (!deps.
RowSize(i)) { n_true_dofs++; }
1092 if (n_true_dofs ==
ndofs)
1107 for (
int i = 0; i < n_true_dofs; i++)
1112 cR_I[n_true_dofs] = n_true_dofs;
1127 for (
int i = 0, true_dof = 0; i <
ndofs; i++)
1131 cP->
Add(i, true_dof, 1.0);
1133 finalized[i] =
true;
1139 inv_deps.
GetRow(i, cols, srow);
1160 int n_finalized = n_true_dofs;
1164 for (
int dof = 0; dof <
ndofs; dof++)
1170 int n_dep = deps.
RowSize(dof);
1172 for (
int j = 0; j < n_dep; j++)
1174 cP->
GetRow(dep_col[j], cols, srow);
1175 srow *= dep_coef[j];
1179 finalized[dof] =
true;
1189 MFEM_VERIFY(n_finalized ==
ndofs,
1190 "Error creating cP matrix: n_finalized = " 1191 << n_finalized <<
", ndofs = " <<
ndofs);
1206 if (
vdim == 1) {
return; }
1208 int height = mat.
Height();
1209 int width = mat.
Width();
1215 for (
int i = 0; i < height; i++)
1217 mat.
GetRow(i, dofs, srow);
1218 for (
int vd = 0; vd <
vdim; vd++)
1298 key_face key = std::make_tuple(is_dg_space, e_ordering, type, m);
1299 auto itr =
L2F.find(key);
1300 if (itr !=
L2F.end())
1330 for (
int i = 0; i <
E2Q_array.Size(); i++)
1333 if (qi->
IntRule == &ir) {
return qi; }
1344 for (
int i = 0; i <
E2Q_array.Size(); i++)
1347 if (qi->
qspace == &qs) {
return qi; }
1364 if (qi->
IntRule == &ir) {
return qi; }
1377 if (qi->
IntRule == &ir) {
return qi; }
1388 const int coarse_ndofs,
const Table &coarse_elem_dof,
1401 if (elem_geoms.
Size() == 1)
1403 const int coarse_ldof = localP[elem_geoms[0]].
SizeJ();
1421 const int fine_ldof = localP[geom].
SizeI();
1426 for (
int vd = 0; vd <
vdim; vd++)
1428 coarse_dofs.Copy(coarse_vdofs);
1431 for (
int i = 0; i < fine_ldof; i++)
1434 int m = (r >= 0) ? r : (-1 - r);
1439 P->
SetRow(r, coarse_vdofs, row);
1446 MFEM_ASSERT(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
1459 int nmat = pmats.
SizeK();
1466 localP.
SetSize(ldof, ldof, nmat);
1467 for (
int i = 0; i < nmat; i++)
1475 const Table* old_elem_dof,
1476 const Table* old_elem_fos)
1478 MFEM_VERIFY(
GetNE() >= old_elem_dof->
Size(),
1479 "Previous mesh is not coarser.");
1484 for (
int i = 0; i < elem_geoms.Size(); i++)
1497 , old_elem_dof(old_elem_dof)
1498 , old_elem_fos(old_elem_fos)
1500 MFEM_VERIFY(fespace->
GetNE() >= old_elem_dof->
Size(),
1501 "Previous mesh is not coarser.");
1503 width = old_ndofs * fespace->
GetVDim();
1508 for (
int i = 0; i < elem_geoms.Size(); i++)
1513 ConstructDoFTrans();
1518 :
Operator(fespace->GetVSize(), coarse_fes->GetVSize()),
1519 fespace(fespace), old_elem_dof(NULL), old_elem_fos(NULL)
1523 for (
int i = 0; i < elem_geoms.Size(); i++)
1526 localP[elem_geoms[i]]);
1538 ConstructDoFTrans();
1543 delete old_elem_dof;
1544 delete old_elem_fos;
1547 void FiniteElementSpace::RefinementOperator
1548 ::ConstructDoFTrans()
1551 for (
int i=0; i<old_DoFTrans.Size(); i++)
1553 old_DoFTrans[i] = NULL;
1557 if (dynamic_cast<const ND_FECollection*>(fec_ref))
1567 const FiniteElement * nd_tet =
1572 new ND_TetDofTransformation(nd_tet->GetOrder());
1575 const FiniteElement * nd_pri =
1580 new ND_WedgeDofTransformation(nd_pri->GetOrder());
1592 Array<int> dofs, vdofs, old_dofs, old_vdofs, old_Fo;
1594 int rvdim = fespace->
GetVDim();
1595 int old_ndofs = width / rvdim;
1599 for (
int k = 0; k < mesh_ref->
GetNE(); k++)
1612 for (
int vd = 0; vd < rvdim; vd++)
1616 old_dofs.
Copy(old_vdofs);
1619 lP.
Mult(subX, subY);
1626 old_DoFTrans[geom]->SetFaceOrientations(old_Fo);
1633 new_doftrans = doftrans;
1637 for (
int vd = 0; vd < rvdim; vd++)
1641 old_dofs.
Copy(old_vdofs);
1644 old_DoFTrans[geom]->InvTransformPrimal(subX);
1645 lP.
Mult(subX, subY);
1652 doftrans = new_doftrans;
1670 Array<int> f_dofs, c_dofs, f_vdofs, c_vdofs, old_Fo;
1672 int rvdim = fespace->
GetVDim();
1673 int old_ndofs = width / rvdim;
1675 Vector subY, subX, subYt;
1677 for (
int k = 0; k < mesh_ref->
GetNE(); k++)
1690 for (
int vd = 0; vd < rvdim; vd++)
1692 f_dofs.
Copy(f_vdofs);
1694 c_dofs.
Copy(c_vdofs);
1699 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1716 old_DoFTrans[geom]->SetFaceOrientations(old_Fo);
1723 new_doftrans = doftrans;
1727 for (
int vd = 0; vd < rvdim; vd++)
1729 f_dofs.
Copy(f_vdofs);
1731 c_dofs.
Copy(c_vdofs);
1735 doftrans->InvTransformDual(subX);
1736 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1745 old_DoFTrans[geom]->TransformDual(subYt);
1751 doftrans = new_doftrans;
1755 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
1773 : geom(g), num_children(n), children(c) { }
1775 bool operator<(
const RefType &other)
const 1777 if (geom < other.geom) {
return true; }
1778 if (geom > other.geom) {
return false; }
1779 if (num_children < other.num_children) {
return true; }
1780 if (num_children > other.num_children) {
return false; }
1781 for (
int i = 0; i < num_children; i++)
1783 if (children[i].one < other.children[i].one) {
return true; }
1784 if (children[i].one > other.children[i].one) {
return false; }
1790 void GetCoarseToFineMap(
const CoarseFineTransformations &cft,
1792 Table &coarse_to_fine,
1793 Array<int> &coarse_to_ref_type,
1794 Table &ref_type_to_matrix,
1795 Array<Geometry::Type> &ref_type_to_geom)
1797 const int fine_ne = cft.embeddings.Size();
1799 for (
int i = 0; i < fine_ne; i++)
1801 coarse_ne = std::max(coarse_ne, cft.embeddings[i].parent);
1805 coarse_to_ref_type.SetSize(coarse_ne);
1806 coarse_to_fine.SetDims(coarse_ne, fine_ne);
1808 Array<int> cf_i(coarse_to_fine.GetI(), coarse_ne+1);
1809 Array<Pair<int,int> > cf_j(fine_ne);
1811 for (
int i = 0; i < fine_ne; i++)
1813 cf_i[cft.embeddings[i].parent+1]++;
1816 MFEM_ASSERT(cf_i.Last() == cf_j.Size(),
"internal error");
1817 for (
int i = 0; i < fine_ne; i++)
1819 const Embedding &e = cft.embeddings[i];
1820 cf_j[cf_i[e.parent]].one = e.matrix;
1821 cf_j[cf_i[e.parent]].two = i;
1824 std::copy_backward(cf_i.begin(), cf_i.end()-1, cf_i.end());
1826 for (
int i = 0; i < coarse_ne; i++)
1828 std::sort(&cf_j[cf_i[i]], cf_j.GetData() + cf_i[i+1]);
1830 for (
int i = 0; i < fine_ne; i++)
1832 coarse_to_fine.GetJ()[i] = cf_j[i].two;
1838 map<RefType,int> ref_type_map;
1839 for (
int i = 0; i < coarse_ne; i++)
1841 const int num_children = cf_i[i+1]-cf_i[i];
1842 MFEM_ASSERT(num_children > 0,
"");
1843 const int fine_el = cf_j[cf_i[i]].two;
1846 const RefType ref_type(geom, num_children, &cf_j[cf_i[i]]);
1847 pair<map<RefType,int>::iterator,
bool> res =
1848 ref_type_map.insert(
1849 pair<const RefType,int>(ref_type, (
int)ref_type_map.size()));
1850 coarse_to_ref_type[i] = res.first->second;
1853 ref_type_to_matrix.MakeI((
int)ref_type_map.size());
1854 ref_type_to_geom.SetSize((
int)ref_type_map.size());
1855 for (map<RefType,int>::iterator it = ref_type_map.begin();
1856 it != ref_type_map.end(); ++it)
1858 ref_type_to_matrix.AddColumnsInRow(it->second, it->first.num_children);
1859 ref_type_to_geom[it->second] = it->first.geom;
1862 ref_type_to_matrix.MakeJ();
1863 for (map<RefType,int>::iterator it = ref_type_map.begin();
1864 it != ref_type_map.end(); ++it)
1866 const RefType &rt = it->first;
1867 for (
int j = 0; j < rt.num_children; j++)
1869 ref_type_to_matrix.AddConnection(it->second, rt.children[j].one);
1872 ref_type_to_matrix.ShiftUpI();
1887 "incompatible coarse and fine FE spaces");
1895 for (
int gi = 0; gi < elem_geoms.
Size(); gi++)
1898 DenseTensor &lP = localP[geom], &lM = localM[geom];
1907 emb_tr.SetIdentityTransformation(geom);
1908 for (
int i = 0; i < pmats.
SizeK(); i++)
1910 emb_tr.SetPointMat(pmats(i));
1918 Table ref_type_to_matrix;
1919 internal::GetCoarseToFineMap(rtrans, *f_mesh, coarse_to_fine,
1920 coarse_to_ref_type, ref_type_to_matrix,
1922 MFEM_ASSERT(coarse_to_fine.Size() == c_fes->
GetNE(),
"");
1924 const int total_ref_types = ref_type_to_geom.Size();
1926 Array<int> ref_type_to_coarse_elem_offset(total_ref_types);
1927 ref_type_to_fine_elem_offset.
SetSize(total_ref_types);
1930 for (
int i = 0; i < total_ref_types; i++)
1933 ref_type_to_coarse_elem_offset[i] = num_ref_types[g];
1934 ref_type_to_fine_elem_offset[i] = num_fine_elems[g];
1936 num_fine_elems[g] += ref_type_to_matrix.
RowSize(i);
1941 if (num_ref_types[g] == 0) {
continue; }
1942 const int fine_dofs = localP[g].
SizeI();
1943 const int coarse_dofs = localP[g].
SizeJ();
1944 localPtMP[g].
SetSize(coarse_dofs, coarse_dofs, num_ref_types[g]);
1945 localR[g].
SetSize(coarse_dofs, fine_dofs, num_fine_elems[g]);
1947 for (
int i = 0; i < total_ref_types; i++)
1950 DenseMatrix &lPtMP = localPtMP[g](ref_type_to_coarse_elem_offset[i]);
1951 int lR_offset = ref_type_to_fine_elem_offset[i];
1952 const int *mi = ref_type_to_matrix.
GetRow(i);
1953 const int nm = ref_type_to_matrix.
RowSize(i);
1955 for (
int s = 0;
s < nm;
s++)
1964 for (
int s = 0;
s < nm;
s++)
1977 delete coarse_elem_dof;
1986 const int fine_vdim = fine_fes->GetVDim();
1987 const int coarse_ndofs = height/fine_vdim;
1988 for (
int coarse_el = 0; coarse_el < coarse_to_fine.Size(); coarse_el++)
1990 coarse_elem_dof->
GetRow(coarse_el, c_vdofs);
1991 fine_fes->DofsToVDofs(c_vdofs, coarse_ndofs);
1996 const int ref_type = coarse_to_ref_type[coarse_el];
1998 const int *fine_elems = coarse_to_fine.GetRow(coarse_el);
1999 const int num_fine_elems = coarse_to_fine.RowSize(coarse_el);
2000 const int lR_offset = ref_type_to_fine_elem_offset[ref_type];
2001 for (
int s = 0;
s < num_fine_elems;
s++)
2004 fine_fes->GetElementVDofs(fine_elems[
s], f_vdofs);
2023 const int nmat = pmats.
SizeK();
2024 const int ldof = fe->
GetDof();
2030 localR.
SetSize(ldof, ldof, nmat);
2031 for (
int i = 0; i < nmat; i++)
2039 const Table* old_elem_dof,
2040 const Table* old_elem_fos)
2044 MFEM_VERIFY(
Nonconforming(),
"Not implemented for conforming meshes.");
2045 MFEM_VERIFY(old_ndofs,
"Missing previous (finer) space.");
2046 MFEM_VERIFY(
ndofs <= old_ndofs,
"Previous space is not finer.");
2054 for (
int i = 0; i < elem_geoms.
Size(); i++)
2067 MFEM_ASSERT(dtrans.
embeddings.Size() == old_elem_dof->
Size(),
"");
2071 for (
int k = 0; k < dtrans.
embeddings.Size(); k++)
2078 old_elem_dof->
GetRow(k, old_dofs);
2080 for (
int vd = 0; vd <
vdim; vd++)
2082 old_dofs.
Copy(old_vdofs);
2085 for (
int i = 0; i < lR.
Height(); i++)
2087 if (!std::isfinite(lR(i, 0))) {
continue; }
2090 int m = (r >= 0) ? r : (-1 - r);
2092 if (is_dg || !mark[m])
2095 R->
SetRow(r, old_vdofs, row);
2106 MFEM_VERIFY(num_marked == R->
Height(),
2107 "internal error: not all rows of R were set.");
2127 int nmat = pmats.
SizeK();
2134 for (
int i = 0; i < nmat; i++)
2143 int vdim_,
int ordering_)
2164 MFEM_VERIFY(mesh_->
NURBSext,
"NURBS FE space requires a NURBS mesh.");
2166 if (NURBSext_ == NULL)
2198 for (
int i=0; i<
DoFTrans.Size(); i++)
2203 if (dynamic_cast<const ND_FECollection*>(
fec))
2235 mfem_error(
"FiniteElementSpace::StealNURBSext");
2244 MFEM_VERIFY(
NURBSext,
"NURBSExt not defined.");
2288 if (
b == -1) {
continue; }
2298 for (
int i = 0; i < nv; i++)
2300 MFEM_VERIFY(fv[i] == bv[i],
2301 "non-matching face and boundary elements detected!");
2306 for (
int i = 0; i < row.
Size(); i++)
2309 face_dof_list.
Append(conn);
2318 MFEM_VERIFY(!
NURBSext,
"internal error");
2323 "Variable order space requires a nonconforming mesh.");
2345 "Mesh was not correctly finalized.");
2356 else if (mixed_faces)
2443 MFEM_ASSERT(bits != 0,
"invalid bit mask");
2444 for (
int order = 0; bits != 0; order++, bits >>= 1)
2446 if (bits & 1) {
return order; }
2473 for (
int j = 0; j < E.
Size(); j++)
2475 edge_orders[E[j]] |= mask;
2481 for (
int j = 0; j < F.
Size(); j++)
2483 face_orders[F[j]] |= mask;
2511 slave_orders |= edge_orders[edge_list.
slaves[i].index];
2514 int min_order =
MinOrder(slave_orders);
2530 if (slave.
index >= 0)
2532 slave_orders |= face_orders[slave.
index];
2535 for (
int j = 0; j < E.
Size(); j++)
2537 slave_orders |= edge_orders[E[j]];
2543 slave_orders |= edge_orders[-1 - slave.
index];
2547 int min_order =
MinOrder(slave_orders);
2559 for (
int j = 0; j < E.
Size(); j++)
2561 edge_orders[E[j]] |= face_orders[i];
2583 int num_ent = entity_orders.
Size();
2592 var_ent_order->
Reserve(num_ent);
2596 for (
int i = 0; i < num_ent; i++)
2601 for (
int order = 0; bits != 0; order++, bits >>= 1)
2609 if (var_ent_order) { var_ent_order->
Append(order); }
2624 int row,
int ndof)
const 2626 const int *beg = var_dof_table.
GetRow(row);
2627 const int *end = var_dof_table.
GetRow(row + 1);
2632 if ((beg[1] - beg[0]) == ndof) {
return beg[0]; }
2636 MFEM_ABORT(
"DOFs not found for ndof = " << ndof);
2646 if (variant >= end - beg) {
return -1; }
2662 if (variant >= end - beg) {
return -1; }
2676 static const char* msg_orders_changed =
2677 "Element orders changed, you need to Update() the space first.";
2714 for (
int i = 0; i < F.
Size(); i++)
2721 -> SetFaceOrientations(Fo);
2730 for (
int i = 0; i < V.
Size(); i++)
2732 for (
int j = 0; j < nv; j++)
2734 dofs.
Append(V[i]*nv + j);
2741 for (
int i = 0; i < E.
Size(); i++)
2746 for (
int j = 0; j < ne; j++)
2755 for (
int i = 0; i < F.
Size(); i++)
2763 for (
int j = 0; j < nf; j++)
2775 for (
int j = 0; j < nb; j++)
2785 if (i < 0 || !mesh->
GetNE()) {
return NULL; }
2786 MFEM_VERIFY(i < mesh->
GetNE(),
2787 "Invalid element id " << i <<
", maximum allowed " <<
mesh->
GetNE()-1);
2804 "internal error: " <<
2827 SetFaceOrientations(Fo);
2860 SetFaceOrientations(Fo);
2869 for (
int i = 0; i < V.
Size(); i++)
2871 for (
int j = 0; j < nv; j++)
2873 dofs.
Append(V[i]*nv + j);
2880 for (
int i = 0; i < E.
Size(); i++)
2885 for (
int j = 0; j < ne; j++)
2897 for (
int j = 0; j < nf; j++)
2920 int order, nf, fbase;
2928 if (variant >= end - beg) {
return -1; }
2930 fbase = beg[variant];
2931 nf = beg[variant+1] - fbase;
2939 if (variant > 0) {
return -1; }
2958 for (
int i = 0; i < V.
Size(); i++)
2960 for (
int j = 0; j < nv; j++)
2962 dofs.
Append(V[i]*nv + j);
2968 for (
int i = 0; i < E.
Size(); i++)
2973 for (
int j = 0; j < ne; j++)
2979 for (
int j = 0; j < nf; j++)
2992 int order, ne, base;
2997 if (variant >= end - beg) {
return -1; }
2999 base = beg[variant];
3000 ne = beg[variant+1] - base;
3007 if (variant > 0) {
return -1; }
3020 for (
int i = 0; i < 2; i++)
3022 for (
int j = 0; j < nv; j++)
3024 dofs.
Append(V[i]*nv + j);
3027 for (
int j = 0; j < ne; j++)
3039 for (
int j = 0; j < nv; j++)
3054 for (
int j = 0; j < nb; j++)
3072 for (
int j = 0, k =
nvdofs+i*ne; j < ne; j++, k++)
3096 for (
int j = 0; j < nf; j++)
3158 "NURBS mesh: only boundary faces are supported!");
3168 MFEM_ASSERT(
mesh->
Dimension() > 1,
"No edges with mesh dimension < 2");
3193 for (
int i = 0; i <
E2Q_array.Size(); i++)
3239 for (
int i = 0; i <
DoFTrans.Size(); i++)
3256 for (
int i = 0; i < elem_geoms.
Size(); i++)
3259 localP[elem_geoms[i]]);
3295 if (RP_case == 0) {
return; }
3296 const bool owner = T.OwnsOperator();
3297 T.SetOperatorOwner(
false);
3308 cR, T.Ptr(), coarse_P,
false, owner,
false));
3330 MFEM_ABORT(
"not implemented yet");
3346 MFEM_ABORT(
"Error in update sequence. Space needs to be updated after " 3347 "each mesh modification.");
3354 MFEM_ABORT(
"Updating space after both mesh change and element order " 3355 "change is not supported. Please update separately after " 3366 Table* old_elem_dof = NULL;
3367 Table* old_elem_fos = NULL;
3393 MFEM_VERIFY(!old_orders_changed,
"Interpolation for element order change " 3394 "is not implemented yet, sorry.");
3404 old_elem_fos, old_ndofs));
3407 old_elem_dof = NULL;
3408 old_elem_fos = NULL;
3427 false,
false,
true));
3436 delete old_elem_dof;
3437 delete old_elem_fos;
3448 int fes_format = 90;
3449 bool nurbs_unit_weights =
false;
3460 MFEM_VERIFY(nurbs_fec,
"invalid FE collection");
3462 const double eps = 5e-14;
3473 os << (fes_format == 90 ?
3474 "FiniteElementSpace\n" :
"MFEM FiniteElementSpace v1.0\n")
3475 <<
"FiniteElementCollection: " <<
fec->
Name() <<
'\n' 3476 <<
"VDim: " <<
vdim <<
'\n' 3477 <<
"Ordering: " <<
ordering <<
'\n';
3479 if (fes_format == 100)
3493 os <<
"NURBS_orders\n";
3500 os <<
"NURBS_periodic\n";
3505 if (!nurbs_unit_weights)
3507 os <<
"NURBS_weights\n";
3511 os <<
"End: MFEM FiniteElementSpace v1.0\n";
3518 int fes_format = 0, ord;
3524 getline(input, buff);
3526 if (buff ==
"FiniteElementSpace") { fes_format = 90; }
3527 else if (buff ==
"MFEM FiniteElementSpace v1.0") { fes_format = 100; }
3528 else { MFEM_ABORT(
"input stream is not a FiniteElementSpace!"); }
3529 getline(input, buff,
' ');
3531 getline(input, buff);
3534 getline(input, buff,
' ');
3536 getline(input, buff,
' ');
3541 if (fes_format == 90)
3545 MFEM_VERIFY(m->
NURBSext,
"NURBS FE collection requires a NURBS mesh!");
3546 const int order = nurbs_fec->
GetOrder();
3554 else if (fes_format == 100)
3559 MFEM_VERIFY(input.good(),
"error reading FiniteElementSpace v1.0");
3560 getline(input, buff);
3562 if (buff ==
"NURBS_order" || buff ==
"NURBS_orders")
3564 MFEM_VERIFY(nurbs_fec,
3565 buff <<
": NURBS FE collection is required!");
3566 MFEM_VERIFY(m->
NURBSext, buff <<
": NURBS mesh is required!");
3567 MFEM_VERIFY(!nurbs_ext, buff <<
": order redefinition!");
3568 if (buff ==
"NURBS_order")
3581 else if (buff ==
"NURBS_periodic")
3588 else if (buff ==
"NURBS_weights")
3590 MFEM_VERIFY(nurbs_ext,
"NURBS_weights: NURBS_orders have to be " 3591 "specified before NURBS_weights!");
3594 else if (buff ==
"element_orders")
3596 MFEM_VERIFY(!nurbs_fec,
"section element_orders cannot be used " 3597 "with a NURBS FE collection");
3598 MFEM_ABORT(
"element_orders: not implemented yet!");
3600 else if (buff ==
"End: MFEM FiniteElementSpace v1.0")
3606 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
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.
Operator that extracts Face degrees of freedom for H1 FiniteElementSpaces.
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.
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
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
void GetVertexVDofs(int i, Array< int > &vdofs) const
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)
Helpers to remove encoded sign from a 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 indexes of degrees of freedom for i'th face element (2D and 3D).
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'.
static constexpr int MaxVarOrder
virtual ~DerefinementOperator()
unsigned matrix
index into NCList::point_matrices[geom]
void AddEdgeFaceDependencies(SparseMatrix &deps, Array< int > &master_dofs, const FiniteElement *master_fe, Array< int > &slave_dofs, int slave_face, const DenseMatrix *pm) const
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.
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.
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.
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).
void AddRow(const int row, const Array< int > &cols, const Vector &srow)
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
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.
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
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
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
double f(const Vector &xvec)
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).
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.
SparseMatrix * cR
Conforming restriction matrix such that cR.cP=I.
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...
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
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 indexes of degrees of freedom in array dofs for i'th element.
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)
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
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 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()
virtual DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element 'elem'.
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
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 indexes of degrees of freedom for i'th boundary element.
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 indexes of degrees of freedom for i'th edge.
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
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
SparseMatrix * cR_hp
A version of the conforming restriction matrix for variable-order spaces.
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
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.
virtual const FaceRestriction * GetFaceRestriction(ElementDofOrdering e_ordering, FaceType, L2FaceValues mul=L2FaceValues::DoubleValued) const
Return an Operator that converts L-vectors to E-vectors on each face.
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
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)
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 ...
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
const QuadratureSpace * qspace
Not owned.