37 assert(quad.
weights.minCoeff() > 0 &&
"Felippa quadrature weight non-positive");
38 assert(fabs(quad.
weights.sum() - 1.0 / 3.0) < 1e-12);
39 assert(quad.
points.minCoeff() >= 0 && quad.
points.maxCoeff() <= 1);
54 const int n = (order + 4) / 2;
58 Eigen::VectorXd t(n), w(n);
62 Eigen::MatrixXd J = Eigen::MatrixXd::Zero(n, n);
63 for (
int i = 1; i < n; ++i)
65 const double b = i / std::sqrt(4.0 * i * i - 1.0);
69 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(J);
71 w = 2.0 * es.eigenvectors().row(0).cwiseAbs2().transpose();
74 const Eigen::VectorXd xi1d = (t.array() + 1.0) * 0.5;
75 const Eigen::VectorXd w1d = w * 0.5;
77 const int nq = n * n * n;
82 for (
int i = 0; i < n; ++i)
83 for (
int j = 0; j < n; ++j)
84 for (
int k = 0; k < n; ++k)
86 const double xi = xi1d(i);
87 const double eta = xi1d(j);
88 const double zeta = xi1d(k);
89 const double one_minus_zeta = 1.0 - zeta;
92 assert(one_minus_zeta > 0 &&
"Duffy Jacobian degenerate: quadrature point at pyramid apex");
93 quad.
points(idx, 0) = xi * one_minus_zeta;
94 quad.
points(idx, 1) = eta * one_minus_zeta;
95 quad.
points(idx, 2) = zeta;
96 quad.
weights(idx) = w1d(i) * w1d(j) * w1d(k) * one_minus_zeta * one_minus_zeta;
100 assert(quad.
weights.minCoeff() > 0 &&
"Duffy quadrature weight non-positive");
101 assert(fabs(quad.
weights.sum() - 1.0 / 3.0) < 1e-10);
102 assert(quad.
points.minCoeff() >= -1e-14);