oILAB
Loading...
Searching...
No Matches
PeriodicFunction.h
Go to the documentation of this file.
1//
2// Created by Nikhil Chandra Admal on 7/4/23.
3//
4
5#ifndef OILAB_PERIODICFUNCTION_H
6#define OILAB_PERIODICFUNCTION_H
7
8#include "Eigen/Dense"
9#include "unsupported/Eigen/CXX11/Tensor"
10#include <iomanip>
11
12namespace oILAB {
13
14template <typename Scalar, int dim> class LatticeFunction;
15
16template <typename Derived, typename Scalar> class Function;
17
18template <typename Scalar, int dim> class PeriodicFunction {
19public:
20 using dcomplex = std::complex<double>;
21 const Eigen::Matrix<double, Eigen::Dynamic, dim> unitCell;
22 Eigen::Tensor<Scalar, dim> values;
23
24 // Construct a zero periodic function
25 explicit PeriodicFunction(
26 const Eigen::array<Eigen::Index, dim> &n,
27 const Eigen::Matrix<double, Eigen::Dynamic, dim> &_unitCell);
28
29 // generates a periodic function from a function centered at the center of a
30 // lattice
31 template <typename T, typename = T, typename = T, int dm = dim,
32 typename = std::enable_if_t<dm == 1>>
33 PeriodicFunction(const Eigen::array<Eigen::Index, dim> &n,
34 const Eigen::Matrix<double, Eigen::Dynamic, dim> &_unitCell,
35 const Function<T, Scalar> &fun);
36
37 template <typename T, typename = T, int dm = dim,
38 typename = std::enable_if_t<dm == 2>>
39 PeriodicFunction(const Eigen::array<Eigen::Index, dim> &n,
40 const Eigen::Matrix<double, Eigen::Dynamic, dim> &_unitCell,
41 const Function<T, Scalar> &fun);
42
43 template <typename T, int dm = dim, typename = std::enable_if_t<dm == 3>>
44 PeriodicFunction(const Eigen::array<Eigen::Index, dim> &n,
45 const Eigen::Matrix<double, Eigen::Dynamic, dim> &_unitCell,
46 const Function<T, Scalar> &fun);
47
49
50 double dot(const PeriodicFunction<Scalar, dim> &other) const;
51
52 template <typename T>
55 };
56
57 template<typename Scalar, int dim, typename = std::enable_if_t<dim==2>>
58 std::basic_ostream<char>& operator<<(std::basic_ostream<char>& s, const PeriodicFunction<Scalar, dim>& fun)
59 {
60 auto n = fun.values.dimensions();
61 assert(n.size() == dim);
62 s << n[0]*n[1] << std::endl;
63 s << std::endl;
64 for (int i = 0; i < n[0]; i++) {
65 for (int j = 0; j < n[1]; j++) {
66 Eigen::Vector<double, Eigen::Dynamic> x = i * fun.unitCell.col(0) / n[0] +
67 j * fun.unitCell.col(1) / n[1];
68 const Eigen::IOFormat fmt(15, 0, " ", "", " ", "", "", "");
69 s << x.transpose().format(fmt) << std::setw(25) << std::setprecision(15) << fun.values(i, j)
70 << std::endl;
71 }
72 }
73 return s;
74 }
75
76 template<typename Scalar, int dim, typename T, typename = std::enable_if_t<dim==3>>
77 std::basic_ostream<char>& operator<<(std::basic_ostream<char>& s, const PeriodicFunction<Scalar, dim>& fun)
78 {
79 auto n = fun.values.dimensions();
80 assert(n.size() == dim);
81 s << n[0]*n[1]*n[2] << std::endl;
82 s << std::endl;
83 for (int i = 0; i < n[0]; i++) {
84 for (int j = 0; j < n[1]; j++) {
85 for (int k = 0; k < n[2]; k++) {
86 Eigen::Vector<double, Eigen::Dynamic> x = i * fun.unitCell.col(0) / n[0] +
87 j * fun.unitCell.col(1) / n[1] +
88 k * fun.unitCell.col(2) / n[2];
89 const Eigen::IOFormat fmt(15, 0, " ", " ", " ", "", "", "");
90 s << x.transpose().format(fmt) << std::setw(25) << std::setprecision(15) << fun.values(i,j,k)
91 << std::endl;
92 }
93 }
94 }
95 return s;
96 }
97
98 } // namespace oILAB
100
101#endif //OILAB_PERIODICFUNCTION_H
PeriodicFunction< Scalar, dim > kernelConvolution(const Function< T, Scalar > &kernel)
Eigen::Tensor< Scalar, dim > values
const Eigen::Matrix< double, Eigen::Dynamic, dim > unitCell
double dot(const PeriodicFunction< Scalar, dim > &other) const
LatticeFunction< dcomplex, dim > fft() const
std::complex< double > dcomplex
basic_ostream< char > & operator<<(basic_ostream< char > &s, const LatticeDirection< dim > &m)