8 #include "element-families.h"
11 #include "precompute.h"
12 #include "sobolev-spaces.h"
29 = std::experimental::mdspan<double,
30 std::experimental::dextents<std::size_t, 2>>;
32 = std::experimental::mdspan<double,
33 std::experimental::dextents<std::size_t, 4>>;
35 = std::experimental::mdspan<
const double,
36 std::experimental::dextents<std::size_t, 2>>;
38 = std::experimental::mdspan<
const double,
39 std::experimental::dextents<std::size_t, 3>>;
41 = std::experimental::mdspan<
const double,
42 std::experimental::dextents<std::size_t, 4>>;
45 = std::experimental::mdarray<double,
46 std::experimental::dextents<std::size_t, 2>>;
48 = std::experimental::mdarray<double,
49 std::experimental::dextents<std::size_t, 4>>;
53 inline std::array<std::vector<cmdspan2_t>, 4>
54 to_mdspan(std::array<std::vector<mdarray2_t>, 4>& x)
56 std::array<std::vector<cmdspan2_t>, 4> x1;
57 for (std::size_t i = 0; i < x.size(); ++i)
58 for (std::size_t j = 0; j < x[i].size(); ++j)
59 x1[i].emplace_back(x[i][j].data(), x[i][j].extents());
66 inline std::array<std::vector<cmdspan4_t>, 4>
67 to_mdspan(std::array<std::vector<mdarray4_t>, 4>& M)
69 std::array<std::vector<cmdspan4_t>, 4> M1;
70 for (std::size_t i = 0; i < M.size(); ++i)
71 for (std::size_t j = 0; j < M[i].size(); ++j)
72 M1[i].emplace_back(M[i][j].data(), M[i][j].extents());
79 inline std::array<std::vector<cmdspan2_t>, 4>
80 to_mdspan(
const std::array<std::vector<std::vector<double>>, 4>& x,
81 const std::array<std::vector<std::array<std::size_t, 2>>, 4>& shape)
83 std::array<std::vector<cmdspan2_t>, 4> x1;
84 for (std::size_t i = 0; i < x.size(); ++i)
85 for (std::size_t j = 0; j < x[i].size(); ++j)
86 x1[i].push_back(cmdspan2_t(x[i][j].data(), shape[i][j]));
93 inline std::array<std::vector<cmdspan4_t>, 4>
94 to_mdspan(
const std::array<std::vector<std::vector<double>>, 4>& M,
95 const std::array<std::vector<std::array<std::size_t, 4>>, 4>& shape)
97 std::array<std::vector<cmdspan4_t>, 4> M1;
98 for (std::size_t i = 0; i < M.size(); ++i)
99 for (std::size_t j = 0; j < M[i].size(); ++j)
100 M1[i].push_back(cmdspan4_t(M[i][j].data(), shape[i][j]));
129 std::tuple<std::array<std::vector<std::vector<double>>, 4>,
130 std::array<std::vector<std::array<std::size_t, 2>>, 4>,
131 std::array<std::vector<std::vector<double>>, 4>,
132 std::array<std::vector<std::array<std::size_t, 4>>, 4>>
134 const std::array<std::vector<cmdspan4_t>, 4>& M,
135 std::size_t tdim, std::size_t value_size);
147 = std::experimental::mdspan<
const double,
148 std::experimental::dextents<std::size_t, 2>>;
150 = std::experimental::mdspan<
const double,
151 std::experimental::dextents<std::size_t, 4>>;
327 const std::array<std::vector<cmdspan2_t>, 4>&
x,
328 const std::array<std::vector<cmdspan4_t>, 4>&
M,
333 std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
341 const std::array<std::vector<cmdspan2_t>, 4>&
x,
342 const std::array<std::vector<cmdspan4_t>, 4>&
M,
347 std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
355 const std::array<std::vector<cmdspan2_t>, 4>&
x,
356 const std::array<std::vector<cmdspan4_t>, 4>&
M,
361 std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
369 const std::array<std::vector<cmdspan2_t>, 4>&
x,
370 const std::array<std::vector<cmdspan4_t>, 4>&
M,
374 std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
409 std::size_t num_points)
const;
432 std::pair<std::vector<double>, std::array<std::size_t, 4>>
433 tabulate(
int nd, impl::cmdspan2_t
x)
const;
458 std::pair<std::vector<double>, std::array<std::size_t, 4>>
459 tabulate(
int nd,
const std::span<const double>&
x,
460 std::array<std::size_t, 2> shape)
const;
487 void tabulate(
int nd, impl::cmdspan2_t
x, impl::mdspan4_t basis)
const;
514 void tabulate(
int nd,
const std::span<const double>&
x,
515 std::array<std::size_t, 2> xshape,
516 const std::span<double>& basis)
const;
540 const std::vector<std::size_t>&
value_shape()
const;
593 std::pair<std::vector<double>, std::array<std::size_t, 3>>
595 std::span<const double> detJ, impl::cmdspan3_t K)
const;
604 std::pair<std::vector<double>, std::array<std::size_t, 3>>
605 pull_back(impl::cmdspan3_t u, impl::cmdspan3_t J,
606 std::span<const double> detJ, impl::cmdspan3_t K)
const;
639 template <
typename O,
typename P,
typename Q,
typename R>
640 std::function<void(O&,
const P&,
const Q&,
double,
const R&)>
map_fn()
const
644 case maps::type::identity:
645 return [](O& u,
const P& U,
const Q&, double,
const R&)
647 assert(U.extent(0) == u.extent(0));
648 assert(U.extent(1) == u.extent(1));
649 for (std::size_t i = 0; i < U.extent(0); ++i)
650 for (std::size_t j = 0; j < U.extent(1); ++j)
653 case maps::type::covariantPiola:
654 return [](O& u,
const P& U,
const Q& J,
double detJ,
const R& K)
656 case maps::type::contravariantPiola:
657 return [](O& u,
const P& U,
const Q& J,
double detJ,
const R& K)
659 case maps::type::doubleCovariantPiola:
660 return [](O& u,
const P& U,
const Q& J,
double detJ,
const R& K)
662 case maps::type::doubleContravariantPiola:
663 return [](O& u,
const P& U,
const Q& J,
double detJ,
const R& K)
666 throw std::runtime_error(
"Map not implemented");
676 const std::vector<std::vector<std::vector<int>>>&
entity_dofs()
const;
768 std::pair<std::vector<double>, std::array<std::size_t, 3>>
776 std::pair<std::vector<double>, std::array<std::size_t, 3>>>
787 std::uint32_t cell_info)
const;
797 std::uint32_t cell_info)
const;
807 template <
typename T>
809 std::uint32_t cell_info)
const;
819 template <
typename T>
822 std::uint32_t cell_info)
const;
832 template <
typename T>
834 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const;
844 template <
typename T>
847 std::uint32_t cell_info)
const;
857 template <
typename T>
860 std::uint32_t cell_info)
const;
870 template <
typename T>
872 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const;
883 template <
typename T>
885 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const;
895 template <
typename T>
897 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const;
903 const std::pair<std::vector<double>, std::array<std::size_t, 2>>&
958 const std::pair<std::vector<double>, std::array<std::size_t, 2>>&
966 const std::pair<std::vector<double>, std::array<std::size_t, 2>>&
1003 const std::pair<std::vector<double>, std::array<std::size_t, 2>>&
1011 std::vector<std::pair<std::vector<double>, std::array<std::size_t, 2>>>,
1052 std::vector<std::pair<std::vector<double>, std::array<std::size_t, 4>>>,
1061 const std::pair<std::vector<double>, std::array<std::size_t, 2>>&
1084 std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
1099 std::size_t _cell_tdim;
1102 std::vector<std::vector<cell::type>> _cell_subentity_types;
1117 int _interpolation_nderivs;
1120 int _highest_degree;
1123 int _highest_complete_degree;
1126 std::vector<std::size_t> _value_shape;
1139 std::pair<std::vector<double>, std::array<std::size_t, 2>> _coeffs;
1142 std::vector<std::vector<std::vector<int>>> _edofs;
1145 std::vector<std::vector<std::vector<int>>> _e_closure_dofs;
1147 using array2_t = std::pair<std::vector<double>, std::array<std::size_t, 2>>;
1148 using array3_t = std::pair<std::vector<double>, std::array<std::size_t, 3>>;
1151 std::map<cell::type, array3_t> _entity_transformations;
1158 std::pair<std::vector<double>, std::array<std::size_t, 2>> _points;
1163 std::vector<std::pair<std::vector<double>, std::array<std::size_t, 2>>>,
1168 std::pair<std::vector<double>, std::array<std::size_t, 2>> _matM;
1172 bool _dof_transformations_are_permutations;
1175 bool _dof_transformations_are_identity;
1180 std::map<cell::type, std::vector<std::vector<std::size_t>>> _eperm;
1185 std::map<cell::type, std::vector<std::vector<std::size_t>>> _eperm_rev;
1188 = std::vector<std::pair<std::vector<std::size_t>, array2_t>>;
1191 std::map<cell::type, trans_data_t> _etrans;
1194 std::map<cell::type, trans_data_t> _etransT;
1197 std::map<cell::type, trans_data_t> _etrans_inv;
1200 std::map<cell::type, trans_data_t> _etrans_invT;
1204 bool _discontinuous;
1207 std::pair<std::vector<double>, std::array<std::size_t, 2>> _dual_matrix;
1214 std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
1218 bool _interpolation_is_identity;
1222 std::pair<std::vector<double>, std::array<std::size_t, 2>> _wcoeffs;
1226 = std::vector<std::pair<std::vector<double>, std::array<std::size_t, 4>>>;
1227 std::array<array4_t, 4> _M;
1259 const std::vector<std::size_t>& value_shape,
1260 const impl::cmdspan2_t& wcoeffs,
1261 const std::array<std::vector<impl::cmdspan2_t>, 4>& x,
1262 const std::array<std::vector<impl::cmdspan4_t>, 4>& M,
1263 int interpolation_nderivs,
maps::type map_type,
1265 int highest_complete_degree,
int highest_degree);
1278 bool discontinuous);
1305 bool discontinuous);
1318 int degree,
bool discontinuous);
1367 template <
typename T>
1370 std::uint32_t cell_info)
const
1372 if (_dof_transformations_are_identity)
1375 if (_cell_tdim >= 2)
1379 int face_start = _cell_tdim == 3 ? 3 * _edofs[2].size() : 0;
1381 for (
auto& edofs0 : _edofs[0])
1382 dofstart += edofs0.size();
1386 auto& [v_size_t, matrix] = _etrans.at(cell::type::interval)[0];
1387 for (std::size_t e = 0; e < _edofs[1].size(); ++e)
1390 if (cell_info >> (face_start + e) & 1)
1393 std::span(v_size_t),
1394 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1397 dofstart += _edofs[1][e].size();
1401 if (_cell_tdim == 3)
1404 for (std::size_t f = 0; f < _edofs[2].size(); ++f)
1406 auto& trans = _etrans.at(_cell_subentity_types[2][f]);
1409 if (cell_info >> (3 * f) & 1)
1411 const auto& m = trans[1];
1412 const auto& v_size_t = std::get<0>(m);
1413 const auto& matrix = std::get<1>(m);
1415 std::span(v_size_t),
1416 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1421 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1423 const auto& m = trans[0];
1424 const auto& v_size_t = std::get<0>(m);
1425 const auto& matrix = std::get<1>(m);
1427 std::span(v_size_t),
1428 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1432 dofstart += _edofs[2][f].size();
1438 template <
typename T>
1440 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1442 if (_dof_transformations_are_identity)
1445 if (_cell_tdim >= 2)
1449 int face_start = _cell_tdim == 3 ? 3 * _edofs[2].size() : 0;
1451 for (
auto& edofs0 : _edofs[0])
1452 dofstart += edofs0.size();
1456 auto& [v_size_t, matrix] = _etransT.at(cell::type::interval)[0];
1457 for (std::size_t e = 0; e < _edofs[1].size(); ++e)
1460 if (cell_info >> (face_start + e) & 1)
1463 std::span(v_size_t),
1464 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1467 dofstart += _edofs[1][e].size();
1471 if (_cell_tdim == 3)
1474 for (std::size_t f = 0; f < _edofs[2].size(); ++f)
1476 auto& trans = _etransT.at(_cell_subentity_types[2][f]);
1479 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1482 auto& v_size_t = std::get<0>(m);
1483 auto& matrix = std::get<1>(m);
1485 std::span(v_size_t),
1486 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1491 if (cell_info >> (3 * f) & 1)
1494 auto& v_size_t = std::get<0>(m);
1495 auto& matrix = std::get<1>(m);
1497 std::span(v_size_t),
1498 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1501 dofstart += _edofs[2][f].size();
1507 template <
typename T>
1509 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1511 if (_dof_transformations_are_identity)
1514 if (_cell_tdim >= 2)
1518 int face_start = _cell_tdim == 3 ? 3 * _edofs[2].size() : 0;
1520 for (
auto& edofs0 : _edofs[0])
1521 dofstart += edofs0.size();
1524 for (std::size_t e = 0; e < _edofs[1].size(); ++e)
1527 if (cell_info >> (face_start + e) & 1)
1529 auto& [v_size_t, matrix] = _etrans_invT.at(cell::type::interval)[0];
1531 cmdspan2_t(matrix.first.data(), matrix.second),
1532 data, dofstart, block_size);
1534 dofstart += _edofs[1][e].size();
1537 if (_cell_tdim == 3)
1540 for (std::size_t f = 0; f < _edofs[2].size(); ++f)
1542 auto& trans = _etrans_invT.at(_cell_subentity_types[2][f]);
1545 if (cell_info >> (3 * f) & 1)
1548 auto& v_size_t = std::get<0>(m);
1549 auto& matrix = std::get<1>(m);
1551 std::span(v_size_t),
1552 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1557 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1559 const auto& m = trans[0];
1560 const auto& v_size_t = std::get<0>(m);
1561 const auto& matrix = std::get<1>(m);
1563 std::span(v_size_t),
1564 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1568 dofstart += _edofs[2][f].size();
1574 template <
typename T>
1576 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1578 if (_dof_transformations_are_identity)
1581 if (_cell_tdim >= 2)
1585 int face_start = _cell_tdim == 3 ? 3 * _edofs[2].size() : 0;
1587 for (
auto& edofs0 : _edofs[0])
1588 dofstart += edofs0.size();
1592 auto& [v_size_t, matrix] = _etrans_inv.at(cell::type::interval)[0];
1593 for (std::size_t e = 0; e < _edofs[1].size(); ++e)
1596 if (cell_info >> (face_start + e) & 1)
1599 std::span(v_size_t),
1600 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1603 dofstart += _edofs[1][e].size();
1607 if (_cell_tdim == 3)
1610 for (std::size_t f = 0; f < _edofs[2].size(); ++f)
1612 auto& trans = _etrans_inv.at(_cell_subentity_types[2][f]);
1615 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1618 auto& v_size_t = std::get<0>(m);
1619 auto& matrix = std::get<1>(m);
1621 std::span(v_size_t),
1622 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1627 if (cell_info >> (3 * f) & 1)
1630 auto& v_size_t = std::get<0>(m);
1631 auto& matrix = std::get<1>(m);
1633 std::span(v_size_t),
1634 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1638 dofstart += _edofs[2][f].size();
1644 template <
typename T>
1646 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1648 if (_dof_transformations_are_identity)
1651 if (_cell_tdim >= 2)
1655 int face_start = _cell_tdim == 3 ? 3 * _edofs[2].size() : 0;
1657 for (
auto& edofs0 : _edofs[0])
1658 dofstart += edofs0.size();
1662 auto& [v_size_t, matrix] = _etrans.at(cell::type::interval)[0];
1663 for (std::size_t e = 0; e < _edofs[1].size(); ++e)
1666 if (cell_info >> (face_start + e) & 1)
1669 std::span(v_size_t),
1670 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1674 dofstart += _edofs[1][e].size();
1678 if (_cell_tdim == 3)
1681 for (std::size_t f = 0; f < _edofs[2].size(); ++f)
1683 auto& trans = _etrans.at(_cell_subentity_types[2][f]);
1686 if (cell_info >> (3 * f) & 1)
1689 auto& v_size_t = std::get<0>(m);
1690 auto& matrix = std::get<1>(m);
1692 std::span(v_size_t),
1693 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1698 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1701 auto& v_size_t = std::get<0>(m);
1702 auto& matrix = std::get<1>(m);
1704 std::span(v_size_t),
1705 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1708 dofstart += _edofs[2][f].size();
1714 template <
typename T>
1716 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1718 if (_dof_transformations_are_identity)
1721 if (_cell_tdim >= 2)
1725 int face_start = _cell_tdim == 3 ? 3 * _edofs[2].size() : 0;
1727 for (
auto& edofs0 : _edofs[0])
1728 dofstart += edofs0.size();
1732 auto& [v_size_t, matrix] = _etrans_invT.at(cell::type::interval)[0];
1733 for (std::size_t e = 0; e < _edofs[1].size(); ++e)
1736 if (cell_info >> (face_start + e) & 1)
1739 std::span(v_size_t),
1740 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1743 dofstart += _edofs[1][e].size();
1747 if (_cell_tdim == 3)
1750 for (std::size_t f = 0; f < _edofs[2].size(); ++f)
1752 auto& trans = _etrans_invT.at(_cell_subentity_types[2][f]);
1755 if (cell_info >> (3 * f) & 1)
1758 auto& v_size_t = std::get<0>(m);
1759 auto& matrix = std::get<1>(m);
1761 std::span(v_size_t),
1762 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1767 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1770 auto& v_size_t = std::get<0>(m);
1771 auto& matrix = std::get<1>(m);
1773 std::span(v_size_t),
1774 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1777 dofstart += _edofs[2][f].size();
1783 template <
typename T>
1785 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1787 if (_dof_transformations_are_identity)
1790 if (_cell_tdim >= 2)
1794 int face_start = _cell_tdim == 3 ? 3 * _edofs[2].size() : 0;
1796 for (
auto& edofs0 : _edofs[0])
1797 dofstart += edofs0.size();
1801 auto& [v_size_t, matrix] = _etransT.at(cell::type::interval)[0];
1802 for (std::size_t e = 0; e < _edofs[1].size(); ++e)
1805 if (cell_info >> (face_start + e) & 1)
1808 std::span(v_size_t),
1809 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1812 dofstart += _edofs[1][e].size();
1816 if (_cell_tdim == 3)
1819 for (std::size_t f = 0; f < _edofs[2].size(); ++f)
1821 auto& trans = _etransT.at(_cell_subentity_types[2][f]);
1824 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1827 auto& v_size_t = std::get<0>(m);
1828 auto& matrix = std::get<1>(m);
1830 std::span(v_size_t),
1831 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1836 if (cell_info >> (3 * f) & 1)
1839 auto& v_size_t = std::get<0>(m);
1840 auto& matrix = std::get<1>(m);
1842 std::span(v_size_t),
1843 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1846 dofstart += _edofs[2][f].size();
1852 template <
typename T>
1854 const std::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1856 if (_dof_transformations_are_identity)
1859 if (_cell_tdim >= 2)
1863 int face_start = _cell_tdim == 3 ? 3 * _edofs[2].size() : 0;
1865 for (
auto& edofs0 : _edofs[0])
1866 dofstart += edofs0.size();
1870 auto& [v_size_t, matrix] = _etrans_inv.at(cell::type::interval)[0];
1871 for (std::size_t e = 0; e < _edofs[1].size(); ++e)
1874 if (cell_info >> (face_start + e) & 1)
1877 std::span(v_size_t),
1878 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1881 dofstart += _edofs[1][e].size();
1885 if (_cell_tdim == 3)
1888 for (std::size_t f = 0; f < _edofs[2].size(); ++f)
1890 auto& trans = _etrans_inv.at(_cell_subentity_types[2][f]);
1893 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1896 auto& v_size_t = std::get<0>(m);
1897 auto& matrix = std::get<1>(m);
1899 std::span(v_size_t),
1900 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1905 if (cell_info >> (3 * f) & 1)
1908 auto& v_size_t = std::get<0>(m);
1909 auto& matrix = std::get<1>(m);
1911 std::span(v_size_t),
1912 cmdspan2_t(matrix.first.data(), matrix.second), data, dofstart,
1916 dofstart += _edofs[2][f].size();
A finite element.
Definition: finite-element.h:145
FiniteElement & operator=(const FiniteElement &element)=default
Assignment operator.
std::map< cell::type, std::pair< std::vector< double >, std::array< std::size_t, 3 > > > entity_transformations() const
Definition: finite-element.cpp:1427
std::pair< std::vector< double >, std::array< std::size_t, 4 > > tabulate(int nd, impl::cmdspan2_t x) const
Compute basis values and derivatives at set of points.
Definition: finite-element.cpp:1049
void apply_inverse_dof_transformation_to_transpose(const std::span< T > &data, int block_size, std::uint32_t cell_info) const
Definition: finite-element.h:1853
cell::type cell_type() const
Definition: finite-element.cpp:1123
FiniteElement & operator=(FiniteElement &&element)=default
Move assignment operator.
sobolev::space sobolev_space() const
Definition: finite-element.cpp:1145
int highest_complete_degree() const
Definition: finite-element.cpp:1129
element::lagrange_variant lagrange_variant() const
Definition: finite-element.cpp:1469
FiniteElement(FiniteElement &&element)=default
Move constructor.
FiniteElement(element::family family, cell::type cell_type, int degree, const std::vector< std::size_t > &value_shape, const cmdspan2_t &wcoeffs, const std::array< std::vector< cmdspan2_t >, 4 > &x, const std::array< std::vector< cmdspan4_t >, 4 > &M, int interpolation_nderivs, maps::type map_type, sobolev::space sobolev_space, bool discontinuous, int highest_complete_degree, int highest_degree, element::lagrange_variant lvariant, element::dpc_variant dvariant, std::vector< std::tuple< std::vector< FiniteElement >, std::vector< int >>> tensor_factors={})
Construct a finite element.
Definition: finite-element.cpp:606
bool operator==(const FiniteElement &e) const
Definition: finite-element.cpp:998
const std::array< std::vector< std::pair< std::vector< double >, std::array< std::size_t, 2 > > >, 4 > & x() const
Definition: finite-element.cpp:1446
void apply_dof_transformation(const std::span< T > &data, int block_size, std::uint32_t cell_info) const
Definition: finite-element.h:1368
bool dof_transformations_are_permutations() const
Definition: finite-element.cpp:1149
maps::type map_type() const
Definition: finite-element.cpp:1143
std::vector< std::tuple< std::vector< FiniteElement >, std::vector< int > > > get_tensor_product_representation() const
Definition: finite-element.cpp:1487
const std::vector< std::vector< std::vector< int > > > & entity_dofs() const
Definition: finite-element.cpp:1166
const std::pair< std::vector< double >, std::array< std::size_t, 2 > > & dual_matrix() const
Definition: finite-element.cpp:1433
void apply_inverse_transpose_dof_transformation_to_transpose(const std::span< T > &data, int block_size, std::uint32_t cell_info) const
Apply inverse transpose DOF transformations to some transposed data.
Definition: finite-element.h:1715
int interpolation_nderivs() const
The number of derivatives needed when interpolating.
Definition: finite-element.cpp:1481
const std::vector< std::vector< std::vector< int > > > & entity_closure_dofs() const
Definition: finite-element.cpp:1172
const std::pair< std::vector< double >, std::array< std::size_t, 2 > > & points() const
Definition: finite-element.cpp:1246
int degree() const
Definition: finite-element.cpp:1125
std::function< void(O &, const P &, const Q &, double, const R &)> map_fn() const
Definition: finite-element.h:640
void apply_transpose_dof_transformation(const std::span< T > &data, int block_size, std::uint32_t cell_info) const
Definition: finite-element.h:1439
const std::vector< std::size_t > & value_shape() const
Definition: finite-element.cpp:1134
const std::pair< std::vector< double >, std::array< std::size_t, 2 > > & coefficient_matrix() const
Definition: finite-element.cpp:1459
bool has_tensor_product_factorisation() const
Definition: finite-element.cpp:1464
~FiniteElement()=default
Destructor.
const std::pair< std::vector< double >, std::array< std::size_t, 2 > > & wcoeffs() const
Definition: finite-element.cpp:1439
int dim() const
Definition: finite-element.cpp:1139
int highest_degree() const
Definition: finite-element.cpp:1127
std::pair< std::vector< double >, std::array< std::size_t, 3 > > push_forward(impl::cmdspan3_t U, impl::cmdspan3_t J, std::span< const double > detJ, impl::cmdspan3_t K) const
Definition: finite-element.cpp:1252
std::array< std::size_t, 4 > tabulate_shape(std::size_t nd, std::size_t num_points) const
Definition: finite-element.cpp:1035
element::dpc_variant dpc_variant() const
Definition: finite-element.cpp:1474
void apply_transpose_dof_transformation_to_transpose(const std::span< T > &data, int block_size, std::uint32_t cell_info) const
Definition: finite-element.h:1784
void apply_dof_transformation_to_transpose(const std::span< T > &data, int block_size, std::uint32_t cell_info) const
Definition: finite-element.h:1645
element::family family() const
Definition: finite-element.cpp:1141
void permute_dofs(const std::span< std::int32_t > &dofs, std::uint32_t cell_info) const
Definition: finite-element.cpp:1319
bool dof_transformations_are_identity() const
Definition: finite-element.cpp:1154
void apply_inverse_dof_transformation(const std::span< T > &data, int block_size, std::uint32_t cell_info) const
Definition: finite-element.h:1575
std::pair< std::vector< double >, std::array< std::size_t, 3 > > pull_back(impl::cmdspan3_t u, impl::cmdspan3_t J, std::span< const double > detJ, impl::cmdspan3_t K) const
Definition: finite-element.cpp:1287
FiniteElement(const FiniteElement &element)=default
Copy constructor.
const std::pair< std::vector< double >, std::array< std::size_t, 2 > > & interpolation_matrix() const
Return a matrix of weights interpolation,.
Definition: finite-element.cpp:1160
bool interpolation_is_identity() const
Definition: finite-element.cpp:1476
std::pair< std::vector< double >, std::array< std::size_t, 3 > > base_transformations() const
Get the base transformations.
Definition: finite-element.cpp:1178
const std::array< std::vector< std::pair< std::vector< double >, std::array< std::size_t, 4 > > >, 4 > & M() const
Definition: finite-element.cpp:1453
bool discontinuous() const
Definition: finite-element.cpp:1147
void apply_inverse_transpose_dof_transformation(const std::span< T > &data, int block_size, std::uint32_t cell_info) const
Definition: finite-element.h:1508
void unpermute_dofs(const std::span< std::int32_t > &dofs, std::uint32_t cell_info) const
Definition: finite-element.cpp:1373
type
Cell type.
Definition: cell.h:20
lagrange_variant
Variants of a Lagrange space that can be created.
Definition: element-families.h:12
dpc_variant
Definition: element-families.h:33
impl::cmdspan4_t cmdspan4_t
Typedef for mdspan.
Definition: finite-element.h:112
impl::cmdspan2_t cmdspan2_t
Typedef for mdspan.
Definition: finite-element.h:110
std::tuple< std::array< std::vector< std::vector< double > >, 4 >, std::array< std::vector< std::array< std::size_t, 2 > >, 4 >, std::array< std::vector< std::vector< double > >, 4 >, std::array< std::vector< std::array< std::size_t, 4 > >, 4 > > make_discontinuous(const std::array< std::vector< cmdspan2_t >, 4 > &x, const std::array< std::vector< cmdspan4_t >, 4 > &M, std::size_t tdim, std::size_t value_size)
Definition: finite-element.cpp:394
family
Available element families.
Definition: element-families.h:46
void covariant_piola(O &&r, const P &U, const Q &, double, const R &K)
Covariant Piola map.
Definition: maps.h:39
void contravariant_piola(O &&r, const P &U, const Q &J, double detJ, const R &)
Contravariant Piola map.
Definition: maps.h:58
void double_contravariant_piola(O &&r, const P &U, const Q &J, double detJ, const R &)
Double contravariant Piola map.
Definition: maps.h:107
void double_covariant_piola(O &&r, const P &U, const Q &J, double, const R &K)
Double covariant Piola map.
Definition: maps.h:79
type
Map type.
Definition: maps.h:17
void apply_matrix_to_transpose(const std::span< const std::size_t > &v_size_t, const std::experimental::mdspan< const T, std::experimental::dextents< std::size_t, 2 >> &M, const std::span< E > &data, std::size_t offset=0, std::size_t block_size=1)
Apply a (precomputed) matrix to some transposed data.
Definition: precompute.h:244
void apply_matrix(const std::span< const std::size_t > &v_size_t, const std::experimental::mdspan< const T, std::experimental::dextents< std::size_t, 2 >> &M, const std::span< E > &data, std::size_t offset=0, std::size_t block_size=1)
Apply a (precomputed) matrix.
Definition: precompute.h:207
space
Sobolev space type.
Definition: sobolev-spaces.h:13
Basix: FEniCS runtime basis evaluation library.
Definition: cell.h:16
FiniteElement create_element(element::family family, cell::type cell, int degree, element::lagrange_variant lvariant, bool discontinuous)
Definition: finite-element.cpp:345
std::string version()
Definition: finite-element.cpp:1494
FiniteElement create_custom_element(cell::type cell_type, const std::vector< std::size_t > &value_shape, const impl::cmdspan2_t &wcoeffs, const std::array< std::vector< impl::cmdspan2_t >, 4 > &x, const std::array< std::vector< impl::cmdspan4_t >, 4 > &M, int interpolation_nderivs, maps::type map_type, sobolev::space sobolev_space, bool discontinuous, int highest_complete_degree, int highest_degree)
Definition: finite-element.cpp:464