14 #include "../mesh/mesh_headers.hpp"
26 template <>
void Ordering::
27 DofsToVDofs<Ordering::byNODES>(
int ndofs,
int vdim,
Array<int> &dofs)
30 int size = dofs.Size();
31 dofs.SetSize(size*vdim);
32 for (
int vd = 1; vd < vdim; vd++)
34 for (
int i = 0; i < size; i++)
36 dofs[i+size*vd] = Map<byNODES>(ndofs, vdim, dofs[i], vd);
41 template <>
void Ordering::
42 DofsToVDofs<Ordering::byVDIM>(
int ndofs,
int vdim,
Array<int> &dofs)
45 int size = dofs.Size();
46 dofs.SetSize(size*vdim);
47 for (
int vd = vdim-1; vd >= 0; vd--)
49 for (
int i = 0; i < size; i++)
51 dofs[i+size*vd] = Map<byVDIM>(ndofs, vdim, dofs[i], vd);
56 int FiniteElementSpace::GetOrder(
int i)
const
58 int GeomType = mesh->GetElementBaseGeometry(i);
59 return fec->FiniteElementForGeometry(GeomType)->GetOrder();
62 int FiniteElementSpace::GetFaceOrder(
int i)
const
64 int GeomType = mesh->GetFaceBaseGeometry(i);
65 return fec->FiniteElementForGeometry(GeomType)->GetOrder();
68 void FiniteElementSpace::DofsToVDofs (
Array<int> &dofs,
int ndofs)
const
70 if (vdim == 1) {
return; }
71 if (ndofs < 0) { ndofs = this->ndofs; }
73 if (ordering == Ordering::byNODES)
75 Ordering::DofsToVDofs<Ordering::byNODES>(ndofs, vdim, dofs);
79 Ordering::DofsToVDofs<Ordering::byVDIM>(ndofs, vdim, dofs);
83 void FiniteElementSpace::DofsToVDofs(
int vd,
Array<int> &dofs,
int ndofs)
const
85 if (vdim == 1) {
return; }
86 if (ndofs < 0) { ndofs = this->ndofs; }
88 if (ordering == Ordering::byNODES)
90 for (
int i = 0; i < dofs.
Size(); i++)
92 dofs[i] = Ordering::Map<Ordering::byNODES>(ndofs, vdim, dofs[i], vd);
97 for (
int i = 0; i < dofs.
Size(); i++)
99 dofs[i] = Ordering::Map<Ordering::byVDIM>(ndofs, vdim, dofs[i], vd);
104 int FiniteElementSpace::DofToVDof(
int dof,
int vd,
int ndofs)
const
106 if (vdim == 1) {
return dof; }
107 if (ndofs < 0) { ndofs = this->ndofs; }
109 if (ordering == Ordering::byNODES)
111 return Ordering::Map<Ordering::byNODES>(ndofs, vdim, dof, vd);
115 return Ordering::Map<Ordering::byVDIM>(ndofs, vdim, dof, vd);
122 int n = vdofs.
Size(), *vdof = vdofs;
123 for (
int i = 0; i < n; i++)
126 if ((j = vdof[i]) < 0)
133 void FiniteElementSpace::GetElementVDofs(
int i,
Array<int> &vdofs)
const
135 GetElementDofs(i, vdofs);
139 void FiniteElementSpace::GetBdrElementVDofs(
int i,
Array<int> &vdofs)
const
141 GetBdrElementDofs(i, vdofs);
145 void FiniteElementSpace::GetFaceVDofs(
int i,
Array<int> &vdofs)
const
147 GetFaceDofs(i, vdofs);
151 void FiniteElementSpace::GetEdgeVDofs(
int i,
Array<int> &vdofs)
const
153 GetEdgeDofs(i, vdofs);
157 void FiniteElementSpace::GetVertexVDofs(
int i,
Array<int> &vdofs)
const
159 GetVertexDofs(i, vdofs);
163 void FiniteElementSpace::GetElementInteriorVDofs(
int i,
Array<int> &vdofs)
const
165 GetElementInteriorDofs(i, vdofs);
169 void FiniteElementSpace::GetEdgeInteriorVDofs(
int i,
Array<int> &vdofs)
const
171 GetEdgeInteriorDofs(i, vdofs);
175 void FiniteElementSpace::BuildElementToDofTable()
const
177 if (elem_dof) {
return; }
181 el_dof -> MakeI (mesh -> GetNE());
182 for (
int i = 0; i < mesh -> GetNE(); i++)
184 GetElementDofs (i, dofs);
185 el_dof -> AddColumnsInRow (i, dofs.
Size());
188 for (
int i = 0; i < mesh -> GetNE(); i++)
190 GetElementDofs (i, dofs);
191 el_dof -> AddConnections (i, (
int *)dofs, dofs.
Size());
193 el_dof -> ShiftUpI();
197 void FiniteElementSpace::RebuildElementToDofTable()
201 BuildElementToDofTable();
204 void FiniteElementSpace::ReorderElementToDofTable()
210 int *J = elem_dof->GetJ(), nnz = elem_dof->Size_of_connections();
211 for (
int k = 0, dof_counter = 0; k < nnz; k++)
213 const int sdof = J[k];
214 const int dof = (sdof < 0) ? -1-sdof : sdof;
215 int new_dof = dof_marker[dof];
218 dof_marker[dof] = new_dof = dof_counter++;
220 J[k] = (sdof < 0) ? -1-new_dof : new_dof;
224 void FiniteElementSpace::BuildDofToArrays()
226 if (dof_elem_array.Size()) {
return; }
228 BuildElementToDofTable();
230 dof_elem_array.SetSize (ndofs);
231 dof_ldof_array.SetSize (ndofs);
233 for (
int i = 0; i < mesh -> GetNE(); i++)
235 const int *dofs = elem_dof -> GetRow(i);
236 const int n = elem_dof -> RowSize(i);
237 for (
int j = 0; j < n; j++)
239 if (dof_elem_array[dofs[j]] < 0)
241 dof_elem_array[dofs[j]] = i;
242 dof_ldof_array[dofs[j]] = j;
250 for (
int i = 0; i < dofs.
Size(); i++)
253 if (k < 0) { k = -1 - k; }
258 void FiniteElementSpace::GetEssentialVDofs(
const Array<int> &bdr_attr_is_ess,
266 for (
int i = 0; i < GetNBE(); i++)
268 if (bdr_attr_is_ess[GetBdrAttribute(i)-1])
270 GetBdrElementVDofs(i, vdofs);
271 mark_dofs(vdofs, ess_vdofs);
280 mesh->ncmesh->GetBoundaryClosure(bdr_attr_is_ess, bdr_verts, bdr_edges);
282 for (
int i = 0; i < bdr_verts.
Size(); i++)
284 GetVertexVDofs(bdr_verts[i], vdofs);
285 mark_dofs(vdofs, ess_vdofs);
287 for (
int i = 0; i < bdr_edges.
Size(); i++)
289 GetEdgeVDofs(bdr_edges[i], vdofs);
290 mark_dofs(vdofs, ess_vdofs);
295 void FiniteElementSpace::GetEssentialTrueDofs(
const Array<int> &bdr_attr_is_ess,
299 GetEssentialVDofs(bdr_attr_is_ess, ess_vdofs);
309 MarkerToList(ess_tdofs, ess_tdof_list);
313 void FiniteElementSpace::MarkerToList(
const Array<int> &marker,
317 for (
int i = 0; i < marker.
Size(); i++)
319 if (marker[i]) { num_marked++; }
323 for (
int i = 0; i < marker.
Size(); i++)
325 if (marker[i]) { list.
Append(i); }
330 void FiniteElementSpace::ListToMarker(
const Array<int> &list,
int marker_size,
335 for (
int i = 0; i < list.
Size(); i++)
337 marker[list[i]] = mark_val;
341 void FiniteElementSpace::ConvertToConformingVDofs(
const Array<int> &dofs,
344 GetConformingProlongation();
345 if (cP) { cP->BooleanMultTranspose(dofs, cdofs); }
346 else { dofs.
Copy(cdofs); }
349 void FiniteElementSpace::ConvertFromConformingVDofs(
const Array<int> &cdofs,
352 GetConformingRestriction();
353 if (cR) { cR->BooleanMultTranspose(cdofs, dofs); }
354 else { cdofs.
Copy(dofs); }
366 for (i = 0; i < mesh -> GetNE(); i++)
368 this -> GetElementVDofs (i, d_vdofs);
369 cfes -> GetElementVDofs (i, c_vdofs);
372 if (d_vdofs.
Size() != c_vdofs.
Size())
374 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
378 for (j = 0; j < d_vdofs.
Size(); j++)
380 R -> Set (c_vdofs[j], d_vdofs[j], 1.0);
398 for (i = 0; i < mesh -> GetNE(); i++)
400 this -> GetElementDofs (i, d_dofs);
401 cfes -> GetElementDofs (i, c_dofs);
404 if (c_dofs.
Size() != 1)
406 "D2Const_GlobalRestrictionMatrix (...)");
409 for (j = 0; j < d_dofs.
Size(); j++)
411 R -> Set (c_dofs[0], d_dofs[j], 1.0);
439 h_fe->
Project(*l_fe, T, loc_restr);
441 for (
int i = 0; i < mesh -> GetNE(); i++)
443 this -> GetElementDofs (i, h_dofs);
444 lfes -> GetElementDofs (i, l_dofs);
446 R -> SetSubMatrix (l_dofs, h_dofs, loc_restr, 1);
457 for (
int i = 0; i < slave_dofs.
Size(); i++)
459 int sdof = slave_dofs[i];
462 for (
int j = 0; j < master_dofs.
Size(); j++)
464 double coef = I(i, j);
465 if (std::abs(coef) > 1e-12)
467 int mdof = master_dofs[j];
468 if (mdof != sdof && mdof != (-1-sdof))
470 deps.
Add(sdof, mdof, coef);
478 static bool DofFinalizable(
int dof,
const Array<bool>& finalized,
479 const SparseMatrix& deps)
481 const int* dep = deps.GetRowColumns(dof);
482 int ndep = deps.RowSize(dof);
485 for (
int i = 0; i < ndep; i++)
487 if (!finalized[dep[i]]) {
return false; }
495 void FiniteElementSpace::GetEdgeFaceDofs(
int type,
int index,
Array<int> &dofs)
500 if (index < mesh->GetNFaces()) { GetFaceDofs(index, dofs); }
504 if (index < mesh->GetNEdges()) { GetEdgeDofs(index, dofs); }
508 void FiniteElementSpace::GetConformingInterpolation()
511 MFEM_VERIFY(dynamic_cast<ParFiniteElementSpace*>(
this) == NULL,
512 "This method should not be used with a ParFiniteElementSpace!");
514 if (cP_is_set) {
return; }
523 for (
int type = 0; type <= 1; type++)
526 : mesh->ncmesh->GetEdgeList();
527 if (!list.
masters.size()) {
continue; }
533 int geom = type ? Geometry::SQUARE : Geometry::SEGMENT;
534 const FiniteElement* fe = fec->FiniteElementForGeometry(geom);
535 if (!fe) {
continue; }
541 for (
unsigned mi = 0; mi < list.
masters.size(); mi++)
544 GetEdgeFaceDofs(type, master.
index, master_dofs);
545 if (!master_dofs.
Size()) {
continue; }
550 GetEdgeFaceDofs(type, slave.
index, slave_dofs);
551 if (!slave_dofs.
Size()) {
continue; }
557 AddDependencies(deps, master_dofs, slave_dofs, I);
566 for (
int i = 0; i < ndofs; i++)
568 if (!deps.
RowSize(i)) { n_true_dofs++; }
572 if (n_true_dofs == ndofs)
581 int *cR_I =
new int[n_true_dofs+1];
582 double *cR_A =
new double[n_true_dofs];
583 cR_J =
new int[n_true_dofs];
584 for (
int i = 0; i < n_true_dofs; i++)
589 cR_I[n_true_dofs] = n_true_dofs;
590 cR =
new SparseMatrix(cR_I, cR_J, cR_A, n_true_dofs, ndofs);
600 for (
int i = 0, true_dof = 0; i < ndofs; i++)
605 cP->Add(i, true_dof++, 1.0);
618 int n_finalized = n_true_dofs;
624 for (
int dof = 0; dof < ndofs; dof++)
626 if (!finalized[dof] && DofFinalizable(dof, finalized, deps))
632 for (
int j = 0; j < n_dep; j++)
634 cP->GetRow(dep_col[j], cols, srow);
636 cP->AddRow(dof, cols, srow);
639 finalized[dof] =
true;
649 if (n_finalized != ndofs)
651 MFEM_ABORT(
"Error creating cP matrix.");
665 if (vdim == 1) {
return; }
667 int height = mat.
Height();
668 int width = mat.
Width();
674 for (
int i = 0; i < height; i++)
676 mat.
GetRow(i, dofs, srow);
677 for (
int vd = 0; vd < vdim; vd++)
680 DofsToVDofs(vd, vdofs, width);
681 vmat->
SetRow(DofToVDof(i, vd, height), vdofs, srow);
692 if (Conforming()) {
return NULL; }
693 if (!cP_is_set) { GetConformingInterpolation(); }
699 if (Conforming()) {
return NULL; }
700 if (!cP_is_set) { GetConformingInterpolation(); }
704 int FiniteElementSpace::GetNConformingDofs()
707 return P ? (P->
Width() / vdim) : ndofs;
711 const Table* old_elem_dof)
713 MFEM_VERIFY(mesh->GetLastOperation() == Mesh::REFINE,
"");
714 MFEM_VERIFY(ndofs >= old_ndofs,
"Previous space is not coarser.");
721 int geom = mesh->GetElementBaseGeometry();
722 const FiniteElement *fe = fec->FiniteElementForGeometry(geom);
732 for (
int i = 0; i < nmat; i++)
742 for (
int k = 0; k < mesh->GetNE(); k++)
747 elem_dof->GetRow(k, dofs);
750 for (
int vd = 0; vd < vdim; vd++)
752 old_dofs.
Copy(old_vdofs);
753 DofsToVDofs(vd, old_vdofs, old_ndofs);
755 for (
int i = 0; i < ldof; i++)
757 int r = DofToVDof(dofs[i], vd);
758 int m = (r >= 0) ? r : (-1 - r);
763 P->
SetRow(r, old_vdofs, row);
770 MFEM_ASSERT(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
791 void FiniteElementSpace::GetLocalDerefinementMatrices(
794 const FiniteElement *fe = fec->FiniteElementForGeometry(geom);
803 int dim = mesh->Dimension();
807 Vector pt(&ipt.
x, dim), shape(ldof);
810 localR.
SetSize(ldof, ldof, nmat);
811 for (
int i = 0; i < nmat; i++)
814 lR = numeric_limits<double>::infinity();
820 for (
int j = 0; j < nodes.
Size(); j++)
828 MFEM_ASSERT(dynamic_cast<const NodalFiniteElement*>(fe),
829 "only nodal FEs are implemented");
837 const Table* old_elem_dof)
839 MFEM_VERIFY(Nonconforming(),
"Not implemented for conforming meshes.");
840 MFEM_VERIFY(old_ndofs,
"Missing previous (finer) space.");
841 MFEM_VERIFY(ndofs <= old_ndofs,
"Previous space is not finer.");
847 mesh->ncmesh->GetDerefinementTransforms();
849 int geom = mesh->ncmesh->GetElementGeometry();
850 int ldof = fec->FiniteElementForGeometry(geom)->GetDof();
853 GetLocalDerefinementMatrices(geom, dtrans, localR);
859 for (
int k = 0; k < dtrans.
embeddings.Size(); k++)
864 elem_dof->GetRow(emb.
parent, dofs);
865 old_elem_dof->
GetRow(k, old_dofs);
867 for (
int vd = 0; vd < vdim; vd++)
869 old_dofs.
Copy(old_vdofs);
870 DofsToVDofs(vd, old_vdofs, old_ndofs);
872 for (
int i = 0; i < lR.
Height(); i++)
874 if (lR(i, 0) == numeric_limits<double>::infinity()) {
continue; }
876 int r = DofToVDof(dofs[i], vd);
877 int m = (r >= 0) ? r : (-1 - r);
882 R->
SetRow(r, old_vdofs, row);
889 MFEM_ASSERT(mark.
Sum() == R->
Height(),
"Not all rows of R set.");
893 FiniteElementSpace::FiniteElementSpace(
Mesh *mesh,
895 int vdim,
int ordering)
911 mfem_error(
"FiniteElementSpace::FiniteElementSpace :\n"
912 " NURBS FE space requires NURBS mesh.");
941 BuildElementToDofTable();
946 if (NURBSext && !own_ext)
948 mfem_error(
"FiniteElementSpace::StealNURBSext");
955 void FiniteElementSpace::UpdateNURBS()
966 ndofs = NURBSext->GetNDof();
967 elem_dof = NURBSext->GetElementDofTable();
968 bdrElem_dof = NURBSext->GetBdrElementDofTable();
971 void FiniteElementSpace::Construct()
980 if ( mesh->Dimension() > 1 )
982 nedofs = mesh->GetNEdges() * fec->DofForGeometry(Geometry::SEGMENT);
1000 if (mesh->Dimension() == 3 && mesh->GetNE())
1007 int fdof = fec->DofForGeometry(mesh->GetFaceBaseGeometry(0));
1010 fdofs =
new int[mesh->GetNFaces()+1];
1012 for (i = 0; i < mesh->GetNFaces(); i++)
1016 fdofs[i+1] = nfdofs;
1021 bdofs =
new int[mesh->GetNE()+1];
1023 for (i = 0; i < mesh->GetNE(); i++)
1025 nbdofs += fec->DofForGeometry(mesh->GetElementBaseGeometry(i));
1026 bdofs[i+1] = nbdofs;
1029 ndofs = nvdofs + nedofs + nfdofs + nbdofs;
1035 void FiniteElementSpace::GetElementDofs (
int i,
Array<int> &dofs)
const
1039 elem_dof -> GetRow (i, dofs);
1044 int k, j, nv, ne, nf, nb, nfd, nd;
1047 dim = mesh->Dimension();
1048 nv = fec->DofForGeometry(Geometry::POINT);
1049 ne = (dim > 1) ? ( fec->DofForGeometry(Geometry::SEGMENT) ) : ( 0 );
1050 nb = fec->DofForGeometry(mesh->GetElementBaseGeometry(i));
1053 mesh->GetElementVertices(i, V);
1057 mesh->GetElementEdges(i, E, Eo);
1062 if (fec->HasFaceDofs(mesh->GetElementBaseGeometry(i)))
1064 mesh->GetElementFaces(i, F, Fo);
1065 for (k = 0; k < F.
Size(); k++)
1067 nfd += fec->DofForGeometry(mesh->GetFaceBaseGeometry(F[k]));
1071 nd = V.
Size() * nv + E.
Size() * ne + nfd + nb;
1075 for (k = 0; k < V.
Size(); k++)
1077 for (j = 0; j < nv; j++)
1079 dofs[k*nv+j] = V[k]*nv+j;
1087 for (k = 0; k < E.
Size(); k++)
1089 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1090 for (j = 0; j < ne; j++)
1094 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1098 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1103 ne = nv + ne * E.
Size();
1107 for (k = 0; k < F.
Size(); k++)
1109 ind = fec->DofOrderForOrientation(mesh->GetFaceBaseGeometry(F[k]),
1111 nf = fec->DofForGeometry(mesh->GetFaceBaseGeometry(F[k]));
1112 for (j = 0; j < nf; j++)
1116 dofs[ne+j] = -1 - ( nvdofs+nedofs+fdofs[F[k]]+(-1-ind[j]) );
1120 dofs[ne+j] = nvdofs+nedofs+fdofs[F[k]]+ind[j];
1126 k = nvdofs + nedofs + nfdofs + bdofs[i];
1127 for (j = 0; j < nb; j++)
1137 fec->FiniteElementForGeometry(mesh->GetElementBaseGeometry(i));
1141 NURBSext->LoadFE(i, FE);
1147 void FiniteElementSpace::GetBdrElementDofs(
int i,
Array<int> &dofs)
const
1151 bdrElem_dof->GetRow(i, dofs);
1156 int k, j, nv, ne, nf, nd, iF, oF;
1159 dim = mesh->Dimension();
1160 nv = fec->DofForGeometry(Geometry::POINT);
1163 mesh->GetBdrElementVertices(i, V);
1165 ne = (dim > 1) ? ( fec->DofForGeometry(Geometry::SEGMENT) ) : ( 0 );
1168 mesh->GetBdrElementEdges(i, E, Eo);
1170 nd = V.
Size() * nv + E.
Size() * ne;
1171 nf = (dim == 3) ? (fec->DofForGeometry(
1172 mesh->GetBdrElementBaseGeometry(i))) : (0);
1176 mesh->GetBdrElementFace(i, &iF, &oF);
1181 for (k = 0; k < V.
Size(); k++)
1183 for (j = 0; j < nv; j++)
1185 dofs[k*nv+j] = V[k]*nv+j;
1193 for (k = 0; k < E.
Size(); k++)
1195 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1196 for (j = 0; j < ne; j++)
1200 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1204 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1212 ne = nv + ne * E.
Size();
1213 ind = (fec->DofOrderForOrientation(
1214 mesh->GetBdrElementBaseGeometry(i), oF));
1215 for (j = 0; j < nf; j++)
1219 dofs[ne+j] = -1 - ( nvdofs+nedofs+fdofs[iF]+(-1-ind[j]) );
1223 dofs[ne+j] = nvdofs+nedofs+fdofs[iF]+ind[j];
1230 void FiniteElementSpace::GetFaceDofs(
int i,
Array<int> &dofs)
const
1232 int j, k, nv, ne, nf, nd,
dim = mesh->Dimension();
1237 nv = fec->DofForGeometry(Geometry::POINT);
1238 ne = (dim > 1) ? fec->DofForGeometry(Geometry::SEGMENT) : 0;
1241 mesh->GetFaceVertices(i, V);
1245 mesh->GetFaceEdges(i, E, Eo);
1247 nf = (fdofs) ? (fdofs[i+1]-fdofs[i]) : (0);
1248 nd = V.
Size() * nv + E.
Size() * ne + nf;
1252 for (k = 0; k < V.
Size(); k++)
1254 for (j = 0; j < nv; j++)
1256 dofs[k*nv+j] = V[k]*nv+j;
1263 for (k = 0; k < E.
Size(); k++)
1265 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1266 for (j = 0; j < ne; j++)
1270 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1274 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1279 ne = nv + ne * E.
Size();
1282 for (j = nvdofs+nedofs+fdofs[i], k = 0; k < nf; j++, k++)
1289 void FiniteElementSpace::GetEdgeDofs(
int i,
Array<int> &dofs)
const
1294 nv = fec->DofForGeometry(Geometry::POINT);
1297 mesh->GetEdgeVertices(i, V);
1299 ne = fec->DofForGeometry(Geometry::SEGMENT);
1303 for (k = 0; k < 2; k++)
1305 for (j = 0; j < nv; j++)
1307 dofs[k*nv+j] = V[k]*nv+j;
1312 for (j = 0, k = nvdofs+i*ne; j < ne; j++, k++)
1318 void FiniteElementSpace::GetVertexDofs(
int i,
Array<int> &dofs)
const
1322 nv = fec->DofForGeometry(Geometry::POINT);
1324 for (j = 0; j < nv; j++)
1330 void FiniteElementSpace::GetElementInteriorDofs (
int i,
Array<int> &dofs)
const
1333 nb = fec -> DofForGeometry (mesh -> GetElementBaseGeometry (i));
1335 k = nvdofs + nedofs + nfdofs + bdofs[i];
1336 for (j = 0; j < nb; j++)
1342 void FiniteElementSpace::GetEdgeInteriorDofs (
int i,
Array<int> &dofs)
const
1346 ne = fec -> DofForGeometry (Geometry::SEGMENT);
1348 for (j = 0, k = nvdofs+i*ne; j < ne; j++, k++)
1354 void FiniteElementSpace::GetFaceInteriorDofs (
int i,
Array<int> &dofs)
const
1358 nf = (fdofs) ? (fdofs[i+1]-fdofs[i]) : (0);
1362 for (j = 0, k = nvdofs+nedofs+fdofs[i]; j < nf; j++, k++)
1373 switch ( mesh->Dimension() )
1376 BE = fec->FiniteElementForGeometry(Geometry::POINT);
1379 BE = fec->FiniteElementForGeometry(Geometry::SEGMENT);
1383 BE = fec->FiniteElementForGeometry(
1384 mesh->GetBdrElementBaseGeometry(i));
1389 NURBSext->LoadBE(i, BE);
1399 switch (mesh->Dimension())
1402 fe = fec->FiniteElementForGeometry(Geometry::POINT);
1405 fe = fec->FiniteElementForGeometry(Geometry::SEGMENT);
1409 fe = fec->FiniteElementForGeometry(mesh->GetFaceBaseGeometry(i));
1420 return fec->FiniteElementForGeometry(Geometry::SEGMENT);
1424 int i,
int geom_type)
const
1426 return fec->TraceFiniteElementForGeometry(geom_type);
1429 FiniteElementSpace::~FiniteElementSpace()
1434 void FiniteElementSpace::Destroy()
1438 if (own_T) {
delete T; }
1440 dof_elem_array.DeleteAll();
1441 dof_ldof_array.DeleteAll();
1445 if (own_ext) {
delete NURBSext; }
1459 if (mesh->GetSequence() == sequence)
1463 if (want_transform && mesh->GetSequence() != sequence + 1)
1465 MFEM_ABORT(
"Error in update sequence. Space needs to be updated after "
1466 "each mesh modification.");
1468 sequence = mesh->GetSequence();
1476 Table* old_elem_dof= NULL;
1482 old_elem_dof = elem_dof;
1489 BuildElementToDofTable();
1494 switch (mesh->GetLastOperation())
1498 T = RefinementMatrix(old_ndofs, old_elem_dof);
1502 case Mesh::DEREFINE:
1504 GetConformingInterpolation();
1505 T = DerefinementMatrix(old_ndofs, old_elem_dof);
1518 delete old_elem_dof;
1521 void FiniteElementSpace::Save(std::ostream &out)
const
1523 out <<
"FiniteElementSpace\n"
1524 <<
"FiniteElementCollection: " << fec->Name() <<
'\n'
1525 <<
"VDim: " << vdim <<
'\n'
1526 <<
"Ordering: " << ordering <<
'\n';
1530 void QuadratureSpace::Construct()
1534 const int num_elem = mesh->GetNE();
1535 element_offsets =
new int[num_elem + 1];
1536 for (
int g = 0; g < Geometry::NumGeom; g++)
1540 for (
int i = 0; i < num_elem; i++)
1542 element_offsets[i] = offset;
1543 int geom = mesh->GetElementBaseGeometry(i);
1544 if (int_rule[geom] == NULL)
1550 element_offsets[num_elem] = size = offset;
1553 QuadratureSpace::QuadratureSpace(
Mesh *mesh_, std::istream &in)
1556 const char *msg =
"invalid input stream";
1559 in >> ident; MFEM_VERIFY(ident ==
"QuadratureSpace", msg);
1560 in >> ident; MFEM_VERIFY(ident ==
"Type:", msg);
1562 if (ident ==
"default_quadrature")
1564 in >> ident; MFEM_VERIFY(ident ==
"Order:", msg);
1569 MFEM_ABORT(
"unknown QuadratureSpace type: " << ident);
1578 out <<
"QuadratureSpace\n"
1579 <<
"Type: default_quadrature\n"
1580 <<
"Order: " <<
order <<
'\n';
int GetNPoints() const
Returns the number of the points in the integration rule.
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 an integration rule - an Array of IntegrationPoint.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
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
Extract all column indices and values from a given row.
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
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
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)
int slaves_end
slave faces
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
int GetGeomType() const
Returns the Geometry::Type of the reference element.
void Set3(const double x1, const double x2, const double x3)
std::vector< Slave > slaves
int GetDof() const
Returns the number of degrees of freedom in the finite element.
void mfem_error(const char *msg)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void Save(std::ostream &out) const
Write the QuadratureSpace to the stream out.
void Update(Vector &x, int k, DenseMatrix &h, Vector &s, Array< Vector * > &v)
NURBSExtension * NURBSext
Optional NURBS mesh extension.
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)
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Linear1DFiniteElement SegmentFE
Defines the position of a fine element within a coarse element.
int matrix
index into CoarseFineTransformations::point_matrices