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());
126 Eigen::RowVectorXd::Constant(2 *
static_cast<Eigen::Index
>(n_pts), -1);
127 result.row(1) = Eigen::RowVector2d(1., 0.).replicate(1, n_pts);
128 result.row(2) = Eigen::RowVector2d(0., 1.).replicate(1, n_pts);
164template <
typename SCALAR>
179 [[nodiscard]]
unsigned Degree()
const override {
return 1; }
193 return (codim == 2) ? 1 : 0;
204 LF_ASSERT_MSG((codim == 2 && subidx < 4) || (codim == 1 && subidx < 4) ||
205 (codim == 0 && subidx == 0),
206 "codim/subidx out of range.");
207 return (codim == 2) ? 1 : 0;
210 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
212 LF_ASSERT_MSG(refcoords.rows() == 2,
213 "Reference coordinates must be 2-vectors");
215 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
216 4, refcoords.cols());
219 ((1 - refcoords.row(0).array()) * (1 - refcoords.row(1).array()))
222 ((refcoords.row(0).array()) * (1 - refcoords.row(1).array())).matrix();
224 ((refcoords.row(0).array()) * (refcoords.row(1).array())).matrix();
226 ((1 - refcoords.row(0).array()) * (refcoords.row(1).array())).matrix();
231 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
233 const Eigen::MatrixXd& refcoords)
const override {
234 LF_ASSERT_MSG(refcoords.rows() == 2,
235 "Reference coordinates must be 2-vectors");
238 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(4, 2 * n_pts);
241 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
243 temp(&result(0, 0), 8, n_pts);
244 temp.row(0) = refcoords.row(1).array() - 1.0;
245 temp.row(1) = 1.0 - refcoords.row(1).array();
246 temp.row(2) = refcoords.row(1).array();
247 temp.row(3) = -refcoords.row(1).array();
248 temp.row(4) = refcoords.row(0).array() - 1.0;
249 temp.row(5) = -refcoords.row(0).array();
250 temp.row(6) = refcoords.row(0).array();
251 temp.row(7) = 1.0 - refcoords.row(0).array();
283template <
typename SCALAR>
298 [[nodiscard]]
unsigned Degree()
const override {
return 1; }
311 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
312 return (codim == 1) ? 1 : 0;
322 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
323 LF_ASSERT_MSG((codim == 1 && subidx < 2) || (codim == 0 && subidx == 0),
324 "codim/subidx out of range.");
325 return (codim == 1) ? 1 : 0;
328 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
330 LF_ASSERT_MSG(refcoords.rows() == 1,
331 "Reference coordinates must be 1-vectors");
334 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
335 2, refcoords.cols());
336 result.row(0) = Eigen::RowVectorXd::Constant(1, n_pts, 1.0) - refcoords;
337 result.row(1) = refcoords;
342 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
344 const Eigen::MatrixXd& refcoords)
const override {
345 LF_ASSERT_MSG(refcoords.rows() == 1,
346 "Reference coordinates must be 1-vectors");
349 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
350 2, refcoords.cols());
351 result.row(0) = Eigen::MatrixXd::Constant(1, n_pts, -1.0);
352 result.row(1) = Eigen::MatrixXd::Constant(1, n_pts, 1.0);
399template <
typename SCALAR>
419 [[nodiscard]]
unsigned Degree()
const override {
return 2; }
435 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
436 return (codim == 0) ? 0 : 1;
447 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
448 return (codim == 0) ? 0 : 1;
458 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
460 LF_ASSERT_MSG(refcoords.rows() == 2,
461 "Reference coordinates must be 2-vectors");
465 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(6, n_pts);
467 auto x0 = refcoords.row(0).array();
468 auto x1 = refcoords.row(1).array();
470 result.row(0) = (2.0 * (1 - x0 - x1) * (0.5 - x0 - x1)).matrix();
471 result.row(1) = (2.0 * x0 * (x0 - 0.5)).matrix();
472 result.row(2) = (2.0 * x1 * (x1 - 0.5)).matrix();
473 result.row(3) = (4.0 * (1 - x0 - x1) * x0).matrix();
474 result.row(4) = (4.0 * x0 * x1).matrix();
475 result.row(5) = (4.0 * (1 - x0 - x1) * x1).matrix();
485 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
487 const Eigen::MatrixXd& refcoords)
const override {
488 LF_ASSERT_MSG(refcoords.rows() == 2,
489 "Reference coordinates must be 2-vectors");
492 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(6, 2 * n_pts);
494 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
496 temp(result.data(), 12, n_pts);
498 auto x0 = refcoords.row(0).array();
499 auto x1 = refcoords.row(1).array();
501 temp.row(0) = -3.0 + 4.0 * x0 + 4.0 * x1;
502 temp.row(1) = 4.0 * x0 - 1.0;
504 temp.row(3) = 4 - 0 - 8.0 * x0 - 4.0 * x1;
505 temp.row(4) = 4.0 * x1;
506 temp.row(5) = -4.0 * x1;
508 temp.row(6) = -3.0 + 4.0 * x0 + 4.0 * x1;
510 temp.row(8) = 4.0 * x1 - 1.0;
511 temp.row(9) = -4 * x0;
512 temp.row(10) = 4.0 * x0;
513 temp.row(11) = 4.0 - 8.0 * x1 - 4.0 * x0;
531 Eigen::Matrix<double, 2,6> nodes;
533 nodes << 0.0, 1.0, 0.0, 0.5, 0.5, 0.0,
534 0.0, 0.0, 1.0, 0.0, 0.5, 0.5;
562template <
typename SCALAR>
579 [[nodiscard]]
unsigned Degree()
const override {
return 2; }
597 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
608 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
626 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
628 LF_ASSERT_MSG(refcoords.rows() == 1,
629 "Reference coordinates must be 1-vectors");
632 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(3, n_pts);
634 auto x = refcoords.row(0).array();
636 result.row(0) = 2.0 * (1.0 - x) * (0.5 - x);
637 result.row(1) = 2.0 * x * (x - 0.5);
639 result.row(2) = 4.0 * (1.0 - x) * x;
652 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
654 const Eigen::MatrixXd& refcoords)
const override {
655 LF_ASSERT_MSG(refcoords.rows() == 1,
656 "Reference coordinates must be 1-vectors");
659 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(3, n_pts);
661 auto x = refcoords.row(0).array();
663 result.row(0) = (4.0 * x - 3.0).matrix();
664 result.row(1) = (4.0 * x - 1.0).matrix();
666 result.row(2) = (4.0 - 8.0 * x).matrix();
674 Eigen::Matrix<double, 1, 3> nodes;
676 nodes << 0.0, 1.0, 0.5;
712template <
typename SCALAR>
730 [[nodiscard]]
unsigned Degree()
const override {
return 2; }
746 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
758 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
779 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
781 LF_ASSERT_MSG(refcoords.rows() == 2,
782 "Reference coordinates must be 2-vectors");
785 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(9, n_pts);
788 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_eval =
789 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(0))).array();
790 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_eval =
791 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(1))).array();
794 for (
int i = 0; i < 9; ++i) {
811 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
813 const Eigen::MatrixXd& refcoords)
const override {
814 LF_ASSERT_MSG(refcoords.rows() == 2,
815 "Reference coordinates must be 2-vectors");
818 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(9, 2 * n_pts);
821 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
823 temp(&result(0, 0), 18, n_pts);
826 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_eval =
827 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(0))).array();
828 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_eval =
829 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(1))).array();
833 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_grad =
834 (
krsf_segment_.GradientsReferenceShapeFunctions(refcoords.row(0)))
836 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_grad =
837 (
krsf_segment_.GradientsReferenceShapeFunctions(refcoords.row(1)))
842 for (
int i = 0; i < 9; ++i) {
865 Eigen::Matrix<double, 2, 9> nodes;
868 nodes << 0.0, 1.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.0, 0.5,
869 0.0, 0.0, 1.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.5;
908template <
typename SCALAR>
912template <
typename SCALAR>
913const Eigen::Matrix<int, 9, 2>
916 (Eigen::Matrix<int,9,2>() << 0, 0,
944template <
typename SCALAR>
962 [[nodiscard]]
unsigned Degree()
const override {
return 3; }
980 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
981 return (codim == 1) ? 2 : 1;
994 LF_ASSERT_MSG(codim <= 2,
"Illegal codim" << codim);
995 LF_ASSERT_MSG((codim == 2 && subidx < 3) || (codim == 1 && subidx < 3) ||
996 (codim == 0 && subidx == 0),
997 "codim/subidx out of range.");
998 return (codim == 1) ? 2 : 1;
1009 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1011 LF_ASSERT_MSG(refcoords.rows() == 2,
1012 "Reference coordinates must be 2-vectors");
1014 const size_type n_pts(refcoords.cols());
1017 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(10, n_pts);
1020 const Eigen::Array<double, 1, Eigen::Dynamic> lambda0 =
1021 1 - refcoords.row(0).array() - refcoords.row(1).array();
1022 const Eigen::Array<double, 1, Eigen::Dynamic> lambda1 =
1023 refcoords.row(0).array();
1024 const Eigen::Array<double, 1, Eigen::Dynamic> lambda2 =
1025 refcoords.row(1).array();
1029 result.row(0) = 4.5 * lambda0 * (lambda0 - 1 / 3.0) * (lambda0 - 2 / 3.0);
1030 result.row(1) = 4.5 * lambda1 * (lambda1 - 1 / 3.0) * (lambda1 - 2 / 3.0);
1031 result.row(2) = 4.5 * lambda2 * (lambda2 - 1 / 3.0) * (lambda2 - 2 / 3.0);
1033 result.row(3) = 13.5 * lambda0 * lambda1 * (lambda0 - 1 / 3.0);
1034 result.row(4) = 13.5 * lambda0 * lambda1 * (lambda1 - 1 / 3.0);
1035 result.row(5) = 13.5 * lambda1 * lambda2 * (lambda1 - 1 / 3.0);
1036 result.row(6) = 13.5 * lambda1 * lambda2 * (lambda2 - 1 / 3.0);
1037 result.row(7) = 13.5 * lambda2 * lambda0 * (lambda2 - 1 / 3.0);
1038 result.row(8) = 13.5 * lambda2 * lambda0 * (lambda0 - 1 / 3.0);
1040 result.row(9) = 27.0 * lambda0 * lambda1 * lambda2;
1052 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1054 const Eigen::MatrixXd& refcoords)
const override {
1055 LF_ASSERT_MSG(refcoords.rows() == 2,
1056 "Reference coordinates must be 2-vectors");
1058 const size_type n_pts(refcoords.cols());
1059 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(10, 2 * n_pts);
1062 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
1064 temp(&result(0, 0), 20, n_pts);
1067 const Eigen::Array<double, 1, Eigen::Dynamic> l0 =
1068 1 - refcoords.row(0).array() - refcoords.row(1).array();
1069 auto l1 = refcoords.row(0).array();
1070 auto l2 = refcoords.row(1).array();
1073 temp.row(0) = -4.5 * ((l0 - 1 / 3.0) * (l0 - 2 / 3.0) +
1074 l0 * (l0 - 2 / 3.0) + l0 * (l0 - 1 / 3.0));
1075 temp.row(10) = -4.5 * ((l0 - 1 / 3.0) * (l0 - 2 / 3.0) +
1076 l0 * (l0 - 2 / 3.0) + l0 * (l0 - 1 / 3.0));
1077 temp.row(1) = 4.5 * ((l1 - 1 / 3.0) * (l1 - 2 / 3.0) + l1 * (l1 - 2 / 3.0) +
1078 l1 * (l1 - 1 / 3.0));
1081 temp.row(12) = 4.5 * ((l2 - 1 / 3.0) * (l2 - 2 / 3.0) +
1082 l2 * (l2 - 2 / 3.0) + l2 * (l2 - 1 / 3.0));
1084 temp.row(3) = 13.5 * (-l1 * (l0 - 1 / 3.0) + l0 * (l0 - 1 / 3.0) - l0 * l1);
1085 temp.row(13) = -13.5 * (l1 * (l0 - 1 / 3.0) + l0 * l1);
1086 temp.row(4) = 13.5 * (-l1 * (l1 - 1 / 3.0) + l0 * (l1 - 1 / 3.0) + l0 * l1);
1087 temp.row(14) = -13.5 * l1 * (l1 - 1 / 3.0);
1088 temp.row(5) = 13.5 * (l2 * (l1 - 1 / 3.0) + l1 * l2);
1089 temp.row(15) = 13.5 * (l1 * (l1 - 1 / 3.0));
1090 temp.row(6) = 13.5 * (l2 * (l2 - 1 / 3.0));
1091 temp.row(16) = 13.5 * (l1 * (l2 - 1 / 3.0) + l1 * l2);
1092 temp.row(7) = -13.5 * l2 * (l2 - 1 / 3.0);
1093 temp.row(17) = 13.5 * (l0 * (l2 - 1 / 3.0) - l2 * (l2 - 1 / 3.0) + l0 * l2);
1094 temp.row(8) = -13.5 * (l2 * (l0 - 1 / 3.0) + l2 * l0);
1095 temp.row(18) = 13.5 * (l0 * (l0 - 1 / 3.0) - l2 * (l0 - 1 / 3.0) - l2 * l0);
1097 temp.row(9) = 27.0 * (-l1 * l2 + l0 * l2);
1098 temp.row(19) = 27.0 * (-l1 * l2 + l0 * l1);
1116 Eigen::Matrix<double, 2, 10> nodes;
1117 Eigen::Matrix<double, 2, 3> vertices;
1118 Eigen::Matrix<double, 2, 6> edges;
1119 Eigen::Matrix<double, 2, 1> center;
1122 vertices << 0.0, 1.0, 0.0,
1124 edges << 1.0, 2.0, 2.0, 1.0, 0.0, 0.0,
1125 0.0, 0.0, 1.0, 2.0, 2.0, 1.0;
1126 center << 1.0 / 3.0,
1130 nodes << vertices, edges, center;
1154template <
typename SCALAR>
1169 [[nodiscard]]
unsigned Degree()
const override {
return 3; }
1180 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
1181 return (codim == 0) ? 2 : 1;
1192 LF_ASSERT_MSG(codim <= 1,
"Illegal codim " << codim);
1193 LF_ASSERT_MSG((codim == 1 && subidx < 2) || (codim == 0 && subidx == 0),
1194 "codim/subidx out of range.");
1195 return (codim == 0) ? 2 : 1;
1198 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1200 LF_ASSERT_MSG(refcoords.rows() == 1,
1201 "Reference coordinates must be 1-vectors");
1202 const size_type n_pts(refcoords.cols());
1204 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(4, n_pts);
1206 auto x = refcoords.row(0).array();
1209 result.row(0) = 4.5 * (1.0 - x) * (1.0 / 3.0 - x) * (2.0 / 3.0 - x);
1210 result.row(1) = 4.5 * x * (x - 1.0 / 3.0) * (x - 2.0 / 3.0);
1213 result.row(2) = 13.5 * x * (1 - x) * (2.0 / 3.0 - x);
1214 result.row(3) = 13.5 * x * (1 - x) * (x - 1.0 / 3.0);
1219 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1221 const Eigen::MatrixXd& refcoords)
const override {
1222 LF_ASSERT_MSG(refcoords.rows() == 1,
1223 "Reference coordinates must be 1-vectors");
1224 const size_type n_pts(refcoords.cols());
1226 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(4, n_pts);
1228 auto x = refcoords.row(0).array();
1231 result.row(0) = -13.5 * x * x + 18.0 * x - 5.5;
1232 result.row(1) = 13.5 * x * x - 9.0 * x + 1.0;
1234 result.row(2) = 40.5 * x * x - 45 * x + 9;
1235 result.row(3) = -40.5 * x * x + 36 * x - 4.5;
1241 Eigen::Matrix<double, 1, 4> nodes;
1242 nodes << 0.0, 1.0, 1.0 / 3.0, 2.0 / 3.0;
1278template <
typename SCALAR>
1293 [[nodiscard]]
unsigned Degree()
const override {
return 3; }
1312 LF_ASSERT_MSG(
false,
"Illegal codim" << codim);
1325 LF_ASSERT_MSG((codim == 2 && subidx < 4) || (codim == 1 && subidx < 4) ||
1326 (codim == 0 && subidx == 0),
1327 "codim/subidx out of range.");
1331 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1333 LF_ASSERT_MSG(refcoords.rows() == 2,
1334 "Reference coordinates must be 2-vectors");
1336 const size_type n_pts(refcoords.cols());
1337 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(
1338 16, refcoords.cols());
1341 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_eval =
1342 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(0))).array();
1343 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_eval =
1344 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(1))).array();
1347 for (
int i = 0; i < 16; ++i) {
1355 [[nodiscard]] Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>
1357 const Eigen::MatrixXd& refcoords)
const override {
1358 LF_ASSERT_MSG(refcoords.rows() == 2,
1359 "Reference coordinates must be 2-vectors");
1361 const size_type n_pts(refcoords.cols());
1362 Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> result(16, 2 * n_pts);
1365 Eigen::Map<Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic>,
1367 temp(&result(0, 0), 32, n_pts);
1370 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_eval =
1371 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(0))).array();
1372 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_eval =
1373 (
krsf_segment_.EvalReferenceShapeFunctions(refcoords.row(1))).array();
1377 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x0_grad =
1378 (
krsf_segment_.GradientsReferenceShapeFunctions(refcoords.row(0)))
1380 Eigen::Array<SCALAR, Eigen::Dynamic, Eigen::Dynamic> segment_x1_grad =
1381 (
krsf_segment_.GradientsReferenceShapeFunctions(refcoords.row(1)))
1386 for (
int i = 0; i < 16; ++i) {
1401 Eigen::Matrix<double, 2, 16> nodes;
1403 Eigen::Matrix<double, 2, 4> vertices;
1404 Eigen::Matrix<double, 2, 8> midpoints;
1405 Eigen::Matrix<double, 2, 4> interior;
1408 vertices << 0.0, 1.0, 1.0, 0.0,
1410 midpoints << 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 0.0,
1411 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0;
1412 interior << 1.0, 2.0, 2.0, 1.0,
1415 midpoints *= 1.0 / 3.0;
1416 interior *= 1.0 / 3.0;
1418 nodes << vertices, midpoints, interior;
1456template <
typename SCALAR>
1460template <
typename SCALAR>
1461const Eigen::Matrix<int, 16, 2>
1464 (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::glb_idx_t glb_idx_t
lf::base::size_type size_type
Collects data structures and algorithms designed for scalar finite element methods primarily meant fo...
lf::assemble::gdof_idx_t gdof_idx_t
lf::assemble::size_type size_type
lf::assemble::glb_idx_t glb_idx_t
lf::assemble::dim_t dim_t
lf::base::sub_idx_t sub_idx_t
lf::assemble::ldof_idx_t ldof_idx_t