9#ifndef INCGb9b63bcccec548419a52fe0b06ffb3fc
10#define INCGb9b63bcccec548419a52fe0b06ffb3fc
12#include <lf/mesh/mesh.h>
38template <
class OP,
class MF>
44 return op_(
mf_(e, local), 0);
55 template <
class U,
class = std::enable_if_t<std::is_arithmetic_v<U>>>
56 auto operator()(
const std::vector<U>& u,
int )
const {
57 const Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> um(u.data(), 1,
59 std::vector<U> result(u.size());
60 Eigen::Map<Eigen::Matrix<U, 1, Eigen::Dynamic>> rm(result.data(), 1,
67 template <
class S,
int R,
int C,
int O,
int MR,
int MC>
68 auto operator()(
const std::vector<Eigen::Matrix<S, R, C, O, MR, MC>>& u,
70 if constexpr (R == 0 || C == 0) {
74 if constexpr (R != Eigen::Dynamic && C != Eigen::Dynamic) {
76 const Eigen::Map<const Eigen::Matrix<S, 1, Eigen::Dynamic>> um(
77 &u[0](0, 0), 1, u.size() * R * C);
78 std::vector<Eigen::Matrix<S, R, C, O, MR, MC>> result(u.size());
79 Eigen::Map<Eigen::Matrix<S, 1, Eigen::Dynamic>> rm(&result[0](0, 0), 1,
85 std::vector<Eigen::Matrix<S, R, C, O, MR, MC>> result(u.size());
86 for (
int i = 0; i < u.size(); ++i) {
94 template <
class S,
int R,
int C,
int O,
int MR,
int MC>
95 auto operator()(
const std::vector<Eigen::Array<S, R, C, O, MR, MC>>& u,
97 if constexpr (R == 0 || C == 0) {
101 if constexpr (R != Eigen::Dynamic && C != Eigen::Dynamic) {
103 Eigen::Map<const Eigen::Array<S, 1, Eigen::Dynamic>> um(&u[0](0, 0), 1,
105 std::vector<Eigen::Array<S, R, C, O, MR, MC>> result(u.size());
106 Eigen::Map<Eigen::Array<S, 1, Eigen::Dynamic>> rm(&result[0](0, 0), 1,
112 std::vector<Eigen::Array<S, R, C, O, MR, MC>> result(u.size());
113 for (
int i = 0; i < u.size(); ++i) {
122 auto operator()(
const std::vector<T>& u,
long )
const {
123 std::vector<T> result(u.size());
124 for (
int i = 0; i < u.size(); ++i) {
131struct UnaryOpSquaredNorm {
133 template <
class U,
class = std::enable_if_t<std::is_arithmetic_v<U>>>
134 auto operator()(
const std::vector<U>& u,
int )
const {
135 const Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> um(u.data(), 1,
137 std::vector<U> result(u.size());
138 Eigen::Map<Eigen::Matrix<U, 1, Eigen::Dynamic>> rm(result.data(), 1,
145 template <
class S,
int R,
int C,
int O,
int MR,
int MC>
146 auto operator()(
const std::vector<Eigen::Matrix<S, R, C, O, MR, MC>>& u,
148 std::vector<double> result(u.size());
149 if constexpr (R != Eigen::Dynamic && C != Eigen::Dynamic) {
152 "squaredNorm only supported for matrices with at least 1 row "
154 if constexpr (C == 1) {
155 const Eigen::Map<const Eigen::Matrix<S, R, Eigen::Dynamic>> um(
156 &u[0](0, 0), R, u.size());
157 Eigen::Map<Eigen::Matrix<S, 1, Eigen::Dynamic>> rm(result.data(), 1,
159 rm = um.cwiseAbs2().colwise().sum();
160 }
else if constexpr (R == 1) {
161 Eigen::Map<const Eigen::Matrix<S, Eigen::Dynamic, C, Eigen::RowMajor>>
162 um(&u[0](0, 0), u.size(), C);
163 Eigen::Map<Eigen::Matrix<S, Eigen::Dynamic, 1>> rm(result.data(),
165 rm = um.cwiseAbs2().rowwise().sum();
168 for (std::size_t i = 0; i < u.size(); ++i) {
169 result[i] = u[i].squaredNorm();
176struct UnaryOpTranspose {
178 template <
class S,
int R,
int C,
int O,
int MR,
int MC>
179 auto operator()(
const std::vector<Eigen::Matrix<S, R, C, O, MR, MC>>& u,
181 std::vector<Eigen::Matrix<S, C, R>> result(u.size());
182 for (std::size_t i = 0; i < u.size(); ++i) {
183 result[i] = u[i].transpose();
189 template <
class S,
int R,
int C,
int O,
int MR,
int MC>
190 auto operator()(
const std::vector<Eigen::Array<S, R, C, O, MR, MC>>& u,
192 std::vector<Eigen::Array<S, C, R>> result(u.size());
193 for (std::size_t i = 0; i < u.size(); ++i) {
194 result[i] = u[i].transpose();
200struct UnaryOpAdjoint {
202 template <
class S,
int R,
int C,
int O,
int MR,
int MC>
203 auto operator()(
const std::vector<Eigen::Matrix<S, R, C, O, MR, MC>>& u,
205 std::vector<Eigen::Matrix<S, C, R>> result(u.size());
206 for (std::size_t i = 0; i < u.size(); ++i) {
207 result[i] = u[i].adjoint();
213struct UnaryOpConjugate {
215 template <base::Scalar U>
216 auto operator()(
const std::vector<U>& u,
int )
const {
217 Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> um(u.data(), 1,
219 std::vector<U> result(u.size());
220 Eigen::Map<Eigen::Matrix<U, 1, Eigen::Dynamic>> rm(result.data(), 1,
227 template <
class S,
int R,
int C,
int O,
int MR,
int MC>
228 auto operator()(
const std::vector<Eigen::Matrix<S, R, C, O, MR, MC>>& u,
230 std::vector<Eigen::Matrix<S, R, C>> result(u.size());
231 for (std::size_t i = 0; i < u.size(); ++i) {
232 result[i] = u[i].conjugate();
238 template <
class S,
int R,
int C,
int O,
int MR,
int MC>
239 auto operator()(
const std::vector<Eigen::Array<S, R, C, O, MR, MC>>& u,
241 std::vector<Eigen::Array<S, R, C>> result(u.size());
242 for (std::size_t i = 0; i < u.size(); ++i) {
243 result[i] = u[i].conjugate();
262template <MeshFunction A>
277template <MeshFunction A>
290template <MeshFunction A>
294 "transpose() only supported for Eigen::Matrix and Eigen::Array "
295 "valued mesh functions");
307template <MeshFunction A>
311 "adjoint only supported for Eigen::Matrix valued mesh "
324template <MeshFunction A>
330 "conjugate() supports only Eigen::Matrix, Eigen::Array or Scalar valued "
Interface class representing a topological entity in a cellular complex
A mesh function representing another mesh function under a pointwise, unary operation.
auto operator-(const A &a) -> MeshFunctionUnary< internal::UnaryOpMinus, A >
Applies the unary minus operator to a mesh function.
auto operator()(const mesh::Entity &e, const Eigen::MatrixXd &local) const
auto squaredNorm(const A &a) -> MeshFunctionUnary< internal::UnaryOpSquaredNorm, A >
Pointwise squared norm of another mesh function.
MeshFunctionUnary(OP op, MF mf)
auto transpose(const A &a) -> MeshFunctionUnary< internal::UnaryOpTranspose, A >
Pointwise transpose of an Eigen::Matrix or Eigen::Array
auto adjoint(const A &a) -> MeshFunctionUnary< internal::UnaryOpAdjoint, A >
Pointwise adjoint of an Eigen::Matrix, i.e. the conjugate transposed of the matrix.
auto conjugate(const A &a) -> MeshFunctionUnary< internal::UnaryOpConjugate, A >
Pointwise conjuagte of an Eigen::Matrix, Eigen::Array or scalar valued mesh function.
Check if a given type T is a Eigen::Array<...>&
Check if a given type T is an Eigen::Matrix.
Concept which is fulfilled if a type T is a scalar type, i.e. if it is a "field" in the mathematical ...
Contains helper functions and classes that all operate on the interface classes defined in lf::mesh.
internal::VectorElement_t< internal::MeshFunctionReturnType_t< R > > MeshFunctionReturnType
Determine the type of objects returned by a MeshFunction.