oILAB
Loading...
Searching...
No Matches
Operator.h
Go to the documentation of this file.
1//
2// Created by Nikhil Chandra Admal on 7/5/23.
3//
4
5#ifndef OILAB_OPERATOR_H
6#define OILAB_OPERATOR_H
7
8#include "../Lattices/LatticeModule.h"
9#include <unsupported/Eigen/CXX11/Tensor>
10
11namespace oILAB {
12template <typename Derived, int dim> class Operator {
13public:
14 using Scalar = double;
15 const Derived &derivedOperator;
16 const Lattice<dim> L;
17 const Eigen::array<Eigen::Index, dim> n;
18
19 Operator(const Eigen::Matrix<double, dim, dim> &A,
20 const Eigen::array<Eigen::Index, dim> &n_)
21 : derivedOperator(static_cast<const Derived &>(*this)), L(A), n(n_) {}
22
23 auto domain() const { return L.latticeBasis; }
24
25 Eigen::Index rows() const {
26 return std::accumulate(begin(n), end(n), 1, std::multiplies<>());
27 }
28 Eigen::Index cols() const {
29 return std::accumulate(begin(n), end(n), 1, std::multiplies<>());
30 }
31
32 void perform_op(const double *x_in, double *y_out) const {
33 derivedOperator.perform_op(x_in, y_out);
34 }
35
36 // implement expression templates for operators
37
38 };
39
40 template<typename E1, typename E2, int dim>
41 class OperatorSum : public Operator<OperatorSum<E1,E2,dim>,dim> {
42 const E1 o1;
43 const E2 o2;
44 public:
45 OperatorSum(const E1 &o1_, const E2 &o2_) : Operator<OperatorSum<E1,E2,dim>,dim>(o1_.L.latticeBasis,o1_.n),
46 o1(o1_), o2(o2_)
47
48 {
49 // ensure that the domains of the two operators and their discretizations match
50 assert(o1.n == o2.n && o1.domain().isApprox(o2.domain()));
51 }
52
53 void perform_op(const double *x_in, double *y_out) const {
54 int nx = this->rows();
55 Eigen::VectorXd y1(nx);
56 Eigen::VectorXd y2(nx);
57 o1.perform_op(x_in, y1.data());
58 o2.perform_op(x_in, y2.data());
59 Eigen::Map<Eigen::VectorXd> y(y_out, nx);
60 y = y1 + y2;
61 }
62 };
63
64 template<typename E1, typename E2, int dim>
65 OperatorSum<E1, E2, dim> operator+(const Operator<E1, dim>& u, const Operator<E2,dim>& v) {
66 return OperatorSum<E1, E2, dim>(*static_cast<const E1 *>(&u), *static_cast<const E2 *>(&v));
67 }
68
69 template<typename T, typename E, int dim>
70 class OperatorScalarProduct : public Operator<OperatorScalarProduct<T,E,dim>,dim> {
71 double s;
72 const E op;
73 public:
74 OperatorScalarProduct(const T& s_, const E& op_) : Operator<OperatorScalarProduct<T,E,dim>,dim>(op_.L.latticeBasis,op_.n),
75 s(s_), op(op_)
76
77 {}
78
79 void perform_op(const double* x_in, double* y_out) const {
80 int nx = this->rows();
81 op.perform_op(x_in, y_out);
82 Eigen::Map<Eigen::VectorXd> y(y_out, nx);
83 y = s * y;
84 }
85 };
86
87 template<typename T, typename E, int dim>
88 OperatorScalarProduct<T, E, dim> operator*(const T &s, const Operator<E, dim> &u) {
89 return OperatorScalarProduct<T, E, dim>(s, *static_cast<const E *>(&u));
90 }
91
92 } // namespace oILAB
93#endif //OILAB_OPERATOR_H
Lattice class.
Definition Lattice.h:31
Eigen::Index rows() const
Definition Operator.h:25
const Eigen::array< Eigen::Index, dim > n
Definition Operator.h:17
Eigen::Index cols() const
Definition Operator.h:28
const Lattice< dim > L
Definition Operator.h:16
Operator(const Eigen::Matrix< double, dim, dim > &A, const Eigen::array< Eigen::Index, dim > &n_)
Definition Operator.h:19
auto domain() const
Definition Operator.h:23
const Derived & derivedOperator
Definition Operator.h:15
void perform_op(const double *x_in, double *y_out) const
Definition Operator.h:32
double Scalar
Definition Operator.h:14
OperatorScalarProduct(const T &s_, const E &op_)
Definition Operator.h:74
void perform_op(const double *x_in, double *y_out) const
Definition Operator.h:79
OperatorSum(const E1 &o1_, const E2 &o2_)
Definition Operator.h:45
void perform_op(const double *x_in, double *y_out) const
Definition Operator.h:53
OperatorSum< E1, E2, dim > operator+(const Operator< E1, dim > &u, const Operator< E2, dim > &v)
Definition Operator.h:65
LatticeVector< dim > operator*(const typename LatticeVector< dim >::IntScalarType &scalar, const LatticeVector< dim > &L)