Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/basix/v0.9.0/cpp/maps_8h_source.html
Home Installation C++ docs Python docs
maps.h
1 // Copyright (c) 2021 Matthew Scroggs
2 // FEniCS Project
3 // SPDX-License-Identifier: MIT
4 
5 #pragma once
6 
7 #include <stdexcept>
8 #include <string>
9 #include <xtensor/xadapt.hpp>
10 #include <xtensor/xtensor.hpp>
11 #include <xtensor/xview.hpp>
12 #include <xtl/xspan.hpp>
13 
15 namespace basix::maps
16 {
17 
19 enum class type
20 {
21  identity,
22  covariantPiola,
23  contravariantPiola,
24  doubleCovariantPiola,
25  doubleContravariantPiola,
26 };
27 
29 const std::string& type_to_str(maps::type type);
30 
31 namespace impl
32 {
33 template <typename O, typename Mat0, typename Mat1, typename Mat2>
34 void dot22(O& r, const Mat0& A, const Mat1& B, const Mat2& C)
35 {
36  assert(A.shape(1) == B.shape(0));
37  r = 0;
38  for (std::size_t i = 0; i < r.shape(0); ++i)
39  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  r(i, j) += A(i, k) * B(k, l) * C(l, j);
43 }
44 
45 template <typename Vec, typename Mat0, typename Mat1>
46 void dot21(Vec& r, const Mat0& A, const Mat1& B)
47 {
48  // assert(A.shape(1) == B.shape(0));
49  r = 0;
50  for (std::size_t i = 0; i < r.shape(0); ++i)
51  for (std::size_t k = 0; k < A.shape(1); ++k)
52  r[i] += A(i, k) * B[k];
53 }
54 
55 template <typename Vec0, typename Vec1, typename Mat0, typename Mat1>
56 void identity(Vec0& r, const Vec1& U, const Mat0& /*J*/, double /*detJ*/,
57  const Mat1& /*K*/)
58 {
59  r = U;
60 }
61 
62 template <typename O, typename P, typename Q, typename R>
63 void covariant_piola(O&& r, const P& U, const Q& /*J*/, double /*detJ*/,
64  const R& K)
65 {
66  auto Kt = xt::transpose(K);
67  for (std::size_t p = 0; p < U.shape(0); ++p)
68  {
69  auto r_p = xt::row(r, p);
70  auto U_p = xt::row(U, p);
71  dot21(r_p, Kt, U_p);
72  }
73 }
74 
75 template <typename O, typename P, typename Q, typename R>
76 void contravariant_piola(O&& r, const P& U, const Q& J, double detJ,
77  const R& /*K*/)
78 {
79  for (std::size_t p = 0; p < U.shape(0); ++p)
80  {
81  auto r_p = xt::row(r, p);
82  auto U_p = xt::row(U, p);
83  dot21(r_p, J, U_p);
84  }
85  r /= detJ;
86 }
87 
88 template <typename O, typename P, typename Q, typename R>
89 void double_covariant_piola(O& r, const P& U, const Q& J, double /*detJ*/,
90  const R& K)
91 {
92  for (std::size_t p = 0; p < U.shape(0); ++p)
93  {
94  auto r_p = xt::row(r, p);
95  auto U_p = xt::row(U, p);
96  auto _U = xt::reshape_view(U_p, {J.shape(1), J.shape(1)});
97  auto _r = xt::reshape_view(r_p, {K.shape(1), K.shape(1)});
98  dot22(_r, xt::transpose(K), _U, K);
99  }
100 }
101 
102 template <typename O, typename P, typename Q, typename R>
103 void double_contravariant_piola(O& r, const P& U, const Q& J, double detJ,
104  const R& /*K*/)
105 {
106  auto Jt = xt::transpose(J);
107  for (std::size_t p = 0; p < U.shape(0); ++p)
108  {
109  auto r_p = xt::row(r, p);
110  auto U_p = xt::row(U, p);
111  auto _U = xt::reshape_view(U_p, {J.shape(1), J.shape(1)});
112  auto _r = xt::reshape_view(r_p, {J.shape(0), J.shape(0)});
113  dot22(_r, J, _U, Jt);
114  }
115  r /= (detJ * detJ);
116 }
117 } // namespace impl
118 
129 template <typename O, typename P, typename Mat0, typename Mat1>
130 void apply_map(O&& u, const P& U, const Mat0& J, double detJ, const Mat1& K,
131  maps::type map_type)
132 {
133  switch (map_type)
134  {
135  case maps::type::identity:
136  return impl::identity(u, U, J, detJ, K);
137  case maps::type::covariantPiola:
138  return impl::covariant_piola(u, U, J, detJ, K);
139  case maps::type::contravariantPiola:
140  return impl::contravariant_piola(u, U, J, detJ, K);
141  case maps::type::doubleCovariantPiola:
142  return impl::double_covariant_piola(u, U, J, detJ, K);
143  case maps::type::doubleContravariantPiola:
144  return impl::double_contravariant_piola(u, U, J, detJ, K);
145  default:
146  throw std::runtime_error("Mapping not yet implemented");
147  }
148 }
149 
150 } // namespace basix::maps
basix::maps::type_to_str
const std::string & type_to_str(maps::type type)
Convert mapping type enum to string.
Definition: maps.cpp:10
basix::maps
Information about finite element maps.
Definition: maps.h:15
basix::maps::apply_map
void apply_map(O &&u, const P &U, const Mat0 &J, double detJ, const Mat1 &K, maps::type map_type)
Definition: maps.h:130
basix::maps::type
type
Cell type.
Definition: maps.h:19