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 <LatticeModule.h>
9#include <unsupported/Eigen/CXX11/Tensor>
10
11namespace gbLAB {
12 template<typename Derived, int dim>
13 class Operator {
14 public:
15 using Scalar = double;
16 const Derived &derivedOperator;
17 const Lattice<dim> L;
18 const Eigen::array<Eigen::Index, dim> n;
19
20 Operator(const Eigen::Matrix<double,dim,dim>& A,
21 const Eigen::array<Eigen::Index,dim>& n_) : derivedOperator(static_cast<const Derived &>(*this)),
22 L(A),
23 n(n_)
24 {
25 }
26
27 auto domain() const { return L.latticeBasis; }
28
29 Eigen::Index rows() const { return std::accumulate(begin(n), end(n), 1, std::multiplies<>()); }
30 Eigen::Index cols() const { return std::accumulate(begin(n), end(n), 1, std::multiplies<>()); }
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}
93#endif //OILAB_OPERATOR_H
Lattice class.
Definition Lattice.h:34
const Derived & derivedOperator
Definition Operator.h:16
Operator(const Eigen::Matrix< double, dim, dim > &A, const Eigen::array< Eigen::Index, dim > &n_)
Definition Operator.h:20
Eigen::Index cols() const
Definition Operator.h:30
Eigen::Index rows() const
Definition Operator.h:29
double Scalar
Definition Operator.h:15
void perform_op(const double *x_in, double *y_out) const
Definition Operator.h:32
const Lattice< dim > L
Definition Operator.h:17
auto domain() const
Definition Operator.h:27
const Eigen::array< Eigen::Index, dim > n
Definition Operator.h:18
void perform_op(const double *x_in, double *y_out) const
Definition Operator.h:79
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:53
OperatorSum(const E1 &o1_, const E2 &o2_)
Definition Operator.h:45
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)