54 auto unitcellLocal= bLocal[0].unitCell;
57 Diff<dim-1> dx({1,0},unitcellLocal,n);
58 Diff<dim-1> dy({0,1},unitcellLocal,n);
61 for(
int i=0; i<dim; ++i)
63 for(
int j=0; j<dim-1; ++j)
66 for(
int k=0; k<dim-1; ++k)
71 dx.perform_op(bLocal[i].values.data(), dlbi_dxk.values.data());
73 dy.perform_op(bLocal[i].values.data(), dlbi_dxk.values.data());
75 alphaij.values= alphaij.values + dlbi_dxk.values;
76 else if (j==1 && k==0)
77 alphaij.values= alphaij.values - dlbi_dxk.values;
79 alpha.push_back(alphaij);
89 Eigen::Matrix<double,dim,dim-1> orthogonalVectors;
90 Eigen::Matrix<double,dim,dim-1> unitCell= b[0].
unitCell;
93 for(
int i=0; i<dim-1; ++i)
95 orthogonalVectors.col(i)= unitCell.col(i);
96 for(
int j=0; j<i; ++j)
97 orthogonalVectors.col(i)-= unitCell.col(i).dot(orthogonalVectors.col(j))* orthogonalVectors.col(j);
98 orthogonalVectors.col(i)= orthogonalVectors.col(i).normalized();
100 Rotation<dim> rotation(orthogonalVectors);
101 assert((rotation*unitCell).row(2).norm()<FLT_EPSILON);
105 Eigen::Matrix<double,dim-1,dim-1> unitcellLocal= (rotation*unitCell).block(0,0,dim-1,dim-1);
106 for(
int i= 0; i<dim; ++i) {
108 for (
int j = 0; j < dim; ++j)
109 temp.values = temp.values + rotation(i, j) * b[j].values;
110 bLocal.push_back(temp);
154 const std::array<Eigen::Index,dim-1>& n,
157 if (HhatInvComponents.size() ==0 ) HhatInvComponents= getHhatInvComponents(domain,n);
158 Eigen::Matrix<double,dim,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
161 std::vector<LatticeFunction<std::complex<double>,dim-1>> lb0hat;
162 for(
int i=0; i<dim; ++i)
166 lb0hat.push_back(
LatticeFunction<std::complex<double>,dim-1>(n,basisVectors));
168 std::vector<LatticeFunction<std::complex<double>,dim-1>> lbhat(lb0hat);
171 if(piPeriodicFunctions.empty()) {
172 for (
const auto& [key, value]: atoms) {
174 Eigen::Matrix<double,dim,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
175 VectorDimD normal(domain.col(0).cross(domain.col(1)));
179 if(abs(value.dot(normal)) < FLT_EPSILON)
182 perturbedValue= value - (value.dot(normal) + FLT_EPSILON) * normal;
183 else if (key(dim)==2)
184 perturbedValue= value - (value.dot(normal) - FLT_EPSILON) * normal;
187 else if (key(dim)==-1 || key(dim)==-2)
189 perturbedValue= value - 2 * value.dot(normal) * normal;
191 piPeriodicFunctions.insert({key, get_pi(domain, n, perturbedValue)});
192 pihatLatticeFunctions.insert({key, get_pihat(domain, n, perturbedValue)});
216 const int numberOfCslPoints= xuPairs.size();
217 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,dim> uMatrix(numberOfCslPoints,dim);
218 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic> P(numberOfCslPoints,numberOfCslPoints);
223 for(
const auto& [xi,ui] : xuPairs)
225 uAverage= uAverage + ui;
227 if (xuPairs.size() != 0)
228 uAverage= uAverage/xuPairs.size();
231 for(
const auto& [xi,ui] : xuPairs)
235 uMatrix.row(row)= ui-uAverage;
237 for(
const auto& [xj,uj] : xuPairs)
240 P(row, col) = pihatLatticeFunctions.at(xj).dot(pihatLatticeFunctions.at(xi));
246 Eigen::Matrix<std::complex<double>,Eigen::Dynamic,dim> alpha(numberOfCslPoints,dim);
247 Eigen::LLT<Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic>> llt;
249 alpha= llt.solve(uMatrix);
253 for(
int i=0; i<dim; ++i)
255 lb0hat[i].values.setZero();
257 for(
const auto& [xj,uj] : xuPairs) {
259 lb0hat[i].values = lb0hat[i].values + pihatLatticeFunctions.at(xj).values * alpha(j,i);
262 for(
int i=0; i<dim; ++i) {
263 lb0[i].values.setZero();
265 for (
const auto &[xj, uj]: xuPairs) {
267 lb0[i].values = lb0[i].values + piPeriodicFunctions.at(xj).values * alpha(j,i).real();
272 Eigen::VectorXcd uFlattened;
273 uFlattened= uMatrix.reshaped();
274 Eigen::VectorXcd lm(dim*numberOfCslPoints);
275 Eigen::MatrixXcd M(dim*numberOfCslPoints,dim*numberOfCslPoints);
278 for (
int i=0; i<dim; ++i)
281 for (
const auto& [xj,uj] : xuPairs)
284 int row= i*numberOfCslPoints + j;
285 for (
int l=0; l<dim; ++l)
288 for(
const auto& [xk,uk] : xuPairs)
291 int col= l*numberOfCslPoints + k;
293 std::complex<double> temp;
295 if (i==0 && l==0) temp = (HhatInvComponents[0]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
296 if (i==1 && l==1) temp = (HhatInvComponents[1]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
297 if (i==2 && l==2) temp = (HhatInvComponents[2]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
298 if ((i==1 && l==2) || (i==2 && l==1)) temp = (HhatInvComponents[3]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
299 if ((i==0 && l==2) || (i==2 && l==0)) temp = (HhatInvComponents[4]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
300 if ((i==0 && l==1) || (i==1 && l==0)) temp = (HhatInvComponents[5]*pihatLatticeFunctions.at(xk)).dot(pihatLatticeFunctions.at(xj));
308 Eigen::LLT<Eigen::Matrix<std::complex<double>,Eigen::Dynamic,Eigen::Dynamic>> llt2;
310 lm= llt2.solve(uFlattened);
312 lbhat[0].values.setZero();
313 lbhat[1].values.setZero();
314 lbhat[2].values.setZero();
316 auto lmMatrix= lm.reshaped(numberOfCslPoints,dim);
318 std::vector<LatticeFunction<std::complex<double>,dim-1>> temp;
320 for (
int i=0; i<dim; ++i) {
321 temp.push_back(
LatticeFunction<std::complex<double>, dim - 1>(n, basisVectors));
323 for (
const auto& [xk,uk] : xuPairs) {
325 temp[i].values = temp[i].values + pihatLatticeFunctions.at(xk).values * lmMatrix(k, i);
329 lbhat[0].values= HhatInvComponents[0].values * temp[0].values +
330 HhatInvComponents[5].values * temp[1].values +
331 HhatInvComponents[4].values * temp[2].values;
333 lbhat[1].values= HhatInvComponents[5].values * temp[0].values +
334 HhatInvComponents[1].values * temp[1].values +
335 HhatInvComponents[3].values * temp[2].values;
337 lbhat[2].values= HhatInvComponents[4].values * temp[0].values +
338 HhatInvComponents[3].values * temp[1].values +
339 HhatInvComponents[2].values * temp[2].values;
341 for (
int i=0; i<dim; ++i)
342 lb[i].values = lbhat[i].ifft().values.real();
345 return std::make_pair(lb,lbhat);
390 const std::array<Eigen::Index,dim-1>& n)
392 Eigen::Matrix<double,Eigen::Dynamic,dim-1> basisVectors(domain.transpose().completeOrthogonalDecomposition().pseudoInverse());
393 std::vector<LatticeFunction<std::complex<double>,dim-1>> output;