45#ifndef MFEM_THREAD_SAFE
53 MFEM_ABORT(
"method is not implemented for this class");
59 MFEM_ABORT(
"method is not implemented for this class");
65 MFEM_ABORT(
"method is not implemented for this class");
72 div_shape *= (1.0 / Trans.
Weight());
78 MFEM_ABORT(
"method is not implemented for this class");
88#ifdef MFEM_THREAD_SAFE
93 curl_shape *= (1.0 / Trans.
Weight());
99 curl_shape *= (1.0 / Trans.
Weight());
102 MFEM_ABORT(
"Invalid dimension, Dim = " <<
dim);
108 MFEM_ABORT(
"method is not overloaded");
114 MFEM_ABORT(
"method is not overloaded");
120 MFEM_ABORT(
"method is not overloaded");
126 MFEM_ABORT(
"method is not overloaded");
133 MFEM_ABORT(
"method is not overloaded");
139 MFEM_ABORT(
"method is not overloaded");
145 MFEM_ABORT(
"method is not overloaded");
151 mfem_error(
"FiniteElement::ProjectFromNodes() (vector) is not overloaded!");
157 MFEM_ABORT(
"method is not overloaded");
162 MFEM_ABORT(
"method is not implemented for this element");
168 MFEM_ABORT(
"method is not implemented for this element");
175 MFEM_ABORT(
"method is not implemented for this element");
182 MFEM_ABORT(
"method is not implemented for this element");
189 MFEM_ABORT(
"method is not implemented for this element");
206#ifdef MFEM_THREAD_SAFE
226 int size = (
dim*(
dim+1))/2;
232 for (
int nd = 0; nd <
dof; nd++)
234 Laplacian[nd] = hess(nd,0) + hess(nd,3) + hess(nd,5);
239 for (
int nd = 0; nd <
dof; nd++)
241 Laplacian[nd] = hess(nd,0) + hess(nd,2);
246 for (
int nd = 0; nd <
dof; nd++)
248 Laplacian[nd] = hess(nd,0);
258 int size = (
dim*(
dim+1))/2;
269 scale[1] = 2*Gij(0,1);
270 scale[2] = 2*Gij(0,2);
272 scale[4] = 2*Gij(1,2);
278 scale[1] = 2*Gij(0,1);
286 for (
int nd = 0; nd <
dof; nd++)
289 for (
int ii = 0; ii < size; ii++)
291 Laplacian[nd] += hess(nd,ii)*scale[ii];
331 int size = (
dim*(
dim+1))/2;
349 for (
int i = 0; i <
dim; i++)
351 for (
int j = 0; j <
dim; j++)
353 for (
int k = 0; k <
dim; k++)
355 for (
int l = 0; l <
dim; l++)
357 lhm(map[i*
dim+j],map[k*
dim+l]) += invJ(i,k)*invJ(j,l);
365 for (
int i = 0; i <
dim*
dim; i++) { mult[map[i]]++; }
370 Mult(hess, lhm, Hessian);
379#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
380 #pragma omp critical (DofToQuad)
386#ifdef MFEM_THREAD_SAFE
405 for (
int i = 0; i < nqpt; i++)
409 for (
int j = 0; j <
dof; j++)
411 d2q->
B[i+nqpt*j] = d2q->
Bt[j+
dof*i] = shape(j);
421 for (
int i = 0; i < nqpt; i++)
425 for (
int d = 0; d <
dim; d++)
427 for (
int j = 0; j <
dof; j++)
429 d2q->
B[i+nqpt*(d+
dim*j)] =
447 for (
int i = 0; i < nqpt; i++)
451 for (
int d = 0; d <
dim; d++)
453 for (
int j = 0; j <
dof; j++)
455 d2q->
G[i+nqpt*(d+
dim*j)] =
469 for (
int i = 0; i < nqpt; i++)
473 for (
int j = 0; j <
dof; j++)
475 d2q->
G[i+nqpt*j] = d2q->
Gt[j+
dof*i] = divshape(j);
486 for (
int i = 0; i < nqpt; i++)
490 for (
int d = 0; d <
cdim; d++)
492 for (
int j = 0; j <
dof; j++)
494 d2q->
G[i+nqpt*(d+
cdim*j)] =
495 d2q->
Gt[j+
dof*(i+nqpt*d)] = curlshape(j, d);
514 MFEM_ABORT(
"method is not implemented for this element");
534#ifdef MFEM_THREAD_SAFE
544 for (
int i = 0; i < fine_fe.
dof; i++)
549 for (
int j = 0; j <
dof; j++)
551 if (fabs(I(i,j) = shape(j)) < 1.0e-12)
577 Vector fine_shape(fs), coarse_shape(cs);
578 DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs);
596 fine_mass_inv.
Mult(fine_coarse_mass, I);
616 Vector fine_shape(fs), coarse_shape(cs);
617 DenseMatrix coarse_mass(cs), coarse_fine_mass(cs, fs);
645 coarse_mass_inv.Mult(coarse_fine_mass, R);
651 R *= 1.0 / Trans.
Weight();
655void NodalFiniteElement::CreateLexicographicFullMap(
const IntegrationRule &ir)
662#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
663 #pragma omp critical (DofToQuad)
673 auto *d2q_new =
new DofToQuad(d2q);
675 const int nqpt = ir.GetNPoints();
679 for (
int i = 0; i < nqpt; i++)
681 for (
int d = 0; d < b_dim; d++)
683 for (
int j = 0; j <
dof; j++)
685 const double val = d2q.B[i + nqpt*(d+b_dim*
lex_ordering[j])];
686 d2q_new->B[i+nqpt*(d+b_dim*j)] = val;
687 d2q_new->Bt[j+
dof*(i+nqpt*d)] = val;
692 const int g_dim = [
this]()
703 for (
int i = 0; i < nqpt; i++)
705 for (
int d = 0; d < g_dim; d++)
707 for (
int j = 0; j <
dof; j++)
709 const double val = d2q.G[i + nqpt*(d+g_dim*
lex_ordering[j])];
710 d2q_new->G[i+nqpt*(d+g_dim*j)] = val;
711 d2q_new->Gt[j+
dof*(i+nqpt*d)] = val;
726#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
727 #pragma omp critical (DofToQuad)
732 if (d2q) {
return *d2q; }
739 CreateLexicographicFullMap(ir);
751 for (
int i = 0; i <
dof; i++)
761 for (
int j = 0; j < fe.
GetDof(); j++)
763 curl(i,j) = w * curl_shape(j,0);
774 trans.Transform(p0, x);
781 trans.InverseJacobian().Mult(v, x);
790#ifdef MFEM_THREAD_SAFE
799 for (
int j = 0; j <
dof; j++)
819 for (
int i = 0; i <
dof; i++)
825 dofs(i) = coeff.
Eval(Trans, ip);
828 dofs(i) *= Trans.
Weight();
839 for (
int i = 0; i <
dof; i++)
843 vc.
Eval (x, Trans, ip);
848 for (
int j = 0; j < x.
Size(); j++)
850 dofs(
dof*j+i) = x(j);
862 for (
int k = 0; k <
dof; k++)
867 for (
int r = 0; r < MQ.
Height(); r++)
869 for (
int d = 0; d < MQ.
Width(); d++)
871 dofs(k+
dof*(d+MQ.
Width()*r)) = MQ(r,d);
887 for (
int k = 0; k <
dof; k++)
890 for (
int j = 0; j < shape.
Size(); j++)
892 I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
898 for (
int k = 0; k <
dof; k++)
906 for (
int j = 0; j < shape.
Size(); j++)
908 I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
919 for (
int k = 0; k <
dof; k++)
946 for (
int k = 0; k <
dof; k++)
952 Mult(dshape, Jinv, grad_k);
957 for (
int j = 0; j < grad_k.Height(); j++)
958 for (
int d = 0; d <
dim; d++)
960 grad(k+d*
dof,j) = grad_k(j,d);
973 for (
int k = 0; k <
dof; k++)
981 for (
int j = 0; j < div_shape.
Size(); j++)
983 div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
988 for (
int j = 0; j < div_shape.
Size(); j++)
990 div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
1000 MFEM_ASSERT(dofs.
Size() == ncomp *
dof,
"Wrong input size.");
1003 for (
int i = 0; i <
dof; i++)
1005 for (
int c = 0; c < ncomp; c++)
1014 int Do,
int O,
int M,
int F)
1028void VectorFiniteElement::CalcShape(
1031 mfem_error(
"Error: Cannot use scalar CalcShape(...) function with\n"
1032 " VectorFiniteElements!");
1035void VectorFiniteElement::CalcDShape(
1036 const IntegrationPoint &ip, DenseMatrix &dshape)
const
1038 mfem_error(
"Error: Cannot use scalar CalcDShape(...) function with\n"
1039 " VectorFiniteElements!");
1060 MFEM_ABORT(
"Invalid dimension, Dim = " <<
dim);
1077 MFEM_ABORT(
"Invalid dimension, Dim = " <<
dim);
1089 MFEM_ABORT(
"Invalid dimension, Dim = " <<
dim);
1112 MFEM_ABORT(
"Invalid dimension, Dim = " <<
dim);
1131 MFEM_ABORT(
"Invalid dimension, Dim = " <<
dim);
1148 MFEM_ABORT(
"Invalid dimension, Dim = " <<
dim);
1152 MFEM_ABORT(
"Invalid MapType = " <<
map_type);
1160#ifdef MFEM_THREAD_SAFE
1165 shape *= (1.0 / Trans.
Weight());
1172#ifdef MFEM_THREAD_SAFE
1185 MFEM_ASSERT(vc.
GetVDim() == sdim,
"");
1187 const bool square_J = (
dim == sdim);
1189 for (
int k = 0; k <
dof; k++)
1195 if (!square_J) { dofs(k) /= Trans.
Weight(); }
1204 const bool square_J = (
dim == sdim);
1206 for (
int k = 0; k <
dof; k++)
1211 &vc[k*sdim], nk + d2n[k]*
dim);
1212 if (!square_J) { dofs(k) /= Trans.
Weight(); }
1223 MFEM_ASSERT(mc.
GetWidth() == sdim,
"");
1224 const bool square_J = (
dim == sdim);
1229 for (
int k = 0; k <
dof; k++)
1235 if (!square_J) { nk_phys /= T.
Weight(); }
1236 MQ.
Mult(nk_phys, dofs_k);
1237 for (
int r = 0; r < MQ.
Height(); r++)
1239 dofs(k+
dof*r) = dofs_k(r);
1255 for (
int k = 0; k <
dof; k++)
1267 for (
int d = 0; d <
dim; d++)
1273 for (
int j = 0; j < shape.
Size(); j++)
1276 if (fabs(s) < 1e-12)
1282 for (
int d = 0; d < sdim; d++)
1284 I(k,j+d*shape.
Size()) = s*vk[d];
1295 const bool square_J = (
dim == sdim);
1298 for (
int k = 0; k <
dof; k++)
1310 if (!square_J) { vshapenk /= Trans.
Weight(); }
1311 for (
int j=0; j<vshapenk.
Size(); j++)
1313 I(k,j) = vshapenk(j);
1326 mfem_error(
"VectorFiniteElement::ProjectCurl2D_RT works only in 2D!");
1334 for (
int k = 0; k <
dof; k++)
1337 tk[0] = -nk[d2n[k]*
dim+1];
1338 tk[1] = nk[d2n[k]*
dim];
1339 dshape.
Mult(tk, grad_k);
1340 for (
int j = 0; j < grad_k.
Size(); j++)
1342 grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1351#ifdef MFEM_THREAD_SAFE
1364 for (
int k = 0; k <
dof; k++)
1378 for (
int j = 0; j < curl_k.
Size(); j++)
1380 curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
1393 for (
int k = 0; k <
dof; k++)
1396 curl_shape.
Mult(nk + d2n[k]*
dim, curl_k);
1397 for (
int j = 0; j < curl_k.
Size(); j++)
1399 curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
1411 for (
int k = 0; k <
dof; k++)
1425 for (
int k = 0; k <
dof; k++)
1440 MFEM_ASSERT(mc.
GetWidth() == sdim,
"");
1445 for (
int k = 0; k <
dof; k++)
1451 MQ.
Mult(tk_phys, dofs_k);
1452 for (
int r = 0; r < MQ.
Height(); r++)
1454 dofs(k+
dof*r) = dofs_k(r);
1470 for (
int k = 0; k <
dof; k++)
1482 for (
int d = 0; d < sdim; d++)
1488 for (
int j = 0; j < shape.
Size(); j++)
1491 if (fabs(s) < 1e-12)
1497 for (
int d = 0; d < sdim; d++)
1499 I(k, j + d*shape.
Size()) = s*vk[d];
1512 for (
int k = 0; k <
dof; k++)
1524 for (
int j=0; j<vshapetk.
Size(); j++)
1526 I(k, j) = vshapetk(j);
1542 for (
int k = 0; k <
dof; k++)
1545 dshape.
Mult(tk + d2t[k]*
dim, grad_k);
1546 for (
int j = 0; j < grad_k.
Size(); j++)
1548 grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1563 DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs);
1564 const int ir_order =
1580 for (
int k=0; k<fs; ++k)
1582 for (
int j=0; j<cs; ++j)
1585 for (
int d1=0; d1<
dim; ++d1)
1587 for (
int d2=0; d2<
dim; ++d2)
1589 Mkj += w*fine_shape(k,d1)*adjJ(d2,d1)*coarse_shape(j,d2);
1592 fine_coarse_mass(k,j) += (fabs(Mkj) < 1e-12) ? 0.0 : Mkj;
1597 fine_mass_inv.
Mult(fine_coarse_mass, I);
1611#ifdef MFEM_THREAD_SAFE
1621 for (
int k = 0; k <
dof; k++)
1632 for (
int i = 0; i <
dim; i++)
1634 Ikj +=
vshape(j, i) * vk[i];
1636 I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1651 DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs);
1652 const int ir_order =
1667 for (
int k=0; k<fs; ++k)
1669 for (
int j=0; j<cs; ++j)
1672 for (
int d1=0; d1<
dim; ++d1)
1674 for (
int d2=0; d2<
dim; ++d2)
1676 Mkj += ip.
weight*fine_shape(k,d1)*J(d1,d2)*coarse_shape(j,d2);
1679 fine_coarse_mass(k,j) += (fabs(Mkj) < 1e-12) ? 0.0 : Mkj;
1684 fine_mass_inv.
Mult(fine_coarse_mass, I);
1696#ifdef MFEM_THREAD_SAFE
1706 for (
int k = 0; k <
dof; k++)
1717 for (
int i = 0; i <
dim; i++)
1719 Ikj +=
vshape(j, i) * vk[i];
1721 I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1734#ifdef MFEM_THREAD_SAFE
1741 for (
int j = 0; j <
dof; j++)
1750 for (
int k = 0; k <
dof; k++)
1753 for (
int d = 0; d <
dim; d++)
1755 R_jk +=
vshape(k,d)*pt_data[d];
1777#ifdef MFEM_THREAD_SAFE
1783 for (
int j = 0; j <
dof; j++)
1790 Jinv.
Mult(tk+
dim*d2t[j], pt_data);
1791 for (
int k = 0; k <
dof; k++)
1794 for (
int d = 0; d <
dim; d++)
1796 R_jk +=
vshape(k,d)*pt_data[d];
1812 : etype(etype), auxiliary_basis(NULL), scale_integrated(false)
1821 for (
int i = 0; i <=
p; i++)
1835 for (
int i = 0; i <=
p; i++)
1837 for (
int j = 0; j < i; j++)
1839 real_t xij = x(i) - x(j);
1844 for (
int i = 0; i <=
p; i++)
1851 for (
int i = 0; i <
p; i++)
1855 mfem_error(
"Poly_1D::Basis::Basis : nodes are not increasing!");
1865 auxiliary_basis =
new Basis(
1887 int i, k,
p = x.Size() - 1;
1897 for (k = 0; k <
p; k++)
1899 if (y >= (x(k) + x(k+1))/2)
1905 for (i = k+1; i <=
p; i++)
1912 l = lk * (y - x(k));
1914 for (i = 0; i < k; i++)
1916 u(i) = l * w(i) / (y - x(i));
1919 for (i++; i <=
p; i++)
1921 u(i) = l * w(i) / (y - x(i));
1929 auxiliary_basis->Eval(y, u_aux, d_aux);
1930 EvalIntegrated(d_aux,
u);
1949 int i, k,
p = x.Size() - 1;
1950 real_t l, lp, lk, sk, si;
1960 for (k = 0; k <
p; k++)
1962 if (y >= (x(k) + x(k+1))/2)
1968 for (i = k+1; i <=
p; i++)
1975 l = lk * (y - x(k));
1978 for (i = 0; i < k; i++)
1980 si = 1.0/(y - x(i));
1982 u(i) = l * si * w(i);
1985 for (i++; i <=
p; i++)
1987 si = 1.0/(y - x(i));
1989 u(i) = l * si * w(i);
1993 for (i = 0; i < k; i++)
1995 d(i) = (lp * w(i) -
u(i))/(y - x(i));
1998 for (i++; i <=
p; i++)
2000 d(i) = (lp * w(i) -
u(i))/(y - x(i));
2008 auxiliary_basis->Eval(y, u_aux, d_aux, d2_aux);
2009 EvalIntegrated(d_aux,
u);
2010 EvalIntegrated(d2_aux,d);
2020 "Basis::Eval with second order derivatives not implemented for"
2021 " etype = " << etype);
2034 int i, k,
p = x.Size() - 1;
2035 real_t l, lp, lp2, lk, sk, si, sk2;
2046 for (k = 0; k <
p; k++)
2048 if (y >= (x(k) + x(k+1))/2)
2054 for (i = k+1; i <=
p; i++)
2061 l = lk * (y - x(k));
2065 for (i = 0; i < k; i++)
2067 si = 1.0/(y - x(i));
2070 u(i) = l * si * w(i);
2073 for (i++; i <=
p; i++)
2075 si = 1.0/(y - x(i));
2078 u(i) = l * si * w(i);
2081 lp2 = lp * sk + l * sk2 + sk * lk;
2083 for (i = 0; i < k; i++)
2085 d(i) = (lp * w(i) -
u(i))/(y - x(i));
2086 d2(i) = (lp2 * w(i) - 2 * d(i))/(y - x(i));
2089 d2(k) = sk2 *
u(k) + sk * d(k);
2090 for (i++; i <=
p; i++)
2092 d(i) = (lp * w(i) -
u(i))/(y - x(i));
2093 d2(i) = (lp2 * w(i) - 2 * d(i))/(y - x(i));
2101 MFEM_ABORT(
"Integrated basis must be evaluated with EvalIntegrated");
2110 "EvalIntegrated is only valid for Integrated basis type");
2111 int p = d_aux_.
Size() - 1;
2115 for (
int j=1; j<
p; ++j)
2117 u[j] =
u[j-1] - d_aux_[j];
2122 if (scale_integrated)
2124 Vector &aux_nodes = auxiliary_basis->x;
2125 for (
int j=0; j<aux_nodes.
Size()-1; ++j)
2127 u[j] *= aux_nodes[j+1] - aux_nodes[j];
2134 scale_integrated = scale_integrated_;
2139 delete auxiliary_basis;
2147 for (
int i = 0; i <=
p; i++)
2149 binom(i,0) = binom(i,i) = 1;
2150 for (
int j = 1; j < i; j++)
2152 binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
2161 for (
int i = 0; i <=
p; i++)
2164 real_t s = sin(M_PI_2*(i + 0.5)/(
p + 1));
2173 for (
int n = 1; n <=
p; n++)
2184 for (
int n = 1; n <=
p; n++)
2204 for (i = 1; i <
p; i++)
2211 for (i--; i > 0; i--)
2232 const real_t xpy = x + y, ptx =
p*x;
2235 for (i = 1; i <
p; i++)
2237 d[i] =
b[i]*z*(i*xpy - ptx);
2244 for (i--; i > 0; i--)
2266 const real_t xpy = x + y, ptx =
p*x;
2269 for (i = 1; i <
p; i++)
2271 d[i] =
b[i]*z*(i*xpy - ptx);
2276 for (i--; i > 0; i--)
2298 for (i = 1; i <
p; i++)
2305 for (i--; i > 0; i--)
2327 for (i = 1; i <
p; i++)
2334 for (i--; i > 0; i--)
2336 u[i] *= (
p - i) * z;
2349 if (
p == 0) {
return; }
2350 u[1] = z = 2.*x - 1.;
2351 for (
int n = 1; n <
p; n++)
2353 u[n+1] = ((2*n + 1)*z*
u[n] - n*
u[n-1])/(n + 1);
2366 if (
p == 0) {
return; }
2367 u[1] = z = 2.*x - 1.;
2369 for (
int n = 1; n <
p; n++)
2371 u[n+1] = ((2*n + 1)*z*
u[n] - n*
u[n-1])/(n + 1);
2372 d[n+1] = (4*n + 2)*
u[n] + d[n-1];
2376void Poly_1D::CalcChebyshev(
const int p,
const real_t x,
real_t *
u)
2383 if (
p == 0) {
return; }
2384 u[1] = z = 2.*x - 1.;
2385 for (
int n = 1; n <
p; n++)
2387 u[n+1] = 2*z*
u[n] -
u[n-1];
2404 if (
p == 0) {
return; }
2405 u[1] = z = 2.*x - 1.;
2407 for (
int n = 1; n <
p; n++)
2409 u[n+1] = 2*z*
u[n] -
u[n-1];
2410 d[n+1] = (n + 1)*(z*d[n]/n + 2*
u[n]);
2430 if (
p == 0) {
return; }
2431 u[1] = z = 2.*x - 1.;
2434 for (
int n = 1; n <
p; n++)
2436 u[n+1] = 2*z*
u[n] -
u[n-1];
2437 d[n+1] = (n + 1)*(z*d[n]/n + 2*
u[n]);
2438 dd[n+1] = (n + 1)*(2.*(n + 1)*d[n] + z*dd[n])/n;
2449#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
2450 #pragma omp critical (Poly1DGetPoints)
2453 std::pair<int, int> key(btype,
p);
2454 auto it = points_container.find(key);
2455 if (it == points_container.end())
2457 it = points_container.emplace(key,
new Array<real_t>(
p + 1, h_mt)).first;
2458 val = it->second.get();
2464 val = it->second.get();
2475#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
2476 #pragma omp critical (Poly1DGetBasis)
2479 std::pair<int, int> key(btype,
p);
2480 auto it = bases_container.find(key);
2481 if (it == bases_container.end())
2487 it = bases_container
2491 val = it->second.get();
2511 for (
int i = 1; i <
p; i++)
2519 const int p1 =
p + 1;
2530 for (
int i = 1; i <
p; i++)
2534 for (
int i = 1; i <
p; i++)
2538 for (
int i = 1; i <
p; i++)
2542 for (
int i = 1; i <
p; i++)
2548 for (
int j = 1; j <
p; j++)
2550 for (
int i = 1; i <
p; i++)
2559 const int p1 =
p + 1;
2563 dof_map[0 + (0 + 0*p1)*p1] = 0;
2575 for (
int i = 1; i <
p; i++)
2577 dof_map[i + (0 + 0*p1)*p1] = o++;
2579 for (
int i = 1; i <
p; i++)
2583 for (
int i = 1; i <
p; i++)
2587 for (
int i = 1; i <
p; i++)
2589 dof_map[0 + (i + 0*p1)*p1] = o++;
2591 for (
int i = 1; i <
p; i++)
2595 for (
int i = 1; i <
p; i++)
2599 for (
int i = 1; i <
p; i++)
2603 for (
int i = 1; i <
p; i++)
2607 for (
int i = 1; i <
p; i++)
2609 dof_map[0 + (0 + i*p1)*p1] = o++;
2611 for (
int i = 1; i <
p; i++)
2615 for (
int i = 1; i <
p; i++)
2619 for (
int i = 1; i <
p; i++)
2625 for (
int j = 1; j <
p; j++)
2627 for (
int i = 1; i <
p; i++)
2629 dof_map[i + ((
p-j) + 0*p1)*p1] = o++;
2632 for (
int j = 1; j <
p; j++)
2634 for (
int i = 1; i <
p; i++)
2636 dof_map[i + (0 + j*p1)*p1] = o++;
2639 for (
int j = 1; j <
p; j++)
2641 for (
int i = 1; i <
p; i++)
2646 for (
int j = 1; j <
p; j++)
2648 for (
int i = 1; i <
p; i++)
2653 for (
int j = 1; j <
p; j++)
2655 for (
int i = 1; i <
p; i++)
2657 dof_map[0 + ((
p-i) + j*p1)*p1] = o++;
2660 for (
int j = 1; j <
p; j++)
2662 for (
int i = 1; i <
p; i++)
2669 for (
int k = 1; k <
p; k++)
2671 for (
int j = 1; j <
p; j++)
2673 for (
int i = 1; i <
p; i++)
2675 dof_map[i + (j + k*p1)*p1] = o++;
2682 MFEM_ABORT(
"invalid dimension: " << dims);
2693 MFEM_ABORT(
"invalid DofMapType: " << dmtype);
2705#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
2706 #pragma omp critical (DofToQuad)
2724 Vector val(ndof), grad(ndof);
2725 for (
int i = 0; i < nqpt; i++)
2730 for (
int j = 0; j < ndof; j++)
2732 d2q->
B[i+nqpt*j] = d2q->
Bt[j+ndof*i] = val(j);
2733 d2q->
G[i+nqpt*j] = d2q->
Gt[j+ndof*i] = grad(j);
2736 dof2quad_array.
Append(d2q);
2783 internal::GetTensorFaceMap(
dim,
order, face_id, face_map);
2796 obasis1d(
poly1d.GetBasis(
p - 1, VerifyOpen(obtype)))
2798 MFEM_VERIFY(dims > 1,
"Constructor for VectorTensorFiniteElement with both "
2799 "open and closed bases is not valid for 1D elements.");
2811 obasis1d(
poly1d.GetBasis(
p, VerifyOpen(obtype)))
2813 MFEM_VERIFY(dims == 1,
"Constructor for VectorTensorFiniteElement without "
2814 "closed basis is only valid for 1D elements.");
2819 for (
int i = 0; i < dof2quad_array_open.Size(); i++)
2821 delete dof2quad_array_open[i];
void SetSize(int m, int n)
Set the 2D array size to m x n.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void Abs()
Replace each entry of the array with its absolute value.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
static int GetQuadrature1D(int b_type)
Get the corresponding Quadrature1D constant, when that makes sense; otherwise return Quadrature1D::In...
static int Check(int b_type)
If the input does not represent a valid BasisType, abort with an error; otherwise return the input.
@ GaussLobatto
Closed type.
@ Positive
Bernstein polynomials.
@ IntegratedGLL
Integrated GLL indicator functions.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the coefficient in the element described by T at the point ip.
void Factor()
Factor the current DenseMatrix, *a.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication with the inverse of dense matrix.
Data type dense matrix using column-major storage.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
void Threshold(real_t eps)
Replace small entries, abs(a_ij) <= eps, with zero.
void SetRow(int r, const real_t *row)
void GetColumnReference(int c, Vector &col)
real_t InnerProduct(const real_t *x, const real_t *y) const
Compute y^t A x.
real_t * Data() const
Returns the matrix data array. Warning: this method casts away constness.
real_t * GetData() const
Returns the matrix data array. Warning: this method casts away constness.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
void Invert()
Replaces the current matrix with its inverse.
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
void GetColumn(int c, Vector &col) const
real_t FNorm2() const
Compute the square of the Frobenius norm of the matrix.
Structure representing the matrices/tensors needed to evaluate (in reference space) the values,...
Mode mode
Describes the contents of the B, Bt, G, and Gt arrays, see Mode.
const IntegrationRule * IntRule
IntegrationRule that defines the quadrature points at which the basis functions of the FE are evaluat...
Array< real_t > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
Mode
Type of data stored in the arrays B, Bt, G, and Gt.
@ FULL
Full multidimensional representation which does not use tensor product structure. The ordering of the...
@ LEXICOGRAPHIC_FULL
Full multidimensional representation which does not use tensor product structure. The ordering of the...
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Array< real_t > B
Basis functions evaluated at quadrature points.
static DofToQuad * SearchArray(const Array< DofToQuad * > &dof2quad_array, const IntegrationRule &ir, DofToQuad::Mode mode)
Auxiliary function for searching DofToQuad arrays.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
Array< real_t > Gt
Transpose of G.
const class FiniteElement * FE
The FiniteElement that created and owns this object.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Array< real_t > Bt
Transpose of B.
DofToQuad Abs() const
Returns absolute value of the maps.
Abstract class for all finite elements.
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
int dof
Number of degrees of freedom.
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &Hessian) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Given a matrix coefficient and a transformation, compute an approximation ("projection") in the local...
virtual ~FiniteElement()
Deconstruct the FiniteElement.
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Compute the discrete divergence matrix from the given FiniteElement onto 'this' FiniteElement....
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector of values at the finite element nodes and a transformation, compute its projection (ap...
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Get the dofs associated with the given face. *dofs is set to an internal array of the local dofc on t...
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
int GetRangeDim() const
Returns the vector dimension for vector-valued finite elements, which is also the dimension of the in...
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
void CalcPhysDShape(ElementTransformation &Trans, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in physical space at the poi...
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Compute the discrete gradient matrix from the given FiniteElement onto 'this' FiniteElement....
virtual void GetFaceMap(const int face_id, Array< int > &face_map) const
Return the mapping from lexicographic face DOFs to lexicographic element DOFs for the given local fac...
int GetDim() const
Returns the reference space dimension for the finite element.
int vdim
Vector dimension of vector-valued basis functions.
void CalcPhysHessian(ElementTransformation &Trans, DenseMatrix &Hessian) const
Evaluate the Hessian of all shape functions of a scalar finite element in physical space at the given...
FiniteElement(int D, Geometry::Type G, int Do, int O, int F=FunctionSpace::Pk)
Construct FiniteElement with given.
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
int orders[Geometry::MaxDim]
Anisotropic orders.
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...
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
int GetRangeType() const
Returns the FiniteElement::RangeType of the element, one of {SCALAR, VECTOR}.
virtual void GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs.
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
int cdim
Dimension of curl for vector-valued basis functions.
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
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...
@ DIV
Implements CalcDivShape methods.
@ NONE
No derivatives implemented.
@ CURL
Implements CalcCurlShape methods.
@ GRAD
Implements CalcDShape methods.
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
Geometry::Type geom_type
Geometry::Type of the reference element.
void CalcPhysDivShape(ElementTransformation &Trans, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in physical space at the po...
Array< DofToQuad * > dof2quad_array
Container for all DofToQuad objects created by the FiniteElement.
void CalcPhysLaplacian(ElementTransformation &Trans, Vector &Laplacian) const
Evaluate the Laplacian of all shape functions of a scalar finite element in physical space at the giv...
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...
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Compute the discrete curl matrix from the given FiniteElement onto 'this' FiniteElement....
virtual void CalcPhysCurlShape(ElementTransformation &Trans, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in physical space at the point de...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
int order
Order/degree of the shape functions.
void CalcPhysLinLaplacian(ElementTransformation &Trans, Vector &Laplacian) const
Evaluate the Laplacian of all shape functions of a scalar finite element in physical space at the giv...
int dim
Dimension of reference space.
void CalcPhysShape(ElementTransformation &Trans, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in physical space at the point ...
Describes the function space on each element.
const IntegrationPoint & GetCenter(int GeomType) const
Return the center of the given Geometry::Type, GeomType.
static bool CheckPoint(int GeomType, const IntegrationPoint &ip)
Check if the given point is inside the given reference element.
Class for integration point with weight.
void Get(real_t *p, const int dim) const
void Set(const real_t x1, const real_t x2, const real_t x3, const real_t w)
void Set3(const real_t x1, const real_t x2, const real_t x3)
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
virtual void Eval(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the matrix coefficient in the element described by T at the point ip, storing the result in ...
int GetWidth() const
Get the width of the matrix.
int GetHeight() const
Get the height of the matrix.
Class for standard nodal finite elements.
void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const override
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
void ReorderLexToNative(int ncomp, Vector &dofs) const
void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const override
Compute the discrete divergence matrix from the given FiniteElement onto 'this' FiniteElement....
void GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const override
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs.
void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const override
Compute the discrete gradient matrix from the given FiniteElement onto 'this' FiniteElement....
void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const override
Given a matrix coefficient and a transformation, compute an approximation ("projection") in the local...
Array< int > lex_ordering
const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const override
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
void GetFaceMap(const int face_id, Array< int > &face_map) const override
Return the mapping from lexicographic face DOFs to lexicographic element DOFs for the given local fac...
NodalTensorFiniteElement(const int dims, const int p, const int btype, const DofMapType dmtype)
const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const override
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
void SetMapType(const int map_type_) override
Set the FiniteElement::MapType of the element to either VALUE or INTEGRAL. Also sets the FiniteElemen...
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Class for evaluating 1D nodal, positive (Bernstein), or integrated (Gerritsma) bases.
void Eval(const real_t x, Vector &u) const
Evaluate the basis functions at point x in [0,1].
bool IsIntegratedType() const
Returns true if the basis is "integrated", false otherwise.
void ScaleIntegrated(bool scale_integrated_)
Set whether the "integrated" basis should be scaled by the subcell sizes. Has no effect for non-integ...
void EvalIntegrated(const Vector &d, Vector &i) const
Evaluate the "integrated" basis type using pre-computed closed basis derivatives.
Basis(const int p, const real_t *nodes, EvalType etype=Barycentric)
Create a nodal or positive (Bernstein) basis of degree p.
static void CalcDBinomTerms(const int p, const real_t x, const real_t y, real_t *d)
Compute the derivatives (w.r.t. x) of the terms in the expansion of the binomial (x + y)^p assuming t...
const real_t * GetPoints(const int p, const int btype, bool on_device=false)
Get the coordinates of the points of the given BasisType, btype.
static const int * Binom(const int p)
Get a pointer to an array containing the binomial coefficients "pchoose k" for k=0,...
Basis & GetBasis(const int p, const int btype)
Get a Poly_1D::Basis object of the given degree and BasisType, btype.
const Array< real_t > * GetPointsArray(const int p, const int btype)
Get the coordinates of the points of the given BasisType, btype.
static void CalcDyBinomTerms(const int p, const real_t x, const real_t y, real_t *d)
Compute the derivatives (w.r.t. y) of the terms in the expansion of the binomial (x + y)^p....
static void CalcLegendre(const int p, const real_t x, real_t *u)
static void CalcBernstein(const int p, const real_t x, real_t *u)
Compute the values of the Bernstein basis functions of order p at coordinate x and store the results ...
EvalType
One-dimensional basis evaluation type.
@ ChangeOfBasis
Use change of basis, O(p^2) Evals.
@ Integrated
Integrated indicator functions (cf. Gerritsma)
@ Positive
Fast evaluation of Bernstein polynomials.
@ Barycentric
Use barycentric Lagrangian interpolation, O(p) Evals.
static void ChebyshevPoints(const int p, real_t *x)
Compute the points for the Chebyshev polynomials of order p and place them in the already allocated x...
static void CalcBasis(const int p, const real_t x, real_t *u)
Evaluate the values of a hierarchical 1D basis at point x hierarchical = k-th basis function is degre...
static void CalcBinomTerms(const int p, const real_t x, const real_t y, real_t *u)
Compute the p terms in the expansion of the binomial (x + y)^p and store them in the already allocate...
static void CalcDxBinomTerms(const int p, const real_t x, const real_t y, real_t *d)
Compute the derivatives (w.r.t. x) of the terms in the expansion of the binomial (x + y)^p....
static void GivePolyPoints(const int np, real_t *pts, const int type)
Class for finite elements with basis functions that return scalar values.
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
Get the matrix I that defines nodal interpolation between this element and the refined element fine_f...
virtual void SetMapType(int M)
Set the FiniteElement::MapType of the element to either VALUE or INTEGRAL. Also sets the FiniteElemen...
void ScalarLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
Get matrix I "Interpolation" defined through local L2-projection in the space defined by the fine_fe.
void ScalarLocalL2Restriction(ElementTransformation &Trans, DenseMatrix &R, const ScalarFiniteElement &coarse_fe) const
Get restriction matrix R defined through local L2-projection in the space defined by the coarse_fe.
static const DofToQuad & GetTensorDofToQuad(const FiniteElement &fe, const IntegrationRule &ir, DofToQuad::Mode mode, const Poly_1D::Basis &basis, bool closed, Array< DofToQuad * > &dof2quad_array)
TensorBasisElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Base class for vector Coefficients that optionally depend on time and space.
int GetVDim()
Returns dimension of the vector.
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
Intermediate class for finite elements whose basis functions return vector values.
void ProjectCurl2D_RT(const real_t *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
void LocalRestriction_RT(const real_t *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &R) const
void Project_ND(const real_t *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Project a vector coefficient onto the ND basis functions.
void Project_RT(const real_t *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Project a vector coefficient onto the RT basis functions.
void LocalInterpolation_RT(const VectorFiniteElement &cfe, const real_t *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
void ProjectMatrixCoefficient_ND(const real_t *tk, const Array< int > &d2t, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Project the rows of the matrix coefficient in an ND space.
void LocalRestriction_ND(const real_t *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &R) const
void LocalL2Projection_RT(const VectorFiniteElement &cfe, ElementTransformation &Trans, DenseMatrix &I) const
void ProjectGrad_ND(const real_t *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
VectorFiniteElement(int D, Geometry::Type G, int Do, int O, int M, int F=FunctionSpace::Pk)
void LocalInterpolation_ND(const VectorFiniteElement &cfe, const real_t *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
void LocalL2Projection_ND(const VectorFiniteElement &cfe, ElementTransformation &Trans, DenseMatrix &I) const
void ProjectCurl_ND(const real_t *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
void ProjectMatrixCoefficient_RT(const real_t *nk, const Array< int > &d2n, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Project the rows of the matrix coefficient in an RT space.
void ProjectCurl3D_RT(const real_t *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
virtual ~VectorTensorFiniteElement()
VectorTensorFiniteElement(const int dims, const int d, const int p, const int cbtype, const int obtype, const int M, const DofMapType dmtype)
void SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
void trans(const Vector &u, Vector &x)
real_t weight(const Vector &x)
real_t u(const Vector &xvec)
void mfem_error(const char *msg)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
void AddMult_a_VWt(const real_t a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
void AddMult_a_VVt(const real_t a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
void AddMult_a_AAt(real_t a, const DenseMatrix &A, DenseMatrix &AAt)
AAt += a * A * A^t.
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
void InvertLinearTrans(ElementTransformation &trans, const IntegrationPoint &pt, Vector &x)
constexpr real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
real_t p(const Vector &x, real_t t)
std::array< int, NCMesh::MaxFaceNodes > nodes