52 auto unitcellLocal= bLocal[0].unitCell;
55 Diff<dim-1> dx({1,0},unitcellLocal,n);
56 Diff<dim-1> dy({0,1},unitcellLocal,n);
59 for(
int i=0; i<dim; ++i)
61 for(
int j=0; j<dim-1; ++j)
64 for(
int k=0; k<dim-1; ++k)
69 dx.perform_op(bLocal[i].values.data(), dlbi_dxk.values.data());
71 dy.perform_op(bLocal[i].values.data(), dlbi_dxk.values.data());
73 alphaij.values= alphaij.values + dlbi_dxk.values;
74 else if (j==1 && k==0)
75 alphaij.values= alphaij.values - dlbi_dxk.values;
77 alpha.push_back(alphaij);
87 Eigen::Matrix<double,dim,dim-1> orthogonalVectors;
88 Eigen::Matrix<double,dim,dim-1> unitCell= b[0].
unitCell;
91 for(
int i=0; i<dim-1; ++i)
93 orthogonalVectors.col(i)= unitCell.col(i);
94 for(
int j=0; j<i; ++j)
95 orthogonalVectors.col(i)-= unitCell.col(i).dot(orthogonalVectors.col(j))* orthogonalVectors.col(j);
96 orthogonalVectors.col(i)= orthogonalVectors.col(i).normalized();
98 Rotation<dim> rotation(orthogonalVectors);
99 assert((rotation*unitCell).row(2).norm()<FLT_EPSILON);
103 Eigen::Matrix<double,dim-1,dim-1> unitcellLocal= (rotation*unitCell).block(0,0,dim-1,dim-1);
104 for(
int i= 0; i<dim; ++i) {
106 for (
int j = 0; j < dim; ++j)
107 temp.values = temp.values + rotation(i, j) * b[j].values;
108 bLocal.push_back(temp);
152 const std::array<Eigen::Index,dim-1>& n,
155 if (HhatInvComponents.size() ==0 ) HhatInvComponents= getHhatInvComponents(domain,n);
156 Eigen::Matrix<double,dim,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
159 std::vector<LatticeFunction<std::complex<double>,dim-1>> lb0hat;
160 for(
int i=0; i<dim; ++i)
164 lb0hat.push_back(
LatticeFunction<std::complex<double>,dim-1>(n,basisVectors));
166 std::vector<LatticeFunction<std::complex<double>,dim-1>> lbhat(lb0hat);
169 if(piPeriodicFunctions.empty()) {
170 for (
const auto& [key, value]: atoms) {
172 Eigen::Matrix<double,dim,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
173 VectorDimD normal(domain.col(0).cross(domain.col(1)));
177 if(abs(value.dot(normal)) < FLT_EPSILON)
180 perturbedValue= value - (value.dot(normal) + FLT_EPSILON) * normal;
181 else if (key(dim)==2)
182 perturbedValue= value - (value.dot(normal) - FLT_EPSILON) * normal;
185 else if (key(dim)==-1 || key(dim)==-2)
187 perturbedValue= value - 2 * value.dot(normal) * normal;
189 piPeriodicFunctions.insert({key, get_pi(domain, n, perturbedValue)});
190 pihatLatticeFunctions.insert({key, get_pihat(domain, n, perturbedValue)});
214 const int numberOfCslPoints= xuPairs.size();
215 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,dim> uMatrix(numberOfCslPoints,dim);
216 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic> P(numberOfCslPoints,numberOfCslPoints);
221 for(
const auto& [xi,ui] : xuPairs)
223 uAverage= uAverage + ui;
225 if (xuPairs.size() != 0)
226 uAverage= uAverage/xuPairs.size();
229 for(
const auto& [xi,ui] : xuPairs)
233 uMatrix.row(row)= ui-uAverage;
235 for(
const auto& [xj,uj] : xuPairs)
238 P(row, col) = pihatLatticeFunctions.at(xj).dot(pihatLatticeFunctions.at(xi));
244 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,dim> alpha(numberOfCslPoints,dim);
245 Eigen::LLT<Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic>> llt;
247 alpha= llt.solve(uMatrix);
251 for(
int i=0; i<dim; ++i)
253 lb0hat[i].values.setZero();
255 for(
const auto& [xj,uj] : xuPairs) {
257 lb0hat[i].values = lb0hat[i].values + pihatLatticeFunctions.at(xj).values * alpha(j,i);
260 for(
int i=0; i<dim; ++i) {
261 lb0[i].values.setZero();
263 for (
const auto &[xj, uj]: xuPairs) {
265 lb0[i].values = lb0[i].values + piPeriodicFunctions.at(xj).values * alpha(j,i).real();
270 Eigen::VectorXcd uFlattened;
271 uFlattened= uMatrix.reshaped();
272 Eigen::VectorXcd lm(dim*numberOfCslPoints);
273 Eigen::MatrixXcd M(dim*numberOfCslPoints,dim*numberOfCslPoints);
276 for (
int i=0; i<dim; ++i)
279 for (
const auto& [xj,uj] : xuPairs)
282 int row= i*numberOfCslPoints + j;
283 for (
int l=0; l<dim; ++l)
286 for(
const auto& [xk,uk] : xuPairs)
289 int col= l*numberOfCslPoints + k;
291 std::complex<double> temp;
293 if (i==0 && l==0) temp = (HhatInvComponents[0]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
294 if (i==1 && l==1) temp = (HhatInvComponents[1]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
295 if (i==2 && l==2) temp = (HhatInvComponents[2]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
296 if ((i==1 && l==2) || (i==2 && l==1)) temp = (HhatInvComponents[3]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
297 if ((i==0 && l==2) || (i==2 && l==0)) temp = (HhatInvComponents[4]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
298 if ((i==0 && l==1) || (i==1 && l==0)) temp = (HhatInvComponents[5]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
306 Eigen::LLT<Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic>> llt2;
308 lm= llt2.solve(uFlattened);
310 lbhat[0].values.setZero();
311 lbhat[1].values.setZero();
312 lbhat[2].values.setZero();
314 auto lmMatrix= lm.reshaped(numberOfCslPoints,dim);
316 std::vector<LatticeFunction<std::complex<double>,dim-1>> temp;
318 for (
int i=0; i<dim; ++i) {
319 temp.push_back(
LatticeFunction<std::complex<double>, dim - 1>(n, basisVectors));
321 for (
const auto& [xk,uk] : xuPairs) {
323 temp[i].values = temp[i].values + pihatLatticeFunctions.at(xk).values * lmMatrix(k, i);
327 lbhat[0].values= HhatInvComponents[0].values * temp[0].values +
328 HhatInvComponents[5].values * temp[1].values +
329 HhatInvComponents[4].values * temp[2].values;
331 lbhat[1].values= HhatInvComponents[5].values * temp[0].values +
332 HhatInvComponents[1].values * temp[1].values +
333 HhatInvComponents[3].values * temp[2].values;
335 lbhat[2].values= HhatInvComponents[4].values * temp[0].values +
336 HhatInvComponents[3].values * temp[1].values +
337 HhatInvComponents[2].values * temp[2].values;
339 for (
int i=0; i<dim; ++i)
340 lb[i].values = lbhat[i].ifft().values.real();
343 return std::make_pair(lb,lbhat);
388 const std::array<Eigen::Index,dim-1>& n)
390 Eigen::Matrix<double,Eigen::Dynamic,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
391 std::vector<LatticeFunction<std::complex<double>,dim-1>> output;