130 require_shape(rotated_overlaps);
132 const int dimension = number_of_wannier_functions_;
133 const Real inverse_kpoint_count = 1.0 /
static_cast<Real>(number_of_kpoints);
138 std::vector<Real> second_moments(
static_cast<std::size_t
>(dimension), 0.0);
145 for (
int kpoint = 0; kpoint < number_of_kpoints; kpoint++) {
149 const Real weight = stencil_.
weight(direction);
150 for (
int wannier = 0; wannier < dimension; wannier++) {
151 const Real phase = diagonal_phase(overlap, wannier, b_vector);
152 for (
int axis = 0; axis < 3; axis++) {
153 terms.
centers_bohr[
static_cast<std::size_t
>(wannier)][axis] -=
154 inverse_kpoint_count * weight * b_vector[axis] * phase;
156 second_moments[
static_cast<std::size_t
>(wannier)] +=
157 inverse_kpoint_count * weight *
158 ((1.0 - std::norm(overlap(wannier, wannier))) + phase * phase);
163 for (
int wannier = 0; wannier < dimension; wannier++) {
166 second_moments[
static_cast<std::size_t
>(wannier)] - center.
dot(center);
169 for (
int kpoint = 0; kpoint < number_of_kpoints; kpoint++) {
173 const Real weight = stencil_.
weight(direction) * inverse_kpoint_count;
176 Real diagonal_square_modulus = 0.0;
177 for (
int wannier = 0; wannier < dimension; wannier++) {
178 diagonal_square_modulus += std::norm(overlap(wannier, wannier));
181 weight * (
static_cast<Real>(dimension) - total_square_modulus);
183 weight * (total_square_modulus - diagonal_square_modulus);
185 for (
int wannier = 0; wannier < dimension; wannier++) {
186 const Real residual =
187 diagonal_phase(overlap, wannier, b_vector) +
205 require_shape(rotated_overlaps);
207 const int dimension = number_of_wannier_functions_;
208 std::vector<DenseMatrix<Complex>> gradients(
209 static_cast<std::size_t
>(number_of_kpoints),
222 const Real scale = -1.0 /
static_cast<Real>(number_of_kpoints);
224 for (
int kpoint = 0; kpoint < number_of_kpoints; kpoint++) {
229 const Real weight = stencil_.
weight(direction);
237 for (
int column = 0; column < dimension; column++) {
238 const Complex diagonal = overlap(column, column);
239 require_nonzero_diagonal(diagonal, column, kpoint);
241 const Real residual =
242 diagonal_phase(overlap, column, b_vector) +
246 for (
int row = 0; row < dimension; row++) {
247 const Complex element = overlap(row, column);
256 const Complex r_element = element * std::conj(diagonal);
257 const Complex t_element = element * column_scale;
259 scale * 4.0 * weight * (0.5 * r_element + 0.5 * t_element);
260 gradient_at_kpoint(row, column) += contribution;
261 gradient_at_kpoint(column, row) -= std::conj(contribution);
283 return phase_branch_->phase_of(overlap(wannier, wannier), wannier, b_vector);