oILAB
Loading...
Searching...
No Matches
PeriodicFunctionImplementation.h
Go to the documentation of this file.
1//
2// Created by Nikhil Chandra Admal on 5/31/24.
3//
4#ifndef OILAB_PERIODICFUNCTIONIMPLEMENTATION_H
5#define OILAB_PERIODICFUNCTIONIMPLEMENTATION_H
6//#include <PeriodicFunction.h>
7#include "FFT.h"
8
9namespace oILAB {
10template <typename Scalar, int dim>
12 const Eigen::array<Eigen::Index, dim> &n,
13 const Eigen::Matrix<double, Eigen::Dynamic, dim> &_unitCell)
14 : values(n), unitCell(_unitCell) {
15 values.setZero();
16 }
17
18 template<typename Scalar, int dim>
19 template<typename T, typename, typename, int dm, typename>
20 PeriodicFunction<Scalar,dim>::PeriodicFunction(const Eigen::array<Eigen::Index,dim>& n,
21 const Eigen::Matrix<double,Eigen::Dynamic,dim>& _unitCell,
22 const Function<T,Scalar>& fun) :
23 values(n), unitCell(_unitCell)
24 {
25 //Eigen::Vector<double,Eigen::Dynamic> center= unitCell.col(0)/2;
26 Eigen::Vector<double,Eigen::Dynamic> center= unitCell.col(0)/2;
27 for (int i = 0; i < n[0]; i++)
28 {
29 Eigen::Vector<double,Eigen::Dynamic> x=i*unitCell.col(0)/n[0];
30 //values(i)= fun(x-center);
31 values(i)= fun(x);
32 }
33 }
34
35 template<typename Scalar, int dim>
36 template<typename T, typename, int dm, typename>
37 PeriodicFunction<Scalar,dim>::PeriodicFunction(const Eigen::array<Eigen::Index,dim>& n,
38 const Eigen::Matrix<double,Eigen::Dynamic,dim>& _unitCell,
39 const Function<T,Scalar>& fun) :
40 values(n), unitCell(_unitCell)
41 {
42 //Eigen::Vector<double,Eigen::Dynamic> center= unitCell.col(0)/2 + unitCell.col(1)/2;
43 for (int i = 0; i < n[0]; i++)
44 {
45 for (int j = 0; j < n[1]; j++)
46 {
47 Eigen::Vector<double,Eigen::Dynamic> x=i*unitCell.col(0)/n[0] + j*unitCell.col(1)/n[1];
48 //values(i,j)= fun(x-center);
49 values(i,j)= fun(x);
50 }
51 }
52 }
53
54 template<typename Scalar, int dim>
55 template<typename T, int dm, typename>
56 PeriodicFunction<Scalar,dim>::PeriodicFunction(const Eigen::array<Eigen::Index,dim>& n,
57 const Eigen::Matrix<double,Eigen::Dynamic,dim>& _unitCell,
58 const Function<T,Scalar>& fun) :
59 values(n), unitCell(_unitCell)
60 {
61 //Eigen::Vector<double,Eigen::Dynamic> center=unitCell.col(0)/2 + unitCell.col(1)/2 + unitCell.col(2)/2;
62 for (int i = 0; i < n[0]; i++) {
63 for (int j = 0; j < n[1]; j++) {
64 for (int k = 0; k < n[2]; k++) {
65 Eigen::Vector<double,Eigen::Dynamic> x= i*unitCell.col(0)/n[0] +
66 j*unitCell.col(1)/n[1] +
67 k*unitCell.col(2)/n[2];
68 //values(i, j, k) = fun(x-center);
69 values(i, j, k) = fun(x);
70 }
71 }
72 }
73 }
74
75
76
77 template<typename Scalar, int dim>
79 {
80 Eigen::Matrix<double,Eigen::Dynamic,dim> basisVectors(unitCell.transpose().completeOrthogonalDecomposition().pseudoInverse());
81 LatticeFunction<dcomplex,dim> pfhat(values.dimensions(),basisVectors);
82 FFT::fft(values.template cast<dcomplex>(),pfhat.values);
83 //return pfhat;
84
85 Eigen::Matrix<double,dim,dim> unitCellGramMatrix;
86 for(int i=0; i<dim; ++i)
87 for(int j=0; j<dim; ++j)
88 unitCellGramMatrix(i,j)= unitCell.col(i).dot(unitCell.col(j));
89 Eigen::array<Eigen::Index,dim> n= this->values.dimensions();
90 int prod= std::accumulate(std::begin(n),
91 std::begin(n) + dim,
92 1,
93 std::multiplies<>{});
94 pfhat.values*= (sqrt(unitCellGramMatrix.determinant())/prod);
95 return pfhat;
96 }
97
98 template<typename Scalar, int dim>
100 {
101 Eigen::Tensor<double,0> sum((this->values * other.values).sum());
102 Eigen::Matrix<double,dim,dim> unitCellGramMatrix;
103 for(int i=0; i<dim; ++i)
104 for(int j=0; j<dim; ++j)
105 unitCellGramMatrix(i,j)= unitCell.col(i).dot(unitCell.col(j));
106 Eigen::array<Eigen::Index,dim> n= this->values.dimensions();
107 int prod= std::accumulate(std::begin(n),
108 std::begin(n) + dim,
109 1,
110 std::multiplies<>{});
111 return sum(0)*sqrt(unitCellGramMatrix.determinant())/prod;
112 }
113
114 // this needs to be corrected as we altered the definition of fft
115 template<typename Scalar, int dim> template <typename T>
117 {
118 // pfhat - fft of the periodic function
119 const auto pfhat(fft());
120 Eigen::array<Eigen::Index,dim> n= values.dimensions();
121 PeriodicFunction<Scalar,dim> output(n, unitCell);
122
123 // fourier transform of the kernel function
124 LatticeFunction<Scalar, dim> pkfhat(kernel.fft(n,pfhat.basisVectors));
125
126 PeriodicFunction<dcomplex,dim> tempOutput(n,unitCell);
127 FFT::ifft(pfhat.values*pkfhat.values,tempOutput.values);
128 output.values = tempOutput.values.real();
129 return output;
130 }
131
132 } // namespace oILAB
133#endif // OILAB_PERIODICFUNCTIONIMPLEMENTATION_H
static void ifft(const Eigen::Tensor< dcomplex, 3 > &in, Eigen::Tensor< dcomplex, 3 > &out)
Definition FFT.h:54
static void fft(const Eigen::Tensor< dcomplex, 3 > &in, Eigen::Tensor< dcomplex, 3 > &out)
Definition FFT.h:17
Eigen::Tensor< Scalar, dim > values
PeriodicFunction< Scalar, dim > kernelConvolution(const Function< T, Scalar > &kernel)
Eigen::Tensor< Scalar, dim > values
PeriodicFunction(const Eigen::array< Eigen::Index, dim > &n, const Eigen::Matrix< double, Eigen::Dynamic, dim > &_unitCell)
const Eigen::Matrix< double, Eigen::Dynamic, dim > unitCell
double dot(const PeriodicFunction< Scalar, dim > &other) const
LatticeFunction< dcomplex, dim > fft() const