17#include <lf/assemble/dofhandler.h>
18#include <lf/fe/fe_point.h>
19#include <lf/fe/scalar_reference_finite_element.h>
56template <
typename SCALAR>
71 [[nodiscard]]
unsigned Degree()
const override {
return 1; }
85 LF_ASSERT_MSG(codim <= 2,
"Illegal codim " << codim);
86 return (codim == 2) ? 1 : 0;
96 LF_ASSERT_MSG(codim <= 2,
"Illegal codim " << codim);
97 LF_ASSERT_MSG((codim == 2 && subidx < 3) || (codim == 1 && subidx < 3) ||
98 (codim == 0 && subidx == 0),
99 "codim/subidx out of range.");
100 return (codim == 2) ? 1 : 0;
103 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
105 LF_ASSERT_MSG(refcoords.rows() == 2,
106 "Reference coordinates must be 2-vectors");
108 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
109 3, refcoords.cols());
110 result.row(0) = Eigen::RowVectorXd::Ones(refcoords.cols()) -
111 refcoords.row(0) - refcoords.row(1);
112 result.block(1, 0, 2, refcoords.cols()) = refcoords;
116 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
118 const Eigen::MatrixXd& refcoords)
const override {
119 LF_ASSERT_MSG(refcoords.rows() == 2,
120 "Reference coordinates must be 2-vectors");
123 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
124 3, 2 * refcoords.cols());
125 result.row(0) = Eigen::RowVectorXd::Constant(2 * n_pts, -1);
126 result.row(1) = Eigen::RowVector2d(1., 0.).replicate(1, n_pts);
127 result.row(2) = Eigen::RowVector2d(0., 1.).replicate(1, n_pts);
163template <
typename SCALAR>
178 [[nodiscard]]
unsigned Degree()
const override {
return 1; }
192 return (codim == 2) ? 1 : 0;
203 LF_ASSERT_MSG((codim == 2 && subidx < 4) || (codim == 1 && subidx < 4) ||
204 (codim == 0 && subidx == 0),
205 "codim/subidx out of range.");
206 return (codim == 2) ? 1 : 0;
209 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
211 LF_ASSERT_MSG(refcoords.rows() == 2,
212 "Reference coordinates must be 2-vectors");
214 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
215 4, refcoords.cols());
218 ((1 - refcoords.row(0).array()) * (1 - refcoords.row(1).array()))
221 ((refcoords.row(0).array()) * (1 - refcoords.row(1).array())).matrix();
223 ((refcoords.row(0).array()) * (refcoords.row(1).array())).matrix();
225 ((1 - refcoords.row(0).array()) * (refcoords.row(1).array())).matrix();
230 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
232 const Eigen::MatrixXd& refcoords)
const override {
233 LF_ASSERT_MSG(refcoords.rows() == 2,
234 "Reference coordinates must be 2-vectors");
237 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(4, 2 * n_pts);
240 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
242 temp(&result(0, 0), 8, n_pts);
243 temp.row(0) = refcoords.row(1).array() - 1.0;
244 temp.row(1) = 1.0 - refcoords.row(1).array();
245 temp.row(2) = refcoords.row(1).array();
246 temp.row(3) = -refcoords.row(1).array();
247 temp.row(4) = refcoords.row(0).array() - 1.0;
248 temp.row(5) = -refcoords.row(0).array();
249 temp.row(6) = refcoords.row(0).array();
250 temp.row(7) = 1.0 - refcoords.row(0).array();
282template <
typename SCALAR>
297 [[nodiscard]]
unsigned Degree()
const override {
return 1; }
310 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
311 return (codim == 1) ? 1 : 0;
321 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
322 LF_ASSERT_MSG((codim == 1 && subidx < 2) || (codim == 0 && subidx == 0),
323 "codim/subidx out of range.");
324 return (codim == 1) ? 1 : 0;
327 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
329 LF_ASSERT_MSG(refcoords.rows() == 1,
330 "Reference coordinates must be 1-vectors");
333 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
334 2, refcoords.cols());
335 result.row(0) = Eigen::RowVectorXd::Constant(1, n_pts, 1.0) - refcoords;
336 result.row(1) = refcoords;
341 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
343 const Eigen::MatrixXd& refcoords)
const override {
344 LF_ASSERT_MSG(refcoords.rows() == 1,
345 "Reference coordinates must be 1-vectors");
348 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
349 2, refcoords.cols());
350 result.row(0) = Eigen::MatrixXd::Constant(1, n_pts, -1.0);
351 result.row(1) = Eigen::MatrixXd::Constant(1, n_pts, 1.0);
398template <
typename SCALAR>
418 [[nodiscard]]
unsigned Degree()
const override {
return 2; }
434 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
435 return (codim == 0) ? 0 : 1;
446 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
447 return (codim == 0) ? 0 : 1;
457 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
459 LF_ASSERT_MSG(refcoords.rows() == 2,
460 "Reference coordinates must be 2-vectors");
464 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(6, n_pts);
466 auto x0 = refcoords.row(0).array();
467 auto x1 = refcoords.row(1).array();
469 result.row(0) = (2.0 * (1 - x0 - x1) * (0.5 - x0 - x1)).matrix();
470 result.row(1) = (2.0 * x0 * (x0 - 0.5)).matrix();
471 result.row(2) = (2.0 * x1 * (x1 - 0.5)).matrix();
472 result.row(3) = (4.0 * (1 - x0 - x1) * x0).matrix();
473 result.row(4) = (4.0 * x0 * x1).matrix();
474 result.row(5) = (4.0 * (1 - x0 - x1) * x1).matrix();
484 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
486 const Eigen::MatrixXd& refcoords)
const override {
487 LF_ASSERT_MSG(refcoords.rows() == 2,
488 "Reference coordinates must be 2-vectors");
491 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(6, 2 * n_pts);
493 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
495 temp(result.data(), 12, n_pts);
497 auto x0 = refcoords.row(0).array();
498 auto x1 = refcoords.row(1).array();
500 temp.row(0) = -3.0 + 4.0 * x0 + 4.0 * x1;
501 temp.row(1) = 4.0 * x0 - 1.0;
503 temp.row(3) = 4 - 0 - 8.0 * x0 - 4.0 * x1;
504 temp.row(4) = 4.0 * x1;
505 temp.row(5) = -4.0 * x1;
507 temp.row(6) = -3.0 + 4.0 * x0 + 4.0 * x1;
509 temp.row(8) = 4.0 * x1 - 1.0;
510 temp.row(9) = -4 * x0;
511 temp.row(10) = 4.0 * x0;
512 temp.row(11) = 4.0 - 8.0 * x1 - 4.0 * x0;
530 Eigen::Matrix<double, 2,6> nodes;
532 nodes << 0.0, 1.0, 0.0, 0.5, 0.5, 0.0,
533 0.0, 0.0, 1.0, 0.0, 0.5, 0.5;
561template <
typename SCALAR>
578 [[nodiscard]]
unsigned Degree()
const override {
return 2; }
596 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
607 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
625 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
627 LF_ASSERT_MSG(refcoords.rows() == 1,
628 "Reference coordinates must be 1-vectors");
631 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(3, n_pts);
633 auto x = refcoords.row(0).array();
635 result.row(0) = 2.0 * (1.0 - x) * (0.5 - x);
636 result.row(1) = 2.0 * x * (x - 0.5);
638 result.row(2) = 4.0 * (1.0 - x) * x;
651 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
653 const Eigen::MatrixXd& refcoords)
const override {
654 LF_ASSERT_MSG(refcoords.rows() == 1,
655 "Reference coordinates must be 1-vectors");
658 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(3, n_pts);
660 auto x = refcoords.row(0).array();
662 result.row(0) = (4.0 * x - 3.0).matrix();
663 result.row(1) = (4.0 * x - 1.0).matrix();
665 result.row(2) = (4.0 - 8.0 * x).matrix();
673 Eigen::Matrix<double, 1, 3> nodes;
675 nodes << 0.0, 1.0, 0.5;
711template <
typename SCALAR>
729 [[nodiscard]]
unsigned Degree()
const override {
return 2; }
745 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
757 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
778 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
780 LF_ASSERT_MSG(refcoords.rows() == 2,
781 "Reference coordinates must be 2-vectors");
784 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(9, n_pts);
787 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_eval =
788 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(0))).array();
789 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_eval =
790 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(1))).array();
793 for (
int i = 0; i < 9; ++i) {
810 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
812 const Eigen::MatrixXd& refcoords)
const override {
813 LF_ASSERT_MSG(refcoords.rows() == 2,
814 "Reference coordinates must be 2-vectors");
817 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(9, 2 * n_pts);
820 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
822 temp(&result(0, 0), 18, n_pts);
825 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_eval =
826 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(0))).array();
827 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_eval =
828 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(1))).array();
832 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_grad =
833 (
krsf_segment_.GradientsReferenceShapeFunctions(refcoords.row(0)))
835 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_grad =
836 (
krsf_segment_.GradientsReferenceShapeFunctions(refcoords.row(1)))
841 for (
int i = 0; i < 9; ++i) {
864 Eigen::Matrix<double, 2, 9> nodes;
867 nodes << 0.0, 1.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.0, 0.5,
868 0.0, 0.0, 1.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.5;
907template <
typename SCALAR>
911template <
typename SCALAR>
912const Eigen::Matrix<int, 9, 2>
915 (Eigen::Matrix<int,9,2>() << 0, 0,
943template <
typename SCALAR>
961 [[nodiscard]]
unsigned Degree()
const override {
return 3; }
979 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
980 return (codim == 1) ? 2 : 1;
993 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
994 LF_ASSERT_MSG((codim == 2 && subidx < 3) || (codim == 1 && subidx < 3) ||
995 (codim == 0 && subidx == 0),
996 "codim/subidx out of range.");
997 return (codim == 1) ? 2 : 1;
1008 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1010 LF_ASSERT_MSG(refcoords.rows() == 2,
1011 "Reference coordinates must be 2-vectors");
1013 const size_type n_pts(refcoords.cols());
1016 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(10, n_pts);
1019 Eigen::Array<double, 1, Eigen::Dynamic> lambda0 =
1020 1 - refcoords.row(0).array() - refcoords.row(1).array();
1021 Eigen::Array<double, 1, Eigen::Dynamic> lambda1 = refcoords.row(0).array();
1022 Eigen::Array<double, 1, Eigen::Dynamic> lambda2 = refcoords.row(1).array();
1026 result.row(0) = 4.5 * lambda0 * (lambda0 - 1 / 3.0) * (lambda0 - 2 / 3.0);
1027 result.row(1) = 4.5 * lambda1 * (lambda1 - 1 / 3.0) * (lambda1 - 2 / 3.0);
1028 result.row(2) = 4.5 * lambda2 * (lambda2 - 1 / 3.0) * (lambda2 - 2 / 3.0);
1030 result.row(3) = 13.5 * lambda0 * lambda1 * (lambda0 - 1 / 3.0);
1031 result.row(4) = 13.5 * lambda0 * lambda1 * (lambda1 - 1 / 3.0);
1032 result.row(5) = 13.5 * lambda1 * lambda2 * (lambda1 - 1 / 3.0);
1033 result.row(6) = 13.5 * lambda1 * lambda2 * (lambda2 - 1 / 3.0);
1034 result.row(7) = 13.5 * lambda2 * lambda0 * (lambda2 - 1 / 3.0);
1035 result.row(8) = 13.5 * lambda2 * lambda0 * (lambda0 - 1 / 3.0);
1037 result.row(9) = 27.0 * lambda0 * lambda1 * lambda2;
1049 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1051 const Eigen::MatrixXd& refcoords)
const override {
1052 LF_ASSERT_MSG(refcoords.rows() == 2,
1053 "Reference coordinates must be 2-vectors");
1055 const size_type n_pts(refcoords.cols());
1056 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(10, 2 * n_pts);
1059 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
1061 temp(&result(0, 0), 20, n_pts);
1064 Eigen::Array<double, 1, Eigen::Dynamic> l0 =
1065 1 - refcoords.row(0).array() - refcoords.row(1).array();
1066 auto l1 = refcoords.row(0).array();
1067 auto l2 = refcoords.row(1).array();
1070 temp.row(0) = -4.5 * ((l0 - 1 / 3.0) * (l0 - 2 / 3.0) +
1071 l0 * (l0 - 2 / 3.0) + l0 * (l0 - 1 / 3.0));
1072 temp.row(10) = -4.5 * ((l0 - 1 / 3.0) * (l0 - 2 / 3.0) +
1073 l0 * (l0 - 2 / 3.0) + l0 * (l0 - 1 / 3.0));
1074 temp.row(1) = 4.5 * ((l1 - 1 / 3.0) * (l1 - 2 / 3.0) + l1 * (l1 - 2 / 3.0) +
1075 l1 * (l1 - 1 / 3.0));
1078 temp.row(12) = 4.5 * ((l2 - 1 / 3.0) * (l2 - 2 / 3.0) +
1079 l2 * (l2 - 2 / 3.0) + l2 * (l2 - 1 / 3.0));
1081 temp.row(3) = 13.5 * (-l1 * (l0 - 1 / 3.0) + l0 * (l0 - 1 / 3.0) - l0 * l1);
1082 temp.row(13) = -13.5 * (l1 * (l0 - 1 / 3.0) + l0 * l1);
1083 temp.row(4) = 13.5 * (-l1 * (l1 - 1 / 3.0) + l0 * (l1 - 1 / 3.0) + l0 * l1);
1084 temp.row(14) = -13.5 * l1 * (l1 - 1 / 3.0);
1085 temp.row(5) = 13.5 * (l2 * (l1 - 1 / 3.0) + l1 * l2);
1086 temp.row(15) = 13.5 * (l1 * (l1 - 1 / 3.0));
1087 temp.row(6) = 13.5 * (l2 * (l2 - 1 / 3.0));
1088 temp.row(16) = 13.5 * (l1 * (l2 - 1 / 3.0) + l1 * l2);
1089 temp.row(7) = -13.5 * l2 * (l2 - 1 / 3.0);
1090 temp.row(17) = 13.5 * (l0 * (l2 - 1 / 3.0) - l2 * (l2 - 1 / 3.0) + l0 * l2);
1091 temp.row(8) = -13.5 * (l2 * (l0 - 1 / 3.0) + l2 * l0);
1092 temp.row(18) = 13.5 * (l0 * (l0 - 1 / 3.0) - l2 * (l0 - 1 / 3.0) - l2 * l0);
1094 temp.row(9) = 27.0 * (-l1 * l2 + l0 * l2);
1095 temp.row(19) = 27.0 * (-l1 * l2 + l0 * l1);
1113 Eigen::Matrix<double, 2, 10> nodes;
1114 Eigen::Matrix<double, 2, 3> vertices;
1115 Eigen::Matrix<double, 2, 6> edges;
1116 Eigen::Matrix<double, 2, 1> center;
1119 vertices << 0.0, 1.0, 0.0,
1121 edges << 1.0, 2.0, 2.0, 1.0, 0.0, 0.0,
1122 0.0, 0.0, 1.0, 2.0, 2.0, 1.0;
1123 center << 1.0 / 3.0,
1127 nodes << vertices, edges, center;
1151template <
typename SCALAR>
1166 [[nodiscard]]
unsigned Degree()
const override {
return 3; }
1177 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
1178 return (codim == 0) ? 2 : 1;
1189 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
1190 LF_ASSERT_MSG((codim == 1 && subidx < 2) || (codim == 0 && subidx == 0),
1191 "codim/subidx out of range.");
1192 return (codim == 0) ? 2 : 1;
1195 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1197 LF_ASSERT_MSG(refcoords.rows() == 1,
1198 "Reference coordinates must be 1-vectors");
1199 const size_type n_pts(refcoords.cols());
1201 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(4, n_pts);
1203 auto x = refcoords.row(0).array();
1206 result.row(0) = 4.5 * (1.0 - x) * (1.0 / 3.0 - x) * (2.0 / 3.0 - x);
1207 result.row(1) = 4.5 * x * (x - 1.0 / 3.0) * (x - 2.0 / 3.0);
1210 result.row(2) = 13.5 * x * (1 - x) * (2.0 / 3.0 - x);
1211 result.row(3) = 13.5 * x * (1 - x) * (x - 1.0 / 3.0);
1216 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1218 const Eigen::MatrixXd& refcoords)
const override {
1219 LF_ASSERT_MSG(refcoords.rows() == 1,
1220 "Reference coordinates must be 1-vectors");
1221 const size_type n_pts(refcoords.cols());
1223 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(4, n_pts);
1225 auto x = refcoords.row(0).array();
1228 result.row(0) = -13.5 * x * x + 18.0 * x - 5.5;
1229 result.row(1) = 13.5 * x * x - 9.0 * x + 1.0;
1231 result.row(2) = 40.5 * x * x - 45 * x + 9;
1232 result.row(3) = -40.5 * x * x + 36 * x - 4.5;
1238 Eigen::Matrix<double, 1, 4> nodes;
1239 nodes << 0.0, 1.0, 1.0 / 3.0, 2.0 / 3.0;
1275template <
typename SCALAR>
1290 [[nodiscard]]
unsigned Degree()
const override {
return 3; }
1309 LF_ASSERT_MSG(
false,
"Illegal codim" << codim);
1322 LF_ASSERT_MSG((codim == 2 && subidx < 4) || (codim == 1 && subidx < 4) ||
1323 (codim == 0 && subidx == 0),
1324 "codim/subidx out of range.");
1328 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1330 LF_ASSERT_MSG(refcoords.rows() == 2,
1331 "Reference coordinates must be 2-vectors");
1333 const size_type n_pts(refcoords.cols());
1334 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
1335 16, refcoords.cols());
1338 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_eval =
1339 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(0))).array();
1340 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_eval =
1341 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(1))).array();
1344 for (
int i = 0; i < 16; ++i) {
1352 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1354 const Eigen::MatrixXd& refcoords)
const override {
1355 LF_ASSERT_MSG(refcoords.rows() == 2,
1356 "Reference coordinates must be 2-vectors");
1358 const size_type n_pts(refcoords.cols());
1359 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(16, 2 * n_pts);
1362 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
1364 temp(&result(0, 0), 32, n_pts);
1367 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_eval =
1368 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(0))).array();
1369 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_eval =
1370 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(1))).array();
1374 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_grad =
1375 (
krsf_segment_.GradientsReferenceShapeFunctions(refcoords.row(0)))
1377 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_grad =
1378 (
krsf_segment_.GradientsReferenceShapeFunctions(refcoords.row(1)))
1383 for (
int i = 0; i < 16; ++i) {
1398 Eigen::Matrix<double, 2, 16> nodes;
1400 Eigen::Matrix<double, 2, 4> vertices;
1401 Eigen::Matrix<double, 2, 8> midpoints;
1402 Eigen::Matrix<double, 2, 4> interior;
1405 vertices << 0.0, 1.0, 1.0, 0.0,
1407 midpoints << 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 0.0,
1408 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0;
1409 interior << 1.0, 2.0, 2.0, 1.0,
1412 midpoints *= 1.0 / 3.0;
1413 interior *= 1.0 / 3.0;
1415 nodes << vertices, midpoints, interior;
1453template <
typename SCALAR>
1457template <
typename SCALAR>
1458const Eigen::Matrix<int, 16, 2>
1461 (Eigen::Matrix<int,16,2>() << 0, 0,
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
const Eigen::MatrixXd & NodeCoords() const
Get the coordinates of the nodes of this reference element.
static constexpr RefEl kTria()
Returns the reference triangle.
constexpr size_type NumNodes() const
The number of nodes of this reference element.
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Interface class for parametric scalar valued finite elements.
Linear Lagrange finite element on the quadrilateral reference element.
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
FeLagrangeO1Quad(const FeLagrangeO1Quad &)=default
size_type NumRefShapeFunctions() const override
The local shape functions: four bilinear basis functions.
size_type NumRefShapeFunctions(dim_t codim) const override
Exactly one shape function attached to each node, none to other sub-entities.
size_type NumEvaluationNodes() const override
Tell the number of evaluation (interpolation) nodes.
FeLagrangeO1Quad(FeLagrangeO1Quad &&) noexcept=default
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t subidx) const override
Exactly one shape function attached to each node, none to other sub-entities.
Eigen::MatrixXd EvaluationNodes() const override
Returns reference coordinates of "evaluation nodes" for evaluation of parametric degrees of freedom,...
unsigned Degree() const override
Request the maximal polynomial degree of the basis functions in this finite element.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Computation of the gradients of all reference shape functions in a number of points.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Evaluation of all reference shape functions in a number of points.
Linear Lagrange finite element on a line segment.
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t subidx) const override
All shape functions attached to nodes.
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Evaluation of all reference shape functions in a number of points.
size_type NumEvaluationNodes() const override
Two evaluation nodes.
FeLagrangeO1Segment(const FeLagrangeO1Segment &)=default
size_type NumRefShapeFunctions(dim_t codim) const override
All shape functions attached to nodes.
unsigned Degree() const override
Request the maximal polynomial degree of the basis functions in this finite element.
Eigen::MatrixXd EvaluationNodes() const override
Evalutation nodes are just the vertices of the segment.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Computation of the gradients of all reference shape functions in a number of points.
FeLagrangeO1Segment(FeLagrangeO1Segment &&) noexcept=default
size_type NumRefShapeFunctions() const override
The local shape functions: barycentric coordinate functions.
Linear Lagrange finite element on triangular reference element.
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t subidx) const override
Exactly one shape function attached to each node, none to other sub-entities.
size_type NumRefShapeFunctions(dim_t codim) const override
Exactly one shape function attached to each node, none to other sub-entities.
size_type NumEvaluationNodes() const override
Three evaluation nodes.
Eigen::MatrixXd EvaluationNodes() const override
Evalutation nodes are just the vertices of the triangle.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Computation of the gradients of all reference shape functions in a number of points.
size_type NumRefShapeFunctions() const override
The local shape functions: barycentric coordinate functions.
unsigned Degree() const override
Request the maximal polynomial degree of the basis functions in this finite element.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Evaluation of all reference shape functions in a number of points.
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
FeLagrangeO1Tria(FeLagrangeO1Tria &&) noexcept=default
FeLagrangeO1Tria(const FeLagrangeO1Tria &)=default
Quadratic Lagrangian finite element on a quadrilateral reference element.
unsigned Degree() const override
Quadratic Lagrangian finite elements sport polynomials of degree 2.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Point evaluation of reference local shape functions in unit square.
static const FeLagrangeO2Segment< SCALAR > krsf_segment_
FeLagrangeO2Quad(const FeLagrangeO2Quad &)=default
FeLagrangeO2Quad(FeLagrangeO2Quad &&) noexcept=default
size_type NumEvaluationNodes() const override
Nine evaluation nodes, same as the number of local shape functions.
Eigen::MatrixXd EvaluationNodes() const override
Evaluation nodes are the vertices, the midpoints of the edges and the center of the quadrilateral.
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t) const override
One shape function is attached to each node and each edge of the quadrilateral. One interior shape fu...
size_type NumRefShapeFunctions(dim_t codim) const override
One shape function is attached to each node and edge of the quadrilateral. One interior shape functio...
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Point evaluation of gradient of reference shape functions for quadratic Lagrangian finite elements on...
size_type NumRefShapeFunctions() const override
Nine local shape functions are associated with a quadrilateral cell.
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
static const Eigen::Matrix< int, 9, 2 > ksegment_to_quad_mapping_
Quadratic Lagrangian finite element on a line segment.
size_type NumEvaluationNodes() const override
Three evaluation nodes, same number as local shape functions.
size_type NumRefShapeFunctions() const override
Three local shape functions are associated with an edge.
FeLagrangeO2Segment(FeLagrangeO2Segment &&) noexcept=default
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t) const override
One shape function attached to each node and one interior shape function.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Evaluation of shape functions on reference segment (unit interval)
FeLagrangeO2Segment(const FeLagrangeO2Segment &)=default
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
Eigen::MatrixXd EvaluationNodes() const override
Evaluation nodes are the endpoints of the segment and its midpoint.
unsigned Degree() const override
Quadratic Lagrangian finite element rely on polynomials of degree 2.
size_type NumRefShapeFunctions(dim_t codim) const override
One shape function attached to each node and one interior shape function.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Evaluation of derivatives of local shape function on reference interval.
Quadratic Lagrangian finite element on a triangular reference element.
FeLagrangeO2Tria(const FeLagrangeO2Tria &)=default
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Point evaluation of reference shape functions.
size_type NumEvaluationNodes() const override
Six evaluation nodes, the same number as local shape functions.
Eigen::MatrixXd EvaluationNodes() const override
Evaluation nodes are the three vertices of the triangle and the three midpoints of its edges.
size_type NumRefShapeFunctions() const override
Six local shape functions are associated with a triangular cell in the case of quadratic Lagrangian f...
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
FeLagrangeO2Tria(FeLagrangeO2Tria &&) noexcept=default
unsigned Degree() const override
Quadratic Lagrangian finite elements rely on polynomials of degree 2.
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t) const override
One shape function attached to each node and one to each edge of the triangle. There are no interior ...
size_type NumRefShapeFunctions(dim_t codim) const override
One shape function attached to each node and one to each edge of the triangle. There are no interior ...
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Point evaluations of gradients of reference shape functions.
Cubic Lagrangian finite element on a quadrilateral reference element.
FeLagrangeO3Quad(const FeLagrangeO3Quad &)=default
Eigen::MatrixXd EvaluationNodes() const override
Returns reference coordinates of "evaluation nodes" for evaluation of parametric degrees of freedom,...
size_type NumEvaluationNodes() const override
Sixteen evaluation nodes.
size_type NumRefShapeFunctions(dim_t codim) const override
One shape function attached to each node and two to each edge of the quadrilateral....
static const FeLagrangeO3Segment< SCALAR > krsf_segment_
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t subidx) const override
One shape function attached to each node and two to each edge of the quadrilateral....
size_type NumRefShapeFunctions() const override
Total number of reference shape functions associated with the reference cell.
unsigned Degree() const override
Request the maximal polynomial degree of the basis functions in this finite element.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Computation of the gradients of all reference shape functions in a number of points.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Evaluation of all reference shape functions in a number of points.
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
static const Eigen::Matrix< int, 16, 2 > ksegment_to_quad_mapping_
FeLagrangeO3Quad(FeLagrangeO3Quad &&) noexcept=default
Cubic Lagrangian finite element on a line segment.
size_type NumRefShapeFunctions() const override
Total number of reference shape functions associated with the reference cell.
unsigned Degree() const override
Request the maximal polynomial degree of the basis functions in this finite element.
FeLagrangeO3Segment(const FeLagrangeO3Segment &)=default
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t subidx) const override
One shape function attached to each node and two interior shape functions.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Evaluation of all reference shape functions in a number of points.
Eigen::MatrixXd EvaluationNodes() const override
Returns reference coordinates of "evaluation nodes" for evaluation of parametric degrees of freedom,...
FeLagrangeO3Segment(FeLagrangeO3Segment &&) noexcept=default
size_type NumEvaluationNodes() const override
Four evaluation nodes.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Computation of the gradients of all reference shape functions in a number of points.
size_type NumRefShapeFunctions(dim_t codim) const override
One shape function attached to each node and two interior shape functions.
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
Cubic Lagrangian finite elment on a triangular reference element.
FeLagrangeO3Tria(const FeLagrangeO3Tria &)=default
size_type NumRefShapeFunctions(dim_t codim, sub_idx_t subidx) const override
One shape function attached to each node and two to each edge of the triangle. There is one interior ...
size_type NumRefShapeFunctions(dim_t codim) const override
One shape function attached to each node and two to each edge of the triangle. There is one interior ...
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > GradientsReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Point evaluations of gradients of reference shape functions.
FeLagrangeO3Tria(FeLagrangeO3Tria &&) noexcept=default
unsigned Degree() const override
Quadratic Lagrangian finite elements rely on polynomials of degree 3.
size_type NumEvaluationNodes() const override
Ten evaluation nodes.
Eigen::Matrix< SCALAR, Eigen::Dynamic, Eigen::Dynamic > EvalReferenceShapeFunctions(const Eigen::MatrixXd &refcoords) const override
Point evaluation of reference shape functions.
base::RefEl RefEl() const override
Tells the type of reference cell underlying the parametric finite element.
size_type NumRefShapeFunctions() const override
Ten local shape functions are associated with a triangular cell in the case of cubic Lagrangian finit...
Eigen::MatrixXd EvaluationNodes() const override
Evaluation nodes are the three vertices of the triangle, two equispaced interio nodes for each edge,...
unsigned int sub_idx_t
type for local indices of sub-entities
lf::base::size_type size_type
lf::base::glb_idx_t glb_idx_t
Collects data structures and algorithms designed for scalar finite element methods primarily meant fo...
lf::base::sub_idx_t sub_idx_t
lf::assemble::glb_idx_t glb_idx_t
lf::assemble::dim_t dim_t
lf::assemble::ldof_idx_t ldof_idx_t
lf::assemble::size_type size_type
lf::assemble::gdof_idx_t gdof_idx_t