28template <>
void Ordering::
29DofsToVDofs<Ordering::byNODES>(
int ndofs,
int vdim,
Array<int> &dofs)
32 int size = dofs.
Size();
34 for (
int vd = 1; vd < vdim; vd++)
36 for (
int i = 0; i < size; i++)
38 dofs[i+size*vd] = Map<byNODES>(ndofs, vdim, dofs[i], vd);
43template <>
void Ordering::
44DofsToVDofs<Ordering::byVDIM>(
int ndofs,
int vdim,
Array<int> &dofs)
47 int size = dofs.
Size();
49 for (
int vd = vdim-1; vd >= 0; vd--)
51 for (
int i = 0; i < size; i++)
53 dofs[i+size*vd] = Map<byVDIM>(ndofs, vdim, dofs[i], vd);
61 ndofs(0), nvdofs(0), nedofs(0), nfdofs(0), nbdofs(0),
63 elem_dof(NULL), elem_fos(NULL), bdr_elem_dof(NULL), bdr_elem_fos(NULL),
65 NURBSext(NULL), own_ext(false),
68 sequence(0), mesh_sequence(0), orders_changed(false), relaxed_hp(false)
75 mesh_ = mesh_ ? mesh_ : orig.
mesh;
76 fec_ = fec_ ? fec_ : orig.
fec;
100 int vdim,
int ordering)
105 int vdim,
int ordering)
111 MFEM_VERIFY(
cP == NULL,
"");
112 MFEM_VERIFY(
cR == NULL,
"");
120 int n = perm->
Size();
122 for (
int i=0; i<n; ++i)
126 perm_mat->
Set(i, j, s);
138 else if (perm != NULL)
149 else if (perm != NULL)
151 cR.reset(perm_mat_tr);
163 "Attempting to set serial prolongation operator for "
164 "parallel finite element space.");
182 "Attempting to set serial restriction operator for "
183 "parallel finite element space.");
199 "Space has not been Updated() after a Mesh change.");
200 MFEM_VERIFY(i >= 0 && i <
GetNE(),
"Invalid element index");
201 MFEM_VERIFY(
p >= 0 &&
p <=
MaxVarOrder,
"Order out of range");
224 "Space has not been Updated() after a Mesh change.");
225 MFEM_VERIFY(i >= 0 && i <
GetNE(),
"Invalid element index");
240 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
244 for (
int i = 0; i < dofs.
Size(); i++)
246 dofs[i] = Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, i, vd);
251 for (
int i = 0; i < dofs.
Size(); i++)
253 dofs[i] = Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, i, vd);
260 if (
vdim == 1) {
return; }
261 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
265 Ordering::DofsToVDofs<Ordering::byNODES>(ndofs_,
vdim, dofs);
269 Ordering::DofsToVDofs<Ordering::byVDIM>(ndofs_,
vdim, dofs);
275 if (
vdim == 1) {
return; }
276 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
280 for (
int i = 0; i < dofs.
Size(); i++)
282 dofs[i] = Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, dofs[i], vd);
287 for (
int i = 0; i < dofs.
Size(); i++)
289 dofs[i] = Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, dofs[i], vd);
296 if (
vdim == 1) {
return dof; }
297 if (ndofs_ < 0) { ndofs_ = this->
ndofs; }
301 return Ordering::Map<Ordering::byNODES>(ndofs_,
vdim, dof, vd);
305 return Ordering::Map<Ordering::byVDIM>(ndofs_,
vdim, dof, vd);
312 int n = vdofs.
Size(), *vdof = vdofs;
313 for (
int i = 0; i < n; i++)
316 if ((j = vdof[i]) < 0)
414 if (el_fos) { el_fos->
MakeJ(); }
453 if (bel_fos) { bel_fos->
MakeJ(); }
466 if (bel_fos) { bel_fos->
ShiftUpI(); }
482 for (
int i = 0; i < fc_dof->
Size(); i++)
488 for (
int i = 0; i < fc_dof->
Size(); i++)
513 for (
int k = 0, dof_counter = 0; k < nnz; k++)
515 const int sdof = J[k];
516 const int dof = (sdof < 0) ? -1-sdof : sdof;
517 int new_dof = dof_marker[dof];
520 dof_marker[dof] = new_dof = dof_counter++;
522 J[k] = (sdof < 0) ? -1-new_dof : new_dof;
535 for (
int i = 0; i <
mesh ->
GetNE(); i++)
537 const int *dofs =
elem_dof -> GetRow(i);
538 const int n =
elem_dof -> RowSize(i);
539 for (
int j = 0; j < n; j++)
564 for (
int j = 0; j < n; j++)
580 mark_array[d >= 0 ? d : -1 - d] = -1;
591 for (
int i = 0; i <
GetNBE(); i++)
603 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
616 for (
auto v : bdr_verts)
625 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
629 for (
auto e : bdr_edges)
638 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
642 for (
auto f : bdr_faces)
651 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
678 std::string error_msg =
"failed dof: ";
679 auto ess_tdofs_ = ess_tdofs.
HostRead();
680 auto ess_tdofs2_ = ess_tdofs2.
HostRead();
681 for (
int i = 0; i < ess_tdofs2.
Size(); ++i)
683 if (
bool(ess_tdofs_[i]) !=
bool(ess_tdofs2_[i]))
685 error_msg += std::to_string(i) +=
"(R ";
686 error_msg += std::to_string(
bool(ess_tdofs_[i])) +=
" P^T ";
687 error_msg += std::to_string(
bool(ess_tdofs2_[i])) +=
") ";
694 MFEM_ASSERT(R->
Width() == ess_vdofs.
Size(),
"!");
695 MFEM_VERIFY(counter == 0,
"internal MFEM error: counter = " << counter
696 <<
' ' << error_msg);
726 for (
int i = 0; i < ext_face_marker.
Size(); i++)
728 if (ext_face_marker[i])
739 for (
auto &d : dofs) { d =
DofToVDof(d, component); }
765 std::string error_msg =
"failed dof: ";
766 auto ext_tdofs_ = ext_tdofs.
HostRead();
767 auto ext_tdofs2_ = ext_tdofs2.
HostRead();
768 for (
int i = 0; i < ext_tdofs2.
Size(); ++i)
770 if (
bool(ext_tdofs_[i]) !=
bool(ext_tdofs2_[i]))
772 error_msg += std::to_string(i) +=
"(R ";
773 error_msg += std::to_string(
bool(ext_tdofs_[i])) +=
" P^T ";
774 error_msg += std::to_string(
bool(ext_tdofs2_[i])) +=
") ";
781 MFEM_ASSERT(R->
Width() == ext_vdofs.
Size(),
"!");
782 MFEM_VERIFY(counter == 0,
"internal MFEM error: counter = " << counter
783 <<
' ' << error_msg);
795 for (
int i = 0; i < marker.
Size(); i++)
797 if (marker[i]) { num_marked++; }
801 list.Reserve(num_marked);
802 for (
int i = 0; i < marker.
Size(); i++)
804 if (marker[i]) { list.Append(i); }
816 for (
int i = 0; i < list.Size(); i++)
818 marker[list[i]] = mark_val;
826 if (
cP) {
cP->BooleanMultTranspose(dofs, cdofs); }
827 else { dofs.
Copy(cdofs); }
834 if (
cR) {
cR->BooleanMultTranspose(cdofs, dofs); }
835 else { cdofs.
Copy(dofs); }
853 if (d_vdofs.
Size() != c_vdofs.
Size())
855 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
859 for (j = 0; j < d_vdofs.
Size(); j++)
861 R -> Set (c_vdofs[j], d_vdofs[j], 1.0);
885 if (c_dofs.
Size() != 1)
887 "D2Const_GlobalRestrictionMatrix (...)");
890 for (j = 0; j < d_dofs.
Size(); j++)
892 R -> Set (c_dofs[0], d_dofs[j], 1.0);
916 for (
int i = 0; i <
mesh ->
GetNE(); i++)
923 if (geom != cached_geom)
925 h_fe =
this ->
GetFE (i);
926 l_fe = lfes ->
GetFE (i);
928 h_fe->
Project(*l_fe, T, loc_restr);
932 for (
int vd = 0; vd < lvdim; vd++)
934 l_dofs.
Copy(l_vdofs);
937 h_dofs.
Copy(h_vdofs);
940 R -> SetSubMatrix (l_vdofs, h_vdofs, loc_restr, 1);
953 for (
int i = skipfirst; i < slave_dofs.
Size(); i++)
955 const int sdof = slave_dofs[i];
958 for (
int j = 0; j < master_dofs.
Size(); j++)
960 const real_t coef = I(i, j);
961 if (std::abs(coef) > 1e-12)
963 const int mdof = master_dofs[j];
964 if (mdof != sdof && mdof != (-1-sdof))
966 deps.
Add(sdof, mdof, coef);
989 MFEM_ASSERT(V.
Size() == E.
Size(),
"");
996 for (
int i = 0; i < E.
Size(); i++)
998 int a = i,
b = (i+1) % V.
Size();
999 if (V[
a] > V[
b]) { std::swap(
a,
b); }
1006 for (
int j = 0; j < 2; j++)
1008 edge_pm(j, 0) = (*pm)(j,
a);
1009 edge_pm(j, 1) = (*pm)(j,
b);
1010 mid[j] = 0.5*((*pm)(j,
a) + (*pm)(j,
b));
1014 const real_t eps = 1e-14;
1015 if (mid[0] > eps && mid[0] < 1-eps &&
1016 mid[1] > eps && mid[1] < 1-eps)
1035 for (
int i = 0; i < ndep; i++)
1037 if (!finalized[dep[i]]) {
return false; }
1064 if (!dofs.
Size()) {
return 0; }
1069 for (
int i = 0; i < nv; i++)
1072 dofs[nv+i] = edof[nv+i];
1076 for (
int i = 0; i < ne; i++)
1078 dofs[face_vert*nv + i] = edof[2*nv + i];
1141 MFEM_ASSERT(ent_dofs.
Size() >= num_ent+1,
"");
1145 for (
int i = 0; i < num_ent; i++)
1147 if (ent_dofs.
RowSize(i) <= 1) {
continue; }
1152 if (geom != last_geom)
1160 const auto *master_fe =
fec->
GetFE(geom,
p);
1161 if (!master_fe) {
break; }
1164 for (
int variant = 1; ; variant++)
1166 const int q =
GetEntityDofs(entity, i, slave_dofs, geom, variant);
1167 if (q < 0) {
break; }
1169 const auto *slave_fe =
fec->
GetFE(geom, q);
1182 "This method should not be used with a ParFiniteElementSpace!");
1197 Array<int> master_dofs, slave_dofs, highest_dofs;
1216 for (
int entity = 2; entity >= 1; entity--)
1219 if (!list.masters.Size()) {
continue; }
1228 if (!master_dofs.
Size()) {
continue; }
1231 if (!master_fe) {
continue; }
1233 switch (master_geom)
1238 default: MFEM_ABORT(
"unsupported geometry");
1241 for (
int si = master.slaves_begin; si < master.slaves_end; si++)
1246 if (!slave_dofs.
Size()) {
break; }
1265 const auto *pm = list.point_matrices[master_geom][slave.
matrix];
1267 slave_dofs, slave.
index, pm);
1278 const int q =
GetEntityDofs(entity, master.index, highest_dofs,
1279 master_geom, nvar-1);
1280 const auto *highest_fe =
fec->
GetFE(master_geom, q);
1297 int n_true_dofs = 0;
1298 for (
int i = 0; i <
ndofs; i++)
1300 if (!deps.
RowSize(i)) { n_true_dofs++; }
1304 if (n_true_dofs ==
ndofs)
1322 for (
int i = 0; i < n_true_dofs; i++)
1327 cR_I[n_true_dofs] = n_true_dofs;
1351 for (
int i = 0, true_dof = 0; i <
ndofs; i++)
1355 cP->
Add(i, true_dof, 1.0);
1357 finalized[i] =
true;
1363 inv_deps.
GetRow(i, cols, srow);
1364 cR_hp->AddRow(true_dof, cols, srow);
1368 cR_hp->Add(true_dof, i, 1.0);
1384 int n_finalized = n_true_dofs;
1388 for (
int dof = 0; dof <
ndofs; dof++)
1394 int n_dep = deps.
RowSize(dof);
1396 for (
int j = 0; j < n_dep; j++)
1398 cP->GetRow(dep_col[j], cols, srow);
1399 srow *= dep_coef[j];
1400 cP->AddRow(dof, cols, srow);
1403 finalized[dof] =
true;
1413 MFEM_VERIFY(n_finalized ==
ndofs,
1414 "Error creating cP matrix: n_finalized = "
1415 << n_finalized <<
", ndofs = " <<
ndofs);
1430 if (
vdim == 1) {
return; }
1432 int height = mat.
Height();
1433 int width = mat.
Width();
1439 for (
int i = 0; i < height; i++)
1441 mat.
GetRow(i, dofs, srow);
1442 for (
int vd = 0; vd <
vdim; vd++)
1549 key_face key = std::make_tuple(is_dg_space, f_ordering, type, m);
1550 auto itr =
L2F.find(key);
1551 if (itr !=
L2F.end())
1585 for (
int i = 0; i <
E2Q_array.Size(); i++)
1588 if (qi->
IntRule == &ir) {
return qi; }
1599 for (
int i = 0; i <
E2Q_array.Size(); i++)
1602 if (qi->
qspace == &qs) {
return qi; }
1619 if (qi->
IntRule == &ir) {
return qi; }
1632 if (qi->
IntRule == &ir) {
return qi; }
1643 const int coarse_ndofs,
const Table &coarse_elem_dof,
1656 if (elem_geoms.
Size() == 1)
1658 const int coarse_ldof = localP[elem_geoms[0]].
SizeJ();
1676 const int fine_ldof = localP[geom].
SizeI();
1681 for (
int vd = 0; vd <
vdim; vd++)
1683 coarse_dofs.
Copy(coarse_vdofs);
1686 for (
int i = 0; i < fine_ldof; i++)
1689 int m = (r >= 0) ? r : (-1 - r);
1694 P->
SetRow(r, coarse_vdofs, row);
1701 MFEM_ASSERT(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
1707 const int coarse_ndofs,
const Table &coarse_elem_dof)
const
1731 const int ldof = fe->
GetDof();
1737 const int fine_ldof = lP.
Height();
1742 for (
int vd = 0; vd <
vdim; vd++)
1744 coarse_dofs.
Copy(coarse_vdofs);
1747 for (
int i = 0; i < fine_ldof; i++)
1750 int m = (r >= 0) ? r : (-1 - r);
1755 P->
SetRow(r, coarse_vdofs, row);
1762 MFEM_VERIFY(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
1775 int nmat = pmats.
SizeK();
1782 localP.
SetSize(ldof, ldof, nmat);
1783 for (
int i = 0; i < nmat; i++)
1791 const Table* old_elem_dof,
1792 const Table* old_elem_fos)
1794 MFEM_VERIFY(
GetNE() >= old_elem_dof->
Size(),
1795 "Previous mesh is not coarser.");
1801 for (
int i = 0; i < elem_geoms.
Size(); i++)
1818 old_elem_dof(old_elem_dof),
1819 old_elem_fos(old_elem_fos)
1821 MFEM_VERIFY(fespace->
GetNE() >= old_elem_dof->
Size(),
1822 "Previous mesh is not coarser.");
1831 for (
int i = 0; i < elem_geoms.
Size(); i++)
1837 ConstructDoFTransArray();
1843 fespace(fespace), old_elem_dof(NULL), old_elem_fos(NULL)
1849 for (
int i = 0; i < elem_geoms.
Size(); i++)
1852 localP[elem_geoms[i]]);
1865 ConstructDoFTransArray();
1870 delete old_elem_dof;
1871 delete old_elem_fos;
1872 for (
int i=0; i<old_DoFTransArray.Size(); i++)
1874 delete old_DoFTransArray[i];
1878void FiniteElementSpace::RefinementOperator::ConstructDoFTransArray()
1881 for (
int i=0; i<old_DoFTransArray.Size(); i++)
1883 old_DoFTransArray[i] = NULL;
1897 const FiniteElement *nd_tet =
1902 new ND_TetDofTransformation(nd_tet->GetOrder());
1905 const FiniteElement *nd_pri =
1910 new ND_WedgeDofTransformation(nd_pri->GetOrder());
1913 const FiniteElement *nd_pyr =
1918 new ND_PyramidDofTransformation(nd_pyr->GetOrder());
1926 Mesh* mesh_ref = fespace->GetMesh();
1930 Array<int> dofs, vdofs, old_dofs, old_vdofs, old_Fo;
1932 int rvdim = fespace->GetVDim();
1933 int old_ndofs = width / rvdim;
1940 for (
int k = 0; k < mesh_ref->
GetNE(); k++)
1944 if (fespace->IsVariableOrder())
1948 const int ldof = fe->
GetDof();
1954 const DenseMatrix &lP = (fespace->IsVariableOrder()) ? eP : localP[geom](
1960 old_elem_dof->GetRow(emb.
parent, old_dofs);
1964 for (
int vd = 0; vd < rvdim; vd++)
1967 fespace->DofsToVDofs(vd, vdofs);
1968 old_dofs.
Copy(old_vdofs);
1969 fespace->DofsToVDofs(vd, old_vdofs, old_ndofs);
1972 lP.
Mult(subX, subY);
1978 old_elem_fos->GetRow(emb.
parent, old_Fo);
1979 old_DoFTrans.SetDofTransformation(*old_DoFTransArray[geom]);
1980 old_DoFTrans.SetFaceOrientations(old_Fo);
1983 for (
int vd = 0; vd < rvdim; vd++)
1986 fespace->DofsToVDofs(vd, vdofs);
1987 old_dofs.
Copy(old_vdofs);
1988 fespace->DofsToVDofs(vd, old_vdofs, old_ndofs);
1991 old_DoFTrans.InvTransformPrimal(subX);
1992 lP.
Mult(subX, subY);
1996 doftrans->
SetVDim(rvdim, fespace->GetOrdering());
2006 Mesh* mesh_ref = fespace->GetMesh();
2013 Array<int> f_dofs, c_dofs, f_vdofs, c_vdofs, old_Fo;
2015 int rvdim = fespace->GetVDim();
2016 int old_ndofs = width / rvdim;
2018 Vector subY, subX, subYt;
2024 for (
int k = 0; k < mesh_ref->
GetNE(); k++)
2029 if (fespace->IsVariableOrder())
2031 fe = fespace->GetFE(k);
2033 const int ldof = fe->
GetDof();
2040 const DenseMatrix &lP = (fespace->IsVariableOrder()) ? eP : localP[geom](
2044 old_elem_dof->GetRow(emb.
parent, c_dofs);
2050 for (
int vd = 0; vd < rvdim; vd++)
2052 f_dofs.
Copy(f_vdofs);
2053 fespace->DofsToVDofs(vd, f_vdofs);
2054 c_dofs.
Copy(c_vdofs);
2055 fespace->DofsToVDofs(vd, c_vdofs, old_ndofs);
2058 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
2073 old_elem_fos->GetRow(emb.
parent, old_Fo);
2074 old_DoFTrans.SetDofTransformation(*old_DoFTransArray[geom]);
2075 old_DoFTrans.SetFaceOrientations(old_Fo);
2077 doftrans->SetVDim();
2078 for (
int vd = 0; vd < rvdim; vd++)
2080 f_dofs.
Copy(f_vdofs);
2081 fespace->DofsToVDofs(vd, f_vdofs);
2082 c_dofs.
Copy(c_vdofs);
2083 fespace->DofsToVDofs(vd, c_vdofs, old_ndofs);
2086 doftrans->InvTransformDual(subX);
2087 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
2095 old_DoFTrans.TransformDual(subYt);
2098 doftrans->SetVDim(rvdim, fespace->GetOrdering());
2101 for (
int p = 0;
p < f_dofs.
Size(); ++
p)
2119 : geom(g), num_children(n), children(c) { }
2121 bool operator<(
const RefType &other)
const
2123 if (geom < other.geom) {
return true; }
2124 if (geom > other.geom) {
return false; }
2125 if (num_children < other.num_children) {
return true; }
2126 if (num_children > other.num_children) {
return false; }
2127 for (
int i = 0; i < num_children; i++)
2129 if (children[i].one < other.children[i].one) {
return true; }
2130 if (children[i].one > other.children[i].one) {
return false; }
2136void GetCoarseToFineMap(
const CoarseFineTransformations &cft,
2138 Table &coarse_to_fine,
2139 Array<int> &coarse_to_ref_type,
2140 Table &ref_type_to_matrix,
2141 Array<Geometry::Type> &ref_type_to_geom)
2143 const int fine_ne = cft.embeddings.Size();
2145 for (
int i = 0; i < fine_ne; i++)
2147 coarse_ne = std::max(coarse_ne, cft.embeddings[i].parent);
2151 coarse_to_ref_type.SetSize(coarse_ne);
2152 coarse_to_fine.SetDims(coarse_ne, fine_ne);
2154 Array<int> cf_i(coarse_to_fine.GetI(), coarse_ne+1);
2155 Array<Pair<int,int> > cf_j(fine_ne);
2157 for (
int i = 0; i < fine_ne; i++)
2159 cf_i[cft.embeddings[i].parent+1]++;
2162 MFEM_ASSERT(cf_i.Last() == cf_j.Size(),
"internal error");
2163 for (
int i = 0; i < fine_ne; i++)
2165 const Embedding &e = cft.embeddings[i];
2166 cf_j[cf_i[e.parent]].one = e.matrix;
2167 cf_j[cf_i[e.parent]].two = i;
2170 std::copy_backward(cf_i.begin(), cf_i.end()-1, cf_i.end());
2172 for (
int i = 0; i < coarse_ne; i++)
2174 std::sort(&cf_j[cf_i[i]], cf_j.GetData() + cf_i[i+1]);
2176 for (
int i = 0; i < fine_ne; i++)
2178 coarse_to_fine.GetJ()[i] = cf_j[i].two;
2184 map<RefType,int> ref_type_map;
2185 for (
int i = 0; i < coarse_ne; i++)
2187 const int num_children = cf_i[i+1]-cf_i[i];
2188 MFEM_ASSERT(num_children > 0,
"");
2189 const int fine_el = cf_j[cf_i[i]].two;
2192 const RefType ref_type(geom, num_children, &cf_j[cf_i[i]]);
2193 pair<map<RefType,int>::iterator,
bool> res =
2194 ref_type_map.insert(
2195 pair<const RefType,int>(ref_type, (
int)ref_type_map.size()));
2196 coarse_to_ref_type[i] = res.first->second;
2199 ref_type_to_matrix.MakeI((
int)ref_type_map.size());
2200 ref_type_to_geom.SetSize((
int)ref_type_map.size());
2201 for (map<RefType,int>::iterator it = ref_type_map.begin();
2202 it != ref_type_map.end(); ++it)
2204 ref_type_to_matrix.AddColumnsInRow(it->second, it->first.num_children);
2205 ref_type_to_geom[it->second] = it->first.geom;
2208 ref_type_to_matrix.MakeJ();
2209 for (map<RefType,int>::iterator it = ref_type_map.begin();
2210 it != ref_type_map.end(); ++it)
2212 const RefType &rt = it->first;
2213 for (
int j = 0; j < rt.num_children; j++)
2215 ref_type_to_matrix.AddConnection(it->second, rt.children[j].one);
2218 ref_type_to_matrix.ShiftUpI();
2233 "incompatible coarse and fine FE spaces");
2241 for (
int gi = 0; gi < elem_geoms.
Size(); gi++)
2244 DenseTensor &lP = localP[geom], &lM = localM[geom];
2254 for (
int i = 0; i < pmats.
SizeK(); i++)
2264 Table ref_type_to_matrix;
2265 internal::GetCoarseToFineMap(rtrans, *f_mesh, coarse_to_fine,
2266 coarse_to_ref_type, ref_type_to_matrix,
2268 MFEM_ASSERT(coarse_to_fine.Size() == c_fes->
GetNE(),
"");
2270 const int total_ref_types = ref_type_to_geom.Size();
2272 Array<int> ref_type_to_coarse_elem_offset(total_ref_types);
2273 ref_type_to_fine_elem_offset.
SetSize(total_ref_types);
2276 for (
int i = 0; i < total_ref_types; i++)
2279 ref_type_to_coarse_elem_offset[i] = num_ref_types[g];
2280 ref_type_to_fine_elem_offset[i] = num_fine_elems[g];
2282 num_fine_elems[g] += ref_type_to_matrix.
RowSize(i);
2287 if (num_ref_types[g] == 0) {
continue; }
2288 const int fine_dofs = localP[g].
SizeI();
2289 const int coarse_dofs = localP[g].
SizeJ();
2290 localPtMP[g].
SetSize(coarse_dofs, coarse_dofs, num_ref_types[g]);
2291 localR[g].
SetSize(coarse_dofs, fine_dofs, num_fine_elems[g]);
2293 for (
int i = 0; i < total_ref_types; i++)
2296 DenseMatrix &lPtMP = localPtMP[g](ref_type_to_coarse_elem_offset[i]);
2297 int lR_offset = ref_type_to_fine_elem_offset[i];
2298 const int *mi = ref_type_to_matrix.
GetRow(i);
2299 const int nm = ref_type_to_matrix.
RowSize(i);
2301 for (
int s = 0; s < nm; s++)
2310 for (
int s = 0; s < nm; s++)
2323 delete coarse_elem_dof;
2332 const int fine_vdim = fine_fes->GetVDim();
2333 const int coarse_ndofs = height/fine_vdim;
2334 for (
int coarse_el = 0; coarse_el < coarse_to_fine.Size(); coarse_el++)
2336 coarse_elem_dof->
GetRow(coarse_el, c_vdofs);
2337 fine_fes->DofsToVDofs(c_vdofs, coarse_ndofs);
2342 const int ref_type = coarse_to_ref_type[coarse_el];
2344 const int *fine_elems = coarse_to_fine.GetRow(coarse_el);
2345 const int num_fine_elems = coarse_to_fine.RowSize(coarse_el);
2346 const int lR_offset = ref_type_to_fine_elem_offset[ref_type];
2347 for (
int s = 0; s < num_fine_elems; s++)
2349 const DenseMatrix &lR = localR[geom](lR_offset+s);
2350 fine_fes->GetElementVDofs(fine_elems[s], f_vdofs);
2369 const int nmat = pmats.
SizeK();
2370 const int ldof = fe->
GetDof();
2376 localR.
SetSize(ldof, ldof, nmat);
2377 for (
int i = 0; i < nmat; i++)
2385 const Table* old_elem_dof,
2386 const Table* old_elem_fos)
2390 MFEM_VERIFY(
Nonconforming(),
"Not implemented for conforming meshes.");
2391 MFEM_VERIFY(old_ndofs,
"Missing previous (finer) space.");
2392 MFEM_VERIFY(
ndofs <= old_ndofs,
"Previous space is not finer.");
2402 for (
int i = 0; i < elem_geoms.
Size(); i++)
2416 MFEM_ASSERT(dtrans.
embeddings.Size() == old_elem_dof->
Size(),
"");
2422 for (
int k = 0; k < dtrans.
embeddings.Size(); k++)
2431 const int ldof = fe->
GetDof();
2445 old_elem_dof->
GetRow(k, old_dofs);
2446 MFEM_VERIFY(old_dofs.
Size() == dofs.
Size(),
2447 "Parent and child must have same #dofs.");
2449 for (
int vd = 0; vd <
vdim; vd++)
2451 old_dofs.
Copy(old_vdofs);
2454 for (
int i = 0; i < lR.
Height(); i++)
2456 if (!std::isfinite(lR(i, 0))) {
continue; }
2459 int m = (r >= 0) ? r : (-1 - r);
2461 if (is_dg || !mark[m])
2464 R->
SetRow(r, old_vdofs, row);
2475 MFEM_VERIFY(num_marked == R->
Height(),
2476 "internal error: not all rows of R were set.");
2496 int nmat = pmats.
SizeK();
2503 for (
int i = 0; i < nmat; i++)
2512 int vdim_,
int ordering_)
2534 MFEM_VERIFY(mesh_->
NURBSext,
"NURBS FE space requires a NURBS mesh.");
2536 if (NURBSext_ == NULL)
2615 mfem_error(
"FiniteElementSpace::StealNURBSext");
2624 MFEM_VERIFY(
NURBSext,
"NURBSExt not defined.");
2667 *
VNURBSext[1]->GetElementDofTable(),offset1 );
2670 *
VNURBSext[1]->GetBdrElementDofTable(),offset1);
2675 int offset2 = offset1 +
VNURBSext[1]->GetNDof();
2680 *
VNURBSext[1]->GetElementDofTable(),offset1,
2681 *
VNURBSext[2]->GetElementDofTable(),offset2);
2684 *
VNURBSext[1]->GetBdrElementDofTable(),offset1,
2685 *
VNURBSext[2]->GetBdrElementDofTable(),offset2);
2719 if (
b == -1) {
continue; }
2729 for (
int i = 0; i < nv; i++)
2731 MFEM_VERIFY(fv[i] == bv[i],
2732 "non-matching face and boundary elements detected!");
2737 for (
int i = 0; i < row.
Size(); i++)
2740 face_dof_list.
Append(conn);
2749 MFEM_VERIFY(!
NURBSext,
"internal error");
2754 "Variable-order space requires a nonconforming mesh.");
2777 "Mesh was not correctly finalized.");
2791 else if (mixed_faces)
2815 MFEM_ASSERT(lastRow.
Size() == 1,
"");
2843 MFEM_ASSERT(lastRow.
Size() == 1,
"");
2897 const Table & loc_var_ent_dofs,
2902 const int osall0 = var_ent_dofs.
GetI()[entity];
2903 const int osall1 = var_ent_dofs.
GetI()[entity + 1];
2905 const int osloc0 = loc_var_ent_dofs.
GetI()[entity];
2906 const int osloc1 = loc_var_ent_dofs.
GetI()[entity + 1];
2910 for (
int i=osloc0; i<osloc1; ++i)
2912 const int order = loc_var_ent_orders[i];
2914 int na = var_ent_dofs.
GetJ()[j + 1] - var_ent_dofs.
GetJ()[j];
2915 while (var_ent_orders[j] != order && j < osall1 - 1)
2919 na = var_ent_dofs.
GetJ()[j + 1] - var_ent_dofs.
GetJ()[j];
2922 MFEM_ASSERT(var_ent_orders[j] == order,
"");
2924 const int n = loc_var_ent_dofs.
GetJ()[i + 1] - loc_var_ent_dofs.
GetJ()[i];
2926 MFEM_ASSERT(n == na &&
2927 n == var_ent_dofs.
GetJ()[j + 1] - var_ent_dofs.
GetJ()[j],
"");
2929 for (
int k=0; k<n; ++k) {
all2local[ndof_all + k] = ndof_loc + k; }
2939 const int na = var_ent_dofs.
GetJ()[j + 1] - var_ent_dofs.
GetJ()[j];
2954 for (
int i=0; i<
nvdofs; ++i)
2988 for (
int i=ndof_all; i<
ndofs; ++i)
2998 MFEM_ASSERT(bits != 0,
"invalid bit mask");
2999 for (
int order = 0; bits != 0; order++, bits >>= 1)
3001 if (bits & 1) {
return order; }
3035 edge_elem_orders = 0;
3036 face_elem_orders = 0;
3050 const int order = localVar ?
elem_order[i] : baseOrder;
3055 for (
int j = 0; j < E.
Size(); j++)
3057 edge_orders[E[j]] |= mask;
3058 edge_elem_orders[E[j]] |= mask;
3069 for (
int j = 0; j < F.
Size(); j++)
3071 face_orders[F[j]] |= mask;
3072 face_elem_orders[F[j]] |= mask;
3096 std::set<int> changedEdges;
3097 std::set<int> changedFaces;
3106 for (
int i = master.slaves_begin; i < master.slaves_end; i++)
3108 slave_orders |= edge_orders[edge_list.
slaves[i].index];
3111 if (slave_orders == 0)
3116 const int min_order_slaves =
MinOrder(slave_orders);
3117 if (edge_orders[master.index] == 0 ||
3118 min_order_slaves <
MinOrder(edge_orders[master.index]))
3120 edge_orders[master.index] |=
VarOrderBits(1) << min_order_slaves;
3121 changedEdges.insert(master.index);
3127 edge_orders[master.index]);
3128 for (
int i = master.slaves_begin; i < master.slaves_end; i++)
3130 if (edge_list.
slaves[i].index >= numEdges)
3136 edge_orders[edge_list.
slaves[i].index] |= min_mask;
3137 if (eo0 != edge_orders[edge_list.
slaves[i].index])
3139 changedEdges.insert(edge_list.
slaves[i].index);
3153 for (
int i = master.slaves_begin; i < master.slaves_end; i++)
3157 if (slave.
index >= 0)
3161 slave_orders |= face_orders[slave.
index];
3163 if (slave.
index >= numFaces)
3169 for (
int j = 0; j < E.
Size(); j++)
3171 slave_orders |= edge_orders[E[j]];
3177 slave_orders |= edge_orders[-1 - slave.
index];
3181 if (slave_orders == 0)
3186 const int min_order_slaves =
MinOrder(slave_orders);
3187 if (face_orders[master.index] == 0 ||
3188 min_order_slaves <
MinOrder(face_orders[master.index]))
3190 face_orders[master.index] |=
VarOrderBits(1) << min_order_slaves;
3191 changedFaces.insert(master.index);
3198 for (
int i = master.slaves_begin; i < master.slaves_end; i++)
3202 if (slave.
index >= 0 && slave.
index < numFaces)
3205 face_orders[slave.
index] |= min_mask;
3206 if (fo0 != face_orders[slave.
index])
3208 changedFaces.insert(slave.
index);
3218 for (
int j = 0; j < E.
Size(); j++)
3221 edge_orders[E[j]] |= face_orders[i];
3222 if (eo0 != edge_orders[E[j]])
3224 changedEdges.insert(E[j]);
3232 edge_orders, face_orders);
3249 for (
int i=0; i<edge_orders.
Size(); ++i)
3251 if (edge_orders[i] == 0)
3253 skip_edges[i] =
true;
3257 for (
int i=0; i<face_orders.
Size(); ++i)
3259 if (face_orders[i] == 0)
3261 skip_faces[i] =
true;
3281 int num_ent = entity_orders.
Size();
3283 int total_dofs_nonghost = 0;
3291 var_ent_order->
Reserve(num_ent);
3294 int nonGhost = num_ent;
3301 for (
int i = 0; i < num_ent; i++)
3318 for (
int order = 0; bits != 0; order++, bits >>= 1)
3325 if (i < nonGhost) { total_dofs_nonghost += dofs; }
3326 if (var_ent_order) { var_ent_order->
Append(order); }
3332 list.Append(
Connection(num_ent, total_dofs));
3336 return total_dofs_nonghost;
3340 int row,
int ndof)
const
3342 const int *beg = var_dof_table.
GetRow(row);
3343 const int *end = var_dof_table.
GetRow(row + 1);
3348 if ((beg[1] - beg[0]) == ndof) {
return beg[0]; }
3352 MFEM_ABORT(
"DOFs not found for ndof = " << ndof);
3367 if (variant >= end - beg) {
return -1; }
3388 if (variant >= end - beg) {
return -1; }
3402static const char* msg_orders_changed =
3403 "Element orders changed, you need to Update() the space first.";
3443 for (
int i = 0; i < F.
Size(); i++)
3461 for (
int i = 0; i < V.
Size(); i++)
3463 for (
int j = 0; j < nv; j++)
3465 dofs.
Append(V[i]*nv + j);
3472 for (
int i = 0; i < E.
Size(); i++)
3477 for (
int j = 0; j < ne; j++)
3486 for (
int i = 0; i < F.
Size(); i++)
3494 for (
int j = 0; j < nf; j++)
3506 for (
int j = 0; j < nb; j++)
3582 for (
int i = 0; i < V.
Size(); i++)
3584 for (
int j = 0; j < nv; j++)
3586 dofs.
Append(V[i]*nv + j);
3593 for (
int i = 0; i < E.
Size(); i++)
3598 for (
int j = 0; j < ne; j++)
3610 for (
int j = 0; j < nf; j++)
3639 int order, nf, fbase;
3647 if (variant >= end - beg) {
return -1; }
3649 fbase = beg[variant];
3650 nf = beg[variant+1] - fbase;
3656 std::stringstream msg;
3657 msg <<
"fec->GetNumDof(" << (fgeom == Geometry::SQUARE ?
"square" :
"triangle")
3658 <<
", " << order <<
") = " << fec->GetNumDof(fgeom, order) <<
" nf " << nf;
3659 msg <<
" face " << face <<
" variant " << variant << std::endl;
3665 if (variant > 0) {
return -1; }
3684 for (
int i = 0; i < V.
Size(); i++)
3686 for (
int j = 0; j < nv; j++)
3688 dofs.
Append(V[i]*nv + j);
3694 for (
int i = 0; i < E.
Size(); i++)
3699 for (
int j = 0; j < ne; j++)
3705 for (
int j = 0; j < nf; j++)
3718 int order, ne, base;
3723 if (variant >= end - beg) {
return -1; }
3725 base = beg[variant];
3726 ne = beg[variant+1] - base;
3733 if (variant > 0) {
return -1; }
3746 for (
int i = 0; i < 2; i++)
3748 for (
int j = 0; j < nv; j++)
3750 dofs.
Append(V[i]*nv + j);
3753 for (
int j = 0; j < ne; j++)
3765 for (
int j = 0; j < nv; j++)
3780 for (
int j = 0; j < nb; j++)
3810 for (
int j = 0; j < nf; j++)
3822 for (
int j = 0, k =
nvdofs+i*ne; j < ne; j++, k++)
3831 "FiniteElementSpace::GetPatchDofs needs a NURBSExtension");
3841 MFEM_ABORT(
"Empty MPI partitions are not permitted!");
3843 MFEM_ABORT(
"Invalid element id:" << i <<
"; minimum allowed:" << 0 <<
3844 ", maximum allowed:" <<
mesh->
GetNE()-1);
3862 "internal error: " <<
3877 MFEM_VERIFY(fe !=
nullptr,
"Could not determine a typical FE!");
3937 "NURBS mesh: only boundary faces are supported!");
3947 MFEM_ASSERT(
mesh->
Dimension() > 1,
"No edges with mesh dimension < 2");
3978 for (
int i = 0; i <
E2Q_array.Size(); i++)
4006 for (
int i = 0; i <
VNURBSext.Size(); i++)
4057 for (
int i = 0; i < elem_geoms.
Size(); i++)
4060 localP[elem_geoms[i]]);
4102 if (RP_case == 0) {
return; }
4115 cR.get(), T.
Ptr(), coarse_P,
false, owner,
false));
4139 Table coarse_to_fine;
4142 for (
int i = 0; i < coarse_to_fine.
Size(); i++)
4144 coarse_to_fine.
GetRow(i, tabrow);
4151 MFEM_ABORT(
"not implemented yet");
4169 MFEM_ABORT(
"Error in update sequence. Space needs to be updated after "
4170 "each mesh modification.");
4177 MFEM_ABORT(
"Updating space after both mesh change and element order "
4178 "change is not supported. Please update separately after "
4189 Table* old_elem_dof = NULL;
4190 Table* old_elem_fos = NULL;
4216 MFEM_VERIFY(!old_orders_changed,
"Interpolation for element order change "
4217 "is not implemented yet, sorry.");
4227 old_elem_fos, old_ndofs));
4230 old_elem_dof = NULL;
4231 old_elem_fos = NULL;
4252 false,
false,
true));
4261 false,
false,
true));
4271 delete old_elem_dof;
4272 delete old_elem_fos;
4280 "p-refinement is not supported in this space");
4292 for (
auto ref : refs)
4320 if (geoms.
Size() != 1) {
return false; }
4334 int fes_nodes_ordering)
const
4337 const int NE = m->
GetNE();
4339 if (NE == 0) { fes_node_pos.
SetSize(0);
return; }
4348 for (
int e = 0; e < NE; e++)
4351 const int mdof_cnt = dofs.
Size() /
dim;
4356 Vector mesh_shape(mdof_cnt), gf_xyz(fdof_cnt *
dim);
4357 for (
int q = 0; q < fdof_cnt; q++)
4360 for (
int d = 0; d <
dim; d++)
4363 gf_xyz(d*fdof_cnt + q) = x * mesh_shape;
4375 int fes_format = 90;
4376 bool nurbs_unit_weights =
false;
4387 MFEM_VERIFY(nurbs_fec,
"invalid FE collection");
4389 const real_t eps = 5e-14;
4400 os << (fes_format == 90 ?
4401 "FiniteElementSpace\n" :
"MFEM FiniteElementSpace v1.0\n")
4402 <<
"FiniteElementCollection: " <<
fec->
Name() <<
'\n'
4403 <<
"VDim: " <<
vdim <<
'\n'
4404 <<
"Ordering: " <<
ordering <<
'\n';
4406 if (fes_format == 100)
4420 os <<
"NURBS_orders\n";
4427 os <<
"NURBS_periodic\n";
4432 if (!nurbs_unit_weights)
4434 os <<
"NURBS_weights\n";
4438 os <<
"End: MFEM FiniteElementSpace v1.0\n";
4442std::shared_ptr<const PRefinementTransferOperator>
4445void FiniteElementSpace
4446::GetEssentialBdrEdgesFaces(
const Array<int> &bdr_attr_is_ess,
4447 std::set<int> & edges, std::set<int> & faces)
const
4450 MFEM_VERIFY(
dim == 2 ||
dim == 3,
"");
4452 for (
int i = 0; i <
GetNBE(); i++)
4464 for (
auto edge : edges_i)
4482 for (
auto e : bdr_edges)
4487 for (
auto f : bdr_faces)
4497 int fes_format = 0, ord;
4503 getline(input, buff);
4505 if (buff ==
"FiniteElementSpace") { fes_format = 90; }
4506 else if (buff ==
"MFEM FiniteElementSpace v1.0") { fes_format = 100; }
4507 else { MFEM_ABORT(
"input stream is not a FiniteElementSpace!"); }
4508 getline(input, buff,
' ');
4510 getline(input, buff);
4513 getline(input, buff,
' ');
4515 getline(input, buff,
' ');
4521 if (fes_format == 90)
4525 MFEM_VERIFY(m->
NURBSext,
"NURBS FE collection requires a NURBS mesh!");
4526 const int order = nurbs_fec->
GetOrder();
4534 else if (fes_format == 100)
4539 MFEM_VERIFY(input.good(),
"error reading FiniteElementSpace v1.0");
4540 getline(input, buff);
4542 if (buff ==
"NURBS_order" || buff ==
"NURBS_orders")
4544 MFEM_VERIFY(nurbs_fec,
4545 buff <<
": NURBS FE collection is required!");
4546 MFEM_VERIFY(m->
NURBSext, buff <<
": NURBS mesh is required!");
4547 MFEM_VERIFY(!nurbs_ext, buff <<
": order redefinition!");
4548 if (buff ==
"NURBS_order")
4561 else if (buff ==
"NURBS_periodic")
4568 else if (buff ==
"NURBS_weights")
4570 MFEM_VERIFY(nurbs_ext,
"NURBS_weights: NURBS_orders have to be "
4571 "specified before NURBS_weights!");
4574 else if (buff ==
"element_orders")
4576 MFEM_VERIFY(!nurbs_fec,
"section element_orders cannot be used "
4577 "with a NURBS FE collection");
4578 MFEM_ABORT(
"element_orders: not implemented yet!");
4580 else if (buff ==
"End: MFEM FiniteElementSpace v1.0")
4586 MFEM_ABORT(
"unknown section: " << buff);
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
void DeleteAll()
Delete the whole array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void Save(std::ostream &out, int fmt=0) const
Save the Array to the stream out using the format fmt. The format fmt can be:
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
T Sum() const
Return the sum of all the array entries using the '+'' operator for class 'T'.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication with the inverse of dense matrix.
Data type dense matrix using column-major storage.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
void UseExternalData(real_t *d, int h, int w)
Change the data array and the size of the DenseMatrix.
void GetRow(int r, Vector &row) const
Rank 3 tensor (array of matrices)
void SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
Abstract base class that defines an interface for element restrictions.
Operator that converts FiniteElementSpace L-vectors to E-vectors.
Abstract data type element.
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
virtual int GetNVertices() const =0
A class that performs interpolation from a face E-vector to quadrature point values and/or derivative...
const IntegrationRule * IntRule
Not owned.
Base class for operators that extracts Face degrees of freedom.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
static FiniteElementCollection * New(const char *name)
Factory method: return a newly allocated FiniteElementCollection according to the given name.
const int * GetDofOrdering(Geometry::Type geom, int p, int ori) const
Variable order version of DofOrderForOrientation().
int GetOrder() const
Return the order (polynomial degree) of the FE collection, corresponding to the order/degree returned...
virtual int GetContType() const =0
int HasFaceDofs(Geometry::Type geom, int p) const
virtual int DofForGeometry(Geometry::Type GeomType) const =0
int GetNumDof(Geometry::Type geom, int p) const
Variable order version of DofForGeometry().
virtual const FiniteElement * TraceFiniteElementForGeometry(Geometry::Type GeomType) const
const FiniteElement * GetTraceFE(Geometry::Type geom, int p) const
Variable order version of TraceFiniteElementForGeometry().
virtual const char * Name() const
const FiniteElement * GetFE(Geometry::Type geom, int p) const
Variable order version of FiniteElementForGeometry().
@ DISCONTINUOUS
Field is discontinuous across element interfaces.
virtual const FiniteElement * FiniteElementForGeometry(Geometry::Type GeomType) const =0
virtual ~DerefinementOperator()
void Mult(const Vector &x, Vector &y) const override
Operator application: y=A(x).
DerefinementOperator(const FiniteElementSpace *f_fes, const FiniteElementSpace *c_fes, BilinearFormIntegrator *mass_integ)
TODO: Implement DofTransformation support.
GridFunction interpolation operator applicable after mesh refinement.
virtual ~RefinementOperator()
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
RefinementOperator(const FiniteElementSpace *fespace, Table *old_elem_dof, Table *old_elem_fos, int old_ndofs)
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
std::unique_ptr< FiniteElementSpace > fesPrev
void Save(std::ostream &out) const
Save finite element space to output stream out.
void DestroyDoFTransArray()
virtual void ApplyGhostElementOrdersToEdgesAndFaces(Array< VarOrderBits > &edge_orders, Array< VarOrderBits > &face_orders) const
Helper function for ParFiniteElementSpace.
int GetEntityVDofs(int entity, int index, Array< int > &dofs, Geometry::Type master_geom=Geometry::INVALID, int variant=0) const
Helper to get vertex, edge or face VDOFs (entity=0,1,2 resp.).
void GetVDofs(int vd, Array< int > &dofs, int ndofs=-1) const
Returns the indices of all of the VDofs for the specified dimension 'vd'.
DofTransformation DoFTrans
static int EncodeDof(int entity_base, int idx)
Helper to encode a sign flip into a DOF index (for Hcurl/Hdiv shapes).
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
void ReorderElementToDofTable()
Reorder the scalar DOFs based on the element ordering.
Array< char > var_face_orders
int GetVectorDim() const
Return the total dimension of a vector in the space.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
void SetRestriction(const SparseMatrix &r)
void BuildNURBSFaceToDofTable() const
Generates partial face_dof table for a NURBS space.
void BuildDofToBdrArrays() const
Initialize internal data that enables the use of the methods GetBdrElementForDof() and GetBdrLocalDof...
static void AddDependencies(SparseMatrix &deps, Array< int > &master_dofs, Array< int > &slave_dofs, DenseMatrix &I, int skipfirst=0)
const Table & GetElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each mesh element,...
Array< int > dof_ldof_array
Array< StatelessDofTransformation * > DoFTransArray
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const
Compute the full set of vdofs corresponding to each entry in dofs.
void GetEdgeInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified edge.
Array< FaceQuadratureInterpolator * > E2BFQ_array
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
Array< FaceQuadratureInterpolator * > E2IFQ_array
Array< int > face_min_nghb_order
DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element 'elem'. The returned indices are offsets into an ldo...
int GetNumElementInteriorDofs(int i) const
Returns the number of degrees of freedom associated with the interior of the specified element.
std::shared_ptr< PRefinementTransferOperator > PTh
virtual void GetExteriorTrueDofs(Array< int > &exterior_dofs, int component=-1) const
Get a list of all true dofs on the exterior of the mesh, exterior_dofs. For spaces with 'vdim' > 1,...
void GetEdgeVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the specified edge, including the DOFs for the vert...
NURBSExtension * NURBSext
virtual int GetFaceDofs(int face, Array< int > &dofs, int variant=0) const
Returns the indices of the degrees of freedom for the specified face, including the DOFs for the edge...
virtual void GetTrueTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
Construct and return an Operator that can be used to transfer true-dof data from coarse_fes,...
static void AdjustVDofs(Array< int > &vdofs)
Remove the orientation information encoded into an array of dofs Some basis function types have a rel...
virtual void GetExteriorVDofs(Array< int > &exterior_vdofs, int component=-1) const
Mark degrees of freedom associated with exterior faces of the mesh. For spaces with 'vdim' > 1,...
SparseMatrix * VariableOrderRefinementMatrix(const int coarse_ndofs, const Table &coarse_elem_dof) const
int GetEdgeOrder(int edge, int variant=0) const
Array< char > loc_var_face_orders
bool Nonconforming() const
void GetVertexVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the specified vertices.
void GetVertexDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the specified vertices.
void BuildFaceToDofTable() const
int GetFaceOrder(int face, int variant=0) const
Returns the polynomial degree of the i'th face finite element.
int GetNumBorderDofs(Geometry::Type geom, int order) const
FiniteElementSpace()
Default constructor: the object is invalid until initialized using the method Load().
Array< int > dof_elem_array
int FindFaceDof(int face, int ndof) const
Similar to FindEdgeDof, but used for mixed meshes too.
static int MinOrder(VarOrderBits bits)
Return the minimum order (least significant bit set) in the bit mask.
static void ListToMarker(const Array< int > &list, int marker_size, Array< int > &marker, int mark_val=-1)
Convert an array of indices (list) to a Boolean marker array where all indices in the list are marked...
MFEM_DEPRECATED void RebuildElementToDofTable()
(
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
bool orders_changed
True if at least one element order changed (variable-order space only).
SparseMatrix * DerefinementMatrix(int old_ndofs, const Table *old_elem_dof, const Table *old_elem_fos)
Calculate GridFunction restriction matrix after mesh derefinement.
friend class PRefinementTransferOperator
void GetLocalRefinementMatrices(Geometry::Type geom, DenseTensor &localP) const
void GetEdgeInteriorVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the interior of the specified edge.
void GetTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
Construct and return an Operator that can be used to transfer GridFunction data from coarse_fes,...
SparseMatrix * D2C_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
Generate the global restriction matrix from a discontinuous FE space to the continuous FE space of th...
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
int GetNBE() const
Returns number of boundary elements in the mesh.
virtual void UpdateMeshPointer(Mesh *new_mesh)
int GetDegenerateFaceDofs(int index, Array< int > &dofs, Geometry::Type master_geom, int variant) const
const QuadratureInterpolator * GetQuadratureInterpolator(const IntegrationRule &ir) const
Return a QuadratureInterpolator that interpolates E-vectors to quadrature point values and/or derivat...
Array< char > ghost_edge_orders
int GetBdrAttribute(int i) const
Array< int > dof_bdr_elem_array
int GetEntityDofs(int entity, int index, Array< int > &dofs, Geometry::Type master_geom=Geometry::INVALID, int variant=0) const
Helper to get vertex, edge or face DOFs (entity=0,1,2 resp.).
virtual const Operator * GetRestrictionOperator() const
An abstract operator that performs the same action as GetRestrictionMatrix.
static constexpr int MaxVarOrder
virtual void CopyProlongationAndRestriction(const FiniteElementSpace &fes, const Array< int > *perm)
Copies the prolongation and restriction matrices from fes.
Array< char > var_edge_orders
std::unique_ptr< Operator > R_transpose
Operator computing the action of the transpose of the restriction.
int MakeDofTable(int ent_dim, const Array< VarOrderBits > &entity_orders, Table &entity_dofs, Array< char > *var_ent_order)
void UpdateElementOrders()
Resize the elem_order array on mesh change.
void MakeVDimMatrix(SparseMatrix &mat) const
Replicate 'mat' in the vector dimension, according to vdim ordering mode.
int GetNF() const
Returns number of faces (i.e. co-dimension 1 entities) in the mesh.
SparseMatrix * H2L_GlobalRestrictionMatrix(FiniteElementSpace *lfes)
Construct the restriction matrix from the FE space given by (*this) to the lower degree FE space give...
SparseMatrix * D2Const_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
Generate the global restriction matrix from a discontinuous FE space to the piecewise constant FE spa...
const FiniteElementCollection * fec
Associated FE collection (not owned).
void GetNodePositions(const Vector &mesh_nodes, Vector &fes_node_pos, int fes_nodes_ordering=Ordering::byNODES) const
Compute the space's node positions w.r.t. given mesh positions. The function uses FiniteElement::GetN...
FiniteElementCollection * Load(Mesh *m, std::istream &input)
Read a FiniteElementSpace from a stream. The returned FiniteElementCollection is owned by the caller.
void BuildBdrElementToDofTable() const
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
Array< QuadratureInterpolator * > E2Q_array
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Ordering::Type GetOrdering() const
Return the ordering method.
NURBSExtension * StealNURBSext()
void GetPatchDofs(int patch, Array< int > &dofs) const
Returns indices of degrees of freedom for NURBS patch index patch. Cartesian ordering is used,...
void BuildDofToArrays_() const
Initialize internal data that enables the use of the methods GetElementForDof() and GetLocalDofForDof...
const Operator * GetRestrictionTransposeOperator() const
Return an operator that performs the transpose of GetRestrictionOperator.
static bool DofFinalizable(int dof, const Array< bool > &finalized, const SparseMatrix &deps)
void GetLocalDerefinementMatrices(Geometry::Type geom, DenseTensor &localR) const
void BuildConformingInterpolation() const
Calculate the cP and cR matrices for a nonconforming mesh.
int GetNE() const
Returns number of elements in the mesh.
int vdim
Vector dimension (number of unknowns per degree of freedom).
Table var_face_dofs
NOTE: also used for spaces with mixed faces.
OperatorHandle L2E_nat
The element restriction operators, see GetElementRestriction().
bool lastUpdatePRef
Flag to indicate whether the last update was for p-refinement.
int * bdofs
internal DOFs of elements if mixed/var-order; NULL otherwise
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
const FiniteElement * GetEdgeElement(int i, int variant=0) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th edge in the ...
Array< char > ghost_face_orders
int GetEdgeDofs(int edge, Array< int > &dofs, int variant=0) const
Returns the indices of the degrees of freedom for the specified edge, including the DOFs for the vert...
std::tuple< bool, ElementDofOrdering, FaceType, L2FaceValues > key_face
The face restriction operators, see GetFaceRestriction().
std::unique_ptr< SparseMatrix > cR
Conforming restriction matrix such that cR.cP=I.
void ConstructDoFTransArray()
void GetElementInteriorVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the interior of the specified element.
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the specified face, including the DOFs for the edge...
Array< char > loc_var_edge_orders
virtual void Update(bool want_transform=true)
Reflect changes in the mesh: update number of DOFs, etc. Also, calculate GridFunction transformation ...
OperatorHandle Th
Transformation to apply to GridFunctions after space Update().
SparseMatrix * RefinementMatrix(int old_ndofs, const Table *old_elem_dof, const Table *old_elem_fos)
std::uint64_t VarOrderBits
Bit-mask representing a set of orders needed by an edge/face.
SparseMatrix * RefinementMatrix_main(const int coarse_ndofs, const Table &coarse_elem_dof, const Table *coarse_elem_fos, const DenseTensor localP[]) const
int ndofs
Number of degrees of freedom. Number of unknowns is ndofs * vdim.
std::unique_ptr< SparseMatrix > cP
void AddEdgeFaceDependencies(SparseMatrix &deps, Array< int > &master_dofs, const FiniteElement *master_fe, Array< int > &slave_dofs, int slave_face, const DenseMatrix *pm) const
const FiniteElement * GetTraceElement(int i, Geometry::Type geom_type) const
Return the trace element from element 'i' to the given 'geom_type'.
const FiniteElement * GetTypicalTraceElement() const
Return a "typical" trace element.
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
Array< NURBSExtension * > VNURBSext
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
void SetVarOrderLocalDofs()
Sets all2local. See documentation of all2local for details.
Mesh * mesh
The mesh that FE space lives on (not owned).
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
void ConvertToConformingVDofs(const Array< int > &dofs, Array< int > &cdofs)
For a partially conforming FE space, convert a marker array (nonzero entries are true) on the partial...
void CalcEdgeFaceVarOrders(Array< VarOrderBits > &edge_orders, Array< VarOrderBits > &face_orders, Array< VarOrderBits > &edge_elem_orders, Array< VarOrderBits > &face_elem_orders, Array< bool > &skip_edges, Array< bool > &skip_faces) const
virtual bool OrderPropagation(const std::set< int > &edges, const std::set< int > &faces, Array< VarOrderBits > &edge_orders, Array< VarOrderBits > &face_orders) const
Returns true if order propagation is done, for variable-order spaces.
std::shared_ptr< const PRefinementTransferOperator > GetPrefUpdateOperator()
void SetElementOrder(int i, int p)
Sets the order of the i'th finite element.
const SparseMatrix * GetHpConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
const SparseMatrix * GetConformingProlongation() const
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
int GetElementOrderImpl(int i) const
Return element order: internal version of GetElementOrder without checks.
int GetNVariants(int entity, int index) const
Return number of possible DOF variants for edge/face (var. order spaces).
virtual ~FiniteElementSpace()
Array< int > dof_bdr_ldof_array
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
const Table * GetElementToFaceOrientationTable() const
DofTransformation * GetBdrElementDofs(int bel, Array< int > &dofs) const
Returns indices of degrees of freedom for boundary element 'bel'. The returned indices are offsets in...
void GetBoundaryTrueDofs(Array< int > &boundary_dofs, int component=-1)
Get a list of all boundary true dofs, boundary_dofs. For spaces with 'vdim' > 1, the 'component' para...
int GetVDim() const
Returns the vector dimension of the finite element space.
const FaceQuadratureInterpolator * GetFaceQuadratureInterpolator(const IntegrationRule &ir, FaceType type) const
Return a FaceQuadratureInterpolator that interpolates E-vectors to quadrature point values and/or der...
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
void GetFaceInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified face.
virtual void PRefineAndUpdate(const Array< pRefinement > &refs, bool want_transfer=true)
int GetNConformingDofs() const
void SetProlongation(const SparseMatrix &p)
Array< int > edge_min_nghb_order
Minimum order among neighboring elements.
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
static int DecodeDof(int dof)
Helper to return the DOF associated with a sign encoded DOF.
void GetElementInteriorDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the interior of the specified element.
virtual int NumGhostEdges() const
Returns the number of ghost edges (nonzero in ParFiniteElementSpace).
bool PRefinementSupported()
void Constructor(Mesh *mesh, NURBSExtension *ext, const FiniteElementCollection *fec, int vdim=1, int ordering=Ordering::byNODES)
Help function for constructors + Load().
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for i'th boundary element. The returned indices are offsets int...
void ConvertFromConformingVDofs(const Array< int > &cdofs, Array< int > &dofs)
For a partially conforming FE space, convert a marker array (nonzero entries are true) on the conform...
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_vdofs, int component=-1) const
Mark degrees of freedom associated with boundary elements with the specified boundary attributes (mar...
virtual int NumGhostFaces() const
Returns the number of ghost faces (nonzero in ParFiniteElementSpace).
int DofToVDof(int dof, int vd, int ndofs=-1) const
Compute a single vdof corresponding to the index dof and the vector index vd.
virtual const FaceRestriction * GetFaceRestriction(ElementDofOrdering f_ordering, FaceType, L2FaceValues mul=L2FaceValues::DoubleValued) const
Return an Operator that converts L-vectors to E-vectors on each face.
int GetCurlDim() const
Return the dimension of the curl of a GridFunction defined on this space.
virtual void GhostFaceOrderToEdges(const Array< VarOrderBits > &face_orders, Array< VarOrderBits > &edge_orders) const
Helper function for ParFiniteElementSpace.
int FindEdgeDof(int edge, int ndof) const
void GetPatchVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom in vdofs for NURBS patch i.
void BuildElementToDofTable() const
std::unique_ptr< SparseMatrix > cR_hp
A version of the conforming restriction matrix for variable-order spaces.
int FindDofs(const Table &var_dof_table, int row, int ndof) const
Search row of a DOF table for a DOF set of size 'ndof', return first DOF.
void VariableOrderMinimumRule(SparseMatrix &deps) const
Abstract class for all finite elements.
int GetRangeDim() const
Returns the vector dimension for vector-valued finite elements, which is also the dimension of the in...
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
int GetDim() const
Returns the reference space dimension for the finite element.
virtual void GetTransferMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
Return interpolation matrix, I, which maps dofs from a coarse element, fe, to the fine dofs on this f...
int GetRangeType() const
Returns the FiniteElement::RangeType of the element, one of {SCALAR, VECTOR}.
virtual void GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs.
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
int GetCurlDim() const
Returns the dimension of the curl for vector-valued finite elements.
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
static const int NumVerts[NumGeom]
Arbitrary order H1-conforming (continuous) finite elements.
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
Operator that converts L2 FiniteElementSpace L-vectors to E-vectors.
Operator that extracts Face degrees of freedom for L2 spaces.
Operator that extracts face degrees of freedom for L2 interface spaces.
Arbitrary order "L2-conforming" discontinuous finite elements.
Class used by MFEM to store pointers to host and/or device memory.
List of mesh geometries stored as Array<Geometry::Type>.
void GetFaceEdges(int i, Array< int > &edges, Array< int > &o) const
void GetGeometries(int dim, Array< Geometry::Type > &el_geoms) const
Return all element geometries of the given dimension present in the mesh.
Operation GetLastOperation() const
Return type of last modification of the mesh.
int GetNEdges() const
Return the number of edges.
void GetBdrElementFace(int i, int *f, int *o) const
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
virtual void GetExteriorFaceMarker(Array< int > &face_marker) const
Populate a marker array identifying exterior faces.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
Geometry::Type GetFaceGeometry(int i) const
Return the Geometry::Type associated with face i.
Geometry::Type GetElementGeometry(int i) const
Geometry::Type GetBdrElementGeometry(int i) const
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
const FiniteElementSpace * GetNodalFESpace() const
Geometry::Type GetTypicalElementGeometry() const
If the local mesh is not empty, return GetElementGeometry(0); otherwise, return a typical Geometry pr...
int GetBdrElementFaceIndex(int be_idx) const
Return the local face (codimension-1) index for the given boundary element index.
int GetNFaces() const
Return the number of faces in a 3D mesh.
const CoarseFineTransformations & GetRefinementTransforms() const
int GetNE() const
Returns number of elements.
const Element * GetFace(int i) const
Return pointer to the i'th face element object.
int Dimension() const
Dimension of the reference space used within the elements.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
void GetBdrElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of bdr element i.
void GetElementFaces(int i, Array< int > &faces, Array< int > &ori) const
Return the indices and the orientations of all faces of element i.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
void GetBdrElementAdjacentElement(int bdr_el, int &el, int &info) const
For the given boundary element, bdr_el, return its adjacent element and its info, i....
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
int GetNBE() const
Returns number of boundary elements.
NCMesh * ncmesh
Optional nonconforming mesh extension.
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
Geometry::Type GetTypicalFaceGeometry() const
If the local mesh is not empty, return GetFaceGeometry(0); otherwise return a typical face geometry p...
Geometry::Type GetElementBaseGeometry(int i) const
Operator that extracts face degrees of freedom for L2 nonconforming spaces.
const NCList & GetNCList(int entity)
Return vertex/edge/face list (entity = 0/1/2, respectively).
const CoarseFineTransformations & GetDerefinementTransforms() const
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
Geometry::Type GetFaceGeometry(int index) const
Return face geometry type. index is the Mesh face number.
virtual void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges, Array< int > &bdr_faces)
Get a list of vertices (2D/3D), edges (3D) and faces (3D) that coincide with boundary elements with t...
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
int GetNFaces() const
Return the number of (2D) faces in the NCMesh.
int GetNEdges() const
Return the number of edges in the NCMesh.
Arbitrary order H(curl)-conforming Nedelec finite elements.
NURBSExtension generally contains multiple NURBSPatch objects spanning an entire Mesh....
const Vector & GetWeights() const
Access function to the vector of weights weights.
const Array< int > & GetSlave() const
int GetNKV() const
Return the number of KnotVectors.
void LoadBE(int i, const FiniteElement *BE) const
Load boundary element i into BE.
Table * GetElementDofTable()
const Array< int > & GetMaster() const
void LoadFE(int i, const FiniteElement *FE) const
Load element i into FE.
void GetPatchDofs(const int patch, Array< int > &dofs)
Return the degrees of freedom in dofs on patch patch, in Cartesian order.
Table * GetBdrElementDofTable()
int GetNDof() const
Return the number of active DOFs.
int GetOrder() const
If all KnotVector orders are identical, return that number. Otherwise, return NURBSFECollection::Vari...
NURBSExtension * GetCurlExtension(int component)
const Array< int > & GetOrders() const
Read-only access to the orders of all KnotVectors.
NURBSExtension * GetDivExtension(int component)
void ConnectBoundaries()
Set DOF maps for periodic BC.
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
int GetOrder() const
Get the order of the NURBS collection: either a positive number, when using fixed order,...
virtual void SetOrder(int Order) const
Set the order and the name, based on the given Order: either a positive number for fixed order,...
virtual void SetDim(const int dim)
Arbitrary order H(curl) NURBS finite elements.
Arbitrary order H(div) NURBS finite elements.
Pointer to an Operator of a specified type.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
bool OwnsOperator() const
Return true if the OperatorHandle owns the held Operator.
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
Operator * Ptr() const
Access the underlying Operator pointer.
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
OpType * Is() const
Return the Operator pointer dynamically cast to a specified OpType.
Operator::Type Type() const
Get the currently set operator type id.
int width
Dimension of the input / number of columns in the matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Type
Enumeration defining IDs for some classes derived from Operator.
@ ANY_TYPE
ID for the base class Operator, i.e. any type.
@ MFEM_SPARSEMAT
ID for class SparseMatrix.
The ordering method used when the number of unknowns per mesh node (vector dimension) is bigger than ...
Abstract parallel finite element space.
Parallel version of NURBSExtension.
General product operator: x -> (A*B)(x) = A(B(x)).
A class that performs interpolation from an E-vector to quadrature point values and/or derivatives (Q...
const IntegrationRule * IntRule
Not owned.
const QuadratureSpace * qspace
Not owned.
Class representing the storage layout of a QuadratureFunction.
int GetRow(const int row, Array< int > &cols, Vector &srow) const override
Extract all column indices and values from a given row.
void Add(const int i, const int j, const real_t val)
void Swap(SparseMatrix &other)
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
int RowSize(const int i) const
Returns the number of elements in row i.
real_t * GetRowEntries(const int row)
Return a pointer to the entries in a row.
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
void Finalize(int skip_zeros=1) override
Finalize the matrix initialization, switching the storage format from LIL to CSR.
void Set(const int i, const int j, const real_t val)
void AddConnections(int r, const int *c, int nc)
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void AddConnection(int r, int c)
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
int Size() const
Returns the number of TYPE I elements.
int Size_of_connections() const
void AddColumnsInRow(int r, int ncol)
void MakeFromList(int nrows, const Array< Connection > &list)
void AddAColumnInRow(int r)
The transpose of a given operator. Switches the roles of the methods Mult() and MultTranspose().
General triple product operator x -> A*B*C*x, with ownership of the factors.
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add elements of the elemvect Vector to the entries listed in dofs. Negative dof values cause the -dof...
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
real_t Max() const
Returns the maximal element of the vector.
void SetSize(int s)
Resize the vector to size s.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
real_t Min() const
Returns the minimal element of the vector.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
int index(int i, int j, int nx, int ny)
void RemoveBasisAndRestriction(const mfem::FiniteElementSpace *fes)
Remove from ceed_basis_map and ceed_restr_map the entries associated with the given fes.
Linear1DFiniteElement SegmentFE
void Swap(Array< T > &, Array< T > &)
void mfem_error(const char *msg)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void DofMapHelper(int entity, const Table &var_ent_dofs, const Table &loc_var_ent_dofs, const Array< char > &var_ent_orders, const Array< char > &loc_var_ent_orders, Array< int > &all2local, int &ndof_all, int &ndof_loc)
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
void filter_dos(std::string &line)
Check for, and remove, a trailing '\r' from and std::string.
bool UsesTensorBasis(const FiniteElementSpace &fes)
Return true if the mesh contains only one topology and the elements are tensor elements.
BiLinear2DFiniteElement QuadrilateralFE
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
ElementDofOrdering GetEVectorOrdering(const FiniteElementSpace &fes)
Return LEXICOGRAPHIC if mesh contains only one topology and the elements are tensor elements,...
void MarkDofs(const Array< int > &dofs, Array< int > &mark_array)
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
@ NATIVE
Native ordering as defined by the FiniteElement.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
MFEM_EXPORT Linear2DFiniteElement TriangleFE
void skip_comment_lines(std::istream &is, const char comment_char)
Check if the stream starts with comment_char. If so skip it.
real_t p(const Vector &x, real_t t)
bool operator<(const Data &d1, const Data &d2)
Helper struct for defining a connectivity table, see Table::MakeFromList.
Defines the position of a fine element within a coarse element.
int parent
Coarse Element index in the coarse mesh.
Geometry::Type Geom() const
Lists all edges/faces in the nonconforming mesh.
Array< Slave > slaves
All MeshIds corresponding to slave faces.
Array< Master > masters
All MeshIds corresponding to master faces.
Nonconforming edge/face within a bigger edge/face.
unsigned matrix
index into NCList::point_matrices[geom]