9 #include <xtensor/xadapt.hpp> 
   10 #include <xtensor/xtensor.hpp> 
   11 #include <xtensor/xview.hpp> 
   12 #include <xtl/xspan.hpp> 
   24   contravariantPiola = 3,
 
   25   doubleCovariantPiola = 4,
 
   26   doubleContravariantPiola = 5,
 
   31 template <
typename O, 
typename Mat0, 
typename Mat1, 
typename Mat2>
 
   32 void dot22(O&& r, 
const Mat0& A, 
const Mat1& B, 
const Mat2& C)
 
   34   assert(A.shape(1) == B.shape(0));
 
   35   using T = 
typename std::decay_t<O>::value_type;
 
   36   for (std::size_t i = 0; i < r.shape(0); ++i)
 
   37     for (std::size_t j = 0; j < r.shape(1); ++j)
 
   40       for (std::size_t k = 0; k < A.shape(1); ++k)
 
   41         for (std::size_t l = 0; l < B.shape(1); ++l)
 
   42           acc += A(i, k) * B(k, l) * C(l, j);
 
   47 template <
typename Vec, 
typename Mat0, 
typename Mat1>
 
   48 void dot21(Vec&& r, 
const Mat0& A, 
const Mat1& B)
 
   50   using T = 
typename std::decay_t<Vec>::value_type;
 
   51   for (std::size_t i = 0; i < r.shape(0); ++i)
 
   54     for (std::size_t k = 0; k < A.shape(1); ++k)
 
   55       acc += A(i, k) * B[k];
 
   62 template <
typename O, 
typename P, 
typename Q, 
typename R>
 
   63 void l2_piola(O&& r, 
const P& U, 
const Q& , 
double detJ, 
const R& )
 
   66   std::for_each(r.begin(), r.end(), [detJ](
auto& ri) { ri /= detJ; });
 
   70 template <
typename O, 
typename P, 
typename Q, 
typename R>
 
   74   auto Kt = xt::transpose(K);
 
   75   for (std::size_t p = 0; p < U.shape(0); ++p)
 
   77     auto r_p = xt::row(r, p);
 
   78     auto U_p = xt::row(U, p);
 
   79     impl::dot21(r_p, Kt, U_p);
 
   84 template <
typename O, 
typename P, 
typename Q, 
typename R>
 
   88   for (std::size_t p = 0; p < U.shape(0); ++p)
 
   90     auto r_p = xt::row(r, p);
 
   91     auto U_p = xt::row(U, p);
 
   92     impl::dot21(r_p, J, U_p);
 
   94   double inv_detJ = 1 / detJ;
 
   95   std::for_each(r.begin(), r.end(), [inv_detJ](
auto& ri) { ri *= inv_detJ; });
 
   99 template <
typename O, 
typename P, 
typename Q, 
typename R>
 
  103   for (std::size_t p = 0; p < U.shape(0); ++p)
 
  105     auto r_p = xt::row(r, p);
 
  106     auto U_p = xt::row(U, p);
 
  107     auto _U = xt::reshape_view(U_p, {J.shape(1), J.shape(1)});
 
  108     auto _r = xt::reshape_view(r_p, {K.shape(1), K.shape(1)});
 
  109     impl::dot22(_r, xt::transpose(K), _U, K);
 
  114 template <
typename O, 
typename P, 
typename Q, 
typename R>
 
  118   auto Jt = xt::transpose(J);
 
  119   for (std::size_t p = 0; p < U.shape(0); ++p)
 
  121     auto r_p = xt::row(r, p);
 
  122     auto U_p = xt::row(U, p);
 
  123     auto _U = xt::reshape_view(U_p, {J.shape(1), J.shape(1)});
 
  124     auto _r = xt::reshape_view(r_p, {J.shape(0), J.shape(0)});
 
  125     impl::dot22(_r, J, _U, Jt);
 
  127   double inv_detJ = 1 / (detJ * detJ);
 
  128   std::for_each(r.begin(), r.end(), [inv_detJ](
auto& ri) { ri *= inv_detJ; });