91 std::list<unsigned int> cellDofs;
92 std::vector<std::list<unsigned int>> edgeDofs(3);
94 Eigen::MatrixXd localDofPositions = Eigen::MatrixXd::Zero(3, result.
NumBasisFunctions);
95 Eigen::MatrixXi localDofTypes = Eigen::MatrixXi::Zero(3, result.
NumBasisFunctions);
97 const double h = 1.0 / order;
99 for (
unsigned int i = 0; i < order + 1; i++)
101 for (
unsigned int j = 0; j < order + 1 - i; j++)
105 if (j > 0 && j < order - i)
106 edgeDofs[0].push_back(dof);
108 else if (i < order && (j == 0 || j == order - i))
111 edgeDofs[2].push_front(dof);
113 edgeDofs[1].push_back(dof);
116 cellDofs.push_back(dof);
118 localDofPositions.col(dof) << (double)j * h, (
double)i * h, 0.0;
119 localDofTypes.col(dof) << order - i - j, j, i;
133 for (
const unsigned int dofIndex : nodeDofs)
135 result.
DofPositions.col(dof) << localDofPositions.col(dofIndex);
136 result.
DofTypes.col(dof) << localDofTypes.col(dofIndex);
139 for (
unsigned int e = 0; e < 3; e++)
141 for (
const unsigned int dofIndex : edgeDofs.at(e))
143 result.
DofPositions.col(dof) << localDofPositions.col(dofIndex);
144 result.
DofTypes.col(dof) << localDofTypes.col(dofIndex);
148 for (
const unsigned int dofIndex : cellDofs)
150 result.
DofPositions.col(dof) << localDofPositions.col(dofIndex);
151 result.
DofTypes.col(dof) << localDofTypes.col(dofIndex);
176 switch (reference_element_data.
Order)
179 return Eigen::VectorXd::Constant(points.cols(), 1.0);
181 const double h = 1.0 / reference_element_data.
Order;
182 const Eigen::ArrayXd x = points.row(0).transpose();
183 const Eigen::ArrayXd y = points.row(1).transpose();
184 Eigen::MatrixXd values = Eigen::MatrixXd::Ones(points.cols(), reference_element_data.
NumBasisFunctions);
188 const Eigen::Vector3i &dofType = reference_element_data.
DofTypes.col(d);
189 const Eigen::Vector3d &dofPosition = reference_element_data.
DofPositions.col(d);
192 for (
unsigned int t = 0; t < static_cast<unsigned int>(dofType[0]); t++)
194 values.col(d).array() *= (1.0 - x - y - t * h);
195 values.col(d) /= (1.0 - dofPosition.x() - dofPosition.y() - t * h);
199 for (
unsigned int t = 0; t < static_cast<unsigned int>(dofType[1]); t++)
201 values.col(d).array() *= (x - t * h);
202 values.col(d) /= (dofPosition.x() - t * h);
206 for (
unsigned int t = 0; t < static_cast<unsigned int>(dofType[2]); t++)
208 values.col(d).array() *= (y - t * h);
209 values.col(d) /= (dofPosition.y() - t * h);
220 switch (reference_element_data.
Order)
223 return std::vector<Eigen::MatrixXd>(reference_element_data.
Dimension,
226 const double h = 1.0 / reference_element_data.
Order;
227 const Eigen::ArrayXd x = points.row(0).transpose().array();
228 const Eigen::ArrayXd y = points.row(1).transpose().array();
229 std::vector<Eigen::MatrixXd> gradValues(reference_element_data.
Dimension,
234 const Eigen::Vector3i &dofType = reference_element_data.
DofTypes.col(d);
235 const Eigen::Vector3d &dofPosition = reference_element_data.
DofPositions.col(d);
237 const unsigned int numProds = dofType[0] + dofType[1] + dofType[2];
239 std::vector<Eigen::ArrayXd> prod_terms(numProds);
240 std::vector<Eigen::Array2d> grad_terms(numProds);
241 double denominator = 1.0;
245 for (
unsigned int t = 0; t < static_cast<unsigned int>(dofType[0]); t++)
247 prod_terms[dt] = (1.0 - x - y - t * h);
248 grad_terms[dt] << -1.0, -1.0;
249 denominator *= (1.0 - dofPosition.x() - dofPosition.y() - t * h);
254 for (
unsigned int t = 0; t < static_cast<unsigned int>(dofType[1]); t++)
256 prod_terms[dt] = (x - t * h);
257 grad_terms[dt] << 1.0, 0.0;
258 denominator *= (dofPosition.x() - t * h);
263 for (
unsigned int t = 0; t < static_cast<unsigned int>(dofType[2]); t++)
265 prod_terms[dt] = (y - t * h);
266 grad_terms[dt] << 0.0, 1.0;
267 denominator *= (dofPosition.y() - t * h);
271 for (
unsigned int i = 0; i < numProds; i++)
273 Eigen::ArrayXd inner_prod = Eigen::ArrayXd::Ones(points.cols());
274 for (
unsigned int j = 0; j < numProds; j++)
277 inner_prod *= prod_terms[j];
280 gradValues[0].col(d).array() += inner_prod * grad_terms[i][0];
281 gradValues[1].col(d).array() += inner_prod * grad_terms[i][1];
284 gradValues[0].col(d) /= denominator;
285 gradValues[1].col(d) /= denominator;
294 const Eigen::MatrixXd &points,
297 switch (reference_element_data.
Order)
301 const Eigen::MatrixXd zero_matrix = Eigen::MatrixXd::Zero(points.cols(), reference_element_data.
NumBasisFunctions);
302 return {zero_matrix, zero_matrix, zero_matrix, zero_matrix};
305 std::array<Eigen::MatrixXd, 4> constant_laplacian;
307 for (
unsigned int der = 0; der < 4; ++der)
308 constant_laplacian[der] = Eigen::MatrixXd::Zero(points.cols(), reference_element_data.
NumBasisFunctions);
310 constant_laplacian[0].col(0) = Eigen::VectorXd::Constant(points.cols(), +4.0);
311 constant_laplacian[1].col(0) = Eigen::VectorXd::Constant(points.cols(), +4.0);
312 constant_laplacian[2].col(0) = Eigen::VectorXd::Constant(points.cols(), +4.0);
313 constant_laplacian[3].col(0) = Eigen::VectorXd::Constant(points.cols(), +4.0);
315 constant_laplacian[0].col(1) = Eigen::VectorXd::Constant(points.cols(), +4.0);
316 constant_laplacian[1].col(1) = Eigen::VectorXd::Constant(points.cols(), +0.0);
317 constant_laplacian[2].col(1) = Eigen::VectorXd::Constant(points.cols(), +0.0);
318 constant_laplacian[3].col(1) = Eigen::VectorXd::Constant(points.cols(), +0.0);
320 constant_laplacian[0].col(2) = Eigen::VectorXd::Constant(points.cols(), +0.0);
321 constant_laplacian[1].col(2) = Eigen::VectorXd::Constant(points.cols(), +0.0);
322 constant_laplacian[2].col(2) = Eigen::VectorXd::Constant(points.cols(), +0.0);
323 constant_laplacian[3].col(2) = Eigen::VectorXd::Constant(points.cols(), +4.0);
325 constant_laplacian[0].col(3) = Eigen::VectorXd::Constant(points.cols(), -8.0);
326 constant_laplacian[1].col(3) = Eigen::VectorXd::Constant(points.cols(), -4.0);
327 constant_laplacian[2].col(3) = Eigen::VectorXd::Constant(points.cols(), -4.0);
328 constant_laplacian[3].col(3) = Eigen::VectorXd::Constant(points.cols(), +0.0);
330 constant_laplacian[0].col(4) = Eigen::VectorXd::Constant(points.cols(), +0.0);
331 constant_laplacian[1].col(4) = Eigen::VectorXd::Constant(points.cols(), +4.0);
332 constant_laplacian[2].col(4) = Eigen::VectorXd::Constant(points.cols(), +4.0);
333 constant_laplacian[3].col(4) = Eigen::VectorXd::Constant(points.cols(), +0.0);
335 constant_laplacian[0].col(5) = Eigen::VectorXd::Constant(points.cols(), +0.0);
336 constant_laplacian[1].col(5) = Eigen::VectorXd::Constant(points.cols(), -4.0);
337 constant_laplacian[2].col(5) = Eigen::VectorXd::Constant(points.cols(), -4.0);
338 constant_laplacian[3].col(5) = Eigen::VectorXd::Constant(points.cols(), -8.0);
340 return constant_laplacian;
343 std::array<Eigen::MatrixXd, 4> laplacian;
345 for (
unsigned int der = 0; der < 4; ++der)
346 laplacian[der] = Eigen::MatrixXd::Zero(points.cols(), reference_element_data.
NumBasisFunctions);
348 const Eigen::ArrayXd x = points.row(0);
349 const Eigen::ArrayXd y = points.row(1);
351 laplacian[0].col(0) = 18.0 - 27.0 * y - 27.0 * x;
352 laplacian[1].col(0) = 18.0 - 27.0 * y - 27.0 * x;
353 laplacian[2].col(0) = 18.0 - 27.0 * y - 27.0 * x;
354 laplacian[3].col(0) = 18.0 - 27.0 * y - 27.0 * x;
356 laplacian[0].col(1) = 27.0 * x - 9;
357 laplacian[1].col(1) = Eigen::VectorXd::Constant(points.cols(), 0.0);
358 laplacian[2].col(1) = Eigen::VectorXd::Constant(points.cols(), 0.0);
359 laplacian[3].col(1) = Eigen::VectorXd::Constant(points.cols(), 0.0);
361 laplacian[0].col(2) = Eigen::VectorXd::Constant(points.cols(), 0.0);
362 laplacian[1].col(2) = Eigen::VectorXd::Constant(points.cols(), 0.0);
363 laplacian[2].col(2) = Eigen::VectorXd::Constant(points.cols(), 0.0);
364 laplacian[3].col(2) = 27.0 * y - 9;
366 laplacian[0].col(3) = 81.0 * x + 54.0 * y - 45.0;
367 laplacian[1].col(3) = 54.0 * x + 27.0 * y - 45.0 / 2.0;
368 laplacian[2].col(3) = 54.0 * x + 27.0 * y - 45.0 / 2.0;
369 laplacian[3].col(3) = 27.0 * x;
371 laplacian[0].col(4) = 36.0 - 27.0 * y - 81.0 * x;
372 laplacian[1].col(4) = 4.5 - 27.0 * x;
373 laplacian[2].col(4) = 4.5 - 27.0 * x;
374 laplacian[3].col(4) = Eigen::VectorXd::Constant(points.cols(), 0.0);
376 laplacian[0].col(5) = 27.0 * y;
377 laplacian[1].col(5) = 27.0 * x - 4.5;
378 laplacian[2].col(5) = 27.0 * x - 4.5;
379 laplacian[3].col(5) = Eigen::VectorXd::Constant(points.cols(), 0.0);
381 laplacian[0].col(6) = Eigen::VectorXd::Constant(points.cols(), 0.0);
382 laplacian[1].col(6) = 27.0 * y - 4.5;
383 laplacian[2].col(6) = 27.0 * y - 4.5;
384 laplacian[3].col(6) = 27.0 * x;
386 laplacian[0].col(7) = Eigen::VectorXd::Constant(points.cols(), 0.0);
387 laplacian[1].col(7) = 4.5 - 27.0 * y;
388 laplacian[2].col(7) = 4.5 - 27.0 * y;
389 laplacian[3].col(7) = 36.0 - 81.0 * y - 27.0 * x;
391 laplacian[0].col(8) = 27.0 * y;
392 laplacian[1].col(8) = 27.0 * x + 54.0 * y - 45.0 / 2.0;
393 laplacian[2].col(8) = 27.0 * x + 54.0 * y - 45.0 / 2.0;
394 laplacian[3].col(8) = 54.0 * x + 81.0 * y - 45.0;
396 laplacian[0].col(9) = -54.0 * y;
397 laplacian[1].col(9) = 27.0 - 54.0 * y - 54.0 * x;
398 laplacian[2].col(9) = 27.0 - 54.0 * y - 54.0 * x;
399 laplacian[3].col(9) = -54.0 * x;
404 const Eigen::MatrixXd zero_matrix = Eigen::MatrixXd::Zero(points.cols(), reference_element_data.
NumBasisFunctions);
405 return {zero_matrix, zero_matrix, zero_matrix, zero_matrix};