25 template <>
void Ordering::
26 DofsToVDofs<Ordering::byNODES>(
int ndofs,
int vdim,
Array<int> &dofs)
29 int size = dofs.Size();
30 dofs.SetSize(size*vdim);
31 for (
int vd = 1; vd < vdim; vd++)
33 for (
int i = 0; i < size; i++)
35 dofs[i+size*vd] = Map<byNODES>(ndofs, vdim, dofs[i], vd);
40 template <>
void Ordering::
41 DofsToVDofs<Ordering::byVDIM>(
int ndofs,
int vdim,
Array<int> &dofs)
44 int size = dofs.Size();
45 dofs.SetSize(size*vdim);
46 for (
int vd = vdim-1; vd >= 0; vd--)
48 for (
int i = 0; i < size; i++)
50 dofs[i+size*vd] = Map<byVDIM>(ndofs, vdim, dofs[i], vd);
55 int FiniteElementSpace::GetOrder(
int i)
const
57 int GeomType = mesh->GetElementBaseGeometry(i);
58 return fec->FiniteElementForGeometry(GeomType)->GetOrder();
61 int FiniteElementSpace::GetFaceOrder(
int i)
const
63 int GeomType = mesh->GetFaceBaseGeometry(i);
64 return fec->FiniteElementForGeometry(GeomType)->GetOrder();
67 void FiniteElementSpace::DofsToVDofs (
Array<int> &dofs,
int ndofs)
const
69 if (vdim == 1) {
return; }
70 if (ndofs < 0) { ndofs = this->ndofs; }
72 if (ordering == Ordering::byNODES)
74 Ordering::DofsToVDofs<Ordering::byNODES>(ndofs, vdim, dofs);
78 Ordering::DofsToVDofs<Ordering::byVDIM>(ndofs, vdim, dofs);
82 void FiniteElementSpace::DofsToVDofs(
int vd,
Array<int> &dofs,
int ndofs)
const
84 if (vdim == 1) {
return; }
85 if (ndofs < 0) { ndofs = this->ndofs; }
87 if (ordering == Ordering::byNODES)
89 for (
int i = 0; i < dofs.
Size(); i++)
91 dofs[i] = Ordering::Map<Ordering::byNODES>(ndofs, vdim, dofs[i], vd);
96 for (
int i = 0; i < dofs.
Size(); i++)
98 dofs[i] = Ordering::Map<Ordering::byVDIM>(ndofs, vdim, dofs[i], vd);
103 int FiniteElementSpace::DofToVDof(
int dof,
int vd,
int ndofs)
const
105 if (vdim == 1) {
return dof; }
106 if (ndofs < 0) { ndofs = this->ndofs; }
108 if (ordering == Ordering::byNODES)
110 return Ordering::Map<Ordering::byNODES>(ndofs, vdim, dof, vd);
114 return Ordering::Map<Ordering::byVDIM>(ndofs, vdim, dof, vd);
121 int n = vdofs.
Size(), *vdof = vdofs;
122 for (
int i = 0; i < n; i++)
125 if ((j = vdof[i]) < 0)
132 void FiniteElementSpace::GetElementVDofs(
int i,
Array<int> &vdofs)
const
134 GetElementDofs(i, vdofs);
138 void FiniteElementSpace::GetBdrElementVDofs(
int i,
Array<int> &vdofs)
const
140 GetBdrElementDofs(i, vdofs);
144 void FiniteElementSpace::GetFaceVDofs(
int i,
Array<int> &vdofs)
const
146 GetFaceDofs(i, vdofs);
150 void FiniteElementSpace::GetEdgeVDofs(
int i,
Array<int> &vdofs)
const
152 GetEdgeDofs(i, vdofs);
156 void FiniteElementSpace::GetVertexVDofs(
int i,
Array<int> &vdofs)
const
158 GetVertexDofs(i, vdofs);
162 void FiniteElementSpace::GetElementInteriorVDofs(
int i,
Array<int> &vdofs)
const
164 GetElementInteriorDofs(i, vdofs);
168 void FiniteElementSpace::GetEdgeInteriorVDofs(
int i,
Array<int> &vdofs)
const
170 GetEdgeInteriorDofs(i, vdofs);
174 void FiniteElementSpace::BuildElementToDofTable()
const
176 if (elem_dof) {
return; }
180 el_dof -> MakeI (mesh -> GetNE());
181 for (
int i = 0; i < mesh -> GetNE(); i++)
183 GetElementDofs (i, dofs);
184 el_dof -> AddColumnsInRow (i, dofs.
Size());
187 for (
int i = 0; i < mesh -> GetNE(); i++)
189 GetElementDofs (i, dofs);
190 el_dof -> AddConnections (i, (
int *)dofs, dofs.
Size());
192 el_dof -> ShiftUpI();
196 void FiniteElementSpace::RebuildElementToDofTable()
200 BuildElementToDofTable();
203 void FiniteElementSpace::BuildDofToArrays()
205 if (dof_elem_array.Size()) {
return; }
207 BuildElementToDofTable();
209 dof_elem_array.SetSize (ndofs);
210 dof_ldof_array.SetSize (ndofs);
212 for (
int i = 0; i < mesh -> GetNE(); i++)
214 const int *dofs = elem_dof -> GetRow(i);
215 const int n = elem_dof -> RowSize(i);
216 for (
int j = 0; j < n; j++)
218 if (dof_elem_array[dofs[j]] < 0)
220 dof_elem_array[dofs[j]] = i;
221 dof_ldof_array[dofs[j]] = j;
229 for (
int i = 0; i < dofs.
Size(); i++)
232 if (k < 0) { k = -1 - k; }
237 void FiniteElementSpace::GetEssentialVDofs(
const Array<int> &bdr_attr_is_ess,
245 for (
int i = 0; i < GetNBE(); i++)
247 if (bdr_attr_is_ess[GetBdrAttribute(i)-1])
249 GetBdrElementVDofs(i, vdofs);
250 mark_dofs(vdofs, ess_vdofs);
259 mesh->ncmesh->GetBoundaryClosure(bdr_attr_is_ess, bdr_verts, bdr_edges);
261 for (
int i = 0; i < bdr_verts.
Size(); i++)
263 GetVertexVDofs(bdr_verts[i], vdofs);
264 mark_dofs(vdofs, ess_vdofs);
266 for (
int i = 0; i < bdr_edges.
Size(); i++)
268 GetEdgeVDofs(bdr_edges[i], vdofs);
269 mark_dofs(vdofs, ess_vdofs);
274 void FiniteElementSpace::GetEssentialTrueDofs(
const Array<int> &bdr_attr_is_ess,
278 GetEssentialVDofs(bdr_attr_is_ess, ess_vdofs);
288 MarkerToList(ess_tdofs, ess_tdof_list);
292 void FiniteElementSpace::MarkerToList(
const Array<int> &marker,
296 for (
int i = 0; i < marker.
Size(); i++)
298 if (marker[i]) { num_marked++; }
302 for (
int i = 0; i < marker.
Size(); i++)
304 if (marker[i]) { list.
Append(i); }
309 void FiniteElementSpace::ListToMarker(
const Array<int> &list,
int marker_size,
314 for (
int i = 0; i < list.
Size(); i++)
316 marker[list[i]] = mark_val;
320 void FiniteElementSpace::ConvertToConformingVDofs(
const Array<int> &dofs,
323 GetConformingProlongation();
324 if (cP) { cP->BooleanMultTranspose(dofs, cdofs); }
325 else { dofs.
Copy(cdofs); }
328 void FiniteElementSpace::ConvertFromConformingVDofs(
const Array<int> &cdofs,
331 GetConformingRestriction();
332 if (cR) { cR->BooleanMultTranspose(cdofs, dofs); }
333 else { cdofs.
Copy(dofs); }
345 for (i = 0; i < mesh -> GetNE(); i++)
347 this -> GetElementVDofs (i, d_vdofs);
348 cfes -> GetElementVDofs (i, c_vdofs);
351 if (d_vdofs.
Size() != c_vdofs.
Size())
353 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
357 for (j = 0; j < d_vdofs.
Size(); j++)
359 R -> Set (c_vdofs[j], d_vdofs[j], 1.0);
377 for (i = 0; i < mesh -> GetNE(); i++)
379 this -> GetElementDofs (i, d_dofs);
380 cfes -> GetElementDofs (i, c_dofs);
383 if (c_dofs.
Size() != 1)
385 "D2Const_GlobalRestrictionMatrix (...)");
388 for (j = 0; j < d_dofs.
Size(); j++)
390 R -> Set (c_dofs[0], d_dofs[j], 1.0);
418 h_fe->
Project(*l_fe, T, loc_restr);
420 for (
int i = 0; i < mesh -> GetNE(); i++)
422 this -> GetElementDofs (i, h_dofs);
423 lfes -> GetElementDofs (i, l_dofs);
425 R -> SetSubMatrix (l_dofs, h_dofs, loc_restr, 1);
436 for (
int i = 0; i < slave_dofs.
Size(); i++)
438 int sdof = slave_dofs[i];
441 for (
int j = 0; j < master_dofs.
Size(); j++)
443 double coef = I(i, j);
444 if (std::abs(coef) > 1e-12)
446 int mdof = master_dofs[j];
447 if (mdof != sdof && mdof != (-1-sdof))
449 deps.
Add(sdof, mdof, coef);
457 static bool DofFinalizable(
int dof,
const Array<bool>& finalized,
458 const SparseMatrix& deps)
460 const int* dep = deps.GetRowColumns(dof);
461 int ndep = deps.RowSize(dof);
464 for (
int i = 0; i < ndep; i++)
466 if (!finalized[dep[i]]) {
return false; }
474 void FiniteElementSpace::GetEdgeFaceDofs(
int type,
int index,
Array<int> &dofs)
479 if (index < mesh->GetNFaces()) { GetFaceDofs(index, dofs); }
483 if (index < mesh->GetNEdges()) { GetEdgeDofs(index, dofs); }
487 void FiniteElementSpace::GetConformingInterpolation()
490 MFEM_VERIFY(dynamic_cast<ParFiniteElementSpace*>(
this) == NULL,
491 "This method should not be used with a ParFiniteElementSpace!");
493 if (cP_is_set) {
return; }
502 for (
int type = 0; type <= 1; type++)
505 : mesh->ncmesh->GetEdgeList();
506 if (!list.
masters.size()) {
continue; }
512 int geom = type ? Geometry::SQUARE : Geometry::SEGMENT;
513 const FiniteElement* fe = fec->FiniteElementForGeometry(geom);
514 if (!fe) {
continue; }
520 for (
unsigned mi = 0; mi < list.
masters.size(); mi++)
523 GetEdgeFaceDofs(type, master.
index, master_dofs);
524 if (!master_dofs.
Size()) {
continue; }
529 GetEdgeFaceDofs(type, slave.
index, slave_dofs);
530 if (!slave_dofs.
Size()) {
continue; }
536 AddDependencies(deps, master_dofs, slave_dofs, I);
545 for (
int i = 0; i < ndofs; i++)
547 if (!deps.
RowSize(i)) { n_true_dofs++; }
551 if (n_true_dofs == ndofs)
560 int *cR_I =
new int[n_true_dofs+1];
561 double *cR_A =
new double[n_true_dofs];
562 cR_J =
new int[n_true_dofs];
563 for (
int i = 0; i < n_true_dofs; i++)
568 cR_I[n_true_dofs] = n_true_dofs;
569 cR =
new SparseMatrix(cR_I, cR_J, cR_A, n_true_dofs, ndofs);
579 for (
int i = 0, true_dof = 0; i < ndofs; i++)
584 cP->Add(i, true_dof++, 1.0);
597 int n_finalized = n_true_dofs;
603 for (
int dof = 0; dof < ndofs; dof++)
605 if (!finalized[dof] && DofFinalizable(dof, finalized, deps))
611 for (
int j = 0; j < n_dep; j++)
613 cP->GetRow(dep_col[j], cols, srow);
615 cP->AddRow(dof, cols, srow);
618 finalized[dof] =
true;
628 if (n_finalized != ndofs)
630 MFEM_ABORT(
"Error creating cP matrix.");
644 if (vdim == 1) {
return; }
646 int height = mat.
Height();
647 int width = mat.
Width();
653 for (
int i = 0; i < height; i++)
655 mat.
GetRow(i, dofs, srow);
656 for (
int vd = 0; vd < vdim; vd++)
659 DofsToVDofs(vd, vdofs, width);
660 vmat->
SetRow(DofToVDof(i, vd, height), vdofs, srow);
671 if (Conforming()) {
return NULL; }
672 if (!cP_is_set) { GetConformingInterpolation(); }
678 if (Conforming()) {
return NULL; }
679 if (!cP_is_set) { GetConformingInterpolation(); }
683 int FiniteElementSpace::GetNConformingDofs()
686 return P ? (P->
Width() / vdim) : ndofs;
690 const Table* old_elem_dof)
692 MFEM_VERIFY(mesh->GetLastOperation() == Mesh::REFINE,
"");
693 MFEM_VERIFY(ndofs >= old_ndofs,
"Previous space is not coarser.");
700 int geom = mesh->GetElementBaseGeometry();
701 const FiniteElement *fe = fec->FiniteElementForGeometry(geom);
711 for (
int i = 0; i < nmat; i++)
721 for (
int k = 0; k < mesh->GetNE(); k++)
726 elem_dof->GetRow(k, dofs);
729 for (
int vd = 0; vd < vdim; vd++)
731 old_dofs.
Copy(old_vdofs);
732 DofsToVDofs(vd, old_vdofs, old_ndofs);
734 for (
int i = 0; i < ldof; i++)
736 int r = DofToVDof(dofs[i], vd);
737 int m = (r >= 0) ? r : (-1 - r);
742 P->
SetRow(r, old_vdofs, row);
749 MFEM_ASSERT(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
770 void FiniteElementSpace::GetLocalDerefinementMatrices(
773 const FiniteElement *fe = fec->FiniteElementForGeometry(geom);
782 int dim = mesh->Dimension();
786 Vector pt(&ipt.
x, dim), shape(ldof);
789 localR.
SetSize(ldof, ldof, nmat);
790 for (
int i = 0; i < nmat; i++)
793 lR = numeric_limits<double>::infinity();
799 for (
int j = 0; j < nodes.
Size(); j++)
807 MFEM_ASSERT(dynamic_cast<const NodalFiniteElement*>(fe),
808 "only nodal FEs are implemented");
816 const Table* old_elem_dof)
818 MFEM_VERIFY(Nonconforming(),
"Not implemented for conforming meshes.");
819 MFEM_VERIFY(old_ndofs,
"Missing previous (finer) space.");
820 MFEM_VERIFY(ndofs <= old_ndofs,
"Previous space is not finer.");
826 mesh->ncmesh->GetDerefinementTransforms();
828 int geom = mesh->ncmesh->GetElementGeometry();
829 int ldof = fec->FiniteElementForGeometry(geom)->GetDof();
832 GetLocalDerefinementMatrices(geom, dtrans, localR);
838 for (
int k = 0; k < dtrans.
embeddings.Size(); k++)
843 elem_dof->GetRow(emb.
parent, dofs);
844 old_elem_dof->
GetRow(k, old_dofs);
846 for (
int vd = 0; vd < vdim; vd++)
848 old_dofs.
Copy(old_vdofs);
849 DofsToVDofs(vd, old_vdofs, old_ndofs);
851 for (
int i = 0; i < lR.
Height(); i++)
853 if (lR(i, 0) == numeric_limits<double>::infinity()) {
continue; }
855 int r = DofToVDof(dofs[i], vd);
856 int m = (r >= 0) ? r : (-1 - r);
861 R->
SetRow(r, old_vdofs, row);
868 MFEM_ASSERT(mark.
Sum() == R->
Height(),
"Not all rows of R set.");
872 FiniteElementSpace::FiniteElementSpace(
Mesh *mesh,
874 int vdim,
int ordering)
890 mfem_error(
"FiniteElementSpace::FiniteElementSpace :\n"
891 " NURBS FE space requires NURBS mesh.");
920 BuildElementToDofTable();
925 if (NURBSext && !own_ext)
927 mfem_error(
"FiniteElementSpace::StealNURBSext");
934 void FiniteElementSpace::UpdateNURBS()
945 ndofs = NURBSext->GetNDof();
946 elem_dof = NURBSext->GetElementDofTable();
947 bdrElem_dof = NURBSext->GetBdrElementDofTable();
950 void FiniteElementSpace::Construct()
959 if ( mesh->Dimension() > 1 )
961 nedofs = mesh->GetNEdges() * fec->DofForGeometry(Geometry::SEGMENT);
979 if (mesh->Dimension() == 3 && mesh->GetNE())
986 int fdof = fec->DofForGeometry(mesh->GetFaceBaseGeometry(0));
989 fdofs =
new int[mesh->GetNFaces()+1];
991 for (i = 0; i < mesh->GetNFaces(); i++)
1000 bdofs =
new int[mesh->GetNE()+1];
1002 for (i = 0; i < mesh->GetNE(); i++)
1004 nbdofs += fec->DofForGeometry(mesh->GetElementBaseGeometry(i));
1005 bdofs[i+1] = nbdofs;
1008 ndofs = nvdofs + nedofs + nfdofs + nbdofs;
1014 void FiniteElementSpace::GetElementDofs (
int i,
Array<int> &dofs)
const
1018 elem_dof -> GetRow (i, dofs);
1023 int k, j, nv, ne, nf, nb, nfd, nd;
1026 dim = mesh->Dimension();
1027 nv = fec->DofForGeometry(Geometry::POINT);
1028 ne = (dim > 1) ? ( fec->DofForGeometry(Geometry::SEGMENT) ) : ( 0 );
1029 nb = fec->DofForGeometry(mesh->GetElementBaseGeometry(i));
1032 mesh->GetElementVertices(i, V);
1036 mesh->GetElementEdges(i, E, Eo);
1041 if (fec->HasFaceDofs(mesh->GetElementBaseGeometry(i)))
1043 mesh->GetElementFaces(i, F, Fo);
1044 for (k = 0; k < F.
Size(); k++)
1046 nfd += fec->DofForGeometry(mesh->GetFaceBaseGeometry(F[k]));
1050 nd = V.
Size() * nv + E.
Size() * ne + nfd + nb;
1054 for (k = 0; k < V.
Size(); k++)
1056 for (j = 0; j < nv; j++)
1058 dofs[k*nv+j] = V[k]*nv+j;
1066 for (k = 0; k < E.
Size(); k++)
1068 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1069 for (j = 0; j < ne; j++)
1073 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1077 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1082 ne = nv + ne * E.
Size();
1086 for (k = 0; k < F.
Size(); k++)
1088 ind = fec->DofOrderForOrientation(mesh->GetFaceBaseGeometry(F[k]),
1090 nf = fec->DofForGeometry(mesh->GetFaceBaseGeometry(F[k]));
1091 for (j = 0; j < nf; j++)
1095 dofs[ne+j] = -1 - ( nvdofs+nedofs+fdofs[F[k]]+(-1-ind[j]) );
1099 dofs[ne+j] = nvdofs+nedofs+fdofs[F[k]]+ind[j];
1105 k = nvdofs + nedofs + nfdofs + bdofs[i];
1106 for (j = 0; j < nb; j++)
1116 fec->FiniteElementForGeometry(mesh->GetElementBaseGeometry(i));
1120 NURBSext->LoadFE(i, FE);
1126 void FiniteElementSpace::GetBdrElementDofs(
int i,
Array<int> &dofs)
const
1130 bdrElem_dof->GetRow(i, dofs);
1135 int k, j, nv, ne, nf, nd, iF, oF;
1138 dim = mesh->Dimension();
1139 nv = fec->DofForGeometry(Geometry::POINT);
1142 mesh->GetBdrElementVertices(i, V);
1144 ne = (dim > 1) ? ( fec->DofForGeometry(Geometry::SEGMENT) ) : ( 0 );
1147 mesh->GetBdrElementEdges(i, E, Eo);
1149 nd = V.
Size() * nv + E.
Size() * ne;
1150 nf = (dim == 3) ? (fec->DofForGeometry(
1151 mesh->GetBdrElementBaseGeometry(i))) : (0);
1155 mesh->GetBdrElementFace(i, &iF, &oF);
1160 for (k = 0; k < V.
Size(); k++)
1162 for (j = 0; j < nv; j++)
1164 dofs[k*nv+j] = V[k]*nv+j;
1172 for (k = 0; k < E.
Size(); k++)
1174 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1175 for (j = 0; j < ne; j++)
1179 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1183 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1191 ne = nv + ne * E.
Size();
1192 ind = (fec->DofOrderForOrientation(
1193 mesh->GetBdrElementBaseGeometry(i), oF));
1194 for (j = 0; j < nf; j++)
1198 dofs[ne+j] = -1 - ( nvdofs+nedofs+fdofs[iF]+(-1-ind[j]) );
1202 dofs[ne+j] = nvdofs+nedofs+fdofs[iF]+ind[j];
1209 void FiniteElementSpace::GetFaceDofs(
int i,
Array<int> &dofs)
const
1211 int j, k, nv, ne, nf, nd,
dim = mesh->Dimension();
1216 nv = fec->DofForGeometry(Geometry::POINT);
1217 ne = (dim > 1) ? fec->DofForGeometry(Geometry::SEGMENT) : 0;
1220 mesh->GetFaceVertices(i, V);
1224 mesh->GetFaceEdges(i, E, Eo);
1226 nf = (fdofs) ? (fdofs[i+1]-fdofs[i]) : (0);
1227 nd = V.
Size() * nv + E.
Size() * ne + nf;
1231 for (k = 0; k < V.
Size(); k++)
1233 for (j = 0; j < nv; j++)
1235 dofs[k*nv+j] = V[k]*nv+j;
1242 for (k = 0; k < E.
Size(); k++)
1244 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1245 for (j = 0; j < ne; j++)
1249 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1253 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1258 ne = nv + ne * E.
Size();
1261 for (j = nvdofs+nedofs+fdofs[i], k = 0; k < nf; j++, k++)
1268 void FiniteElementSpace::GetEdgeDofs(
int i,
Array<int> &dofs)
const
1273 nv = fec->DofForGeometry(Geometry::POINT);
1276 mesh->GetEdgeVertices(i, V);
1278 ne = fec->DofForGeometry(Geometry::SEGMENT);
1282 for (k = 0; k < 2; k++)
1284 for (j = 0; j < nv; j++)
1286 dofs[k*nv+j] = V[k]*nv+j;
1291 for (j = 0, k = nvdofs+i*ne; j < ne; j++, k++)
1297 void FiniteElementSpace::GetVertexDofs(
int i,
Array<int> &dofs)
const
1301 nv = fec->DofForGeometry(Geometry::POINT);
1303 for (j = 0; j < nv; j++)
1309 void FiniteElementSpace::GetElementInteriorDofs (
int i,
Array<int> &dofs)
const
1312 nb = fec -> DofForGeometry (mesh -> GetElementBaseGeometry (i));
1314 k = nvdofs + nedofs + nfdofs + bdofs[i];
1315 for (j = 0; j < nb; j++)
1321 void FiniteElementSpace::GetEdgeInteriorDofs (
int i,
Array<int> &dofs)
const
1325 ne = fec -> DofForGeometry (Geometry::SEGMENT);
1327 for (j = 0, k = nvdofs+i*ne; j < ne; j++, k++)
1337 switch ( mesh->Dimension() )
1340 BE = fec->FiniteElementForGeometry(Geometry::POINT);
1343 BE = fec->FiniteElementForGeometry(Geometry::SEGMENT);
1347 BE = fec->FiniteElementForGeometry(
1348 mesh->GetBdrElementBaseGeometry(i));
1353 NURBSext->LoadBE(i, BE);
1363 switch (mesh->Dimension())
1366 fe = fec->FiniteElementForGeometry(Geometry::POINT);
1369 fe = fec->FiniteElementForGeometry(Geometry::SEGMENT);
1373 fe = fec->FiniteElementForGeometry(mesh->GetFaceBaseGeometry(i));
1384 return fec->FiniteElementForGeometry(Geometry::SEGMENT);
1388 int i,
int geom_type)
const
1390 return fec->TraceFiniteElementForGeometry(geom_type);
1393 FiniteElementSpace::~FiniteElementSpace()
1398 void FiniteElementSpace::Destroy()
1402 if (own_T) {
delete T; }
1404 dof_elem_array.DeleteAll();
1405 dof_ldof_array.DeleteAll();
1409 if (own_ext) {
delete NURBSext; }
1423 if (mesh->GetSequence() == sequence)
1427 if (want_transform && mesh->GetSequence() != sequence + 1)
1429 MFEM_ABORT(
"Error in update sequence. Space needs to be updated after "
1430 "each mesh modification.");
1432 sequence = mesh->GetSequence();
1440 Table* old_elem_dof= NULL;
1446 old_elem_dof = elem_dof;
1453 BuildElementToDofTable();
1458 switch (mesh->GetLastOperation())
1462 T = RefinementMatrix(old_ndofs, old_elem_dof);
1466 case Mesh::DEREFINE:
1468 GetConformingInterpolation();
1469 T = DerefinementMatrix(old_ndofs, old_elem_dof);
1482 delete old_elem_dof;
1485 void FiniteElementSpace::Save(std::ostream &out)
const
1487 out <<
"FiniteElementSpace\n"
1488 <<
"FiniteElementCollection: " << fec->Name() <<
'\n'
1489 <<
"VDim: " << vdim <<
'\n'
1490 <<
"Ordering: " << ordering <<
'\n';
Abstract class for Finite Elements.
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
void Set(const double *p, const int dim)
int Size() const
Logical size of the array.
int RowSize(const int i) const
Returns the number of elements in row i.
void Get(double *p, const int dim) const
void Add(const int i, const int j, const double a)
Class for integration rule.
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
void InvertLinearTrans(IsoparametricTransformation &trans, const DenseMatrix &invdfdx, const IntegrationPoint &pt, Vector &x)
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, but treat all elements as booleans (zero=false, nonzero=true).
Lists all edges/faces in the nonconforming mesh.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols.
void Copy(Array ©) const
Create a copy of the current array.
Piecewise-(bi)linear continuous finite elements.
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void SetSize(int i, int j, int k)
void OrientedPointMatrix(DenseMatrix &oriented_matrix) const
Return the point matrix oriented according to the master and slave edges.
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
double * GetRowEntries(const int row)
Return a pointer to the entries in a row.
int GetNE() const
Returns number of elements in the mesh.
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
int Append(const T &el)
Append element to array, resize if necessary.
std::vector< Master > masters
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
const IntegrationRule & GetNodes() const
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
virtual const FiniteElement * FiniteElementForGeometry(int GeomType) const
void SetRow(int r, const Vector &row)
virtual void Finalize(int skip_zeros=1)
int slaves_end
slave faces
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
int GetGeomType() const
Returns the geometry type:
void Set3(const double x1, const double x2, const double x3)
std::vector< Slave > slaves
int GetDof() const
Returns the degrees of freedom in the FE space.
void mfem_error(const char *msg)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void Update(Vector &x, int k, DenseMatrix &h, Vector &s, Array< Vector * > &v)
NURBSExtension * NURBSext
Class for integration point with weight.
General triple product operator x -> A*B*C*x, with ownership of the factors.
void GetRow(int r, Vector &row)
int parent
element index in the coarse mesh
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
void MakeRef(T *, int)
Make this Array a reference to a pointer.
void Mult(const double *x, double *y) const
Matrix vector multiplication.
static bool CheckPoint(int GeomType, const IntegrationPoint &ip)
Check if the given point is inside the given reference element.
void Swap(SparseMatrix &other)
virtual int DofForGeometry(int GeomType) const
BiLinear2DFiniteElement QuadrilateralFE
Rank 3 tensor (array of matrices)
Linear1DFiniteElement SegmentFE
Defines the position of a fine element within a coarse element.
int matrix
index into CoarseFineTransformations::point_matrices