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,
267 for (
int i = 0; i < GetNBE(); i++)
269 if (bdr_attr_is_ess[GetBdrAttribute(i)-1])
274 GetBdrElementVDofs(i, vdofs);
275 mark_dofs(vdofs, ess_vdofs);
279 GetBdrElementDofs(i, dofs);
280 for (
int d = 0; d < dofs.
Size(); d++)
281 { dofs[d] = DofToVDof(dofs[d], component); }
282 mark_dofs(dofs, ess_vdofs);
292 mesh->ncmesh->GetBoundaryClosure(bdr_attr_is_ess, bdr_verts, bdr_edges);
294 for (
int i = 0; i < bdr_verts.
Size(); i++)
298 GetVertexVDofs(bdr_verts[i], vdofs);
299 mark_dofs(vdofs, ess_vdofs);
303 GetVertexDofs(bdr_verts[i], dofs);
304 for (
int d = 0; d < dofs.
Size(); d++)
305 { dofs[d] = DofToVDof(dofs[d], component); }
306 mark_dofs(dofs, ess_vdofs);
309 for (
int i = 0; i < bdr_edges.
Size(); i++)
313 GetEdgeVDofs(bdr_edges[i], vdofs);
314 mark_dofs(vdofs, ess_vdofs);
318 GetEdgeDofs(bdr_edges[i], dofs);
319 for (
int d = 0; d < dofs.
Size(); d++)
320 { dofs[d] = DofToVDof(dofs[d], component); }
321 mark_dofs(dofs, ess_vdofs);
327 void FiniteElementSpace::GetEssentialTrueDofs(
const Array<int> &bdr_attr_is_ess,
332 GetEssentialVDofs(bdr_attr_is_ess, ess_vdofs, component);
342 MarkerToList(ess_tdofs, ess_tdof_list);
346 void FiniteElementSpace::MarkerToList(
const Array<int> &marker,
350 for (
int i = 0; i < marker.
Size(); i++)
352 if (marker[i]) { num_marked++; }
356 for (
int i = 0; i < marker.
Size(); i++)
358 if (marker[i]) { list.
Append(i); }
363 void FiniteElementSpace::ListToMarker(
const Array<int> &list,
int marker_size,
368 for (
int i = 0; i < list.
Size(); i++)
370 marker[list[i]] = mark_val;
374 void FiniteElementSpace::ConvertToConformingVDofs(
const Array<int> &dofs,
377 GetConformingProlongation();
378 if (cP) { cP->BooleanMultTranspose(dofs, cdofs); }
379 else { dofs.
Copy(cdofs); }
382 void FiniteElementSpace::ConvertFromConformingVDofs(
const Array<int> &cdofs,
385 GetConformingRestriction();
386 if (cR) { cR->BooleanMultTranspose(cdofs, dofs); }
387 else { cdofs.
Copy(dofs); }
399 for (i = 0; i < mesh -> GetNE(); i++)
401 this -> GetElementVDofs (i, d_vdofs);
402 cfes -> GetElementVDofs (i, c_vdofs);
405 if (d_vdofs.
Size() != c_vdofs.
Size())
407 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
411 for (j = 0; j < d_vdofs.
Size(); j++)
413 R -> Set (c_vdofs[j], d_vdofs[j], 1.0);
431 for (i = 0; i < mesh -> GetNE(); i++)
433 this -> GetElementDofs (i, d_dofs);
434 cfes -> GetElementDofs (i, c_dofs);
437 if (c_dofs.
Size() != 1)
439 "D2Const_GlobalRestrictionMatrix (...)");
442 for (j = 0; j < d_dofs.
Size(); j++)
444 R -> Set (c_dofs[0], d_dofs[j], 1.0);
472 h_fe->
Project(*l_fe, T, loc_restr);
474 for (
int i = 0; i < mesh -> GetNE(); i++)
476 this -> GetElementDofs (i, h_dofs);
477 lfes -> GetElementDofs (i, l_dofs);
479 R -> SetSubMatrix (l_dofs, h_dofs, loc_restr, 1);
490 for (
int i = 0; i < slave_dofs.
Size(); i++)
492 int sdof = slave_dofs[i];
495 for (
int j = 0; j < master_dofs.
Size(); j++)
497 double coef = I(i, j);
498 if (std::abs(coef) > 1e-12)
500 int mdof = master_dofs[j];
501 if (mdof != sdof && mdof != (-1-sdof))
503 deps.
Add(sdof, mdof, coef);
511 static bool DofFinalizable(
int dof,
const Array<bool>& finalized,
512 const SparseMatrix& deps)
514 const int* dep = deps.GetRowColumns(dof);
515 int ndep = deps.RowSize(dof);
518 for (
int i = 0; i < ndep; i++)
520 if (!finalized[dep[i]]) {
return false; }
528 void FiniteElementSpace::GetEdgeFaceDofs(
int type,
int index,
Array<int> &dofs)
534 if (index < mesh->GetNFaces()) { GetFaceDofs(index, dofs); }
538 if (index < mesh->GetNEdges()) { GetEdgeDofs(index, dofs); }
542 void FiniteElementSpace::GetConformingInterpolation()
const
545 MFEM_VERIFY(dynamic_cast<const ParFiniteElementSpace*>(
this) == NULL,
546 "This method should not be used with a ParFiniteElementSpace!");
548 if (cP_is_set) {
return; }
557 for (
int type = 0; type <= 1; type++)
560 : mesh->ncmesh->GetEdgeList();
561 if (!list.
masters.size()) {
continue; }
567 int geom = type ? Geometry::SQUARE : Geometry::SEGMENT;
568 const FiniteElement* fe = fec->FiniteElementForGeometry(geom);
569 if (!fe) {
continue; }
575 for (
unsigned mi = 0; mi < list.
masters.size(); mi++)
578 GetEdgeFaceDofs(type, master.
index, master_dofs);
579 if (!master_dofs.
Size()) {
continue; }
584 GetEdgeFaceDofs(type, slave.
index, slave_dofs);
585 if (!slave_dofs.
Size()) {
continue; }
592 AddDependencies(deps, master_dofs, slave_dofs, I);
601 for (
int i = 0; i < ndofs; i++)
603 if (!deps.
RowSize(i)) { n_true_dofs++; }
607 if (n_true_dofs == ndofs)
616 int *cR_I =
new int[n_true_dofs+1];
617 double *cR_A =
new double[n_true_dofs];
618 cR_J =
new int[n_true_dofs];
619 for (
int i = 0; i < n_true_dofs; i++)
624 cR_I[n_true_dofs] = n_true_dofs;
625 cR =
new SparseMatrix(cR_I, cR_J, cR_A, n_true_dofs, ndofs);
635 for (
int i = 0, true_dof = 0; i < ndofs; i++)
640 cP->Add(i, true_dof++, 1.0);
653 int n_finalized = n_true_dofs;
659 for (
int dof = 0; dof < ndofs; dof++)
661 if (!finalized[dof] && DofFinalizable(dof, finalized, deps))
667 for (
int j = 0; j < n_dep; j++)
669 cP->GetRow(dep_col[j], cols, srow);
671 cP->AddRow(dof, cols, srow);
674 finalized[dof] =
true;
684 if (n_finalized != ndofs)
686 MFEM_ABORT(
"Error creating cP matrix.");
700 if (vdim == 1) {
return; }
702 int height = mat.
Height();
703 int width = mat.
Width();
709 for (
int i = 0; i < height; i++)
711 mat.
GetRow(i, dofs, srow);
712 for (
int vd = 0; vd < vdim; vd++)
715 DofsToVDofs(vd, vdofs, width);
716 vmat->
SetRow(DofToVDof(i, vd, height), vdofs, srow);
725 const SparseMatrix* FiniteElementSpace::GetConformingProlongation()
const
727 if (Conforming()) {
return NULL; }
728 if (!cP_is_set) { GetConformingInterpolation(); }
732 const SparseMatrix* FiniteElementSpace::GetConformingRestriction()
const
734 if (Conforming()) {
return NULL; }
735 if (!cP_is_set) { GetConformingInterpolation(); }
739 int FiniteElementSpace::GetNConformingDofs()
const
742 return P ? (P->
Width() / vdim) : ndofs;
746 const Table* old_elem_dof)
748 MFEM_VERIFY(mesh->GetLastOperation() == Mesh::REFINE,
"");
749 MFEM_VERIFY(ndofs >= old_ndofs,
"Previous space is not coarser.");
756 int geom = mesh->GetElementBaseGeometry();
757 const FiniteElement *fe = fec->FiniteElementForGeometry(geom);
767 for (
int i = 0; i < nmat; i++)
778 for (
int k = 0; k < mesh->GetNE(); k++)
783 elem_dof->GetRow(k, dofs);
786 for (
int vd = 0; vd < vdim; vd++)
788 old_dofs.
Copy(old_vdofs);
789 DofsToVDofs(vd, old_vdofs, old_ndofs);
791 for (
int i = 0; i < ldof; i++)
793 int r = DofToVDof(dofs[i], vd);
794 int m = (r >= 0) ? r : (-1 - r);
799 P->
SetRow(r, old_vdofs, row);
806 MFEM_ASSERT(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
827 void FiniteElementSpace::GetLocalDerefinementMatrices(
830 const FiniteElement *fe = fec->FiniteElementForGeometry(geom);
839 int dim = mesh->Dimension();
843 Vector pt(&ipt.
x, dim), shape(ldof);
846 localR.
SetSize(ldof, ldof, nmat);
847 for (
int i = 0; i < nmat; i++)
850 lR = numeric_limits<double>::infinity();
857 for (
int j = 0; j < nodes.
Size(); j++)
865 MFEM_ASSERT(dynamic_cast<const NodalFiniteElement*>(fe),
866 "only nodal FEs are implemented");
874 const Table* old_elem_dof)
876 MFEM_VERIFY(Nonconforming(),
"Not implemented for conforming meshes.");
877 MFEM_VERIFY(old_ndofs,
"Missing previous (finer) space.");
878 MFEM_VERIFY(ndofs <= old_ndofs,
"Previous space is not finer.");
884 mesh->ncmesh->GetDerefinementTransforms();
886 int geom = mesh->ncmesh->GetElementGeometry();
887 int ldof = fec->FiniteElementForGeometry(geom)->GetDof();
890 GetLocalDerefinementMatrices(geom, dtrans, localR);
896 for (
int k = 0; k < dtrans.
embeddings.Size(); k++)
901 elem_dof->GetRow(emb.
parent, dofs);
902 old_elem_dof->
GetRow(k, old_dofs);
904 for (
int vd = 0; vd < vdim; vd++)
906 old_dofs.
Copy(old_vdofs);
907 DofsToVDofs(vd, old_vdofs, old_ndofs);
909 for (
int i = 0; i < lR.
Height(); i++)
911 if (lR(i, 0) == numeric_limits<double>::infinity()) {
continue; }
913 int r = DofToVDof(dofs[i], vd);
914 int m = (r >= 0) ? r : (-1 - r);
919 R->
SetRow(r, old_vdofs, row);
926 MFEM_ASSERT(mark.
Sum() == R->
Height(),
"Not all rows of R set.");
930 FiniteElementSpace::FiniteElementSpace(
Mesh *mesh,
932 int vdim,
int ordering)
948 mfem_error(
"FiniteElementSpace::FiniteElementSpace :\n"
949 " NURBS FE space requires NURBS mesh.");
978 BuildElementToDofTable();
983 if (NURBSext && !own_ext)
985 mfem_error(
"FiniteElementSpace::StealNURBSext");
992 void FiniteElementSpace::UpdateNURBS()
1003 ndofs = NURBSext->GetNDof();
1004 elem_dof = NURBSext->GetElementDofTable();
1005 bdrElem_dof = NURBSext->GetBdrElementDofTable();
1008 void FiniteElementSpace::Construct()
1017 if ( mesh->Dimension() > 1 )
1019 nedofs = mesh->GetNEdges() * fec->DofForGeometry(Geometry::SEGMENT);
1037 if (mesh->Dimension() == 3 && mesh->GetNE())
1044 int fdof = fec->DofForGeometry(mesh->GetFaceBaseGeometry(0));
1047 fdofs =
new int[mesh->GetNFaces()+1];
1049 for (i = 0; i < mesh->GetNFaces(); i++)
1053 fdofs[i+1] = nfdofs;
1058 bdofs =
new int[mesh->GetNE()+1];
1060 for (i = 0; i < mesh->GetNE(); i++)
1062 nbdofs += fec->DofForGeometry(mesh->GetElementBaseGeometry(i));
1063 bdofs[i+1] = nbdofs;
1066 ndofs = nvdofs + nedofs + nfdofs + nbdofs;
1072 void FiniteElementSpace::GetElementDofs (
int i,
Array<int> &dofs)
const
1076 elem_dof -> GetRow (i, dofs);
1081 int k, j, nv, ne, nf, nb, nfd, nd;
1084 dim = mesh->Dimension();
1085 nv = fec->DofForGeometry(Geometry::POINT);
1086 ne = (dim > 1) ? ( fec->DofForGeometry(Geometry::SEGMENT) ) : ( 0 );
1087 nb = fec->DofForGeometry(mesh->GetElementBaseGeometry(i));
1090 mesh->GetElementVertices(i, V);
1094 mesh->GetElementEdges(i, E, Eo);
1099 if (fec->HasFaceDofs(mesh->GetElementBaseGeometry(i)))
1101 mesh->GetElementFaces(i, F, Fo);
1102 for (k = 0; k < F.
Size(); k++)
1104 nfd += fec->DofForGeometry(mesh->GetFaceBaseGeometry(F[k]));
1108 nd = V.
Size() * nv + E.
Size() * ne + nfd + nb;
1112 for (k = 0; k < V.
Size(); k++)
1114 for (j = 0; j < nv; j++)
1116 dofs[k*nv+j] = V[k]*nv+j;
1124 for (k = 0; k < E.
Size(); k++)
1126 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1127 for (j = 0; j < ne; j++)
1131 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1135 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1140 ne = nv + ne * E.
Size();
1144 for (k = 0; k < F.
Size(); k++)
1146 ind = fec->DofOrderForOrientation(mesh->GetFaceBaseGeometry(F[k]),
1148 nf = fec->DofForGeometry(mesh->GetFaceBaseGeometry(F[k]));
1149 for (j = 0; j < nf; j++)
1153 dofs[ne+j] = -1 - ( nvdofs+nedofs+fdofs[F[k]]+(-1-ind[j]) );
1157 dofs[ne+j] = nvdofs+nedofs+fdofs[F[k]]+ind[j];
1163 k = nvdofs + nedofs + nfdofs + bdofs[i];
1164 for (j = 0; j < nb; j++)
1174 fec->FiniteElementForGeometry(mesh->GetElementBaseGeometry(i));
1178 NURBSext->LoadFE(i, FE);
1184 void FiniteElementSpace::GetBdrElementDofs(
int i,
Array<int> &dofs)
const
1188 bdrElem_dof->GetRow(i, dofs);
1193 int k, j, nv, ne, nf, nd, iF, oF;
1196 dim = mesh->Dimension();
1197 nv = fec->DofForGeometry(Geometry::POINT);
1200 mesh->GetBdrElementVertices(i, V);
1202 ne = (dim > 1) ? ( fec->DofForGeometry(Geometry::SEGMENT) ) : ( 0 );
1205 mesh->GetBdrElementEdges(i, E, Eo);
1207 nd = V.
Size() * nv + E.
Size() * ne;
1208 nf = (dim == 3) ? (fec->DofForGeometry(
1209 mesh->GetBdrElementBaseGeometry(i))) : (0);
1213 mesh->GetBdrElementFace(i, &iF, &oF);
1218 for (k = 0; k < V.
Size(); k++)
1220 for (j = 0; j < nv; j++)
1222 dofs[k*nv+j] = V[k]*nv+j;
1230 for (k = 0; k < E.
Size(); k++)
1232 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1233 for (j = 0; j < ne; j++)
1237 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1241 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1249 ne = nv + ne * E.
Size();
1250 ind = (fec->DofOrderForOrientation(
1251 mesh->GetBdrElementBaseGeometry(i), oF));
1252 for (j = 0; j < nf; j++)
1256 dofs[ne+j] = -1 - ( nvdofs+nedofs+fdofs[iF]+(-1-ind[j]) );
1260 dofs[ne+j] = nvdofs+nedofs+fdofs[iF]+ind[j];
1267 void FiniteElementSpace::GetFaceDofs(
int i,
Array<int> &dofs)
const
1269 int j, k, nv, ne, nf, nd,
dim = mesh->Dimension();
1274 nv = fec->DofForGeometry(Geometry::POINT);
1275 ne = (dim > 1) ? fec->DofForGeometry(Geometry::SEGMENT) : 0;
1278 mesh->GetFaceVertices(i, V);
1282 mesh->GetFaceEdges(i, E, Eo);
1284 nf = (fdofs) ? (fdofs[i+1]-fdofs[i]) : (0);
1285 nd = V.
Size() * nv + E.
Size() * ne + nf;
1289 for (k = 0; k < V.
Size(); k++)
1291 for (j = 0; j < nv; j++)
1293 dofs[k*nv+j] = V[k]*nv+j;
1300 for (k = 0; k < E.
Size(); k++)
1302 ind = fec->DofOrderForOrientation(Geometry::SEGMENT, Eo[k]);
1303 for (j = 0; j < ne; j++)
1307 dofs[nv+k*ne+j] = -1 - ( nvdofs+E[k]*ne+(-1-ind[j]) );
1311 dofs[nv+k*ne+j] = nvdofs+E[k]*ne+ind[j];
1316 ne = nv + ne * E.
Size();
1319 for (j = nvdofs+nedofs+fdofs[i], k = 0; k < nf; j++, k++)
1326 void FiniteElementSpace::GetEdgeDofs(
int i,
Array<int> &dofs)
const
1331 nv = fec->DofForGeometry(Geometry::POINT);
1334 mesh->GetEdgeVertices(i, V);
1336 ne = fec->DofForGeometry(Geometry::SEGMENT);
1340 for (k = 0; k < 2; k++)
1342 for (j = 0; j < nv; j++)
1344 dofs[k*nv+j] = V[k]*nv+j;
1349 for (j = 0, k = nvdofs+i*ne; j < ne; j++, k++)
1355 void FiniteElementSpace::GetVertexDofs(
int i,
Array<int> &dofs)
const
1359 nv = fec->DofForGeometry(Geometry::POINT);
1361 for (j = 0; j < nv; j++)
1367 void FiniteElementSpace::GetElementInteriorDofs (
int i,
Array<int> &dofs)
const
1370 nb = fec -> DofForGeometry (mesh -> GetElementBaseGeometry (i));
1372 k = nvdofs + nedofs + nfdofs + bdofs[i];
1373 for (j = 0; j < nb; j++)
1379 void FiniteElementSpace::GetEdgeInteriorDofs (
int i,
Array<int> &dofs)
const
1383 ne = fec -> DofForGeometry (Geometry::SEGMENT);
1385 for (j = 0, k = nvdofs+i*ne; j < ne; j++, k++)
1391 void FiniteElementSpace::GetFaceInteriorDofs (
int i,
Array<int> &dofs)
const
1395 nf = (fdofs) ? (fdofs[i+1]-fdofs[i]) : (0);
1399 for (j = 0, k = nvdofs+nedofs+fdofs[i]; j < nf; j++, k++)
1410 switch ( mesh->Dimension() )
1413 BE = fec->FiniteElementForGeometry(Geometry::POINT);
1416 BE = fec->FiniteElementForGeometry(Geometry::SEGMENT);
1420 BE = fec->FiniteElementForGeometry(
1421 mesh->GetBdrElementBaseGeometry(i));
1426 NURBSext->LoadBE(i, BE);
1436 switch (mesh->Dimension())
1439 fe = fec->FiniteElementForGeometry(Geometry::POINT);
1442 fe = fec->FiniteElementForGeometry(Geometry::SEGMENT);
1446 fe = fec->FiniteElementForGeometry(mesh->GetFaceBaseGeometry(i));
1457 return fec->FiniteElementForGeometry(Geometry::SEGMENT);
1461 int i,
int geom_type)
const
1463 return fec->TraceFiniteElementForGeometry(geom_type);
1466 FiniteElementSpace::~FiniteElementSpace()
1471 void FiniteElementSpace::Destroy()
1475 if (own_T) {
delete T; }
1477 dof_elem_array.DeleteAll();
1478 dof_ldof_array.DeleteAll();
1482 if (own_ext) {
delete NURBSext; }
1496 if (mesh->GetSequence() == sequence)
1500 if (want_transform && mesh->GetSequence() != sequence + 1)
1502 MFEM_ABORT(
"Error in update sequence. Space needs to be updated after "
1503 "each mesh modification.");
1505 sequence = mesh->GetSequence();
1513 Table* old_elem_dof= NULL;
1519 old_elem_dof = elem_dof;
1526 BuildElementToDofTable();
1531 switch (mesh->GetLastOperation())
1535 T = RefinementMatrix(old_ndofs, old_elem_dof);
1539 case Mesh::DEREFINE:
1541 GetConformingInterpolation();
1542 T = DerefinementMatrix(old_ndofs, old_elem_dof);
1555 delete old_elem_dof;
1558 void FiniteElementSpace::Save(std::ostream &
out)
const
1560 out <<
"FiniteElementSpace\n"
1561 <<
"FiniteElementCollection: " << fec->Name() <<
'\n'
1562 <<
"VDim: " << vdim <<
'\n'
1563 <<
"Ordering: " << ordering <<
'\n';
1567 void QuadratureSpace::Construct()
1571 const int num_elem = mesh->GetNE();
1572 element_offsets =
new int[num_elem + 1];
1573 for (
int g = 0; g < Geometry::NumGeom; g++)
1577 for (
int i = 0; i < num_elem; i++)
1579 element_offsets[i] = offset;
1580 int geom = mesh->GetElementBaseGeometry(i);
1581 if (int_rule[geom] == NULL)
1587 element_offsets[num_elem] = size = offset;
1590 QuadratureSpace::QuadratureSpace(
Mesh *mesh_, std::istream &in)
1593 const char *msg =
"invalid input stream";
1596 in >> ident; MFEM_VERIFY(ident ==
"QuadratureSpace", msg);
1597 in >> ident; MFEM_VERIFY(ident ==
"Type:", msg);
1599 if (ident ==
"default_quadrature")
1601 in >> ident; MFEM_VERIFY(ident ==
"Order:", msg);
1606 MFEM_ABORT(
"unknown QuadratureSpace type: " << ident);
1615 out <<
"QuadratureSpace\n"
1616 <<
"Type: default_quadrature\n"
1617 <<
"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.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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