8 #include "element-families.h" 
   10 #include "precompute.h" 
   16 #include <xtensor/xtensor.hpp> 
   17 #include <xtensor/xview.hpp> 
   18 #include <xtl/xspan.hpp> 
   39 std::tuple<std::array<std::vector<xt::xtensor<double, 2>>, 4>,
 
   40            std::array<std::vector<xt::xtensor<double, 3>>, 4>>
 
   42                    const std::array<std::vector<xt::xtensor<double, 3>>, 4>& M,
 
   43                    int tdim, 
int value_size);
 
  224       const xt::xtensor<double, 2>& 
wcoeffs,
 
  225       const std::array<std::vector<xt::xtensor<double, 2>>, 4>& 
x,
 
  226       const std::array<std::vector<xt::xtensor<double, 3>>, 4>& 
M,
 
  230       std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
 
  238       const xt::xtensor<double, 2>& 
wcoeffs,
 
  239       const std::array<std::vector<xt::xtensor<double, 2>>, 4>& 
x,
 
  240       const std::array<std::vector<xt::xtensor<double, 3>>, 4>& 
M,
 
  243       std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
 
  251       const xt::xtensor<double, 2>& 
wcoeffs,
 
  252       const std::array<std::vector<xt::xtensor<double, 2>>, 4>& 
x,
 
  253       const std::array<std::vector<xt::xtensor<double, 3>>, 4>& 
M,
 
  256       std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
 
  264       const xt::xtensor<double, 2>& 
wcoeffs,
 
  265       const std::array<std::vector<xt::xtensor<double, 2>>, 4>& 
x,
 
  266       const std::array<std::vector<xt::xtensor<double, 3>>, 4>& 
M,
 
  269       std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
 
  304                                             std::size_t num_points) 
const;
 
  327   xt::xtensor<double, 4> 
tabulate(
int nd,
 
  328                                   const xt::xtensor<double, 2>& 
x) 
const;
 
  355   void tabulate(
int nd, 
const xt::xtensor<double, 2>& 
x,
 
  356                 xt::xtensor<double, 4>& basis) 
const;
 
  429   xt::xtensor<double, 3> 
push_forward(
const xt::xtensor<double, 3>& U,
 
  430                                       const xt::xtensor<double, 3>& J,
 
  431                                       const xtl::span<const double>& detJ,
 
  432                                       const xt::xtensor<double, 3>& K) 
const;
 
  440   xt::xtensor<double, 3> 
pull_back(
const xt::xtensor<double, 3>& u,
 
  441                                    const xt::xtensor<double, 3>& J,
 
  442                                    const xtl::span<const double>& detJ,
 
  443                                    const xt::xtensor<double, 3>& K) 
const;
 
  476   template <
typename O, 
typename P, 
typename Q, 
typename R>
 
  477   std::function<void(O&, 
const P&, 
const Q&, 
double, 
const R&)> 
map_fn()
 const 
  481     case maps::type::identity:
 
  482       return [](O& u, 
const P& U, 
const Q&, double, 
const R&) { u.assign(U); };
 
  483     case maps::type::L2Piola:
 
  484       return [](O& u, 
const P& U, 
const Q& J, 
double detJ, 
const R& K)
 
  486     case maps::type::covariantPiola:
 
  487       return [](O& u, 
const P& U, 
const Q& J, 
double detJ, 
const R& K)
 
  489     case maps::type::contravariantPiola:
 
  490       return [](O& u, 
const P& U, 
const Q& J, 
double detJ, 
const R& K)
 
  492     case maps::type::doubleCovariantPiola:
 
  493       return [](O& u, 
const P& U, 
const Q& J, 
double detJ, 
const R& K)
 
  495     case maps::type::doubleContravariantPiola:
 
  496       return [](O& u, 
const P& U, 
const Q& J, 
double detJ, 
const R& K)
 
  499       throw std::runtime_error(
"Map not implemented");
 
  530   const std::vector<std::vector<std::vector<int>>>& 
entity_dofs() 
const;
 
  633                     std::uint32_t cell_info) 
const;
 
  643                       std::uint32_t cell_info) 
const;
 
  653   template <
typename T>
 
  655                                 std::uint32_t cell_info) 
const;
 
  665   template <
typename T>
 
  668                                           std::uint32_t cell_info) 
const;
 
  678   template <
typename T>
 
  680       const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info) 
const;
 
  690   template <
typename T>
 
  693                                         std::uint32_t cell_info) 
const;
 
  703   template <
typename T>
 
  706                                              std::uint32_t cell_info) 
const;
 
  716   template <
typename T>
 
  718       const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info) 
const;
 
  728   template <
typename T>
 
  730       const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info) 
const;
 
  740   template <
typename T>
 
  742       const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info) 
const;
 
  748   const xt::xtensor<double, 2>& 
points() 
const;
 
  839   const xt::xtensor<double, 2>& 
wcoeffs() 
const;
 
  844   const std::array<std::vector<xt::xtensor<double, 2>>, 4>& 
x() 
const;
 
  878   const std::array<std::vector<xt::xtensor<double, 3>>, 4>& 
M() 
const;
 
  903   std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
 
  915   std::size_t _cell_tdim;
 
  918   std::vector<std::vector<cell::type>> _cell_subentity_types;
 
  936   int _highest_complete_degree;
 
  939   std::vector<int> _value_shape;
 
  949   xt::xtensor<double, 2> _coeffs;
 
  957   std::vector<std::vector<int>> _num_edofs;
 
  961   std::vector<std::vector<int>> _num_e_closure_dofs;
 
  964   std::vector<std::vector<std::vector<int>>> _edofs;
 
  967   std::vector<std::vector<std::vector<int>>> _e_closure_dofs;
 
  970   std::map<cell::type, xt::xtensor<double, 3>> _entity_transformations;
 
  977   xt::xtensor<double, 2> _points;
 
  981   std::array<std::vector<xt::xtensor<double, 2>>, 4> _x;
 
  984   xt::xtensor<double, 2> _matM;
 
  988   bool _dof_transformations_are_permutations;
 
  991   bool _dof_transformations_are_identity;
 
  996   std::map<cell::type, std::vector<std::vector<std::size_t>>> _eperm;
 
 1001   std::map<cell::type, std::vector<std::vector<std::size_t>>> _eperm_rev;
 
 1005            std::vector<std::tuple<std::vector<std::size_t>, std::vector<double>,
 
 1006                                   xt::xtensor<double, 2>>>>
 
 1011            std::vector<std::tuple<std::vector<std::size_t>, std::vector<double>,
 
 1012                                   xt::xtensor<double, 2>>>>
 
 1017            std::vector<std::tuple<std::vector<std::size_t>, std::vector<double>,
 
 1018                                   xt::xtensor<double, 2>>>>
 
 1023            std::vector<std::tuple<std::vector<std::size_t>, std::vector<double>,
 
 1024                                   xt::xtensor<double, 2>>>>
 
 1029   bool _discontinuous;
 
 1032   xt::xtensor<double, 2> _dual_matrix;
 
 1039   std::vector<std::tuple<std::vector<FiniteElement>, std::vector<int>>>
 
 1043   bool _interpolation_is_identity;
 
 1047   xt::xtensor<double, 2> _wcoeffs;
 
 1050   std::array<std::vector<xt::xtensor<double, 3>>, 4> _M;
 
 1074     cell::type cell_type, 
const std::vector<std::size_t>& value_shape,
 
 1075     const xt::xtensor<double, 2>& wcoeffs,
 
 1076     const std::array<std::vector<xt::xtensor<double, 2>>, 4>& x,
 
 1077     const std::array<std::vector<xt::xtensor<double, 3>>, 4>& M,
 
 1078     maps::type map_type, 
bool discontinuous, 
int highest_complete_degree,
 
 1079     int highest_degree);
 
 1092                              bool discontinuous);
 
 1119                              bool discontinuous);
 
 1132                              int degree, 
bool discontinuous);
 
 1181 template <
typename T>
 
 1184                                              std::uint32_t cell_info)
 const 
 1186   if (_dof_transformations_are_identity)
 
 1189   if (_cell_tdim >= 2)
 
 1193     int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
 
 1195         = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
 
 1198     for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
 
 1201       if (cell_info >> (face_start + e) & 1)
 
 1203                                  dofstart, block_size);
 
 1204       dofstart += _num_edofs[1][e];
 
 1207     if (_cell_tdim == 3)
 
 1210       for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
 
 1213         if (cell_info >> (3 * f) & 1)
 
 1215                                    data, dofstart, block_size);
 
 1218         for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
 
 1220                                    data, dofstart, block_size);
 
 1221         dofstart += _num_edofs[2][f];
 
 1227 template <
typename T>
 
 1229     const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info)
 const 
 1231   if (_dof_transformations_are_identity)
 
 1234   if (_cell_tdim >= 2)
 
 1238     int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
 
 1240         = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
 
 1243     for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
 
 1246       if (cell_info >> (face_start + e) & 1)
 
 1248                                  dofstart, block_size);
 
 1249       dofstart += _num_edofs[1][e];
 
 1252     if (_cell_tdim == 3)
 
 1255       for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
 
 1258         for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
 
 1260                                    data, dofstart, block_size);
 
 1262         if (cell_info >> (3 * f) & 1)
 
 1264                                    data, dofstart, block_size);
 
 1265         dofstart += _num_edofs[2][f];
 
 1271 template <
typename T>
 
 1273     const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info)
 const 
 1275   if (_dof_transformations_are_identity)
 
 1278   if (_cell_tdim >= 2)
 
 1282     int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
 
 1284         = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
 
 1287     for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
 
 1290       if (cell_info >> (face_start + e) & 1)
 
 1292                                  dofstart, block_size);
 
 1293       dofstart += _num_edofs[1][e];
 
 1296     if (_cell_tdim == 3)
 
 1299       for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
 
 1302         if (cell_info >> (3 * f) & 1)
 
 1304               _etrans_invT.at(_cell_subentity_types[2][f])[1], data, dofstart,
 
 1308         for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
 
 1310               _etrans_invT.at(_cell_subentity_types[2][f])[0], data, dofstart,
 
 1312         dofstart += _num_edofs[2][f];
 
 1318 template <
typename T>
 
 1320     const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info)
 const 
 1322   if (_dof_transformations_are_identity)
 
 1325   if (_cell_tdim >= 2)
 
 1329     int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
 
 1331         = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
 
 1334     for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
 
 1337       if (cell_info >> (face_start + e) & 1)
 
 1339                                  dofstart, block_size);
 
 1340       dofstart += _num_edofs[1][e];
 
 1343     if (_cell_tdim == 3)
 
 1346       for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
 
 1349         for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
 
 1351               _etrans_inv.at(_cell_subentity_types[2][f])[0], data, dofstart,
 
 1354         if (cell_info >> (3 * f) & 1)
 
 1356               _etrans_inv.at(_cell_subentity_types[2][f])[1], data, dofstart,
 
 1358         dofstart += _num_edofs[2][f];
 
 1364 template <
typename T>
 
 1366     const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info)
 const 
 1368   if (_dof_transformations_are_identity)
 
 1371   if (_cell_tdim >= 2)
 
 1375     int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
 
 1377         = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
 
 1380     for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
 
 1383       if (cell_info >> (face_start + e) & 1)
 
 1385             _etrans.at(cell::type::interval)[0], data, dofstart, block_size);
 
 1386       dofstart += _num_edofs[1][e];
 
 1389     if (_cell_tdim == 3)
 
 1392       for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
 
 1395         if (cell_info >> (3 * f) & 1)
 
 1397               _etrans.at(_cell_subentity_types[2][f])[1], data, dofstart,
 
 1401         for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
 
 1403               _etrans.at(_cell_subentity_types[2][f])[0], data, dofstart,
 
 1405         dofstart += _num_edofs[2][f];
 
 1411 template <
typename T>
 
 1413     const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info)
 const 
 1415   if (_dof_transformations_are_identity)
 
 1418   if (_cell_tdim >= 2)
 
 1422     int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
 
 1424         = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
 
 1427     for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
 
 1430       if (cell_info >> (face_start + e) & 1)
 
 1432             _etrans_invT.at(cell::type::interval)[0], data, dofstart,
 
 1434       dofstart += _num_edofs[1][e];
 
 1437     if (_cell_tdim == 3)
 
 1440       for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
 
 1443         if (cell_info >> (3 * f) & 1)
 
 1445               _etrans_invT.at(_cell_subentity_types[2][f])[1], data, dofstart,
 
 1449         for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
 
 1451               _etrans_invT.at(_cell_subentity_types[2][f])[0], data, dofstart,
 
 1453         dofstart += _num_edofs[2][f];
 
 1459 template <
typename T>
 
 1461     const xtl::span<T>& data, 
int block_size, std::uint32_t cell_info)
 const 
 1463   if (_dof_transformations_are_identity)
 
 1466   if (_cell_tdim >= 2)
 
 1470     int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
 
 1472         = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
 
 1475     for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
 
 1478       if (cell_info >> (face_start + e) & 1)
 
 1480             _etransT.at(cell::type::interval)[0], data, dofstart, block_size);
 
 1481       dofstart += _num_edofs[1][e];
 
 1484     if (_cell_tdim == 3)
 
 1487       for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
 
 1490         for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
 
 1492               _etransT.at(_cell_subentity_types[2][f])[0], data, dofstart,
 
 1496         if (cell_info >> (3 * f) & 1)
 
 1498               _etransT.at(_cell_subentity_types[2][f])[1], data, dofstart,
 
 1501         dofstart += _num_edofs[2][f];
 
 1507 template <
typename T>
 
 1509     const xtl::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 * _num_edofs[2].size() : 0;
 
 1520         = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
 
 1523     for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
 
 1526       if (cell_info >> (face_start + e) & 1)
 
 1528             _etrans_inv.at(cell::type::interval)[0], data, dofstart,
 
 1530       dofstart += _num_edofs[1][e];
 
 1533     if (_cell_tdim == 3)
 
 1536       for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
 
 1539         for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
 
 1541               _etrans_inv.at(_cell_subentity_types[2][f])[0], data, dofstart,
 
 1545         if (cell_info >> (3 * f) & 1)
 
 1547               _etrans_inv.at(_cell_subentity_types[2][f])[1], data, dofstart,
 
 1550         dofstart += _num_edofs[2][f];