9#ifndef __9bad469d38e04e8ab67391ce50c2c480
10#define __9bad469d38e04e8ab67391ce50c2c480
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 <
class U,
class V,
106 class =
typename std::enable_if<base::is_scalar<U> &&
107 base::is_scalar<V>>::type>
108 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
int
110 Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> um(&u[0], 1,
112 Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> vm(&v[0], 1,
114 std::vector<
decltype(U(0) + V(0))> result(u.size());
115 Eigen::Map<Eigen::Matrix<
decltype(U(0) + V(0)), 1, Eigen::Dynamic>> rm(
116 &result[0], 1, u.size());
124 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
125 int R2,
int C2,
int O2,
int MR2,
int MC2>
126 auto operator()(
const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& u,
127 const std::vector<Eigen::Matrix<S2, R2, C2, O2, MR2, MC2>>& v,
129 using scalar_t =
decltype(S1(0) + S2(0));
130 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
131 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
133 static_assert(R1 == R2,
"cannot add matrices with different #rows.");
134 static_assert(C1 == C2,
"cannot add matrices with different #cols.");
136 Eigen::Map<const Eigen::Matrix<S1, 1, Eigen::Dynamic>> um(
137 &u[0](0, 0), 1, u.size() * R1 * C1);
138 Eigen::Map<const Eigen::Matrix<S2, 1, Eigen::Dynamic>> vm(
139 &v[0](0, 0), 1, v.size() * R1 * C1);
141 std::vector<Eigen::Matrix<scalar_t, R1, C1>> result(u.size());
142 Eigen::Map<Eigen::Matrix<scalar_t, 1, Eigen::Dynamic>> rm(
143 &result[0](0, 0), 1, u.size() * R1 * C1);
147 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
148 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
150 constexpr int fixedRows = std::max(R1, R2);
151 constexpr int fixedCols = std::max(C1, C2);
153 std::vector<Eigen::Matrix<scalar_t, fixedRows, fixedCols>> result(
155 for (
int i = 0; i < u.size(); ++i) {
156 LF_ASSERT_MSG(u[i].rows() == v[i].rows(),
157 "mismatch in #rows of matrices added to each other.");
158 LF_ASSERT_MSG(u[i].cols() == v[i].cols(),
159 "mismatch in #cols of matrices added to each other.");
160 result[i] = u[i] + v[i];
165 std::vector<Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
167 result.reserve(u.size());
168 for (
int i = 0; i < u.size(); ++i) {
169 LF_ASSERT_MSG(u[i].rows() == v[i].rows(),
170 "mismatch in #rows of matrices added to each other.");
171 LF_ASSERT_MSG(u[i].cols() == v[i].cols(),
172 "mismatch in #cols of matrices added to each other.");
173 result.emplace_back(u[i] + v[i]);
182 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
183 int R2,
int C2,
int O2,
int MR2,
int MC2>
184 auto operator()(
const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& u,
185 const std::vector<Eigen::Array<S2, R2, C2, O2, MR2, MC2>>& v,
187 using scalar_t =
decltype(S1(0) + S2(0));
188 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
189 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
191 static_assert(R1 == R2,
"cannot add arrays with different #rows.");
192 static_assert(C1 == C2,
"cannot add arrays with different #cols.");
194 Eigen::Map<const Eigen::Array<S1, 1, Eigen::Dynamic>> um(
195 &u[0](0, 0), 1, u.size() * R1 * C1);
196 Eigen::Map<const Eigen::Array<S2, 1, Eigen::Dynamic>> vm(
197 &v[0](0, 0), 1, v.size() * R1 * C1);
199 std::vector<Eigen::Array<scalar_t, R1, C1>> result(u.size());
200 Eigen::Map<Eigen::Array<scalar_t, 1, Eigen::Dynamic>> rm(
201 &result[0](0, 0), 1, u.size() * R1 * C1);
205 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
206 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
208 constexpr int fixedRows = std::max(R1, R2);
209 constexpr int fixedCols = std::max(C1, C2);
211 std::vector<Eigen::Array<scalar_t, fixedRows, fixedCols>> result(
213 for (
int i = 0; i < u.size(); ++i) {
214 LF_ASSERT_MSG(u[i].rows() == v[i].rows(),
215 "mismatch in #rows of arrays added to each other.");
216 LF_ASSERT_MSG(u[i].cols() == v[i].cols(),
217 "mismatch in #cols of arrays added to each other.");
218 result[i] = u[i] + v[i];
223 std::vector<Eigen::Array<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
225 result.reserve(u.size());
226 for (
int i = 0; i < u.size(); ++i) {
227 LF_ASSERT_MSG(u[i].rows() == v[i].rows(),
228 "mismatch in #rows of arrays added to each other.");
229 LF_ASSERT_MSG(u[i].cols() == v[i].cols(),
230 "mismatch in #cols of arrays added to each other.");
231 result.emplace_back(u[i] + v[i]);
240 template <
class U,
class V>
241 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
243 std::vector<
decltype(u[0] + v[0])> result(u.size());
244 for (
int i = 0; i < result.size(); ++i) {
245 result[i] = u[i] + v[i];
263struct OperatorSubtraction {
274 template <
class U,
class V,
275 class =
typename std::enable_if<base::is_scalar<U> &&
276 base::is_scalar<V>>::type>
277 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
int
279 Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> um(&u[0], 1,
281 Eigen::Map<const Eigen::Matrix<U, 1, Eigen::Dynamic>> vm(&v[0], 1,
283 std::vector<
decltype(U(0) + V(0))> result(u.size());
284 Eigen::Map<Eigen::Matrix<
decltype(U(0) + V(0)), 1, Eigen::Dynamic>> rm(
285 &result[0], 1, u.size());
293 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
294 int R2,
int C2,
int O2,
int MR2,
int MC2>
295 auto operator()(
const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& u,
296 const std::vector<Eigen::Matrix<S2, R2, C2, O2, MR2, MC2>>& v,
298 using scalar_t =
decltype(S1(0) + S2(0));
299 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
300 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
302 static_assert(R1 == R2,
"cannot subtract matrices with different #rows.");
303 static_assert(C1 == C2,
"cannot subtract matrices with different #cols.");
305 Eigen::Map<const Eigen::Matrix<S1, 1, Eigen::Dynamic>> um(
306 &u[0](0, 0), 1, u.size() * R1 * C1);
307 Eigen::Map<const Eigen::Matrix<S2, 1, Eigen::Dynamic>> vm(
308 &v[0](0, 0), 1, v.size() * R1 * C1);
310 std::vector<Eigen::Matrix<scalar_t, R1, C1>> result(u.size());
311 Eigen::Map<Eigen::Matrix<scalar_t, 1, Eigen::Dynamic>> rm(
312 &result[0](0, 0), 1, u.size() * R1 * C1);
316 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
317 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
319 constexpr int fixedRows = std::max(R1, R2);
320 constexpr int fixedCols = std::max(C1, C2);
322 std::vector<Eigen::Matrix<scalar_t, fixedRows, fixedCols>> result(
324 for (std::size_t i = 0; i < u.size(); ++i) {
326 u[i].rows() == v[i].rows(),
327 "mismatch in #rows of matrices subtracted from each other.");
329 u[i].cols() == v[i].cols(),
330 "mismatch in #cols of matrices subtracted from each other.");
331 result[i] = u[i] - v[i];
336 std::vector<Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
338 result.reserve(u.size());
339 for (
unsigned long i = 0; i < u.size(); ++i) {
341 u[i].rows() == v[i].rows(),
342 "mismatch in #rows of matrices subtracted from each other.");
344 u[i].cols() == v[i].cols(),
345 "mismatch in #cols of matrices subtracted from each other.");
346 result.emplace_back(u[i] - v[i]);
355 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
356 int R2,
int C2,
int O2,
int MR2,
int MC2>
357 auto operator()(
const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& u,
358 const std::vector<Eigen::Array<S2, R2, C2, O2, MR2, MC2>>& v,
360 using scalar_t =
decltype(S1(0) - S2(0));
361 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
362 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
364 static_assert(R1 == R2,
"cannot subtract arrays with different #rows.");
365 static_assert(C1 == C2,
"cannot subtract arrays with different #cols.");
367 Eigen::Map<const Eigen::Array<S1, 1, Eigen::Dynamic>> um(
368 &u[0](0, 0), 1, u.size() * R1 * C1);
369 Eigen::Map<const Eigen::Array<S2, 1, Eigen::Dynamic>> vm(
370 &v[0](0, 0), 1, v.size() * R1 * C1);
372 std::vector<Eigen::Array<scalar_t, R1, C1>> result(u.size());
373 Eigen::Map<Eigen::Array<scalar_t, 1, Eigen::Dynamic>> rm(
374 &result[0](0, 0), 1, u.size() * R1 * C1);
378 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
379 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
381 constexpr int fixedRows = std::max(R1, R2);
382 constexpr int fixedCols = std::max(C1, C2);
384 std::vector<Eigen::Array<scalar_t, fixedRows, fixedCols>> result(
386 for (
int i = 0; i < u.size(); ++i) {
388 u[i].rows() == v[i].rows(),
389 "mismatch in #rows of arrays subtracted from each other.");
391 u[i].cols() == v[i].cols(),
392 "mismatch in #cols of arrays subtracted from each other.");
393 result[i] = u[i] - v[i];
398 std::vector<Eigen::Array<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
400 result.reserve(u.size());
401 for (
int i = 0; i < u.size(); ++i) {
403 u[i].rows() == v[i].rows(),
404 "mismatch in #rows of arrays subtracted from each other.");
406 u[i].cols() == v[i].cols(),
407 "mismatch in #cols of arrays subtracted from each other.");
408 result.emplace_back(u[i] - v[i]);
417 template <
class U,
class V>
418 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
420 std::vector<
decltype(u[0] + v[0])> result(u.size(),
421 decltype(u[0] + v[0])());
422 for (
int i = 0; i < result.size(); ++i) {
423 result[i] = u[i] - v[i];
441struct OperatorMultiplication {
452 template <
class U,
class V,
453 class =
typename std::enable_if_t<base::is_scalar<U> &&
455 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
int
457 Eigen::Map<const Eigen::Array<U, 1, Eigen::Dynamic>> um(&u[0], 1, u.size());
458 Eigen::Map<const Eigen::Array<V, 1, Eigen::Dynamic>> vm(&v[0], 1, v.size());
459 std::vector<
decltype(U(0) * V(0))> result(u.size());
460 Eigen::Map<Eigen::Array<
decltype(U(0) * V(0)), 1, Eigen::Dynamic>> rm(
461 &result[0], 1, u.size());
467 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
468 int R2,
int C2,
int O2,
int MR2,
int MC2>
469 auto operator()(
const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& u,
470 const std::vector<Eigen::Matrix<S2, R2, C2, O2, MR2, MC2>>& v,
472 using scalar_t =
decltype(S1(0) * S2(0));
473 if constexpr (R1 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
475 static_assert(C1 == Eigen::Dynamic || R2 == Eigen::Dynamic || C1 == R2,
476 "#cols of lhs doesn't match #rows of rhs");
478 std::vector<Eigen::Matrix<scalar_t, R1, C2>> result(u.size());
479 for (std::size_t i = 0; i < u.size(); ++i) {
480 LF_ASSERT_MSG(u[i].cols() == v[i].rows(),
481 "#cols of lhs doesn't match #rows of rhs");
482 result[i] = u[i] * v[i];
487 std::vector<Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
489 result.reserve(u.size());
490 for (
int i = 0; i < u.size(); ++i) {
491 LF_ASSERT_MSG(u[i].cols() == v[i].rows(),
492 "#cols of lhs doesn't match #rows of rhs");
493 result.emplace_back(u[i] * v[i]);
502 template <
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
class S2,
503 int R2,
int C2,
int O2,
int MR2,
int MC2>
504 auto operator()(
const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& u,
505 const std::vector<Eigen::Array<S2, R2, C2, O2, MR2, MC2>>& v,
507 using scalar_t =
decltype(S1(0) * S2(0));
508 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic &&
509 R2 != Eigen::Dynamic && C2 != Eigen::Dynamic) {
511 static_assert(R1 == R2,
"cannot multiply arrays with different #rows.");
512 static_assert(C1 == C2,
"cannot multiply arrays with different #cols.");
514 Eigen::Map<const Eigen::Array<S1, 1, Eigen::Dynamic>> um(
515 &u[0](0, 0), 1, u.size() * R1 * C1);
516 Eigen::Map<const Eigen::Array<S2, 1, Eigen::Dynamic>> vm(
517 &v[0](0, 0), 1, v.size() * R1 * C1);
519 std::vector<Eigen::Array<scalar_t, R1, C1>> result(u.size());
520 Eigen::Map<Eigen::Array<scalar_t, 1, Eigen::Dynamic>> rm(
521 &result[0](0, 0), 1, u.size() * R1 * C1);
525 if constexpr ((R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) ||
526 (R2 != Eigen::Dynamic && C2 != Eigen::Dynamic)) {
528 constexpr int fixedRows = std::max(R1, R2);
529 constexpr int fixedCols = std::max(C1, C2);
531 std::vector<Eigen::Array<scalar_t, fixedRows, fixedCols>> result(
533 for (
int i = 0; i < u.size(); ++i) {
535 u[i].rows() == v[i].rows(),
536 "mismatch in #rows of arrays multiplied with each other.");
538 u[i].cols() == v[i].cols(),
539 "mismatch in #cols of arrays multiplied with each other.");
540 result[i] = u[i] * v[i];
545 std::vector<Eigen::Array<scalar_t, Eigen::Dynamic, Eigen::Dynamic>>
547 result.reserve(u.size());
548 for (
int i = 0; i < u.size(); ++i) {
550 u[i].rows() == v[i].rows(),
551 "mismatch in #rows of arrays multiplied with each other.");
553 u[i].cols() == v[i].cols(),
554 "mismatch in #cols of arrays multiplied with each other.");
555 result.emplace_back(u[i] * v[i]);
562 template <
class U,
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
563 class = std::enable_if_t<base::is_scalar<U>>>
564 auto operator()(
const std::vector<U>& u,
565 const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& v,
567 using scalar_t =
decltype(u[0] * v[0](0, 0));
568 std::vector<Eigen::Matrix<scalar_t, R1, C1>> result(u.size());
569 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) {
571 Eigen::Map<const Eigen::Array<S1, R1 * C1, Eigen::Dynamic>> vm(
572 v[0].data(), R1 * C1, v.size());
573 Eigen::Map<Eigen::Array<scalar_t, R1 * C1, Eigen::Dynamic>> rm(
574 result[0].data(), R1 * C1, v.size());
575 Eigen::Map<const Eigen::Array<U, 1, Eigen::Dynamic>> um(u.data(), 1,
578 rm = vm * um.template replicate<R1 * C1, 1>();
581 for (std::size_t i = 0; i < u.size(); ++i) {
582 result[i] = u[i] * v[i];
589 template <
class U,
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
590 class = std::enable_if_t<base::is_scalar<U>>>
591 auto operator()(
const std::vector<Eigen::Matrix<S1, R1, C1, O1, MR1, MC1>>& v,
592 const std::vector<U>& u,
int )
const {
593 return operator()(u, v, 0);
597 template <
class U,
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
598 class = std::enable_if_t<base::is_scalar<U>>>
599 auto operator()(
const std::vector<U>& u,
600 const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& v,
602 using scalar_t =
decltype(u[0] * v[0](0, 0));
603 std::vector<Eigen::Array<scalar_t, R1, C1>> result(u.size());
604 if constexpr (R1 != Eigen::Dynamic && C1 != Eigen::Dynamic) {
606 Eigen::Map<const Eigen::Array<S1, R1 * C1, Eigen::Dynamic>> vm(
607 v[0].data(), R1 * C1, v.size());
608 Eigen::Map<Eigen::Array<scalar_t, R1 * C1, Eigen::Dynamic>> rm(
609 result[0].data(), R1 * C1, v.size());
610 Eigen::Map<const Eigen::Array<U, 1, Eigen::Dynamic>> um(u.data(), 1,
613 rm = vm * um.template replicate<R1 * C1, 1>();
616 for (std::size_t i = 0; i < u.size(); ++i) {
617 result[i] = u[i] * v[i];
624 template <
class U,
class S1,
int R1,
int C1,
int O1,
int MR1,
int MC1,
625 class = std::enable_if_t<base::is_scalar<U>>>
626 auto operator()(
const std::vector<Eigen::Array<S1, R1, C1, O1, MR1, MC1>>& v,
627 const std::vector<U>& u,
int )
const {
628 return operator()(u, v, 0);
632 template <
class U,
class V>
633 auto operator()(
const std::vector<U>& u,
const std::vector<V>& v,
635 std::vector<
decltype(u[0] * v[0])> result;
636 result.reserve(u.size());
637 for (
int i = 0; i < result.size(); ++i) {
638 result.emplace_back(u[i] * v[i]);
669template <
class A,
class B,
670 class = std::enable_if_t<isMeshFunction<A> && isMeshFunction<B>>>
698template <
class A,
class B,
699 class = std::enable_if_t<isMeshFunction<A> && isMeshFunction<B>>>
727template <
class A,
class B,
728 class = std::enable_if_t<isMeshFunction<A> && isMeshFunction<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)
Add's two mesh functions.
auto operator*(const A &a, const B &b)
Multiply two mesh functions with each other.
auto operator()(const lf::mesh::Entity &e, const Eigen::MatrixXd &local) const
auto operator-(const A &a, const B &b)
Subtracts two mesh functions.
Contains helper functions and classes that all operate on the interface classes defined in lf::mesh.