11 #include "element-families.h"
13 #include "precompute.h"
19 #include <xtensor/xadapt.hpp>
20 #include <xtensor/xcomplex.hpp>
21 #include <xtensor/xtensor.hpp>
22 #include <xtensor/xview.hpp>
23 #include <xtl/xspan.hpp>
185 cell::type cell_type,
const xt::xtensor<double, 2>& B,
186 const std::vector<std::vector<xt::xtensor<double, 3>>>& M,
187 const std::vector<std::vector<xt::xtensor<double, 2>>>& x,
int degree,
188 double kappa_tol = 0.0);
213 const xt::xtensor<double, 3>& coeffs,
214 const std::map<
cell::type, xt::xtensor<double, 3>>&
216 const std::array<std::vector<xt::xtensor<double, 2>>, 4>& x,
217 const std::array<std::vector<xt::xtensor<double, 3>>, 4>& M,
252 xt::xtensor<double, 4>
tabulate(
int nd,
const xt::xarray<double>& x)
const;
258 void tabulate(
int nd,
const xt::xarray<double>& x,
259 xt::xtensor<double, 4>& basis_data)
const;
285 element::family
family()
const;
313 xt::xtensor<double, 3>
315 const xt::xtensor<double, 3>& J,
316 const xtl::span<const double>& detJ,
317 const xt::xtensor<double, 3>& K)
const;
334 template <
typename O,
typename P,
typename Q,
typename S,
typename T>
342 for (std::size_t i = 0; i < U.shape(0); ++i)
344 auto _J = xt::view(J, i, xt::all(), xt::all());
345 auto _K = xt::view(K, i, xt::all(), xt::all());
346 auto _U = xt::view(U, i, xt::all(), xt::all());
347 auto _u = xt::view(u, i, xt::all(), xt::all());
358 xt::xtensor<double, 3>
map_pull_back(
const xt::xtensor<double, 3>& u,
359 const xt::xtensor<double, 3>& J,
360 const xtl::span<const double>& detJ,
361 const xt::xtensor<double, 3>& K)
const;
378 template <
typename O,
typename P,
typename Q,
typename S,
typename T>
383 for (std::size_t i = 0; i < u.shape(0); ++i)
385 auto _J = xt::view(J, i, xt::all(), xt::all());
386 auto _K = xt::view(K, i, xt::all(), xt::all());
387 auto _u = xt::view(u, i, xt::all(), xt::all());
388 auto _U = xt::view(U, i, xt::all(), xt::all());
420 const std::vector<std::vector<std::set<int>>>&
entity_dofs()
const;
517 std::uint32_t cell_info)
const;
523 std::uint32_t cell_info)
const;
529 template <
typename T>
531 std::uint32_t cell_info)
const;
537 template <
typename T>
540 std::uint32_t cell_info)
const;
546 template <
typename T>
548 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const;
554 template <
typename T>
557 std::uint32_t cell_info)
const;
563 template <
typename T>
566 std::uint32_t cell_info)
const;
572 template <
typename T>
574 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const;
580 template <
typename T>
582 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const;
588 template <
typename T>
590 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const;
596 const xt::xtensor<double, 2>&
points()
const;
617 std::size_t _cell_tdim;
620 std::vector<std::vector<cell::type>> _cell_subentity_types;
623 element::family _family;
629 std::vector<int> _value_shape;
639 xt::xtensor<double, 2> _coeffs;
647 std::vector<std::vector<int>> _num_edofs;
650 std::vector<std::vector<int>> _num_e_closure_dofs;
653 std::vector<std::vector<std::set<int>>> _edofs;
656 std::vector<std::vector<std::set<int>>> _e_closure_dofs;
659 std::map<cell::type, xt::xtensor<double, 3>> _entity_transformations;
666 xt::xtensor<double, 2> _points;
670 std::array<std::vector<xt::xtensor<double, 2>>, 4> _x;
673 xt::xtensor<double, 2> _matM;
676 std::array<std::vector<xt::xtensor<double, 3>>, 4> _matM_new;
679 bool _dof_transformations_are_permutations;
682 bool _dof_transformations_are_identity;
687 std::map<cell::type, std::vector<std::vector<std::size_t>>> _eperm;
692 std::map<cell::type, std::vector<std::vector<std::size_t>>> _eperm_rev;
696 std::vector<std::tuple<std::vector<std::size_t>, std::vector<double>,
697 xt::xtensor<double, 2>>>>
702 std::vector<std::tuple<std::vector<std::size_t>, std::vector<double>,
703 xt::xtensor<double, 2>>>>
708 std::vector<std::tuple<std::vector<std::size_t>, std::vector<double>,
709 xt::xtensor<double, 2>>>>
714 std::vector<std::tuple<std::vector<std::size_t>, std::vector<double>,
715 xt::xtensor<double, 2>>>>
731 template <
typename T>
734 std::uint32_t cell_info)
const
736 if (_dof_transformations_are_identity)
743 int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
745 = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
748 for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
751 if (cell_info >> (face_start + e) & 1)
753 dofstart, block_size);
754 dofstart += _num_edofs[1][e];
760 for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
763 if (cell_info >> (3 * f) & 1)
765 data, dofstart, block_size);
768 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
770 data, dofstart, block_size);
771 dofstart += _num_edofs[2][f];
777 template <
typename T>
779 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const
781 if (_dof_transformations_are_identity)
788 int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
790 = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
793 for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
796 if (cell_info >> (face_start + e) & 1)
798 dofstart, block_size);
799 dofstart += _num_edofs[1][e];
805 for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
808 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
810 data, dofstart, block_size);
812 if (cell_info >> (3 * f) & 1)
814 data, dofstart, block_size);
815 dofstart += _num_edofs[2][f];
821 template <
typename T>
823 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const
825 if (_dof_transformations_are_identity)
832 int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
834 = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
837 for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
840 if (cell_info >> (face_start + e) & 1)
842 dofstart, block_size);
843 dofstart += _num_edofs[1][e];
849 for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
852 if (cell_info >> (3 * f) & 1)
854 _etrans_invT.at(_cell_subentity_types[2][f])[1], data, dofstart,
858 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
860 _etrans_invT.at(_cell_subentity_types[2][f])[0], data, dofstart,
862 dofstart += _num_edofs[2][f];
868 template <
typename T>
870 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const
872 if (_dof_transformations_are_identity)
879 int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
881 = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
884 for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
887 if (cell_info >> (face_start + e) & 1)
889 dofstart, block_size);
890 dofstart += _num_edofs[1][e];
896 for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
899 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
901 _etrans_inv.at(_cell_subentity_types[2][f])[0], data, dofstart,
904 if (cell_info >> (3 * f) & 1)
906 _etrans_inv.at(_cell_subentity_types[2][f])[1], data, dofstart,
908 dofstart += _num_edofs[2][f];
914 template <
typename T>
916 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const
918 if (_dof_transformations_are_identity)
925 int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
927 = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
930 for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
933 if (cell_info >> (face_start + e) & 1)
935 _etrans.at(cell::type::interval)[0], data, dofstart, block_size);
936 dofstart += _num_edofs[1][e];
942 for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
945 if (cell_info >> (3 * f) & 1)
947 _etrans.at(_cell_subentity_types[2][f])[1], data, dofstart,
951 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
953 _etrans.at(_cell_subentity_types[2][f])[0], data, dofstart,
955 dofstart += _num_edofs[2][f];
961 template <
typename T>
963 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const
965 if (_dof_transformations_are_identity)
972 int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
974 = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
977 for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
980 if (cell_info >> (face_start + e) & 1)
982 _etrans_invT.at(cell::type::interval)[0], data, dofstart,
984 dofstart += _num_edofs[1][e];
990 for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
993 if (cell_info >> (3 * f) & 1)
995 _etrans_invT.at(_cell_subentity_types[2][f])[1], data, dofstart,
999 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1001 _etrans_invT.at(_cell_subentity_types[2][f])[0], data, dofstart,
1003 dofstart += _num_edofs[2][f];
1009 template <
typename T>
1011 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1013 if (_dof_transformations_are_identity)
1016 if (_cell_tdim >= 2)
1020 int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
1022 = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
1025 for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
1028 if (cell_info >> (face_start + e) & 1)
1030 _etransT.at(cell::type::interval)[0], data, dofstart, block_size);
1031 dofstart += _num_edofs[1][e];
1034 if (_cell_tdim == 3)
1037 for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
1040 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1042 _etransT.at(_cell_subentity_types[2][f])[0], data, dofstart,
1046 if (cell_info >> (3 * f) & 1)
1048 _etransT.at(_cell_subentity_types[2][f])[1], data, dofstart,
1051 dofstart += _num_edofs[2][f];
1057 template <
typename T>
1059 const xtl::span<T>& data,
int block_size, std::uint32_t cell_info)
const
1061 if (_dof_transformations_are_identity)
1064 if (_cell_tdim >= 2)
1068 int face_start = _cell_tdim == 3 ? 3 * _num_edofs[2].size() : 0;
1070 = std::accumulate(_num_edofs[0].cbegin(), _num_edofs[0].cend(), 0);
1073 for (std::size_t e = 0; e < _num_edofs[1].size(); ++e)
1076 if (cell_info >> (face_start + e) & 1)
1078 _etrans_inv.at(cell::type::interval)[0], data, dofstart,
1080 dofstart += _num_edofs[1][e];
1083 if (_cell_tdim == 3)
1086 for (std::size_t f = 0; f < _num_edofs[2].size(); ++f)
1089 for (std::uint32_t r = 0; r < (cell_info >> (3 * f + 1) & 3); ++r)
1091 _etrans_inv.at(_cell_subentity_types[2][f])[0], data, dofstart,
1095 if (cell_info >> (3 * f) & 1)
1097 _etrans_inv.at(_cell_subentity_types[2][f])[1], data, dofstart,
1100 dofstart += _num_edofs[2][f];