23 int FiniteElementSpace::GetOrder(
int i)
const
25 int GeomType = mesh->GetElementBaseGeometry(i);
26 return fec->FiniteElementForGeometry(GeomType)->GetOrder();
29 int FiniteElementSpace::GetFaceOrder(
int i)
const
31 int GeomType = mesh->GetFaceBaseGeometry(i);
32 return fec->FiniteElementForGeometry(GeomType)->GetOrder();
35 void FiniteElementSpace::DofsToVDofs (
Array<int> &dofs)
const
39 if (vdim == 1) {
return; }
46 case Ordering::byNODES:
47 for (i = 1; i < vdim; i++)
48 for (j = 0; j < size; j++)
51 dofs[size * i + j] = -1 - ( ndofs * i + (-1-dofs[j]) );
55 dofs[size * i + j] = ndofs * i + dofs[j];
59 case Ordering::byVDIM:
60 for (i = vdim-1; i >= 0; i--)
61 for (j = 0; j < size; j++)
64 dofs[size * i + j] = -1 - ( (-1-dofs[j]) * vdim + i );
68 dofs[size * i + j] = dofs[j] * vdim + i;
74 void FiniteElementSpace::DofsToVDofs(
int vd,
Array<int> &dofs,
int ndofs)
const
84 if (ordering == Ordering::byNODES)
86 for (
int i = 0; i < dofs.
Size(); i++)
91 dofs[i] = -1 - ((-1-dof) + vd * ndofs);
95 dofs[i] = dof + vd * ndofs;
101 for (
int i = 0; i < dofs.
Size(); i++)
106 dofs[i] = -1 - ((-1-dof) * vdim + vd);
110 dofs[i] = dof * vdim + vd;
116 int FiniteElementSpace::DofToVDof(
int dof,
int vd,
int ndofs)
const
126 if (ordering == Ordering::byNODES)
130 return -1 - ((-1-dof) + vd * ndofs);
134 return dof + vd * ndofs;
139 return -1 - ((-1-dof) * vdim + vd);
143 return dof * vdim + vd;
150 int n = vdofs.
Size(), *vdof = vdofs;
151 for (
int i = 0; i < n; i++)
154 if ((j = vdof[i]) < 0)
161 void FiniteElementSpace::GetElementVDofs(
int i,
Array<int> &vdofs)
const
163 GetElementDofs(i, vdofs);
167 void FiniteElementSpace::GetBdrElementVDofs(
int i,
Array<int> &vdofs)
const
169 GetBdrElementDofs(i, vdofs);
173 void FiniteElementSpace::GetFaceVDofs(
int i,
Array<int> &vdofs)
const
175 GetFaceDofs(i, vdofs);
179 void FiniteElementSpace::GetEdgeVDofs(
int i,
Array<int> &vdofs)
const
181 GetEdgeDofs(i, vdofs);
185 void FiniteElementSpace::GetVertexVDofs(
int i,
Array<int> &vdofs)
const
187 GetVertexDofs(i, vdofs);
191 void FiniteElementSpace::GetElementInteriorVDofs(
int i,
Array<int> &vdofs)
const
193 GetElementInteriorDofs(i, vdofs);
197 void FiniteElementSpace::GetEdgeInteriorVDofs(
int i,
Array<int> &vdofs)
const
199 GetEdgeInteriorDofs(i, vdofs);
203 void FiniteElementSpace::BuildElementToDofTable()
205 if (elem_dof) {
return; }
209 el_dof -> MakeI (mesh -> GetNE());
210 for (
int i = 0; i < mesh -> GetNE(); i++)
212 GetElementDofs (i, dofs);
213 el_dof -> AddColumnsInRow (i, dofs.
Size());
216 for (
int i = 0; i < mesh -> GetNE(); i++)
218 GetElementDofs (i, dofs);
219 el_dof -> AddConnections (i, (
int *)dofs, dofs.
Size());
221 el_dof -> ShiftUpI();
225 void FiniteElementSpace::BuildDofToArrays()
227 if (dof_elem_array.Size())
231 BuildElementToDofTable();
233 dof_elem_array.SetSize (ndofs);
234 dof_ldof_array.SetSize (ndofs);
236 for (
int i = 0; i < mesh -> GetNE(); i++)
238 const int *dofs = elem_dof -> GetRow(i);
239 const int n = elem_dof -> RowSize(i);
240 for (
int j = 0; j < n; j++)
241 if (dof_elem_array[dofs[j]] < 0)
243 dof_elem_array[dofs[j]] = i;
244 dof_ldof_array[dofs[j]] = j;
249 DenseMatrix * FiniteElementSpace::LocalInterpolation
255 for (i = 0; i < RefData.Size(); i++)
256 if (RefData[i] -> type == type)
260 { ConstructRefinementData (k,num_c_dofs,type); l = i; }
264 int num_fine_elems = RefData[l] -> num_fine_elems;
265 rows.
SetSize(RefData[l] -> num_fine_dofs);
267 for (i = 0; i < num_fine_elems; i++)
269 GetElementDofs(mesh->GetFineElem(k,i),g_dofs);
270 RefData[l] -> fl_to_fc -> GetRow (i, l_dofs);
271 for (j = 0; j < l_dofs.
Size(); j++)
273 rows[l_dofs[j]] = g_dofs[j];
277 return RefData[l] -> I;
292 for (
int d = 0; d < vdim; d++)
294 Array<int> rows_sub(rows.
GetData() + d*nr, nr);
295 Array<int> cols_sub(cols.
GetData() + d*nc, nc);
301 SparseMatrix * FiniteElementSpace::GlobalRestrictionMatrix
311 one_vdim = (ordering == Ordering::byNODES) ? 1 : 0;
316 MFEM_VERIFY(vdim == 1 || one_vdim == 0,
317 "parameter 'one_vdim' must be 0 for nonconforming mesh.");
318 return NC_GlobalRestrictionMatrix(cfes, mesh->ncmesh);
321 mesh->SetState(Mesh::TWO_LEVEL_COARSE);
322 int vdim_or_1 = (one_vdim ? 1 : vdim);
325 for (k = 0; k < mesh -> GetNE(); k++)
329 mesh->SetState(Mesh::TWO_LEVEL_FINE);
330 r = LocalInterpolation(k, rows.
Size(), mesh->GetRefinementType(k), cols);
337 SetVDofSubMatrixTranspose(*R, rows, cols, *r, vdim_or_1);
339 mesh->SetState(Mesh::TWO_LEVEL_COARSE);
345 SparseMatrix* FiniteElementSpace::NC_GlobalRestrictionMatrix
361 for (
int k = 0; k < mesh->GetNE(); k++)
363 mesh->SetState(Mesh::TWO_LEVEL_COARSE);
366 mesh->SetState(Mesh::TWO_LEVEL_FINE);
367 this->GetElementDofs(k, cols);
369 if (!transforms[k].IsIdentity())
371 int geom = mesh->GetElementBaseGeometry(k);
372 const FiniteElement *fe = fec->FiniteElementForGeometry(geom);
383 for (
int i = 0; i < I.Height(); i++)
386 if (col < 0) { col = -1 - col; }
395 this->DofsToVDofs(cols);
396 SetVDofSubMatrixTranspose(*R, rows, cols, I, vdim);
400 MFEM_ASSERT(rows.
Size() == cols.
Size(),
"");
401 for (
int i = 0; i < rows.
Size(); i++)
404 if (col < 0) { col = -1 - col; }
408 for (
int vd = 0; vd < vdim; vd++)
411 this->DofToVDof(cols[i], vd), 1.0);
418 delete [] transforms;
424 for (
int i = 0; i < dofs.
Size(); i++)
427 if (k < 0) { k = -1 - k; }
432 void FiniteElementSpace::GetEssentialVDofs(
const Array<int> &bdr_attr_is_ess,
440 for (
int i = 0; i < GetNBE(); i++)
442 if (bdr_attr_is_ess[GetBdrAttribute(i)-1])
444 GetBdrElementVDofs(i, vdofs);
445 mark_dofs(vdofs, ess_vdofs);
454 mesh->ncmesh->GetBoundaryClosure(bdr_attr_is_ess, bdr_verts, bdr_edges);
456 for (
int i = 0; i < bdr_verts.
Size(); i++)
458 GetVertexVDofs(bdr_verts[i], vdofs);
459 mark_dofs(vdofs, ess_vdofs);
461 for (
int i = 0; i < bdr_edges.
Size(); i++)
463 GetEdgeVDofs(bdr_edges[i], vdofs);
464 mark_dofs(vdofs, ess_vdofs);
469 void FiniteElementSpace::GetEssentialTrueDofs(
const Array<int> &bdr_attr_is_ess,
473 GetEssentialVDofs(bdr_attr_is_ess, ess_vdofs);
483 MarkerToList(ess_tdofs, ess_tdof_list);
487 void FiniteElementSpace::MarkerToList(
const Array<int> &marker,
491 for (
int i = 0; i < marker.
Size(); i++)
493 if (marker[i]) { num_marked++; }
497 for (
int i = 0; i < marker.
Size(); i++)
499 if (marker[i]) { list.
Append(i); }
504 void FiniteElementSpace::ListToMarker(
const Array<int> &list,
int marker_size,
509 for (
int i = 0; i < list.
Size(); i++)
511 marker[list[i]] = mark_val;
515 void FiniteElementSpace::ConvertToConformingVDofs(
const Array<int> &dofs,
518 GetConformingProlongation();
519 if (cP) { cP->BooleanMultTranspose(dofs, cdofs); }
520 else { dofs.
Copy(cdofs); }
523 void FiniteElementSpace::ConvertFromConformingVDofs(
const Array<int> &cdofs,
526 GetConformingRestriction();
527 if (cR) { cR->BooleanMultTranspose(cdofs, dofs); }
528 else { cdofs.
Copy(dofs); }
531 void FiniteElementSpace::EliminateEssentialBCFromGRM
534 int i, j, k, one_vdim;
537 one_vdim = (cfes -> GetNDofs() == R -> Height()) ? 1 : 0;
539 mesh -> SetState (Mesh::TWO_LEVEL_COARSE);
540 if (bdr_attr_is_ess.
Size() != 0)
542 for (i = 0; i < cfes -> GetNBE(); i++)
544 if (bdr_attr_is_ess[cfes -> GetBdrAttribute (i)-1])
548 cfes -> GetBdrElementDofs (i, dofs);
552 cfes -> GetBdrElementVDofs (i, dofs);
554 for (j = 0; j < dofs.
Size(); j++)
556 if ( (k = dofs[j]) >= 0 )
558 R -> EliminateRow(k);
562 R -> EliminateRow(-1-k);
571 SparseMatrix * FiniteElementSpace::GlobalRestrictionMatrix
576 R = GlobalRestrictionMatrix (cfes, one_vdim);
577 EliminateEssentialBCFromGRM (cfes, bdr_attr_is_ess, R);
591 for (i = 0; i < mesh -> GetNE(); i++)
593 this -> GetElementVDofs (i, d_vdofs);
594 cfes -> GetElementVDofs (i, c_vdofs);
597 if (d_vdofs.
Size() != c_vdofs.
Size())
599 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
603 for (j = 0; j < d_vdofs.
Size(); j++)
605 R -> Set (c_vdofs[j], d_vdofs[j], 1.0);
623 for (i = 0; i < mesh -> GetNE(); i++)
625 this -> GetElementDofs (i, d_dofs);
626 cfes -> GetElementDofs (i, c_dofs);
629 if (c_dofs.
Size() != 1)
631 "D2Const_GlobalRestrictionMatrix (...)");
634 for (j = 0; j < d_dofs.
Size(); j++)
636 R -> Set (c_dofs[0], d_dofs[j], 1.0);
664 h_fe->
Project(*l_fe, T, loc_restr);
666 for (
int i = 0; i < mesh -> GetNE(); i++)
668 this -> GetElementDofs (i, h_dofs);
669 lfes -> GetElementDofs (i, l_dofs);
671 R -> SetSubMatrix (l_dofs, h_dofs, loc_restr, 1);
682 for (
int i = 0; i < slave_dofs.
Size(); i++)
684 int sdof = slave_dofs[i];
687 for (
int j = 0; j < master_dofs.
Size(); j++)
689 double coef = I(i, j);
690 if (std::abs(coef) > 1e-12)
692 int mdof = master_dofs[j];
693 if (mdof != sdof && mdof != (-1-sdof))
695 deps.
Add(sdof, mdof, coef);
703 static bool DofFinalizable(
int dof,
const Array<bool>& finalized,
704 const SparseMatrix& deps)
706 const int* dep = deps.GetRowColumns(dof);
707 int ndep = deps.RowSize(dof);
710 for (
int i = 0; i < ndep; i++)
712 if (!finalized[dep[i]]) {
return false; }
720 void FiniteElementSpace::GetEdgeFaceDofs(
int type,
int index,
Array<int> &dofs)
725 if (index < mesh->GetNFaces()) { GetFaceDofs(index, dofs); }
729 if (index < mesh->GetNEdges()) { GetEdgeDofs(index, dofs); }
733 void FiniteElementSpace::GetConformingInterpolation()
736 MFEM_VERIFY(dynamic_cast<ParFiniteElementSpace*>(
this) == NULL,
737 "This method should not be used with a ParFiniteElementSpace!");
745 for (
int type = 0; type <= 1; type++)
748 : mesh->ncmesh->GetEdgeList();
749 if (!list.
masters.size()) {
continue; }
755 int geom = type ? Geometry::SQUARE : Geometry::SEGMENT;
756 const FiniteElement* fe = fec->FiniteElementForGeometry(geom);
757 if (!fe) {
continue; }
763 for (
unsigned mi = 0; mi < list.
masters.size(); mi++)
766 GetEdgeFaceDofs(type, master.
index, master_dofs);
767 if (!master_dofs.
Size()) {
continue; }
772 GetEdgeFaceDofs(type, slave.
index, slave_dofs);
773 if (!slave_dofs.
Size()) {
continue; }
779 AddDependencies(deps, master_dofs, slave_dofs, I);
788 for (
int i = 0; i < ndofs; i++)
790 if (!deps.
RowSize(i)) { n_true_dofs++; }
794 if (n_true_dofs == ndofs)
803 int *cR_I =
new int[n_true_dofs+1];
804 double *cR_A =
new double[n_true_dofs];
805 cR_J =
new int[n_true_dofs];
806 for (
int i = 0; i < n_true_dofs; i++)
811 cR_I[n_true_dofs] = n_true_dofs;
812 cR =
new SparseMatrix(cR_I, cR_J, cR_A, n_true_dofs, ndofs);
822 for (
int i = 0, true_dof = 0; i < ndofs; i++)
827 cP->Add(i, true_dof++, 1.0);
840 int n_finalized = n_true_dofs;
846 for (
int dof = 0; dof < ndofs; dof++)
848 if (!finalized[dof] && DofFinalizable(dof, finalized, deps))
854 for (
int j = 0; j < n_dep; j++)
856 cP->GetRow(dep_col[j], cols, srow);
858 cP->AddRow(dof, cols, srow);
861 finalized[dof] =
true;
871 if (n_finalized != ndofs)
873 MFEM_ABORT(
"Error creating cP matrix.");
887 if (vdim == 1) {
return; }
889 int height = mat.
Height();
890 int width = mat.
Width();
896 for (
int i = 0; i < height; i++)
898 mat.
GetRow(i, dofs, srow);
899 for (
int vd = 0; vd < vdim; vd++)
902 DofsToVDofs(vd, vdofs, width);
903 vmat->
SetRow(DofToVDof(i, vd, height), vdofs, srow);
914 if (Conforming()) {
return NULL; }
915 if (!cP) { GetConformingInterpolation(); }
921 if (Conforming()) {
return NULL; }
922 if (!cR) { GetConformingInterpolation(); }
926 int FiniteElementSpace::GetNConformingDofs()
929 return P ? (P->
Width() / vdim) : ndofs;
965 FiniteElementSpace::FiniteElementSpace(
Mesh *m,
967 int vdim,
int ordering)
972 this->ordering = ordering;
980 mfem_error(
"FiniteElementSpace::FiniteElementSpace :\n"
981 " NURBS FE space requires NURBS mesh.");
986 if (mesh->NURBSext->GetOrder() == Order)
988 NURBSext = mesh->NURBSext;
1010 if (NURBSext && !own_ext)
1012 mfem_error(
"FiniteElementSpace::StealNURBSext");
1019 void FiniteElementSpace::UpdateNURBS()
1030 ndofs = NURBSext->GetNDof();
1032 elem_dof = NURBSext->GetElementDofTable();
1034 bdrElem_dof = NURBSext->GetBdrElementDofTable();
1037 void FiniteElementSpace::Constructor()
1046 if ( mesh->Dimension() > 1 )
1048 nedofs = mesh->GetNEdges() * fec->DofForGeometry(Geometry::SEGMENT);
1068 if (mesh->Dimension() == 3)
1075 int fdof = fec->DofForGeometry(mesh->GetFaceBaseGeometry(0));
1078 fdofs =
new int[mesh->GetNFaces()+1];
1080 for (i = 0; i < mesh->GetNFaces(); i++)
1084 fdofs[i+1] = nfdofs;
1089 bdofs =
new int[mesh->GetNE()+1];
1091 for (i = 0; i < mesh->GetNE(); i++)
1093 nbdofs += fec->DofForGeometry(mesh->GetElementBaseGeometry(i));
1094 bdofs[i+1] = nbdofs;
1097 ndofs = nvdofs + nedofs + nfdofs + nbdofs;
1100 void FiniteElementSpace::GetElementDofs (
int i,
Array<int> &dofs)
const
1104 elem_dof -> GetRow (i, dofs);
1109 int k, j, nv, ne, nf, nb, nfd, nd;
1112 dim = mesh->Dimension();
1113 nv = fec->DofForGeometry(Geometry::POINT);
1114 ne = (dim > 1) ? ( fec->DofForGeometry(Geometry::SEGMENT) ) : ( 0 );
1115 nb = fec->DofForGeometry(mesh->GetElementBaseGeometry(i));
1118 mesh->GetElementVertices(i, V);
1122 mesh->GetElementEdges(i, E, Eo);
1127 if (fec->HasFaceDofs(mesh->GetElementBaseGeometry(i)))
1129 mesh->GetElementFaces(i, F, Fo);
1130 for (k = 0; k < F.
Size(); k++)
1132 nfd += fec->DofForGeometry(mesh->GetFaceBaseGeometry(F[k]));
1136 nd = V.
Size() * nv + E.
Size() * ne + nfd + nb;
1140 for (k = 0; k < V.
Size(); k++)
1142 for (j = 0; j < nv; j++)
1144 dofs[k*nv+j] = V[k]*nv+j;
1152 for (k = 0; k < E.
Size(); k++)
1154 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1155 for (j = 0; j < ne; j++)
1159 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1163 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1168 ne = nv + ne * E.
Size();
1172 for (k = 0; k < F.
Size(); k++)
1174 ind = fec->DofOrderForOrientation(mesh->GetFaceBaseGeometry(F[k]),
1176 nf = fec->DofForGeometry(mesh->GetFaceBaseGeometry(F[k]));
1177 for (j = 0; j < nf; j++)
1181 dofs[ne+j] = -1 - ( nvdofs+nedofs+fdofs[F[k]]+(-1-ind[j]) );
1185 dofs[ne+j] = nvdofs+nedofs+fdofs[F[k]]+ind[j];
1191 k = nvdofs + nedofs + nfdofs + bdofs[i];
1192 for (j = 0; j < nb; j++)
1202 fec->FiniteElementForGeometry(mesh->GetElementBaseGeometry(i));
1206 NURBSext->LoadFE(i, FE);
1212 void FiniteElementSpace::GetBdrElementDofs(
int i,
Array<int> &dofs)
const
1216 bdrElem_dof->GetRow(i, dofs);
1221 int k, j, nv, ne, nf, nd, iF, oF;
1224 dim = mesh->Dimension();
1225 nv = fec->DofForGeometry(Geometry::POINT);
1228 mesh->GetBdrElementVertices(i, V);
1230 ne = (dim > 1) ? ( fec->DofForGeometry(Geometry::SEGMENT) ) : ( 0 );
1233 mesh->GetBdrElementEdges(i, E, Eo);
1235 nd = V.
Size() * nv + E.
Size() * ne;
1236 nf = (dim == 3) ? (fec->DofForGeometry(
1237 mesh->GetBdrElementBaseGeometry(i))) : (0);
1241 mesh->GetBdrElementFace(i, &iF, &oF);
1246 for (k = 0; k < V.
Size(); k++)
1248 for (j = 0; j < nv; j++)
1250 dofs[k*nv+j] = V[k]*nv+j;
1258 for (k = 0; k < E.
Size(); k++)
1260 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1261 for (j = 0; j < ne; j++)
1265 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1269 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1277 ne = nv + ne * E.
Size();
1278 ind = (fec->DofOrderForOrientation(
1279 mesh->GetBdrElementBaseGeometry(i), oF));
1280 for (j = 0; j < nf; j++)
1284 dofs[ne+j] = -1 - ( nvdofs+nedofs+fdofs[iF]+(-1-ind[j]) );
1288 dofs[ne+j] = nvdofs+nedofs+fdofs[iF]+ind[j];
1295 void FiniteElementSpace::GetFaceDofs(
int i,
Array<int> &dofs)
const
1297 int j, k, nv, ne, nf, nd,
dim = mesh->Dimension();
1302 nv = fec->DofForGeometry(Geometry::POINT);
1303 ne = (dim > 1) ? fec->DofForGeometry(Geometry::SEGMENT) : 0;
1306 mesh->GetFaceVertices(i, V);
1310 mesh->GetFaceEdges(i, E, Eo);
1312 nf = (fdofs) ? (fdofs[i+1]-fdofs[i]) : (0);
1313 nd = V.
Size() * nv + E.
Size() * ne + nf;
1317 for (k = 0; k < V.
Size(); k++)
1319 for (j = 0; j < nv; j++)
1321 dofs[k*nv+j] = V[k]*nv+j;
1328 for (k = 0; k < E.
Size(); k++)
1330 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1331 for (j = 0; j < ne; j++)
1335 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1339 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1344 ne = nv + ne * E.
Size();
1347 for (j = nvdofs+nedofs+fdofs[i], k = 0; k < nf; j++, k++)
1354 void FiniteElementSpace::GetEdgeDofs(
int i,
Array<int> &dofs)
const
1359 nv = fec->DofForGeometry(Geometry::POINT);
1362 mesh->GetEdgeVertices(i, V);
1364 ne = fec->DofForGeometry(Geometry::SEGMENT);
1368 for (k = 0; k < 2; k++)
1370 for (j = 0; j < nv; j++)
1372 dofs[k*nv+j] = V[k]*nv+j;
1377 for (j = 0, k = nvdofs+i*ne; j < ne; j++, k++)
1383 void FiniteElementSpace::GetVertexDofs(
int i,
Array<int> &dofs)
const
1387 nv = fec->DofForGeometry(Geometry::POINT);
1389 for (j = 0; j < nv; j++)
1395 void FiniteElementSpace::GetElementInteriorDofs (
int i,
Array<int> &dofs)
const
1398 nb = fec -> DofForGeometry (mesh -> GetElementBaseGeometry (i));
1400 k = nvdofs + nedofs + nfdofs + bdofs[i];
1401 for (j = 0; j < nb; j++)
1407 void FiniteElementSpace::GetEdgeInteriorDofs (
int i,
Array<int> &dofs)
const
1411 ne = fec -> DofForGeometry (Geometry::SEGMENT);
1413 for (j = 0, k = nvdofs+i*ne; j < ne; j++, k++)
1423 switch ( mesh->Dimension() )
1426 BE = fec->FiniteElementForGeometry(Geometry::POINT);
1429 BE = fec->FiniteElementForGeometry(Geometry::SEGMENT);
1433 BE = fec->FiniteElementForGeometry(
1434 mesh->GetBdrElementBaseGeometry(i));
1439 NURBSext->LoadBE(i, BE);
1449 switch (mesh->Dimension())
1452 fe = fec->FiniteElementForGeometry(Geometry::POINT);
1455 fe = fec->FiniteElementForGeometry(Geometry::SEGMENT);
1459 fe = fec->FiniteElementForGeometry(mesh->GetFaceBaseGeometry(i));
1470 return fec->FiniteElementForGeometry(Geometry::SEGMENT);
1474 int i,
int geom_type)
const
1476 return fec->TraceFiniteElementForGeometry(geom_type);
1479 FiniteElementSpace::~FiniteElementSpace()
1483 for (
int i = 0; i < RefData.Size(); i++)
1489 void FiniteElementSpace::Destructor()
1494 dof_elem_array.DeleteAll();
1495 dof_ldof_array.DeleteAll();
1499 if (own_ext) {
delete NURBSext; }
1531 void FiniteElementSpace::UpdateAndInterpolate(
int num_grid_fns, ...)
1533 if (mesh->GetState() == Mesh::NORMAL)
1535 MFEM_ABORT(
"Mesh must be in two-level state, please call "
1536 "Mesh::UseTwoLevelState before refining.");
1548 va_start(vl, num_grid_fns);
1549 for (
int i = 0; i < num_grid_fns; i++)
1554 MFEM_ABORT(
"Cannot interpolate: grid function is not based "
1565 mesh->SetState(Mesh::TWO_LEVEL_FINE);
1568 void FiniteElementSpace::ConstructRefinementData (
int k,
int num_c_dofs,
1576 data -> type = type;
1577 data -> num_fine_elems = mesh -> GetNumFineElems(k);
1581 data -> fl_to_fc =
new Table(data -> num_fine_elems, num_c_dofs);
1582 for (i = 0; i < data -> num_fine_elems; i++)
1584 GetElementDofs(mesh -> GetFineElem(k,i), g_dofs);
1585 for (j = 0; j < g_dofs.
Size(); j++)
1587 data -> fl_to_fc -> Push (i,dofs.
Union(g_dofs[j]));
1590 data -> fl_to_fc -> Finalize();
1591 data -> num_fine_dofs = dofs.
Size();
1596 int geomtype = mesh->GetElementBaseGeometry(k);
1597 const FiniteElement *fe = fec -> FiniteElementForGeometry(geomtype);
1599 int nedofs = fe -> GetDof();
1608 data -> I =
new DenseMatrix(data -> num_fine_dofs, nedofs);
1610 for (i=0; i < data -> num_fine_elems; i++)
1613 trans = mesh -> GetFineElemTrans(k,i);
1615 fe -> GetLocalInterpolation (*trans, I);
1616 data -> fl_to_fc -> GetRow(i,row);
1618 for (j=0; j < nedofs; j++)
1625 for (l=0; l < nedofs; l++)
1627 (*(data->
I))(row[j],l) = I(j,l);
1632 RefData.Append(data);
1635 void FiniteElementSpace::Save(std::ostream &out)
const
1637 out <<
"FiniteElementSpace\n"
1638 <<
"FiniteElementCollection: " << fec->Name() <<
'\n'
1639 <<
"VDim: " << vdim <<
'\n'
1640 <<
"Ordering: " << ordering <<
'\n';
Abstract class for Finite Elements.
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
int Size() const
Logical size of the array.
int RowSize(const int i) const
Returns the number of elements in row i.
void Add(const int i, const int j, const double a)
int GetNDofs() const
Returns number of degrees of freedom.
int ndofs
Number of degrees of freedom. Number of unknowns are ndofs*vdim.
Class for grid function - Vector with associated FE space.
int DofToVDof(int dof, int vd, int ndofs=-1) const
FineTransform * GetFineTransforms()
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
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.
T * GetData()
Returns the data.
Piecewise-(bi)linear continuous finite elements.
Data type dense matrix using column-major storage.
int vdim
Vector dimension (number of unknowns per degree of freedom).
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
double * GetRowEntries(const int row)
Return a pointer to the entries in a row.
int RefinementType
Type of refinement (int, a tree, etc.)
const FiniteElementCollection * fec
Array< int > dof_elem_array
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 GetElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
Array< int > dof_ldof_array
virtual const FiniteElement * FiniteElementForGeometry(int GeomType) const
A class for non-conforming AMR on higher-order hexahedral, quadrilateral or triangular meshes...
FiniteElementSpace * FESpace()
virtual void Finalize(int skip_zeros=1)
int Union(const T &el)
Append element when it is not yet in the array, return index.
int slaves_end
slave faces
int GetGeomType() const
Returns the geometry type:
void Swap(Array< T > &, Array< T > &)
Data kept for every type of refinement.
std::vector< Slave > slaves
Abstract finite element space.
int GetDof() const
Returns the degrees of freedom in the FE space.
void SetSubMatrixTranspose(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void mfem_error(const char *msg)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void Set(const int i, const int j, const double a)
void Update(Vector &x, int k, DenseMatrix &h, Vector &s, Array< Vector * > &v)
Mesh * mesh
The mesh that FE space lives on.
void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
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 DofsToVDofs(Array< int > &dofs) const
NURBSExtension * NURBSext
void Swap(SparseMatrix &other)
virtual int DofForGeometry(int GeomType) const
BiLinear2DFiniteElement QuadrilateralFE
DenseMatrix * I
Local interpolation matrix.
Linear1DFiniteElement SegmentFE
DenseMatrix point_matrix
position within the master