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