oILAB
Loading...
Searching...
No Matches
LatticeFunctionImplementation.h
Go to the documentation of this file.
1//
2// Created by Nikhil Chandra Admal on 5/31/24.
3//
4#ifndef OILAB_LATTICEFUNCTIONIMPLEMENTATION_H
5#define OILAB_LATTICEFUNCTIONIMPLEMENTATION_H
6#include <FFT.h>
7#include <iostream>
8#include <numeric>
9
10namespace gbLAB
11{
12 template<typename Scalar, int dim>
13 LatticeFunction<Scalar,dim>::LatticeFunction(const Eigen::array<Eigen::Index,dim>& n,
14 const Eigen::Matrix<double,Eigen::Dynamic,dim>& _basisVectors) :
15 values(n), basisVectors(_basisVectors)
16 {
17 values.setZero();
18 }
19
20 template<typename Scalar, int dim>
21 template<typename T, typename, typename, int dm, typename>
22 LatticeFunction<Scalar,dim>::LatticeFunction(const Eigen::array<Eigen::Index, dim> &n,
23 const Eigen::Matrix<double, Eigen::Dynamic, dim> &_basisVectors,
24 const Function<T,Scalar>& fun) :
25 values(n), basisVectors(_basisVectors) {
26 for (int i = 0; i < n[0]; i++) {
27 int in= i > n[0]/2 ? i-n[0] : i;
28 values(i) = fun(in * basisVectors.col(0));
29 }
30 }
31
32 template<typename Scalar, int dim>
33 template<typename T, typename, int dm, typename>
34 LatticeFunction<Scalar,dim>::LatticeFunction(const Eigen::array<Eigen::Index, dim> &n,
35 const Eigen::Matrix<double,Eigen::Dynamic,dim>& _basisVectors,
36 const Function<T,Scalar>& fun) :
37 values(n), basisVectors(_basisVectors) {
38 for (int i = 0; i < n[0]; i++) {
39 for (int j = 0; j < n[1]; j++) {
40 //values(i, j) = fun(i * basisVectors.col(0) + j * basisVectors.col(1));
41 int in= i > n[0]/2 ? i-n[0] : i;
42 int jn= j > n[1]/2 ? j-n[1] : j;
43 values(i,j) = fun(in * basisVectors.col(0) + jn * basisVectors.col(1));
44 }
45 }
46 }
47
48 template<typename Scalar, int dim>
49 template<typename T, int dm, typename>
50 LatticeFunction<Scalar,dim>::LatticeFunction(const Eigen::array<Eigen::Index, dim> &n,
51 const Eigen::Matrix<double, Eigen::Dynamic, dim> &_basisVectors,
52 const Function<T, Scalar> &fun) :
53 values(n), basisVectors(_basisVectors) {
54 for (int i = 0; i < n[0]; i++) {
55 for (int j = 0; j < n[1]; j++) {
56 for (int k = 0; k < n[2]; k++) {
57 //values(i, j, k) = fun(i * basisVectors.col(0) + j * basisVectors.col(1) + k * basisVectors.col(2));
58 int in= i>n[0]/2 ? i-n[0] : i;
59 int jn= j>n[1]/2 ? j-n[1] : j;
60 int kn= k>n[2]/2 ? k-n[2] : k;
61 values(i, j, k) = fun(in * basisVectors.col(0) +
62 jn * basisVectors.col(1) +
63 kn * basisVectors.col(2));
64 }
65 }
66 }
67 }
68
69 template<typename Scalar, int dim>
70 std::complex<double> LatticeFunction<Scalar,dim>::dot(const LatticeFunction<std::complex<double>,dim>& other) const
71 {
72 Eigen::Tensor<std::complex<double>,0> sum((this->values * other.values.conjugate()).sum());
73 Eigen::Matrix<double,dim,dim> gramMatrix;
74 for(int i=0; i<dim; ++i)
75 for(int j=0; j<dim; ++j)
76 gramMatrix(i,j)= basisVectors.col(i).dot(basisVectors.col(j));
77 return sum(0) * sqrt(gramMatrix.determinant());
78
79 }
80
81 template<typename Scalar, int dim>
83 {
84 Eigen::Matrix<double,Eigen::Dynamic,dim> unitCell(basisVectors.transpose().completeOrthogonalDecomposition().pseudoInverse());
85 PeriodicFunction<dcomplex,dim> pf(values.dimensions(),unitCell);
86 FFT::ifft(values.template cast<dcomplex>(),pf.values);
87 //return pf;
88 // Calculate the area spanned by the unit cell vectors
89 Eigen::Matrix<double,dim,dim> unitCellGramMatrix;
90 for(int i=0; i<dim; ++i)
91 for(int j=0; j<dim; ++j)
92 unitCellGramMatrix(i,j)= unitCell.col(i).dot(unitCell.col(j));
93
94 Eigen::array<Eigen::Index,dim> n= this->values.dimensions();
95 int prod= std::accumulate(std::begin(n),
96 std::begin(n) + dim,
97 1,
98 std::multiplies<>{});
99 pf.values= pf.values * (dcomplex)(prod/sqrt(unitCellGramMatrix.determinant()));
100 return pf;
101 }
102
103 template<typename Scalar, int dim>
105 {
106 // assert that the two lattice functions have the same domain
107 const auto n= lf1.values.dimensions();
109 output.values= lf1.values * lf2.values;
110 return output;
111 }
112}
113#endif // OILAB_LATTICEFUNCTIONIMPLEMENTATION_H
static void ifft(const Eigen::Tensor< dcomplex, 3 > &in, Eigen::Tensor< dcomplex, 3 > &out)
Definition FFT.h:54
Eigen::Tensor< Scalar, dim > values
PeriodicFunction< dcomplex, dim > ifft() const
const Eigen::Matrix< double, Eigen::Dynamic, dim > basisVectors
std::complex< double > dcomplex
LatticeFunction(const Eigen::array< Eigen::Index, dim > &n, const Eigen::Matrix< double, Eigen::Dynamic, dim > &_basisVectors)
std::complex< double > dot(const LatticeFunction< std::complex< double >, dim > &other) const
Eigen::Tensor< Scalar, dim > values
LatticeVector< dim > operator*(const typename LatticeVector< dim >::IntScalarType &scalar, const LatticeVector< dim > &L)