9#ifndef INCG9bad469d38e04e8ab67391ce50c2c480
10#define INCG9bad469d38e04e8ab67391ce50c2c480
15#include "mesh_function_traits.h"
50template <
class OP,
class A,
class B>
60 :
op_(std::move(op)),
a_(std::move(a)),
b_(std::move(b)) {}
66 const Eigen::MatrixXd& local)
const {
67 return op_(
a_(e, local),
b_(e, local), 0);
95struct OperatorAddition {
105 template <base::Scalar U, base::Scalar V>
106 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
int
108 const Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> um(u.data(), 1,
110 const Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> vm(v.data(), 1,
112 std::vector<
decltype(U(0) + V(0))> result(u.size());
114 Eigen::Map<Eigen::Matrix<
decltype(U(0) + V(0)), 1, Eigen::Dynamic>> rm(
115 result.data(), 1, u.size());
123 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
124 int R2,
int C2,
int O2,
int MR2,
int MC2>
125 auto operator()(
const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& u,
126 const std::vector<Eigen::Matrix<S2, R2, C2, O2, MR2, MC2>>& v,
128 using scalar_t =
decltype(S1(0) + S2(0));
129 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
130 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
132 static_assert(R1 == R2,
"cannot add matrices with different #rows.");
133 static_assert(C1 == C2,
"cannot add matrices with different #cols.");
135 Eigen::Map<const Eigen::Matrix<S1, 1, Eigen::Dynamic>> um(
136 &u[0](0, 0), 1, u.size() * R1 * C1);
137 Eigen::Map<const Eigen::Matrix<S2, 1, Eigen::Dynamic>> vm(
138 &v[0](0, 0), 1, v.size() * R1 * C1);
140 std::vector<Eigen::Matrix<scalar_t, R1, C1>> result(u.size());
141 Eigen::Map<Eigen::Matrix<scalar_t, 1, Eigen::Dynamic>> rm(
142 &result[0](0, 0), 1, u.size() * R1 * C1);
146 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
147 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
149 constexpr int fixedRows = std::max(R1, R2);
150 constexpr int fixedCols = std::max(C1, C2);
152 std::vector<Eigen::Matrix<scalar_t, fixedRows, fixedCols>> result(
154 for (
int i = 0; i < u.size(); ++i) {
155 LF_ASSERT_MSG(u[i].rows() == v[i].rows(),
156 "mismatch in #rows of matrices added to each other.");
157 LF_ASSERT_MSG(u[i].cols() == v[i].cols(),
158 "mismatch in #cols of matrices added to each other.");
159 result[i] = u[i] + v[i];
164 std::vector<Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
166 result.reserve(u.size());
167 for (
int i = 0; i < u.size(); ++i) {
168 LF_ASSERT_MSG(u[i].rows() == v[i].rows(),
169 "mismatch in #rows of matrices added to each other.");
170 LF_ASSERT_MSG(u[i].cols() == v[i].cols(),
171 "mismatch in #cols of matrices added to each other.");
172 result.emplace_back(u[i] + v[i]);
181 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
182 int R2,
int C2,
int O2,
int MR2,
int MC2>
183 auto operator()(
const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& u,
184 const std::vector<Eigen::Array<S2, R2, C2, O2, MR2, MC2>>& v,
186 using scalar_t =
decltype(S1(0) + S2(0));
187 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
188 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
190 static_assert(R1 == R2,
"cannot add arrays with different #rows.");
191 static_assert(C1 == C2,
"cannot add arrays with different #cols.");
193 Eigen::Map<const Eigen::Array<S1, 1, Eigen::Dynamic>> um(
194 &u[0](0, 0), 1, u.size() * R1 * C1);
195 Eigen::Map<const Eigen::Array<S2, 1, Eigen::Dynamic>> vm(
196 &v[0](0, 0), 1, v.size() * R1 * C1);
198 std::vector<Eigen::Array<scalar_t, R1, C1>> result(u.size());
199 Eigen::Map<Eigen::Array<scalar_t, 1, Eigen::Dynamic>> rm(
200 &result[0](0, 0), 1, u.size() * R1 * C1);
204 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
205 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
207 constexpr int fixedRows = std::max(R1, R2);
208 constexpr int fixedCols = std::max(C1, C2);
210 std::vector<Eigen::Array<scalar_t, fixedRows, fixedCols>> result(
212 for (
int i = 0; i < u.size(); ++i) {
213 LF_ASSERT_MSG(u[i].rows() == v[i].rows(),
214 "mismatch in #rows of arrays added to each other.");
215 LF_ASSERT_MSG(u[i].cols() == v[i].cols(),
216 "mismatch in #cols of arrays added to each other.");
217 result[i] = u[i] + v[i];
222 std::vector<Eigen::Array<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
224 result.reserve(u.size());
225 for (
int i = 0; i < u.size(); ++i) {
226 LF_ASSERT_MSG(u[i].rows() == v[i].rows(),
227 "mismatch in #rows of arrays added to each other.");
228 LF_ASSERT_MSG(u[i].cols() == v[i].cols(),
229 "mismatch in #cols of arrays added to each other.");
230 result.emplace_back(u[i] + v[i]);
239 template <
class U,
class V>
240 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
242 std::vector<
decltype(u[0] + v[0])> result(u.size());
243 for (
int i = 0; i < result.size(); ++i) {
244 result[i] = u[i] + v[i];
262struct OperatorSubtraction {
273 template <base::Scalar U, base::Scalar V>
274 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
int
276 const Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> um(u.data(), 1,
278 const Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> vm(v.data(), 1,
280 std::vector<
decltype(U(0) + V(0))> result(u.size());
282 Eigen::Map<Eigen::Matrix<
decltype(U(0) + V(0)), 1, Eigen::Dynamic>> rm(
283 result.data(), 1, u.size());
291 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
292 int R2,
int C2,
int O2,
int MR2,
int MC2>
293 auto operator()(
const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& u,
294 const std::vector<Eigen::Matrix<S2, R2, C2, O2, MR2, MC2>>& v,
296 using scalar_t =
decltype(S1(0) + S2(0));
297 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
298 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
300 static_assert(R1 == R2,
"cannot subtract matrices with different #rows.");
301 static_assert(C1 == C2,
"cannot subtract matrices with different #cols.");
303 Eigen::Map<const Eigen::Matrix<S1, 1, Eigen::Dynamic>> um(
304 &u[0](0, 0), 1, u.size() * R1 * C1);
305 Eigen::Map<const Eigen::Matrix<S2, 1, Eigen::Dynamic>> vm(
306 &v[0](0, 0), 1, v.size() * R1 * C1);
308 std::vector<Eigen::Matrix<scalar_t, R1, C1>> result(u.size());
309 Eigen::Map<Eigen::Matrix<scalar_t, 1, Eigen::Dynamic>> rm(
310 &result[0](0, 0), 1, u.size() * R1 * C1);
314 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
315 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
317 constexpr int fixedRows = std::max(R1, R2);
318 constexpr int fixedCols = std::max(C1, C2);
320 std::vector<Eigen::Matrix<scalar_t, fixedRows, fixedCols>> result(
322 for (std::size_t i = 0; i < u.size(); ++i) {
324 u[i].rows() == v[i].rows(),
325 "mismatch in #rows of matrices subtracted from each other.");
327 u[i].cols() == v[i].cols(),
328 "mismatch in #cols of matrices subtracted from each other.");
329 result[i] = u[i] - v[i];
334 std::vector<Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
336 result.reserve(u.size());
337 for (
unsigned long i = 0; i < u.size(); ++i) {
339 u[i].rows() == v[i].rows(),
340 "mismatch in #rows of matrices subtracted from each other.");
342 u[i].cols() == v[i].cols(),
343 "mismatch in #cols of matrices subtracted from each other.");
344 result.emplace_back(u[i] - v[i]);
353 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
354 int R2,
int C2,
int O2,
int MR2,
int MC2>
355 auto operator()(
const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& u,
356 const std::vector<Eigen::Array<S2, R2, C2, O2, MR2, MC2>>& v,
358 using scalar_t =
decltype(S1(0) - S2(0));
359 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
360 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
362 static_assert(R1 == R2,
"cannot subtract arrays with different #rows.");
363 static_assert(C1 == C2,
"cannot subtract arrays with different #cols.");
365 Eigen::Map<const Eigen::Array<S1, 1, Eigen::Dynamic>> um(
366 &u[0](0, 0), 1, u.size() * R1 * C1);
367 Eigen::Map<const Eigen::Array<S2, 1, Eigen::Dynamic>> vm(
368 &v[0](0, 0), 1, v.size() * R1 * C1);
370 std::vector<Eigen::Array<scalar_t, R1, C1>> result(u.size());
371 Eigen::Map<Eigen::Array<scalar_t, 1, Eigen::Dynamic>> rm(
372 &result[0](0, 0), 1, u.size() * R1 * C1);
376 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
377 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
379 constexpr int fixedRows = std::max(R1, R2);
380 constexpr int fixedCols = std::max(C1, C2);
382 std::vector<Eigen::Array<scalar_t, fixedRows, fixedCols>> result(
384 for (
int i = 0; i < u.size(); ++i) {
386 u[i].rows() == v[i].rows(),
387 "mismatch in #rows of arrays subtracted from each other.");
389 u[i].cols() == v[i].cols(),
390 "mismatch in #cols of arrays subtracted from each other.");
391 result[i] = u[i] - v[i];
396 std::vector<Eigen::Array<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
398 result.reserve(u.size());
399 for (
int i = 0; i < u.size(); ++i) {
401 u[i].rows() == v[i].rows(),
402 "mismatch in #rows of arrays subtracted from each other.");
404 u[i].cols() == v[i].cols(),
405 "mismatch in #cols of arrays subtracted from each other.");
406 result.emplace_back(u[i] - v[i]);
415 template <
class U,
class V>
416 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
418 std::vector<
decltype(u[0] + v[0])> result(u.size(),
419 decltype(u[0] + v[0])());
420 for (
int i = 0; i < result.size(); ++i) {
421 result[i] = u[i] - v[i];
439struct OperatorMultiplication {
450 template <base::Scalar U, base::Scalar V>
451 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
int
453 Eigen::Map<const Eigen::Array<U, 1, Eigen::Dynamic>> um(u.data(), 1,
455 Eigen::Map<const Eigen::Array<V, 1, Eigen::Dynamic>> vm(v.data(), 1,
457 std::vector<
decltype(U(0) * V(0))> result(u.size());
458 Eigen::Map<Eigen::Array<
decltype(U(0) * V(0)), 1, Eigen::Dynamic>> rm(
459 result.data(), 1, u.size());
465 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
466 int R2,
int C2,
int O2,
int MR2,
int MC2>
467 auto operator()(
const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& u,
468 const std::vector<Eigen::Matrix<S2, R2, C2, O2, MR2, MC2>>& v,
470 using scalar_t =
decltype(S1(0) * S2(0));
471 if constexpr (R1 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
473 static_assert(C1 == Eigen::Dynamic || R2 == Eigen::Dynamic || C1 == R2,
474 "#cols of lhs doesn't match #rows of rhs");
476 std::vector<Eigen::Matrix<scalar_t, R1, C2>> result(u.size());
477 for (std::size_t i = 0; i < u.size(); ++i) {
478 LF_ASSERT_MSG(u[i].cols() == v[i].rows(),
479 "#cols of lhs doesn't match #rows of rhs");
480 result[i] = u[i] * v[i];
485 std::vector<Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
487 result.reserve(u.size());
488 for (
int i = 0; i < u.size(); ++i) {
489 LF_ASSERT_MSG(u[i].cols() == v[i].rows(),
490 "#cols of lhs doesn't match #rows of rhs");
491 result.emplace_back(u[i] * v[i]);
500 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
501 int R2,
int C2,
int O2,
int MR2,
int MC2>
502 auto operator()(
const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& u,
503 const std::vector<Eigen::Array<S2, R2, C2, O2, MR2, MC2>>& v,
505 using scalar_t =
decltype(S1(0) * S2(0));
506 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
507 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
509 static_assert(R1 == R2,
"cannot multiply arrays with different #rows.");
510 static_assert(C1 == C2,
"cannot multiply arrays with different #cols.");
512 Eigen::Map<const Eigen::Array<S1, 1, Eigen::Dynamic>> um(
513 &u[0](0, 0), 1, u.size() * R1 * C1);
514 Eigen::Map<const Eigen::Array<S2, 1, Eigen::Dynamic>> vm(
515 &v[0](0, 0), 1, v.size() * R1 * C1);
517 std::vector<Eigen::Array<scalar_t, R1, C1>> result(u.size());
518 Eigen::Map<Eigen::Array<scalar_t, 1, Eigen::Dynamic>> rm(
519 &result[0](0, 0), 1, u.size() * R1 * C1);
523 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
524 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
526 constexpr int fixedRows = std::max(R1, R2);
527 constexpr int fixedCols = std::max(C1, C2);
529 std::vector<Eigen::Array<scalar_t, fixedRows, fixedCols>> result(
531 for (
int i = 0; i < u.size(); ++i) {
533 u[i].rows() == v[i].rows(),
534 "mismatch in #rows of arrays multiplied with each other.");
536 u[i].cols() == v[i].cols(),
537 "mismatch in #cols of arrays multiplied with each other.");
538 result[i] = u[i] * v[i];
543 std::vector<Eigen::Array<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
545 result.reserve(u.size());
546 for (
int i = 0; i < u.size(); ++i) {
548 u[i].rows() == v[i].rows(),
549 "mismatch in #rows of arrays multiplied with each other.");
551 u[i].cols() == v[i].cols(),
552 "mismatch in #cols of arrays multiplied with each other.");
553 result.emplace_back(u[i] * v[i]);
560 template <base::Scalar U,
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1>
561 auto operator()(
const std::vector<U>& u,
562 const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& v,
564 using scalar_t =
decltype(u[0] * v[0](0, 0));
565 std::vector<Eigen::Matrix<scalar_t, R1, C1>> result(u.size());
566 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) {
568 Eigen::Map<const Eigen::Array<S1, R1 * C1, Eigen::Dynamic>> vm(
569 v[0].data(), R1 * C1, v.size());
570 Eigen::Map<Eigen::Array<scalar_t, R1 * C1, Eigen::Dynamic>> rm(
571 result[0].data(), R1 * C1, v.size());
572 Eigen::Map<const Eigen::Array<U, 1, Eigen::Dynamic>> um(u.data(), 1,
575 rm = vm * um.template replicate<R1 * C1, 1>();
578 for (std::size_t i = 0; i < u.size(); ++i) {
579 result[i] = u[i] * v[i];
586 template <base::Scalar U,
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1>
587 auto operator()(
const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& v,
588 const std::vector<U>& u,
int )
const {
589 return operator()(u, v, 0);
593 template <base::Scalar U,
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1>
594 auto operator()(
const std::vector<U>& u,
595 const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& v,
597 using scalar_t =
decltype(u[0] * v[0](0, 0));
598 std::vector<Eigen::Array<scalar_t, R1, C1>> result(u.size());
599 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) {
601 Eigen::Map<const Eigen::Array<S1, R1 * C1, Eigen::Dynamic>> vm(
602 v[0].data(), R1 * C1, v.size());
603 Eigen::Map<Eigen::Array<scalar_t, R1 * C1, Eigen::Dynamic>> rm(
604 result[0].data(), R1 * C1, v.size());
605 Eigen::Map<const Eigen::Array<U, 1, Eigen::Dynamic>> um(u.data(), 1,
608 rm = vm * um.template replicate<R1 * C1, 1>();
611 for (std::size_t i = 0; i < u.size(); ++i) {
612 result[i] = u[i] * v[i];
619 template <base::Scalar U,
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1>
620 auto operator()(
const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& v,
621 const std::vector<U>& u,
int )
const {
622 return operator()(u, v, 0);
626 template <
class U,
class V>
627 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
629 std::vector<
decltype(u[0] * v[0])> result;
630 result.reserve(u.size());
631 for (
int i = 0; i < result.size(); ++i) {
632 result.emplace_back(u[i] * v[i]);
663template <MeshFunction A, MeshFunction B>
692template <MeshFunction A, MeshFunction B>
721template <MeshFunction A, MeshFunction B>
Interface class representing a topological entity in a cellular complex
A MeshFunction which combines two other mesh functions using a binary operator (advanced use).
MeshFunctionBinary(OP op, A a, B b)
Create a new MeshFunctionBinary.
auto operator*(const A &a, const B &b) -> MeshFunctionBinary< internal::OperatorMultiplication, A, B >
Multiply two mesh functions with each other.
auto operator-(const A &a, const B &b) -> MeshFunctionBinary< internal::OperatorSubtraction, A, B >
Subtracts two mesh functions.
auto operator()(const lf::mesh::Entity &e, const Eigen::MatrixXd &local) const
auto operator+(const A &a, const B &b) -> MeshFunctionBinary< internal::OperatorAddition, A, B >
Add's two mesh functions.
Contains helper functions and classes that all operate on the interface classes defined in lf::mesh.