Basix
Toggle main menu visibility
Loading...
Searching...
No Matches
cpp
basix
maps.h
1
// Copyright (c) 2021-2022 Matthew Scroggs and Garth N. Wells
2
// FEniCS Project
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
#include "mdspan.hpp"
8
#include "types.h"
9
#include <algorithm>
10
#include <stdexcept>
11
#include <type_traits>
12
14
namespace
basix::maps
15
{
16
17
namespace
impl
18
{
21
template
<
typename
T,
typename
=
void
>
22
struct
scalar_value_type
23
{
25
typedef
T value_type;
26
};
28
template
<
typename
T>
29
struct
scalar_value_type<T, std::void_t<typename T::value_type>>
30
{
31
typedef
typename
T::value_type value_type;
32
};
34
template
<
typename
T>
35
using
scalar_value_type_t =
typename
scalar_value_type<T>::value_type;
36
}
// namespace impl
37
39
enum class
type
40
{
41
identity = 0,
42
L2Piola = 1,
43
covariantPiola = 2,
44
contravariantPiola = 3,
45
doubleCovariantPiola = 4,
46
doubleContravariantPiola = 5,
47
};
48
50
template
<
typename
O,
typename
P,
typename
Q,
typename
R>
51
void
l2_piola
(O&& r,
const
P& U,
const
Q&
/*J*/
,
double
detJ,
const
R&
/*K*/
)
52
{
53
assert(U.extent(0) == r.extent(0));
54
assert(U.extent(1) == r.extent(1));
55
for
(std::size_t i = 0; i < U.extent(0); ++i)
56
for
(std::size_t j = 0; j < U.extent(1); ++j)
57
r(i, j) = U(i, j) / detJ;
58
}
59
61
template
<
typename
O,
typename
P,
typename
Q,
typename
R>
62
void
covariant_piola
(O&& r,
const
P& U,
const
Q&
/*J*/
,
double
/*detJ*/
,
63
const
R& K)
64
{
65
using
T =
typename
std::decay_t<O>::value_type;
66
using
Z =
typename
impl::scalar_value_type_t<T>;
67
for
(std::size_t p = 0; p < U.extent(0); ++p)
68
{
69
// r_p = K^T U_p, where p indicates the p-th row
70
for
(std::size_t i = 0; i < r.extent(1); ++i)
71
{
72
T acc = 0;
73
for
(std::size_t k = 0; k < K.extent(0); ++k)
74
acc +=
static_cast<
Z
>
(K(k, i)) * U(p, k);
75
r(p, i) = acc;
76
}
77
}
78
}
79
81
template
<
typename
O,
typename
P,
typename
Q,
typename
R>
82
void
contravariant_piola
(O&& r,
const
P& U,
const
Q& J,
double
detJ,
83
const
R&
/*K*/
)
84
{
85
using
T =
typename
std::decay_t<O>::value_type;
86
using
Z =
typename
impl::scalar_value_type_t<T>;
87
for
(std::size_t p = 0; p < U.extent(0); ++p)
88
{
89
for
(std::size_t i = 0; i < r.extent(1); ++i)
90
{
91
T acc = 0;
92
for
(std::size_t k = 0; k < J.extent(1); ++k)
93
acc +=
static_cast<
Z
>
(J(i, k)) * U(p, k);
94
r(p, i) = acc;
95
}
96
}
97
98
std::transform(r.data_handle(), r.data_handle() + r.size(), r.data_handle(),
99
[detJ](
auto
ri) { return ri / static_cast<Z>(detJ); });
100
}
101
103
template
<
typename
O,
typename
P,
typename
Q,
typename
R>
104
void
double_covariant_piola
(O&& r,
const
P& U,
const
Q&
/*J*/
,
double
/*detJ*/
,
105
const
R& K)
106
{
107
using
T =
typename
std::decay_t<O>::value_type;
108
using
Z =
typename
impl::scalar_value_type_t<T>;
109
for
(std::size_t p = 0; p < U.extent(0); ++p)
110
{
111
md::mdspan<const T, md::dextents<std::size_t, 2>> _U(
112
U.data_handle() + p * U.extent(1), K.extent(0), K.extent(0));
113
md::mdspan<T, md::dextents<std::size_t, 2>> _r(
114
r.data_handle() + p * r.extent(1), K.extent(1), K.extent(1));
115
// _r = K^T _U K
116
for
(std::size_t i = 0; i < _r.extent(0); ++i)
117
{
118
for
(std::size_t j = 0; j < _r.extent(1); ++j)
119
{
120
T acc = 0;
121
for
(std::size_t k = 0; k < K.extent(0); ++k)
122
for
(std::size_t l = 0; l < _U.extent(1); ++l)
123
acc +=
static_cast<
Z
>
(K(k, i)) * _U(k, l) *
static_cast<
Z
>
(K(l, j));
124
_r(i, j) = acc;
125
}
126
}
127
}
128
}
129
131
template
<
typename
O,
typename
P,
typename
Q,
typename
R>
132
void
double_contravariant_piola
(O&& r,
const
P& U,
const
Q& J,
double
detJ,
133
const
R&
/*K*/
)
134
{
135
using
T =
typename
std::decay_t<O>::value_type;
136
using
Z =
typename
impl::scalar_value_type_t<T>;
137
for
(std::size_t p = 0; p < U.extent(0); ++p)
138
{
139
md::mdspan<const T, md::dextents<std::size_t, 2>> _U(
140
U.data_handle() + p * U.extent(1), J.extent(1), J.extent(1));
141
md::mdspan<T, md::dextents<std::size_t, 2>> _r(
142
r.data_handle() + p * r.extent(1), J.extent(0), J.extent(0));
143
144
// _r = J U J^T
145
for
(std::size_t i = 0; i < _r.extent(0); ++i)
146
{
147
for
(std::size_t j = 0; j < _r.extent(1); ++j)
148
{
149
T acc = 0;
150
for
(std::size_t k = 0; k < J.extent(1); ++k)
151
for
(std::size_t l = 0; l < _U.extent(1); ++l)
152
acc +=
static_cast<
Z
>
(J(i, k)) * _U(k, l) *
static_cast<
Z
>
(J(j, l));
153
_r(i, j) = acc;
154
}
155
}
156
}
157
158
std::transform(r.data_handle(), r.data_handle() + r.size(), r.data_handle(),
159
[detJ](
auto
ri) { return ri / static_cast<Z>(detJ * detJ); });
160
}
161
162
}
// namespace basix::maps
basix::maps
Information about finite element maps.
Definition
maps.h:15
basix::maps::l2_piola
void l2_piola(O &&r, const P &U, const Q &, double detJ, const R &)
L2 Piola map.
Definition
maps.h:51
basix::maps::covariant_piola
void covariant_piola(O &&r, const P &U, const Q &, double, const R &K)
Covariant Piola map.
Definition
maps.h:62
basix::maps::contravariant_piola
void contravariant_piola(O &&r, const P &U, const Q &J, double detJ, const R &)
Contravariant Piola map.
Definition
maps.h:82
basix::maps::double_contravariant_piola
void double_contravariant_piola(O &&r, const P &U, const Q &J, double detJ, const R &)
Double contravariant Piola map.
Definition
maps.h:132
basix::maps::double_covariant_piola
void double_covariant_piola(O &&r, const P &U, const Q &, double, const R &K)
Double covariant Piola map.
Definition
maps.h:104
basix::maps::type
type
Map type.
Definition
maps.h:40
Generated by
1.17.0