Skip to content

Commit 307ac27

Browse files
committed
LCAO per-atom gamma: add per-band weight normalization
Fix weight computation: normalize w_In per band before multiplying by gamma_unwrapped[n]. Without this, the Log-per-atom gamma after Löwdin orthogonalization doesn't sum to the Wilson loop determinant. Per-string gamma for gdir=3 (1x1x2) verified correct: gI = (-1.98, -2.39, -2.39) sum = -6.76 ~ Wilson determinant -6.75 [DeltaP P1] still prints ~(0,0,0) because branch selection in deltap_wannier.cpp:1070-1150 shifts values to match previous-step's reference (which is zero on first call). Branch selection is a separate issue from weight normalization. BN LCAO regression: gamma=(3.999, 3.500), passes.
1 parent 54c3963 commit 307ac27

1 file changed

Lines changed: 20 additions & 14 deletions

File tree

source/source_lcao/module_deltap/deltap_wannier.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,26 +1011,32 @@ void DeltaP::compute_wannier_polarization(
10111011
std::vector<double> smo_weight_sum_per_atom(nat_, 0.0);
10121012
std::vector<double> r_elec_per_atom(nat_, 0.0);
10131013
std::vector<std::vector<double>> w_In_matrix(n_dim, std::vector<double>(nat_, 0.0));
1014-
for (int iat = 0; iat < nat_; ++iat)
1015-
{
1016-
int r = nproj_per_atom_[iat];
1017-
int row_offset = 0;
1018-
for (int i = 0; i < iat; ++i)
1019-
row_offset += nproj_per_atom_[i];
1020-
double gamma_I = 0.0;
1021-
double w_sum = 0.0;
1022-
double r_weighted = 0.0;
1023-
for (int n = 0; n < n_dim; ++n)
1014+
// First pass: compute raw weights per band per atom
1015+
for (int n = 0; n < n_dim; ++n)
1016+
for (int iat = 0; iat < nat_; ++iat)
10241017
{
1018+
int row_offset = 0;
1019+
for (int i = 0; i < iat; ++i) row_offset += nproj_per_atom_[i];
1020+
int r = nproj_per_atom_[iat];
10251021
double w_In = 0.0;
10261022
for (int a = row_offset; a < row_offset + r; ++a)
10271023
w_In += std::norm(tilde_proj[a + n * m_dim]);
10281024
if (w_In < 0) w_In = 0;
10291025
w_In_matrix[n][iat] = w_In;
1030-
gamma_I += w_In * gamma_unwrapped[n];
1031-
w_sum += w_In;
1032-
double r_n = -a_alpha * gamma_unwrapped[n] / (2.0 * ModuleBase::PI);
1033-
r_weighted += w_In * r_n;
1026+
}
1027+
1028+
// Normalize per band and compute per-atom gamma
1029+
for (int iat = 0; iat < nat_; ++iat)
1030+
{
1031+
double gamma_I = 0.0, w_sum = 0.0, r_weighted = 0.0;
1032+
for (int n = 0; n < n_dim; ++n)
1033+
{
1034+
double w_tot = 0.0;
1035+
for (int j = 0; j < nat_; ++j) w_tot += w_In_matrix[n][j];
1036+
double w_norm = (w_tot > 1e-30) ? w_In_matrix[n][iat] / w_tot : 0.0;
1037+
gamma_I += w_norm * gamma_unwrapped[n];
1038+
w_sum += w_norm;
1039+
r_weighted += w_norm * (-a_alpha * gamma_unwrapped[n] / (2.0 * ModuleBase::PI));
10341040
}
10351041
gamma_accum[iat] += gamma_I;
10361042
gamma_I_per_atom[iat] = gamma_I;

0 commit comments

Comments
 (0)