53 auto unitcellLocal= bLocal[0].unitCell;
56 Diff<dim-1> dx({1,0},unitcellLocal,n);
57 Diff<dim-1> dy({0,1},unitcellLocal,n);
60 for(
int i=0; i<dim; ++i)
62 for(
int j=0; j<dim-1; ++j)
65 for(
int k=0; k<dim-1; ++k)
70 dx.perform_op(bLocal[i].values.data(), dlbi_dxk.values.data());
72 dy.perform_op(bLocal[i].values.data(), dlbi_dxk.values.data());
74 alphaij.values= alphaij.values + dlbi_dxk.values;
75 else if (j==1 && k==0)
76 alphaij.values= alphaij.values - dlbi_dxk.values;
78 alpha.push_back(alphaij);
88 Eigen::Matrix<double,dim,dim-1> orthogonalVectors;
89 Eigen::Matrix<double,dim,dim-1> unitCell= b[0].
unitCell;
92 for(
int i=0; i<dim-1; ++i)
94 orthogonalVectors.col(i)= unitCell.col(i);
95 for(
int j=0; j<i; ++j)
96 orthogonalVectors.col(i)-= unitCell.col(i).dot(orthogonalVectors.col(j))* orthogonalVectors.col(j);
97 orthogonalVectors.col(i)= orthogonalVectors.col(i).normalized();
100 assert((rotation*unitCell).row(2).norm()<FLT_EPSILON);
104 Eigen::Matrix<double,dim-1,dim-1> unitcellLocal= (rotation*unitCell).block(0,0,dim-1,dim-1);
105 for(
int i= 0; i<dim; ++i) {
107 for (
int j = 0; j < dim; ++j)
108 temp.values = temp.values + rotation(i, j) * b[j].values;
109 bLocal.push_back(temp);
153 const std::array<Eigen::Index,dim-1>& n,
156 if (HhatInvComponents.size() ==0 ) HhatInvComponents= getHhatInvComponents(domain,n);
157 Eigen::Matrix<double,dim,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
160 std::vector<LatticeFunction<std::complex<double>,dim-1>> lb0hat;
161 for(
int i=0; i<dim; ++i)
165 lb0hat.push_back(
LatticeFunction<std::complex<double>,dim-1>(n,basisVectors));
167 std::vector<LatticeFunction<std::complex<double>,dim-1>> lbhat(lb0hat);
170 if(piPeriodicFunctions.empty()) {
171 for (
const auto& [key, value]: atoms) {
173 Eigen::Matrix<double,dim,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
174 VectorDimD normal(domain.col(0).cross(domain.col(1)));
178 if(abs(value.dot(normal)) < FLT_EPSILON)
181 perturbedValue= value - (value.dot(normal) + FLT_EPSILON) * normal;
182 else if (key(dim)==2)
183 perturbedValue= value - (value.dot(normal) - FLT_EPSILON) * normal;
186 else if (key(dim)==-1 || key(dim)==-2)
188 perturbedValue= value - 2 * value.dot(normal) * normal;
190 piPeriodicFunctions.insert({key, get_pi(domain, n, perturbedValue)});
191 pihatLatticeFunctions.insert({key, get_pihat(domain, n, perturbedValue)});
215 const int numberOfCslPoints= xuPairs.size();
216 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,dim> uMatrix(numberOfCslPoints,dim);
217 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic> P(numberOfCslPoints,numberOfCslPoints);
222 for(
const auto& [xi,ui] : xuPairs)
224 uAverage= uAverage + ui;
226 if (xuPairs.size() != 0)
227 uAverage= uAverage/xuPairs.size();
230 for(
const auto& [xi,ui] : xuPairs)
234 uMatrix.row(row)= ui-uAverage;
236 for(
const auto& [xj,uj] : xuPairs)
239 P(row, col) = pihatLatticeFunctions.at(xj).dot(pihatLatticeFunctions.at(xi));
245 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,dim> alpha(numberOfCslPoints,dim);
246 Eigen::LLT<Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic>> llt;
248 alpha= llt.solve(uMatrix);
252 for(
int i=0; i<dim; ++i)
254 lb0hat[i].values.setZero();
256 for(
const auto& [xj,uj] : xuPairs) {
258 lb0hat[i].values = lb0hat[i].values + pihatLatticeFunctions.at(xj).values * alpha(j,i);
261 for(
int i=0; i<dim; ++i) {
262 lb0[i].values.setZero();
264 for (
const auto &[xj, uj]: xuPairs) {
266 lb0[i].values = lb0[i].values + piPeriodicFunctions.at(xj).values * alpha(j,i).real();
271 Eigen::VectorXcd uFlattened;
272 uFlattened= uMatrix.reshaped();
273 Eigen::VectorXcd lm(dim*numberOfCslPoints);
274 Eigen::MatrixXcd M(dim*numberOfCslPoints,dim*numberOfCslPoints);
277 for (
int i=0; i<dim; ++i)
280 for (
const auto& [xj,uj] : xuPairs)
283 int row= i*numberOfCslPoints + j;
284 for (
int l=0; l<dim; ++l)
287 for(
const auto& [xk,uk] : xuPairs)
290 int col= l*numberOfCslPoints + k;
292 std::complex<double> temp;
294 if (i==0 && l==0) temp = (HhatInvComponents[0]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
295 if (i==1 && l==1) temp = (HhatInvComponents[1]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
296 if (i==2 && l==2) temp = (HhatInvComponents[2]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
297 if ((i==1 && l==2) || (i==2 && l==1)) temp = (HhatInvComponents[3]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
298 if ((i==0 && l==2) || (i==2 && l==0)) temp = (HhatInvComponents[4]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
299 if ((i==0 && l==1) || (i==1 && l==0)) temp = (HhatInvComponents[5]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
307 Eigen::LLT<Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic>> llt2;
309 lm= llt2.solve(uFlattened);
311 lbhat[0].values.setZero();
312 lbhat[1].values.setZero();
313 lbhat[2].values.setZero();
315 auto lmMatrix= lm.reshaped(numberOfCslPoints,dim);
317 std::vector<LatticeFunction<std::complex<double>,dim-1>> temp;
319 for (
int i=0; i<dim; ++i) {
320 temp.push_back(
LatticeFunction<std::complex<double>, dim - 1>(n, basisVectors));
322 for (
const auto& [xk,uk] : xuPairs) {
324 temp[i].values = temp[i].values + pihatLatticeFunctions.at(xk).values * lmMatrix(k, i);
328 lbhat[0].values= HhatInvComponents[0].values * temp[0].values +
329 HhatInvComponents[5].values * temp[1].values +
330 HhatInvComponents[4].values * temp[2].values;
332 lbhat[1].values= HhatInvComponents[5].values * temp[0].values +
333 HhatInvComponents[1].values * temp[1].values +
334 HhatInvComponents[3].values * temp[2].values;
336 lbhat[2].values= HhatInvComponents[4].values * temp[0].values +
337 HhatInvComponents[3].values * temp[1].values +
338 HhatInvComponents[2].values * temp[2].values;
340 for (
int i=0; i<dim; ++i)
341 lb[i].values = lbhat[i].ifft().values.real();
344 return std::make_pair(lb,lbhat);
389 const std::array<Eigen::Index,dim-1>& n)
391 Eigen::Matrix<double,Eigen::Dynamic,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
392 std::vector<LatticeFunction<std::complex<double>,dim-1>> output;