14 #include "../general/text.hpp"
15 #include "../general/forall.hpp"
16 #include "../mesh/mesh_headers.hpp"
28 template <>
void Ordering::
29 DofsToVDofs<Ordering::byNODES>(
int ndofs,
int vdim,
Array<int> &dofs)
32 int size = dofs.Size();
33 dofs.SetSize(size*vdim);
34 for (
int vd = 1; vd < vdim; vd++)
36 for (
int i = 0; i < size; i++)
38 dofs[i+size*vd] = Map<byNODES>(ndofs, vdim, dofs[i], vd);
43 template <>
void Ordering::
44 DofsToVDofs<Ordering::byVDIM>(
int ndofs,
int vdim,
Array<int> &dofs)
47 int size = dofs.Size();
48 dofs.SetSize(size*vdim);
49 for (
int vd = vdim-1; vd >= 0; vd--)
51 for (
int i = 0; i < size; i++)
53 dofs[i+size*vd] = Map<byVDIM>(ndofs, vdim, dofs[i], vd);
59 FiniteElementSpace::FiniteElementSpace()
60 : mesh(NULL), fec(NULL), vdim(0), ordering(
Ordering::byNODES),
61 ndofs(0), nvdofs(0), nedofs(0), nfdofs(0), nbdofs(0),
62 fdofs(NULL), bdofs(NULL),
63 elem_dof(NULL), bdrElem_dof(NULL),
64 NURBSext(NULL), own_ext(false),
65 cP(NULL), cR(NULL), cP_is_set(false),
74 mesh = mesh ? mesh : orig.
mesh;
75 fec = fec ? fec : orig.
fec;
109 if (
vdim == 1) {
return; }
110 if (ndofs < 0) { ndofs = this->
ndofs; }
114 Ordering::DofsToVDofs<Ordering::byNODES>(
ndofs,
vdim, dofs);
118 Ordering::DofsToVDofs<Ordering::byVDIM>(
ndofs,
vdim, dofs);
124 if (
vdim == 1) {
return; }
125 if (ndofs < 0) { ndofs = this->
ndofs; }
129 for (
int i = 0; i < dofs.
Size(); i++)
131 dofs[i] = Ordering::Map<Ordering::byNODES>(
ndofs,
vdim, dofs[i], vd);
136 for (
int i = 0; i < dofs.
Size(); i++)
138 dofs[i] = Ordering::Map<Ordering::byVDIM>(
ndofs,
vdim, dofs[i], vd);
145 if (
vdim == 1) {
return dof; }
146 if (ndofs < 0) { ndofs = this->
ndofs; }
150 return Ordering::Map<Ordering::byNODES>(
ndofs,
vdim, dof, vd);
154 return Ordering::Map<Ordering::byVDIM>(
ndofs,
vdim, dof, vd);
161 int n = vdofs.
Size(), *vdof = vdofs;
162 for (
int i = 0; i < n; i++)
165 if ((j = vdof[i]) < 0)
221 for (
int i = 0; i <
mesh ->
GetNE(); i++)
224 el_dof -> AddColumnsInRow (i, dofs.
Size());
227 for (
int i = 0; i <
mesh ->
GetNE(); i++)
230 el_dof -> AddConnections (i, (
int *)dofs, dofs.
Size());
232 el_dof -> ShiftUpI();
250 for (
int k = 0, dof_counter = 0; k < nnz; k++)
252 const int sdof = J[k];
253 const int dof = (sdof < 0) ? -1-sdof : sdof;
254 int new_dof = dof_marker[dof];
257 dof_marker[dof] = new_dof = dof_counter++;
259 J[k] = (sdof < 0) ? -1-new_dof : new_dof;
272 for (
int i = 0; i <
mesh ->
GetNE(); i++)
274 const int *dofs =
elem_dof -> GetRow(i);
275 const int n =
elem_dof -> RowSize(i);
276 for (
int j = 0; j < n; j++)
289 for (
int i = 0; i < dofs.
Size(); i++)
292 if (k < 0) { k = -1 - k; }
306 for (
int i = 0; i <
GetNBE(); i++)
314 mark_dofs(vdofs, ess_vdofs);
319 for (
int d = 0; d < dofs.
Size(); d++)
320 { dofs[d] =
DofToVDof(dofs[d], component); }
321 mark_dofs(dofs, ess_vdofs);
333 for (
int i = 0; i < bdr_verts.
Size(); i++)
338 mark_dofs(vdofs, ess_vdofs);
343 for (
int d = 0; d < dofs.
Size(); d++)
344 { dofs[d] =
DofToVDof(dofs[d], component); }
345 mark_dofs(dofs, ess_vdofs);
348 for (
int i = 0; i < bdr_edges.
Size(); i++)
353 mark_dofs(vdofs, ess_vdofs);
358 for (
int d = 0; d < dofs.
Size(); d++)
359 { dofs[d] =
DofToVDof(dofs[d], component); }
360 mark_dofs(dofs, ess_vdofs);
390 for (
int i = 0; i < marker.
Size(); i++)
392 if (marker[i]) { num_marked++; }
396 for (
int i = 0; i < marker.
Size(); i++)
398 if (marker[i]) { list.
Append(i); }
408 for (
int i = 0; i < list.
Size(); i++)
410 marker[list[i]] = mark_val;
419 else { dofs.
Copy(cdofs); }
427 else { cdofs.
Copy(dofs); }
445 if (d_vdofs.
Size() != c_vdofs.
Size())
447 mfem_error (
"FiniteElementSpace::D2C_GlobalRestrictionMatrix (...)");
451 for (j = 0; j < d_vdofs.
Size(); j++)
453 R -> Set (c_vdofs[j], d_vdofs[j], 1.0);
477 if (c_dofs.
Size() != 1)
479 "D2Const_GlobalRestrictionMatrix (...)");
482 for (j = 0; j < d_dofs.
Size(); j++)
484 R -> Set (c_dofs[0], d_dofs[j], 1.0);
507 for (
int i = 0; i <
mesh ->
GetNE(); i++)
514 if (geom != cached_geom)
516 h_fe =
this ->
GetFE (i);
517 l_fe = lfes ->
GetFE (i);
519 h_fe->
Project(*l_fe, T, loc_restr);
523 R -> SetSubMatrix (l_dofs, h_dofs, loc_restr, 1);
535 for (
int i = 0; i < slave_dofs.
Size(); i++)
537 int sdof = slave_dofs[i];
540 for (
int j = 0; j < master_dofs.
Size(); j++)
542 double coef = I(i, j);
543 if (std::abs(coef) > 1e-12)
545 int mdof = master_dofs[j];
546 if (mdof != sdof && mdof != (-1-sdof))
548 deps.
Add(sdof, mdof, coef);
563 for (
int i = 0; i < ndep; i++)
565 if (!finalized[dep[i]]) {
return false; }
585 MFEM_VERIFY(dynamic_cast<const ParFiniteElementSpace*>(
this) == NULL,
586 "This method should not be used with a ParFiniteElementSpace!");
598 for (
int entity = 1; entity <= 2; entity++)
602 if (!list.
masters.size()) {
continue; }
610 if (!fe) {
continue; }
616 for (
unsigned mi = 0; mi < list.
masters.size(); mi++)
620 if (!master_dofs.
Size()) {
continue; }
626 if (!slave_dofs.
Size()) {
continue; }
642 for (
int i = 0; i <
ndofs; i++)
644 if (!deps.
RowSize(i)) { n_true_dofs++; }
648 if (n_true_dofs == ndofs)
657 int *cR_I =
new int[n_true_dofs+1];
658 double *cR_A =
new double[n_true_dofs];
659 cR_J =
new int[n_true_dofs];
660 for (
int i = 0; i < n_true_dofs; i++)
665 cR_I[n_true_dofs] = n_true_dofs;
676 for (
int i = 0, true_dof = 0; i <
ndofs; i++)
681 cP->
Add(i, true_dof++, 1.0);
694 int n_finalized = n_true_dofs;
700 for (
int dof = 0; dof <
ndofs; dof++)
708 for (
int j = 0; j < n_dep; j++)
715 finalized[dof] =
true;
725 if (n_finalized != ndofs)
727 MFEM_ABORT(
"Error creating cP matrix.");
743 if (
vdim == 1) {
return; }
745 int height = mat.
Height();
746 int width = mat.
Width();
752 for (
int i = 0; i < height; i++)
754 mat.
GetRow(i, dofs, srow);
755 for (
int vd = 0; vd <
vdim; vd++)
794 if (dg_space) {
return NULL; }
815 for (
int i = 0; i <
E2Q_array.Size(); i++)
818 if (qi->
IntRule == &ir) {
return qi; }
829 for (
int i = 0; i <
E2Q_array.Size(); i++)
832 if (qi->
qspace == &qs) {
return qi; }
841 const int coarse_ndofs,
const Table &coarse_elem_dof,
852 if (elem_geoms.
Size() == 1)
854 const int coarse_ldof = localP[elem_geoms[0]].
SizeJ();
872 const int fine_ldof = localP[
geom].
SizeI();
877 for (
int vd = 0; vd <
vdim; vd++)
879 coarse_dofs.Copy(coarse_vdofs);
882 for (
int i = 0; i < fine_ldof; i++)
885 int m = (r >= 0) ? r : (-1 - r);
890 P->
SetRow(r, coarse_vdofs, row);
897 MFEM_ASSERT(mark.
Sum() == P->
Height(),
"Not all rows of P set.");
910 int nmat = pmats.
SizeK();
917 localP.
SetSize(ldof, ldof, nmat);
918 for (
int i = 0; i < nmat; i++)
927 const Table* old_elem_dof)
929 MFEM_VERIFY(
ndofs >= old_ndofs,
"Previous space is not coarser.");
934 for (
int i = 0; i < elem_geoms.
Size(); i++)
945 , old_elem_dof(old_elem_dof)
947 MFEM_VERIFY(fespace->
GetNDofs() >= old_ndofs,
948 "Previous space is not coarser.");
950 width = old_ndofs * fespace->
GetVDim();
955 for (
int i = 0; i < elem_geoms.Size(); i++)
963 :
Operator(fespace->GetVSize(), coarse_fes->GetVSize()),
964 fespace(fespace), old_elem_dof(NULL)
968 for (
int i = 0; i < elem_geoms.Size(); i++)
971 localP[elem_geoms[i]]);
995 int old_ndofs = width /
vdim;
997 for (
int k = 0; k < mesh->
GetNE(); k++)
1006 for (
int vd = 0; vd <
vdim; vd++)
1008 old_dofs.
Copy(old_vdofs);
1011 for (
int i = 0; i < dofs.
Size(); i++)
1013 double rsign, osign;
1014 int r = fespace->
DofToVDof(dofs[i], vd);
1020 for (
int j = 0; j < old_vdofs.
Size(); j++)
1023 value += x[o] * lP(i, j) * osign;
1025 y[r] = value * rsign;
1041 "incompatible coarse and fine FE spaces");
1049 for (
int gi = 0; gi < elem_geoms.
Size(); gi++)
1061 emb_tr.SetIdentityTransformation(geom);
1062 for (
int i = 0; i < pmats.
SizeK(); i++)
1064 emb_tr.GetPointMat() = pmats(i);
1065 emb_tr.FinalizeTransformation();
1073 Table ref_type_to_matrix;
1075 ref_type_to_matrix, ref_type_to_geom);
1076 MFEM_ASSERT(coarse_to_fine.
Size() == c_fes->
GetNE(),
"");
1078 const int total_ref_types = ref_type_to_geom.
Size();
1080 Array<int> ref_type_to_coarse_elem_offset(total_ref_types);
1081 ref_type_to_fine_elem_offset.
SetSize(total_ref_types);
1084 for (
int i = 0; i < total_ref_types; i++)
1087 ref_type_to_coarse_elem_offset[i] = num_ref_types[g];
1088 ref_type_to_fine_elem_offset[i] = num_fine_elems[g];
1090 num_fine_elems[g] += ref_type_to_matrix.
RowSize(i);
1095 if (num_ref_types[g] == 0) {
continue; }
1096 const int fine_dofs = localP[g].
SizeI();
1097 const int coarse_dofs = localP[g].
SizeJ();
1098 localPtMP[g].
SetSize(coarse_dofs, coarse_dofs, num_ref_types[g]);
1099 localR[g].
SetSize(coarse_dofs, fine_dofs, num_fine_elems[g]);
1101 for (
int i = 0; i < total_ref_types; i++)
1104 DenseMatrix &lPtMP = localPtMP[g](ref_type_to_coarse_elem_offset[i]);
1105 int lR_offset = ref_type_to_fine_elem_offset[i];
1106 const int *mi = ref_type_to_matrix.
GetRow(i);
1107 const int nm = ref_type_to_matrix.
RowSize(i);
1109 for (
int s = 0; s < nm; s++)
1118 for (
int s = 0; s < nm; s++)
1131 delete coarse_elem_dof;
1140 const int vdim = fine_fes->GetVDim();
1141 const int coarse_ndofs = height/
vdim;
1142 for (
int coarse_el = 0; coarse_el < coarse_to_fine.Size(); coarse_el++)
1144 coarse_elem_dof->GetRow(coarse_el, c_vdofs);
1145 fine_fes->DofsToVDofs(c_vdofs, coarse_ndofs);
1149 const int ref_type = coarse_to_ref_type[coarse_el];
1151 const int *fine_elems = coarse_to_fine.GetRow(coarse_el);
1152 const int num_fine_elems = coarse_to_fine.RowSize(coarse_el);
1153 const int lR_offset = ref_type_to_fine_elem_offset[ref_type];
1154 for (
int s = 0; s < num_fine_elems; s++)
1157 fine_fes->GetElementVDofs(fine_elems[s], f_vdofs);
1160 AddMult(lR, loc_x_mat, loc_y_mat);
1175 const int nmat = pmats.
SizeK();
1176 const int ldof = fe->
GetDof();
1182 localR.
SetSize(ldof, ldof, nmat);
1183 for (
int i = 0; i < nmat; i++)
1193 const Table* old_elem_dof)
1195 MFEM_VERIFY(
Nonconforming(),
"Not implemented for conforming meshes.");
1196 MFEM_VERIFY(old_ndofs,
"Missing previous (finer) space.");
1197 MFEM_VERIFY(
ndofs <= old_ndofs,
"Previous space is not finer.");
1205 for (
int i = 0; i < elem_geoms.
Size(); i++)
1211 if (elem_geoms.
Size() == 1)
1214 localR[elem_geoms[0]].SizeI());
1226 MFEM_ASSERT(dtrans.
embeddings.Size() == old_elem_dof->
Size(),
"");
1229 for (
int k = 0; k < dtrans.
embeddings.Size(); k++)
1236 old_elem_dof->
GetRow(k, old_dofs);
1238 for (
int vd = 0; vd <
vdim; vd++)
1240 old_dofs.
Copy(old_vdofs);
1243 for (
int i = 0; i < lR.
Height(); i++)
1245 if (lR(i, 0) ==
infinity()) {
continue; }
1248 int m = (r >= 0) ? r : (-1 - r);
1253 R->
SetRow(r, old_vdofs, row);
1261 MFEM_VERIFY(num_marked == R->
Height(),
1262 "internal error: not all rows of R were set.");
1280 int nmat = pmats.
SizeK();
1287 for (
int i = 0; i < nmat; i++)
1314 mfem_error(
"FiniteElementSpace::FiniteElementSpace :\n"
1315 " NURBS FE space requires NURBS mesh.");
1318 if (NURBSext == NULL)
1334 this->NURBSext = NULL;
1345 mfem_error(
"FiniteElementSpace::StealNURBSext");
1371 MFEM_ASSERT(!
NURBSext,
"internal error");
1399 bool have_face_dofs =
false;
1405 have_face_dofs =
true;
1448 int k, j, nv, ne, nf, nb, nfd, nd,
dim;
1469 for (k = 0; k < F.
Size(); k++)
1475 nd = V.
Size() * nv + E.
Size() * ne + nfd + nb;
1479 for (k = 0; k < V.
Size(); k++)
1481 for (j = 0; j < nv; j++)
1483 dofs[k*nv+j] = V[k]*nv+j;
1491 for (k = 0; k < E.
Size(); k++)
1494 for (j = 0; j < ne; j++)
1498 dofs[nv+k*ne+j] = -1 - (
nvdofs+E[k]*ne+(-1-ind[j]) );
1502 dofs[nv+k*ne+j] =
nvdofs+E[k]*ne+ind[j];
1507 ne = nv + ne * E.
Size();
1511 for (k = 0; k < F.
Size(); k++)
1516 for (j = 0; j < nf; j++)
1533 for (j = 0; j < nb; j++)
1543 if (i < 0 || !mesh->
GetNE()) {
return NULL; }
1544 MFEM_VERIFY(i < mesh->
GetNE(),
1545 "Invalid element id " << i <<
", maximum allowed " <<
mesh->
GetNE()-1);
1567 int k, j, nv, ne, nf, nd, iF, oF,
dim;
1581 nd = V.
Size() * nv + E.
Size() * ne;
1592 for (k = 0; k < V.
Size(); k++)
1594 for (j = 0; j < nv; j++)
1596 dofs[k*nv+j] = V[k]*nv+j;
1604 for (k = 0; k < E.
Size(); k++)
1607 for (j = 0; j < ne; j++)
1611 dofs[nv+k*ne+j] = -1 - (
nvdofs+E[k]*ne+(-1-ind[j]) );
1615 dofs[nv+k*ne+j] =
nvdofs+E[k]*ne+ind[j];
1623 ne = nv + ne * E.
Size();
1626 for (j = 0; j < nf; j++)
1659 nd = V.
Size() * nv + E.
Size() * ne + nf;
1663 for (k = 0; k < V.
Size(); k++)
1665 for (j = 0; j < nv; j++)
1667 dofs[k*nv+j] = V[k]*nv+j;
1674 for (k = 0; k < E.
Size(); k++)
1677 for (j = 0; j < ne; j++)
1681 dofs[nv+k*ne+j] = -1 - (
nvdofs+E[k]*ne+(-1-ind[j]) );
1685 dofs[nv+k*ne+j] =
nvdofs+E[k]*ne+ind[j];
1690 ne = nv + ne * E.
Size();
1714 for (k = 0; k < 2; k++)
1716 for (j = 0; j < nv; j++)
1718 dofs[k*nv+j] = V[k]*nv+j;
1723 for (j = 0, k =
nvdofs+i*ne; j < ne; j++, k++)
1735 for (j = 0; j < nv; j++)
1745 nb =
fec -> DofForGeometry (
mesh -> GetElementBaseGeometry (i));
1748 for (j = 0; j < nb; j++)
1760 for (j = 0, k =
nvdofs+i*ne; j < ne; j++, k++)
1853 for (
int i = 0; i <
E2Q_array.Size(); i++)
1886 for (
int i = 0; i < elem_geoms.
Size(); i++)
1889 localP[elem_geoms[i]]);
1923 if (RP_case == 0) {
return; }
1936 cR, T.
Ptr(), coarse_P,
false, owner,
false));
1950 MFEM_ABORT(
"Error in update sequence. Space needs to be updated after "
1951 "each mesh modification.");
1961 Table* old_elem_dof = NULL;
1988 old_elem_dof = NULL;
2006 false,
false,
true));
2015 delete old_elem_dof;
2021 int fes_format = 90;
2022 bool nurbs_unit_weights =
false;
2033 MFEM_VERIFY(nurbs_fec,
"invalid FE collection");
2035 const double eps = 5e-14;
2046 out << (fes_format == 90 ?
2047 "FiniteElementSpace\n" :
"MFEM FiniteElementSpace v1.0\n")
2048 <<
"FiniteElementCollection: " <<
fec->
Name() <<
'\n'
2049 <<
"VDim: " <<
vdim <<
'\n'
2050 <<
"Ordering: " <<
ordering <<
'\n';
2052 if (fes_format == 100)
2066 out <<
"NURBS_orders\n";
2073 out <<
"NURBS_periodic\n";
2078 if (!nurbs_unit_weights)
2080 out <<
"NURBS_weights\n";
2084 out <<
"End: MFEM FiniteElementSpace v1.0\n";
2091 int fes_format = 0, ord;
2097 getline(input, buff);
2099 if (buff ==
"FiniteElementSpace") { fes_format = 90; }
2100 else if (buff ==
"MFEM FiniteElementSpace v1.0") { fes_format = 100; }
2101 else { MFEM_ABORT(
"input stream is not a FiniteElementSpace!"); }
2102 getline(input, buff,
' ');
2104 getline(input, buff);
2107 getline(input, buff,
' ');
2109 getline(input, buff,
' ');
2114 if (fes_format == 90)
2118 MFEM_VERIFY(m->
NURBSext,
"NURBS FE collection requires a NURBS mesh!");
2119 const int order = nurbs_fec->
GetOrder();
2127 else if (fes_format == 100)
2132 MFEM_VERIFY(input.good(),
"error reading FiniteElementSpace v1.0");
2133 getline(input, buff);
2135 if (buff ==
"NURBS_order" || buff ==
"NURBS_orders")
2137 MFEM_VERIFY(nurbs_fec,
2138 buff <<
": NURBS FE collection is required!");
2139 MFEM_VERIFY(m->
NURBSext, buff <<
": NURBS mesh is required!");
2140 MFEM_VERIFY(!NURBSext, buff <<
": order redefinition!");
2141 if (buff ==
"NURBS_order")
2154 else if (buff ==
"NURBS_periodic")
2161 else if (buff ==
"NURBS_weights")
2163 MFEM_VERIFY(NURBSext,
"NURBS_weights: NURBS_orders have to be "
2164 "specified before NURBS_weights!");
2167 else if (buff ==
"element_orders")
2169 MFEM_VERIFY(!nurbs_fec,
"section element_orders cannot be used "
2170 "with a NURBS FE collection");
2171 MFEM_ABORT(
"element_orders: not implemented yet!");
2173 else if (buff ==
"End: MFEM FiniteElementSpace v1.0")
2179 MFEM_ABORT(
"unknown section: " << buff);
2195 element_offsets =
new int[num_elem + 1];
2200 for (
int i = 0; i < num_elem; i++)
2202 element_offsets[i] = offset;
2204 if (int_rule[geom] == NULL)
2210 element_offsets[num_elem] = size = offset;
2216 const char *msg =
"invalid input stream";
2219 in >> ident; MFEM_VERIFY(ident ==
"QuadratureSpace", msg);
2220 in >> ident; MFEM_VERIFY(ident ==
"Type:", msg);
2222 if (ident ==
"default_quadrature")
2224 in >> ident; MFEM_VERIFY(ident ==
"Order:", msg);
2229 MFEM_ABORT(
"unknown QuadratureSpace type: " << ident);
2238 out <<
"QuadratureSpace\n"
2239 <<
"Type: default_quadrature\n"
2240 <<
"Order: " <<
order <<
'\n';
2246 : dom_fes(dom_fes_), ran_fes(ran_fes_),
2248 fw_t_oper(), bw_t_oper()
2253 MFEM_VERIFY(par_dom == par_ran,
"the domain and range FE spaces must both"
2254 " be either serial or parallel");
2265 return *t_oper.
Ptr();
2275 MFEM_VERIFY(mat != NULL,
"Operator is not a SparseMatrix");
2278 t_oper.
Reset(const_cast<SparseMatrix*>(mat),
false);
2291 const int RP_case = bool(out_cR) + 2*bool(in_cP);
2295 t_oper.
Reset(const_cast<Operator*>(&oper),
false);
2308 out_cR, &oper, in_cP,
false,
false,
false));
2314 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
2336 else if ((hy_mat = dynamic_cast<const HypreParMatrix *>(&oper)))
2345 MFEM_ABORT(
"unknown Operator type");
2352 false,
false,
false));
2356 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
2361 return *t_oper.
Ptr();
2396 for (
int i = 0; i < elem_geoms.Size(); i++)
2399 localP[elem_geoms[i]]);
2406 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
2436 MFEM_ABORT(
"unknown type of FE space");
2447 MFEM_ABORT(
"Operator::Type is not supported: " <<
oper_type);
2456 : fes_ho(fes_ho_), fes_lor(fes_lor_)
2460 "mixed meshes are not supported");
2463 if (mesh_ho->
GetNE() == 0) {
return; }
2467 ndof_lor = fe_lor->
GetDof();
2468 ndof_ho = fe_ho->
GetDof();
2470 const int nel_lor = fes_lor.
GetNE();
2471 const int nel_ho = fes_ho.
GetNE();
2473 nref = nel_lor/nel_ho;
2480 for (
int ilor=0; ilor<nel_lor; ++ilor)
2489 R.
SetSize(ndof_lor*nref, ndof_ho, nel_ho);
2491 P.
SetSize(ndof_ho, ndof_lor*nref, nel_ho);
2493 DenseMatrix Minv_lor(ndof_lor*nref, ndof_lor*nref);
2512 Vector shape_ho(ndof_ho);
2513 Vector shape_lor(ndof_lor);
2519 for (
int iho=0; iho<nel_ho; ++iho)
2521 for (
int iref=0; iref<nref; ++iref)
2524 int ilor = ho2lor.
GetRow(iho)[iref];
2527 M_lor.
CopyMN(M_lor_el, iref*ndof_lor, iref*ndof_lor);
2531 Minv_lor.
CopyMN(M_lor_el, iref*ndof_lor, iref*ndof_lor);
2559 M_mixed.
CopyMN(M_mixed_el, iref*ndof_lor, 0);
2566 RtMlorR_inv.
Mult(RtMlor, P(iho));
2573 int vdim = fes_ho.GetVDim();
2577 for (
int iho=0; iho<fes_ho.GetNE(); ++iho)
2579 fes_ho.GetElementVDofs(iho, vdofs);
2583 for (
int iref=0; iref<nref; ++iref)
2585 int ilor = ho2lor.GetRow(iho)[iref];
2586 for (
int vd=0; vd<vdim; ++vd)
2588 fes_lor.GetElementDofs(ilor, vdofs);
2589 fes_lor.DofsToVDofs(vd, vdofs);
2599 int vdim = fes_ho.GetVDim();
2603 for (
int iho=0; iho<fes_ho.GetNE(); ++iho)
2606 for (
int iref=0; iref<nref; ++iref)
2608 int ilor = ho2lor.GetRow(iho)[iref];
2609 for (
int vd=0; vd<vdim; ++vd)
2611 fes_lor.GetElementDofs(ilor, vdofs);
2612 fes_lor.DofsToVDofs(vd, vdofs);
2619 fes_ho.GetElementVDofs(iho, vdofs);
2645 vdim(fes.GetVDim()),
2646 byvdim(fes.GetOrdering() ==
Ordering::byVDIM),
2647 ndofs(fes.GetNDofs()),
2648 dof(ne > 0 ? fes.GetFE(0)->GetDof() : 0),
2657 const int *dof_map = NULL;
2658 if (dof_reorder &&
ne > 0)
2660 for (
int e = 0; e <
ne; ++e)
2665 if (el) {
continue; }
2666 mfem_error(
"Finite element not suitable for lexicographic ordering");
2672 MFEM_VERIFY(fe_dof_map.
Size() > 0,
"invalid dof map");
2673 dof_map = fe_dof_map.
GetData();
2676 const int* elementMap = e2dTable.
GetJ();
2678 for (
int i = 0; i <=
ndofs; ++i)
2682 for (
int e = 0; e <
ne; ++e)
2684 for (
int d = 0; d <
dof; ++d)
2686 const int gid = elementMap[dof*e + d];
2691 for (
int i = 1; i <=
ndofs; ++i)
2696 for (
int e = 0; e <
ne; ++e)
2698 for (
int d = 0; d <
dof; ++d)
2700 const int did = (!dof_reorder)?d:dof_map[d];
2701 const int gid = elementMap[dof*e + did];
2702 const int lid = dof*e + d;
2708 for (
int i =
ndofs; i > 0; --i)
2719 const int vd =
vdim;
2725 MFEM_FORALL(i,
ndofs,
2727 const int offset = d_offsets[i];
2728 const int nextOffset = d_offsets[i+1];
2729 for (
int c = 0; c < vd; ++c)
2731 const double dofValue = d_x(t?c:i,t?i:c);
2732 for (
int j = offset; j < nextOffset; ++j)
2734 const int idx_j = d_indices[j];
2735 d_y(idx_j % nd, c, idx_j / nd) = dofValue;
2745 const int vd =
vdim;
2751 MFEM_FORALL(i,
ndofs,
2753 const int offset = d_offsets[i];
2754 const int nextOffset = d_offsets[i + 1];
2755 for (
int c = 0; c < vd; ++c)
2757 double dofValue = 0;
2758 for (
int j = offset; j < nextOffset; ++j)
2760 const int idx_j = d_indices[j];
2761 dofValue += d_x(idx_j % nd, c, idx_j / nd);
2763 d_y(t?c:i,t?i:c) = dofValue;
2777 if (fespace->
GetNE() == 0) {
return; }
2779 MFEM_VERIFY(dynamic_cast<const ScalarFiniteElement*>(fe) != NULL,
2780 "Only scalar finite elements are supported");
2791 if (fespace->
GetNE() == 0) {
return; }
2793 MFEM_VERIFY(dynamic_cast<const ScalarFiniteElement*>(fe) != NULL,
2794 "Only scalar finite elements are supported");
2797 template<const
int T_VDIM, const
int T_ND, const
int T_NQ>
2806 const int eval_flags)
2808 const int nd = maps.
ndof;
2809 const int nq = maps.
nqpt;
2810 const int ND = T_ND ? T_ND : nd;
2811 const int NQ = T_NQ ? T_NQ : nq;
2812 const int VDIM = T_VDIM ? T_VDIM : vdim;
2815 MFEM_VERIFY(VDIM == 2 || !(eval_flags &
DETERMINANTS),
"");
2824 const int ND = T_ND ? T_ND : nd;
2825 const int NQ = T_NQ ? T_NQ : nq;
2826 const int VDIM = T_VDIM ? T_VDIM : vdim;
2827 constexpr
int max_ND = T_ND ? T_ND :
MAX_ND2D;
2828 constexpr
int max_VDIM = T_VDIM ? T_VDIM :
MAX_VDIM2D;
2829 double s_E[max_VDIM*max_ND];
2830 for (
int d = 0; d < ND; d++)
2832 for (
int c = 0; c < VDIM; c++)
2834 s_E[c+d*VDIM] = E(d,c,e);
2837 for (
int q = 0; q < NQ; ++q)
2841 double ed[max_VDIM];
2842 for (
int c = 0; c < VDIM; c++) { ed[c] = 0.0; }
2843 for (
int d = 0; d < ND; ++d)
2845 const double b = B(q,d);
2846 for (
int c = 0; c < VDIM; c++) { ed[c] += b*s_E[c+d*VDIM]; }
2848 for (
int c = 0; c < VDIM; c++) { val(q,c,e) = ed[c]; }
2850 if ((eval_flags &
DERIVATIVES) || (eval_flags & DETERMINANTS))
2854 for (
int i = 0; i < 2*VDIM; i++) { D[i] = 0.0; }
2855 for (
int d = 0; d < ND; ++d)
2857 const double wx = G(q,0,d);
2858 const double wy = G(q,1,d);
2859 for (
int c = 0; c < VDIM; c++)
2861 double s_e = s_E[c+d*VDIM];
2862 D[c+VDIM*0] += s_e * wx;
2863 D[c+VDIM*1] += s_e * wy;
2866 if (eval_flags & DERIVATIVES)
2868 for (
int c = 0; c < VDIM; c++)
2870 der(q,c,0,e) = D[c+VDIM*0];
2871 der(q,c,1,e) = D[c+VDIM*1];
2874 if (VDIM == 2 && (eval_flags & DETERMINANTS))
2878 det(q,e) = D[0]*D[3] - D[1]*D[2];
2885 template<const
int T_VDIM, const
int T_ND, const
int T_NQ>
2894 const int eval_flags)
2896 const int nd = maps.
ndof;
2897 const int nq = maps.
nqpt;
2898 const int ND = T_ND ? T_ND : nd;
2899 const int NQ = T_NQ ? T_NQ : nq;
2900 const int VDIM = T_VDIM ? T_VDIM : vdim;
2903 MFEM_VERIFY(VDIM == 3 || !(eval_flags &
DETERMINANTS),
"");
2912 const int ND = T_ND ? T_ND : nd;
2913 const int NQ = T_NQ ? T_NQ : nq;
2914 const int VDIM = T_VDIM ? T_VDIM : vdim;
2915 constexpr
int max_ND = T_ND ? T_ND :
MAX_ND2D;
2916 constexpr
int max_VDIM = T_VDIM ? T_VDIM :
MAX_VDIM2D;
2917 double s_E[max_VDIM*max_ND];
2918 for (
int d = 0; d < ND; d++)
2920 for (
int c = 0; c < VDIM; c++)
2922 s_E[c+d*VDIM] = E(d,c,e);
2925 for (
int q = 0; q < NQ; ++q)
2929 double ed[max_VDIM];
2930 for (
int c = 0; c < VDIM; c++) { ed[c] = 0.0; }
2931 for (
int d = 0; d < ND; ++d)
2933 const double b = B(q,d);
2934 for (
int c = 0; c < VDIM; c++) { ed[c] += b*s_E[c+d*VDIM]; }
2936 for (
int c = 0; c < VDIM; c++) { val(q,c,e) = ed[c]; }
2938 if ((eval_flags &
DERIVATIVES) || (eval_flags & DETERMINANTS))
2942 for (
int i = 0; i < 3*VDIM; i++) { D[i] = 0.0; }
2943 for (
int d = 0; d < ND; ++d)
2945 const double wx = G(q,0,d);
2946 const double wy = G(q,1,d);
2947 const double wz = G(q,2,d);
2948 for (
int c = 0; c < VDIM; c++)
2950 double s_e = s_E[c+d*VDIM];
2951 D[c+VDIM*0] += s_e * wx;
2952 D[c+VDIM*1] += s_e * wy;
2953 D[c+VDIM*2] += s_e * wz;
2956 if (eval_flags & DERIVATIVES)
2958 for (
int c = 0; c < VDIM; c++)
2960 der(q,c,0,e) = D[c+VDIM*0];
2961 der(q,c,1,e) = D[c+VDIM*1];
2962 der(q,c,2,e) = D[c+VDIM*2];
2965 if (VDIM == 3 && (eval_flags & DETERMINANTS))
2969 det(q,e) = D[0] * (D[4] * D[8] - D[5] * D[7]) +
2970 D[3] * (D[2] * D[7] - D[1] * D[8]) +
2971 D[6] * (D[1] * D[5] - D[2] * D[4]);
2979 const Vector &e_vec,
unsigned eval_flags,
2982 const int ne = fespace->
GetNE();
2983 if (ne == 0) {
return; }
2984 const int vdim = fespace->
GetVDim();
2990 const int nd = maps.
ndof;
2991 const int nq = maps.
nqpt;
3000 const int eval_flags) = NULL;
3005 switch (100*nd + nq)
3008 case 101: eval_func = &Eval2D<1,1,1>;
break;
3009 case 104: eval_func = &Eval2D<1,1,4>;
break;
3011 case 404: eval_func = &Eval2D<1,4,4>;
break;
3012 case 409: eval_func = &Eval2D<1,4,9>;
break;
3014 case 909: eval_func = &Eval2D<1,9,9>;
break;
3015 case 916: eval_func = &Eval2D<1,9,16>;
break;
3017 case 1616: eval_func = &Eval2D<1,16,16>;
break;
3018 case 1625: eval_func = &Eval2D<1,16,25>;
break;
3019 case 1636: eval_func = &Eval2D<1,16,36>;
break;
3021 case 2525: eval_func = &Eval2D<1,25,25>;
break;
3022 case 2536: eval_func = &Eval2D<1,25,36>;
break;
3023 case 2549: eval_func = &Eval2D<1,25,49>;
break;
3024 case 2564: eval_func = &Eval2D<1,25,64>;
break;
3026 if (nq >= 100 || !eval_func)
3028 eval_func = &Eval2D<1>;
3033 switch (1000*nd + nq)
3036 case 1001: eval_func = &Eval3D<1,1,1>;
break;
3037 case 1008: eval_func = &Eval3D<1,1,8>;
break;
3039 case 8008: eval_func = &Eval3D<1,8,8>;
break;
3040 case 8027: eval_func = &Eval3D<1,8,27>;
break;
3042 case 27027: eval_func = &Eval3D<1,27,27>;
break;
3043 case 27064: eval_func = &Eval3D<1,27,64>;
break;
3045 case 64064: eval_func = &Eval3D<1,64,64>;
break;
3046 case 64125: eval_func = &Eval3D<1,64,125>;
break;
3047 case 64216: eval_func = &Eval3D<1,64,216>;
break;
3049 case 125125: eval_func = &Eval3D<1,125,125>;
break;
3050 case 125216: eval_func = &Eval3D<1,125,216>;
break;
3052 if (nq >= 1000 || !eval_func)
3054 eval_func = &Eval3D<1>;
3058 else if (vdim == dim)
3062 switch (100*nd + nq)
3065 case 404: eval_func = &Eval2D<2,4,4>;
break;
3066 case 409: eval_func = &Eval2D<2,4,9>;
break;
3068 case 909: eval_func = &Eval2D<2,9,9>;
break;
3069 case 916: eval_func = &Eval2D<2,9,16>;
break;
3071 case 1616: eval_func = &Eval2D<2,16,16>;
break;
3072 case 1625: eval_func = &Eval2D<2,16,25>;
break;
3073 case 1636: eval_func = &Eval2D<2,16,36>;
break;
3075 case 2525: eval_func = &Eval2D<2,25,25>;
break;
3076 case 2536: eval_func = &Eval2D<2,25,36>;
break;
3077 case 2549: eval_func = &Eval2D<2,25,49>;
break;
3078 case 2564: eval_func = &Eval2D<2,25,64>;
break;
3080 if (nq >= 100 || !eval_func)
3082 eval_func = &Eval2D<2>;
3087 switch (1000*nd + nq)
3090 case 8008: eval_func = &Eval3D<3,8,8>;
break;
3091 case 8027: eval_func = &Eval3D<3,8,27>;
break;
3093 case 27027: eval_func = &Eval3D<3,27,27>;
break;
3094 case 27064: eval_func = &Eval3D<3,27,64>;
break;
3096 case 64064: eval_func = &Eval3D<3,64,64>;
break;
3097 case 64125: eval_func = &Eval3D<3,64,125>;
break;
3098 case 64216: eval_func = &Eval3D<3,64,216>;
break;
3100 case 125125: eval_func = &Eval3D<3,125,125>;
break;
3101 case 125216: eval_func = &Eval3D<3,125,216>;
break;
3103 if (nq >= 1000 || !eval_func)
3105 eval_func = &Eval3D<3>;
3111 eval_func(ne, vdim, maps, e_vec, q_val, q_der, q_det, eval_flags);
3115 MFEM_ABORT(
"case not supported yet");
3120 unsigned eval_flags,
const Vector &q_val,
const Vector &q_der,
3123 MFEM_ABORT(
"this method is not implemented yet");
int GetNPoints() const
Returns the number of the points in the integration rule.
Abstract class for Finite Elements.
int GetOrder() const
Get the order of the NURBS collection: either a positive number, when using fixed order...
virtual ~InterpolationGridTransfer()
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
const Operator & MakeTrueOperator(FiniteElementSpace &fes_in, FiniteElementSpace &fes_out, const Operator &oper, OperatorHandle &t_oper)
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Ordering::Type GetOrdering() const
Return the ordering method.
int Size() const
Logical size of the array.
void GetFaceEdges(int i, Array< int > &, Array< int > &) const
int RowSize(const int i) const
Returns the number of elements in row i.
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
void GetVertexVDofs(int i, Array< int > &vdofs) const
void Add(const int i, const int j, const double a)
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
const Vector & GetWeights() const
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
void BuildTranspose() const
Build and store internally the transpose of this matrix which will be used in the methods AddMultTran...
int GetNDofs() const
Returns number of degrees of freedom.
int ndofs
Number of degrees of freedom. Number of unknowns is ndofs * vdim.
Class for an integration rule - an Array of IntegrationPoint.
const Array< int > & GetMaster() const
void GetElementInteriorVDofs(int i, Array< int > &vdofs) const
int DofToVDof(int dof, int vd, int ndofs=-1) const
For scalar fields; preserves volume integrals.
void GetBdrElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of bdr element i.
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
const CoarseFineTransformations & GetDerefinementTransforms()
virtual void Update(bool want_transform=true)
void SetSize(int dim, int connections_per_row)
Set the size and the number of connections for the table.
void LoadBE(int i, const FiniteElement *BE) const
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
BilinearFormIntegrator * mass_integ
Ownership depends on own_mass_integ.
void BuildElementToDofTable() const
const IntegrationRule & GetElementIntRule(int idx) const
Get the IntegrationRule associated with mesh element idx.
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
DerefinementOperator(const FiniteElementSpace *f_fes, const FiniteElementSpace *c_fes, BilinearFormIntegrator *mass_integ)
void Prolongate(const Vector &x, Vector &y) const
static const int MAX_ND2D
FiniteElementSpace & dom_fes
Domain FE space.
const FiniteElement * GetTraceElement(int i, Geometry::Type geom_type) const
Return the trace element from element 'i' to the given 'geom_type'.
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
HypreParMatrix * LeftDiagMult(const SparseMatrix &D, HYPRE_Int *row_starts=NULL) const
Multiply the HypreParMatrix on the left by a block-diagonal parallel matrix D and return the result a...
void SetSize(int s)
Resize the vector to size s.
SparseMatrix * RefinementMatrix(int old_ndofs, const Table *old_elem_dof)
SparseMatrix * DerefinementMatrix(int old_ndofs, const Table *old_elem_dof)
Calculate GridFunction restriction matrix after mesh derefinement.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
static int DecodeDof(int dof, double &sign)
Helper to remove encoded sign from a DOF.
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
SparseMatrix * RefinementMatrix_main(const int coarse_ndofs, const Table &coarse_elem_dof, const DenseTensor localP[]) const
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
Lists all edges/faces in the nonconforming mesh.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void GetElementFaces(int i, Array< int > &, Array< int > &) const
Return the indices and the orientations of all faces of element i.
Pointer to an Operator of a specified type.
static const int MAX_NQ3D
Operator::Type Type() const
Get the currently set operator type id.
virtual const FiniteElement * FiniteElementForGeometry(Geometry::Type GeomType) const =0
void Copy(Array ©) const
Create a copy of the current array.
virtual ~DerefinementOperator()
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
int GetFaceOrder(int i) const
Returns the order of the i'th face finite element.
T * GetData()
Returns the data.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_vdofs, int component=-1) const
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Data type dense matrix using column-major storage.
int vdim
Vector dimension (number of unknowns per degree of freedom).
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void GetEntityDofs(int entity, int index, Array< int > &dofs) const
Helper to get vertex, edge or face DOFs (entity=0,1,2 resp.).
Operator::Type oper_type
Desired Operator::Type for the construction of all operators defined by the underlying transfer algor...
void Save(std::ostream &out, int fmt=0) const
Save the Array to the stream out using the format fmt. The format fmt can be:
int GetBdrAttribute(int i) const
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
void SetSize(int i, int j, int k)
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
int GetNE() const
Returns number of elements.
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
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
void RebuildElementToDofTable()
Geometry::Type GetFaceBaseGeometry(int i) const
Abstract parallel finite element space.
Evaluate the derivatives at quadrature points.
const FiniteElement * GetFaceElement(int i) const
virtual void GetTrueTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
Construct and return an Operator that can be used to transfer true-dof data from coarse_fes, defined on a coarse mesh, to this FE space, defined on a refined mesh.
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
FiniteElementCollection * Load(Mesh *m, std::istream &input)
Read a FiniteElementSpace from a stream. The returned FiniteElementCollection is owned by the caller...
virtual const Operator & ForwardOperator()
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
void Factor()
Factor the current DenseMatrix, *a.
double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
int HasFaceDofs(Geometry::Type GeomType) const
static bool IsEnabled()
Return true if any backend other than Backend::CPU is enabled.
double * GetData() const
Returns the matrix data array.
void AddRow(const int row, const Array< int > &cols, const Vector &srow)
double * GetRowEntries(const int row)
Return a pointer to the entries in a row.
double * GetData() const
Return a pointer to the beginning of the Vector data.
const FiniteElementCollection * fec
Associated FE collection (not owned).
OperatorHandle Th
Transformation to apply to GridFunctions after space Update().
Geometry::Type GetElementBaseGeometry(int i) const
int Size_of_connections() const
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A * B.
void GetLocalDerefinementMatrices(Geometry::Type geom, DenseTensor &localR) const
bool HasGeometry(Geometry::Type geom) const
Return true iff the given geom is encountered in the mesh. Geometries of dimensions lower than Dimens...
void skip_comment_lines(std::istream &is, const char comment_char)
void DeleteAll()
Delete whole array.
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
static const int MAX_ND3D
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
Array< int > dof_elem_array
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
void GetFaceInteriorDofs(int i, Array< int > &dofs) const
virtual int DofForGeometry(Geometry::Type GeomType) const =0
virtual void GetFaceDofs(int i, Array< int > &dofs) const
FiniteElementSpace & ran_fes
Range FE space.
void ConvertFromConformingVDofs(const Array< int > &cdofs, Array< int > &dofs)
const Operator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims...dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
ID for class SparseMatrix.
const Array< int > & GetSlave() const
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
int GetNE() const
Returns number of elements in the mesh.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
void GetVertexDofs(int i, Array< int > &dofs) const
virtual const Operator & BackwardOperator()
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
General product operator: x -> (A*B)(x) = A(B(x)).
ID for the base class Operator, i.e. any type.
const FiniteElement * GetEdgeElement(int i) const
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const
Extract all column indices and values from a given row.
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
int GetNBE() const
Returns number of boundary elements in the mesh.
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.
Mesh * GetMesh() const
Returns the mesh.
OperatorHandle F
Forward, coarse-to-fine, operator.
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
A class that performs interpolation from an E-vector to quadrature point values and/or derivatives (Q...
GridTransfer(FiniteElementSpace &dom_fes_, FiniteElementSpace &ran_fes_)
std::vector< Master > masters
SparseMatrix * cR
Conforming restriction matrix such that cR.cP=I.
void GetRow(int r, Vector &row) const
const IntegrationRule * IntRule
Not owned.
SparseMatrix * D2Const_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
SparseMatrix * D2C_GlobalRestrictionMatrix(FiniteElementSpace *cfes)
void AddConnection(int r, int c)
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...
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
virtual void GetElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void BuildConformingInterpolation() const
Calculate the cP and cR matrices for a nonconforming mesh.
NURBSExtension * StealNURBSext()
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
virtual ~RefinementOperator()
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
virtual const FiniteElement * TraceFiniteElementForGeometry(Geometry::Type GeomType) const
L2Projection(const FiniteElementSpace &fes_ho_, const FiniteElementSpace &fes_lor_)
static void AddDependencies(SparseMatrix &deps, Array< int > &master_dofs, Array< int > &slave_dofs, DenseMatrix &I)
Array< int > dof_ldof_array
const Array< int > & GetOrders() const
Read-only access to the orders of all knot vectors.
ElementRestriction(const FiniteElementSpace &, ElementDofOrdering)
int Size() const
Returns the number of TYPE I elements.
int GetVDim() const
Returns vector dimension.
static const int MAX_VDIM2D
virtual void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges)
Array< QuadratureInterpolator * > E2Q_array
void GetEdgeDofs(int i, Array< int > &dofs) const
Operator * Ptr() const
Access the underlying Operator pointer.
OperatorHandle L2E_nat
The element restriction operators, see GetElementRestriction().
int slaves_end
slave faces
void GetTransferOperator(const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
Construct and return an Operator that can be used to transfer GridFunction data from coarse_fes...
OperatorHandle B
Backward, fine-to-coarse, operator.
void GetElementInteriorDofs(int i, Array< int > &dofs) const
void GetLocalRefinementMatrices(Geometry::Type geom, DenseTensor &localP) const
int GetOrder() const
If all orders are identical, return that number. Otherwise, return NURBSFECollection::VariableOrder.
List of mesh geometries stored as Array<Geometry::Type>.
virtual const Operator & BackwardOperator()
Return an Operator that transfers GridFunctions from the range FE space back to GridFunctions in the ...
void GetBdrElementFace(int i, int *, int *) const
Return the index and the orientation of the face of bdr element i. (3D)
const FiniteElementSpace & fes
void SetMassIntegrator(BilinearFormIntegrator *mass_integ_, bool own_mass_integ_=true)
Assign a mass integrator to be used in the construction of the backward, fine-to-coarse, transfer operator.
double Min() const
Returns the minimal element of the vector.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
QuadratureInterpolator(const FiniteElementSpace &fes, const IntegrationRule &ir)
Type
Enumeration defining IDs for some classes derived from Operator.
virtual const int * DofOrderForOrientation(Geometry::Type GeomType, int Or) const =0
Returns an array, say p, that maps a local permuted index i to a local base index: base_i = p[i]...
RefinementOperator(const FiniteElementSpace *fespace, Table *old_elem_dof, int old_ndofs)
void LoadFE(int i, const FiniteElement *FE) const
void SetOrder(int Order) const
Set the order and the name, based on the given Order: either a positive number for fixed order...
Operator that converts FiniteElementSpace L-vectors to E-vectors.
std::vector< Slave > slaves
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Nonconforming edge/face within a bigger edge/face.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
virtual ~FiniteElementSpace()
bool OwnsOperator() const
Return true if the OperatorHandle owns the held Operator.
SparseMatrix * H2L_GlobalRestrictionMatrix(FiniteElementSpace *lfes)
static void Eval2D(const int NE, const int vdim, const DofToQuad &maps, const Vector &e_vec, Vector &q_val, Vector &q_der, Vector &q_det, const int eval_flags)
Template compute kernel for 2D.
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
L2Prolongation * B
Backward, fine-to-coarse, operator.
int GetOrder(int i) const
Returns the order of the i'th finite element.
void Save(std::ostream &out) const
Write the QuadratureSpace to the stream out.
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged...
Table * GetElementDofTable()
Structure representing the matrices/tensors needed to evaluate (in reference space) the values...
void MakeVDimMatrix(SparseMatrix &mat) const
Table * GetBdrElementDofTable()
bool own_mass_integ
Ownership flag for mass_integ.
The ordering method used when the number of unknowns per mesh node (vector dimension) is bigger than ...
void GetEdgeInteriorVDofs(int i, Array< int > &vdofs) const
const CoarseFineTransformations & GetRefinementTransforms()
int height
Dimension of the output / number of rows in the matrix.
L2Projection * F
Forward, coarse-to-fine, operator.
Operation GetLastOperation() const
Return type of last modification of the mesh.
Array< double > B
Basis functions evaluated at quadrature points.
const Array< int > & GetDofMap() const
Get an Array<int> that maps lexicographically ordered indices to the indices of the respective nodes/...
static FiniteElementCollection * New(const char *name)
Factory method: return a newly allocated FiniteElementCollection according to the given name...
bool Nonconforming() const
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
virtual void GetBdrElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom for i'th boundary element.
Assuming the derivative at quadrature points form a matrix, this flag can be used to compute and stor...
NURBSExtension * NURBSext
Optional NURBS mesh extension.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
virtual const Operator & ForwardOperator()
Return an Operator that transfers GridFunctions from the domain FE space to GridFunctions in the rang...
void ConvertToConformingVDofs(const Array< int > &dofs, Array< int > &cdofs)
virtual const char * Name() const
static void Eval3D(const int NE, const int vdim, const DofToQuad &maps, const Vector &e_vec, Vector &q_val, Vector &q_der, Vector &q_det, const int eval_flags)
Template compute kernel for 3D.
Class for integration point with weight.
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
Full multidimensional representation which does not use tensor product structure. The ordering of the...
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
Mesh * mesh
The mesh that FE space lives on (not owned).
const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
void ReorderElementToDofTable()
Reorder the scalar DOFs based on the element ordering.
GridFunction interpolation operator applicable after mesh refinement.
double Max() const
Returns the maximal element of the vector.
static const int DimStart[MaxDim+2]
int GetNConformingDofs() const
static const int MAX_VDIM3D
void GetEdgeInteriorDofs(int i, Array< int > &dofs) const
void Mult(const Vector &e_vec, unsigned eval_flags, Vector &q_val, Vector &q_der, Vector &q_det) const
Interpolate the E-vector e_vec to quadrature points.
const QuadratureInterpolator * GetQuadratureInterpolator(const IntegrationRule &ir) const
Return a QuadratureInterpolator that interpolates E-vectors to quadrature point values and/or derivat...
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
General triple product operator x -> A*B*C*x, with ownership of the factors.
virtual void GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs. ...
Array< double > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i'th element.
Lexicographic ordering for tensor-product FiniteElements.
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
int parent
Element index in the coarse mesh.
FiniteElementSpace()
Default constructor: the object is invalid until initialized using the method Load().
QuadratureSpace(Mesh *mesh_, int order_)
Create a QuadratureSpace based on the global rules from IntRules.
void Constructor(Mesh *mesh, NURBSExtension *ext, const FiniteElementCollection *fec, int vdim=1, int ordering=Ordering::byNODES)
Help function for constructors + Load().
NCMesh * ncmesh
Optional non-conforming mesh extension.
Geometry::Type GetBdrElementBaseGeometry(int i) const
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th face element (2D and 3D).
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
void GetEdgeVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th edge.
HYPRE_Int * GetTrueDofOffsets() const
static void ListToMarker(const Array< int > &list, int marker_size, Array< int > &marker, int mark_val=-1)
virtual void Mult(const Vector &x, Vector &y) const
Perform the L2 projection onto the LOR space.
int GetNEdges() const
Return the number of edges.
void filter_dos(std::string &line)
void MakeRef(T *, int)
Make this Array a reference to a pointer.
int GetNFaces() const
Return the number of faces in a 3D mesh.
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
For scalar fields; preserves point values.
ID for class HypreParMatrix.
void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco)
Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this.
const Table & GetElementToDofTable() const
virtual void GetTransferMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
Return interpolation matrix, I, which maps dofs from a coarse element, fe, to the fine dofs on this f...
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
static const int MAX_NQ2D
static bool DofFinalizable(int dof, const Array< bool > &finalized, const SparseMatrix &deps)
Class representing the storage layout of a QuadratureFunction.
void UseExternalData(double *d, int h, int w)
Change the data array and the size of the DenseMatrix.
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement for the i'th boundary element.
NURBSExtension * NURBSext
void GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th boundary element.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Wrapper for hypre's ParCSR matrix class.
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
void Swap(SparseMatrix &other)
BiLinear2DFiniteElement QuadrilateralFE
Rank 3 tensor (array of matrices)
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
void Save(std::ostream &out) const
Linear1DFiniteElement SegmentFE
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
static void AdjustVDofs(Array< int > &vdofs)
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
int width
Dimension of the input / number of columns in the matrix.
Integrator for (Q u, v) for VectorFiniteElements.
void MultTranspose(unsigned eval_flags, const Vector &q_val, const Vector &q_der, Vector &e_vec) const
Perform the transpose operation of Mult(). (TODO)
Defines the position of a fine element within a coarse element.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
int matrix
Index into the DenseTensor corresponding to the parent Geometry::Type stored in CoarseFineTransformat...
Arbitrary order "L2-conforming" discontinuous finite elements.
Evaluate the values at quadrature points.
void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
const QuadratureSpace * qspace
Not owned.
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const