Octopus
berry_oct_m Module Reference

Berry-phase routines for periodic dipoles, static polarization, and the finite-field electric enthalpy potential. More...

Detailed Description

Berry-phase routines for periodic dipoles, static polarization, and the finite-field electric enthalpy potential.

The module contains two related implementations:

  • the older single-point Berry phase used by the finite-field machinery and large-supercell dipoles;
  • the k-point string Berry phase used to write the modern-theory static polarization after a ground-state SCF calculation.

Data Types

type  berry_t
 Parameters controlling the inner Berry-potential SCF loop. More...
 

Functions/Subroutines

subroutine, public berry_init (this, namespace)
 
subroutine, public berry_write_polarization (namespace, space, mesh, st, ions, kpoints, iunit)
 Compute and write the static modern-theory polarization after SCF. More...
 
subroutine berry_polarization_phase (namespace, space, mesh, st, latt, kpoints, berry_phase)
 Evaluate Berry phases along each periodic reciprocal-lattice direction. More...
 
subroutine berry_neighbor_kpoint (namespace, space, mesh, latt, st, neighbor, gvectors, iq, iq_next, det)
 Advance one step on a Berry-phase k-string and return the link determinant. More...
 
subroutine berry_build_kpoint_strings (namespace, space, kpoints, neighbor, gvectors)
 Tabulate the k-point strings of a full Monkhorst-Pack grid. More...
 
integer pure function berry_kpoint_key (space, kpoints, label)
 Flatten a Monkhorst-Pack grid label into a single index. More...
 
integer function berry_occupied_states (namespace, st, iq, iq_next)
 Return the number of occupied states shared by two neighboring k-points. More...
 
complex(real64) function berry_overlap_det (st, namespace, space, mesh, latt, nocc, iq, iq_next, gvector)
 Determinant of the occupied-manifold overlap matrix for one k-point link. More...
 
subroutine berry_overlap_matrix (st, namespace, space, mesh, latt, nocc, iq, iq_next, gvector, matrix)
 Build the occupied-state overlap matrix for a Berry-phase k-point link. More...
 
subroutine berry_write_polarization_info (space, iunit, berry_phase, electronic_dipole, ionic_dipole, total_dipole, electronic_pol, ionic_pol, total_pol, pol_quantum)
 Write the static polarization information. More...
 
subroutine berry_write_total_polarization_info (space, iunit, total_pol)
 Write the total polarization. More...
 
subroutine berry_polarization_units (space, unit_pol, unit_c_m2)
 Polarization unit. More...
 
subroutine, public berry_perform_internal_scf (this, namespace, space, eigensolver, gr, st, hm, iter, ks, ions, ext_partners)
 Inner self-consistency loop for a static electric field in periodic systems. More...
 
subroutine, public calc_dipole (dipole, space, mesh, st, ions)
 Calculate the total dipole used by the finite-field Berry machinery. More...
 
real(real64) function, public berry_dipole (st, namespace, mesh, latt, space, dir)
 Use the single-point Berry-phase method to calculate a periodic dipole. More...
 
complex(real64) function berry_phase_det (st, namespace, mesh, latt, space, dir, ik)
 Determinant entering the single-point Berry-phase dipole. More...
 
subroutine, public berry_potential (st, namespace, space, mesh, latt, e_field, pot)
 Local potential for electric enthalpy of a uniform field. More...
 
real(real64) function, public berry_energy_correction (st, namespace, space, mesh, latt, e_field, vberry)
 Return the Berry electric-enthalpy correction for the active field. More...
 

Function/Subroutine Documentation

◆ berry_init()

subroutine, public berry_oct_m::berry_init ( type(berry_t), intent(inout)  this,
type(namespace_t), intent(in)  namespace 
)

Definition at line 184 of file berry.F90.

◆ berry_write_polarization()

subroutine, public berry_oct_m::berry_write_polarization ( type(namespace_t), intent(in)  namespace,
class(space_t), intent(in)  space,
class(mesh_t), intent(in)  mesh,
type(states_elec_t), intent(in)  st,
type(ions_t), intent(in)  ions,
type(kpoints_t), intent(in)  kpoints,
integer, intent(in)  iunit 
)

Compute and write the static modern-theory polarization after SCF.

This routine evaluates the electronic Berry phase on full Monkhorst-Pack k-point strings, combines it with the ionic dipole, and writes it. The polarization is only defined modulo the reported polarization quantum.

Definition at line 213 of file berry.F90.

◆ berry_polarization_phase()

subroutine berry_oct_m::berry_polarization_phase ( type(namespace_t), intent(in)  namespace,
class(space_t), intent(in)  space,
class(mesh_t), intent(in)  mesh,
type(states_elec_t), intent(in)  st,
type(lattice_vectors_t), intent(in)  latt,
type(kpoints_t), intent(in)  kpoints,
real(real64), dimension(:), intent(out), contiguous  berry_phase 
)
private

Evaluate Berry phases along each periodic reciprocal-lattice direction.

For each direction, the full k-point grid is decomposed into closed one-dimensional strings. The phase accumulated on each string is the argument of the product of occupied-manifold overlap determinants, and the final phase is averaged over the strings transverse to that direction.

Definition at line 310 of file berry.F90.

◆ berry_neighbor_kpoint()

subroutine berry_oct_m::berry_neighbor_kpoint ( type(namespace_t), intent(in)  namespace,
class(space_t), intent(in)  space,
class(mesh_t), intent(in)  mesh,
type(lattice_vectors_t), intent(in)  latt,
type(states_elec_t), intent(in)  st,
integer, dimension(:), intent(in), contiguous  neighbor,
integer, dimension(:, :), intent(in), contiguous  gvectors,
integer, intent(in)  iq,
integer, intent(out)  iq_next,
complex(real64), intent(out)  det 
)
private

Advance one step on a Berry-phase k-string and return the link determinant.

The input index iq is the electronic-state k/spin index. The routine takes the neighboring real k-point and the reciprocal-lattice vector of the link from the string tables built by berry_build_kpoint_strings, preserves the spin channel for spin-polarized calculations, determines the occupied manifold, and evaluates the corresponding overlap determinant.

Parameters
[in]neighbor(nkpoints) next k-point on the string
[in]gvectors(dim, nkpoints) reciprocal vector of that link

Definition at line 397 of file berry.F90.

◆ berry_build_kpoint_strings()

subroutine berry_oct_m::berry_build_kpoint_strings ( type(namespace_t), intent(in)  namespace,
class(space_t), intent(in)  space,
type(kpoints_t), intent(in)  kpoints,
integer, dimension(:, :), intent(out), allocatable  neighbor,
integer, dimension(:, :, :), intent(out), allocatable  gvectors 
)
private

Tabulate the k-point strings of a full Monkhorst-Pack grid.

The labels number the points of the unfolded grid, while the k-points themselves are stored folded into the first Brillouin zone. A neighbor can therefore differ from k - dk by a reciprocal-lattice vector, which is returned in gvectors and enters the overlap of that link as the periodic-gauge factor exp(-i G.r).

The strings run towards decreasing k. Octopus stores the periodic part u_{nk} of the Bloch state in the convention psi_{nk} = exp(-i k.r) u_{nk}, so u_{nk} is the periodic part of the state of wavevector -k in the usual convention, and the Berry phase of King-Smith and Vanderbilt is therefore accumulated along -k in terms of the stored labels. Traversing the string the other way conjugates the overlap of every regular link but not the one that closes the string, and the resulting phase then fails to converge with the number of points on the string.

Parameters
[out]neighbor(nkpoints, periodic_dim)
[out]gvectors(dim, nkpoints, periodic_dim)

Definition at line 447 of file berry.F90.

◆ berry_kpoint_key()

integer pure function berry_oct_m::berry_kpoint_key ( class(space_t), intent(in)  space,
type(kpoints_t), intent(in)  kpoints,
integer, dimension(:), intent(in)  label 
)
private

Flatten a Monkhorst-Pack grid label into a single index.

Parameters
[in]label(periodic_dim) position on the grid, from 1 to nik_axis

Definition at line 519 of file berry.F90.

◆ berry_occupied_states()

integer function berry_oct_m::berry_occupied_states ( type(namespace_t), intent(in)  namespace,
type(states_elec_t), intent(in)  st,
integer, intent(in)  iq,
integer, intent(in)  iq_next 
)
private

Return the number of occupied states shared by two neighboring k-points.

The static polarization implementation assumes an insulating occupied manifold, so adjacent k-points must have the same highest occupied state.

Definition at line 539 of file berry.F90.

◆ berry_overlap_det()

complex(real64) function berry_oct_m::berry_overlap_det ( type(states_elec_t), intent(in)  st,
type(namespace_t), intent(in)  namespace,
class(space_t), intent(in)  space,
class(mesh_t), intent(in)  mesh,
type(lattice_vectors_t), intent(in)  latt,
integer, intent(in)  nocc,
integer, intent(in)  iq,
integer, intent(in)  iq_next,
integer, dimension(:), intent(in), contiguous  gvector 
)
private

Determinant of the occupied-manifold overlap matrix for one k-point link.

The determinant is raised to the spin degeneracy stored in stsmearel_per_state, matching the convention used elsewhere in this module for Berry-phase determinants.

Definition at line 569 of file berry.F90.

◆ berry_overlap_matrix()

subroutine berry_oct_m::berry_overlap_matrix ( type(states_elec_t), intent(in)  st,
type(namespace_t), intent(in)  namespace,
class(space_t), intent(in)  space,
class(mesh_t), intent(in)  mesh,
type(lattice_vectors_t), intent(in)  latt,
integer, intent(in)  nocc,
integer, intent(in)  iq,
integer, intent(in)  iq_next,
integer, dimension(:), intent(in), contiguous  gvector,
complex(real64), dimension(:, :), intent(out), contiguous  matrix 
)
private

Build the occupied-state overlap matrix for a Berry-phase k-point link.

Matrix elements are <u_{m,k}|exp(-i G.r)|u_{n,k+b}>, where G is nonzero only for links that wrap across the Brillouin-zone boundary.

Definition at line 604 of file berry.F90.

◆ berry_write_polarization_info()

subroutine berry_oct_m::berry_write_polarization_info ( class(space_t), intent(in)  space,
integer, intent(in)  iunit,
real(real64), dimension(:), intent(in), contiguous  berry_phase,
real(real64), dimension(:), intent(in), contiguous  electronic_dipole,
real(real64), dimension(:), intent(in), contiguous  ionic_dipole,
real(real64), dimension(:), intent(in), contiguous  total_dipole,
real(real64), dimension(:), intent(in), contiguous  electronic_pol,
real(real64), dimension(:), intent(in), contiguous  ionic_pol,
real(real64), dimension(:), intent(in), contiguous  total_pol,
real(real64), dimension(:), intent(in), contiguous  pol_quantum 
)
private

Write the static polarization information.

Definition at line 703 of file berry.F90.

◆ berry_write_total_polarization_info()

subroutine berry_oct_m::berry_write_total_polarization_info ( class(space_t), intent(in)  space,
integer, intent(in)  iunit,
real(real64), dimension(:), intent(in), contiguous  total_pol 
)
private

Write the total polarization.

Definition at line 792 of file berry.F90.

◆ berry_polarization_units()

subroutine berry_oct_m::berry_polarization_units ( class(space_t), intent(in)  space,
type(unit_t), intent(out)  unit_pol,
type(unit_t), intent(out)  unit_c_m2 
)
private

Polarization unit.

Definition at line 817 of file berry.F90.

◆ berry_perform_internal_scf()

subroutine, public berry_oct_m::berry_perform_internal_scf ( type(berry_t), intent(in)  this,
type(namespace_t), intent(in)  namespace,
type(electron_space_t), intent(in)  space,
type(eigensolver_t), intent(inout)  eigensolver,
type(grid_t), intent(in)  gr,
type(states_elec_t), intent(inout)  st,
type(hamiltonian_elec_t), intent(inout)  hm,
integer, intent(in)  iter,
type(v_ks_t), intent(inout)  ks,
type(ions_t), intent(in)  ions,
type(partner_list_t), intent(in)  ext_partners 
)

Inner self-consistency loop for a static electric field in periodic systems.

This updates the Berry potential, recomputes the electric enthalpy correction, refreshes the Kohn-Sham potential, and iterates until the Berry-phase dipole stops changing or MaximumIterBerry is reached.

Definition at line 838 of file berry.F90.

◆ calc_dipole()

subroutine, public berry_oct_m::calc_dipole ( real(real64), dimension(:), intent(out), contiguous  dipole,
class(space_t), intent(in)  space,
class(mesh_t), intent(in)  mesh,
type(states_elec_t), intent(in)  st,
type(ions_t), intent(in)  ions 
)

Calculate the total dipole used by the finite-field Berry machinery.

Periodic directions use the single-point Berry-phase dipole and are folded back by the polarization quantum. Non-periodic directions use the ordinary real-space electronic multipole plus the ionic dipole.

TODO: This should be a method of the electronic system directly that can be exposed.

Definition at line 918 of file berry.F90.

◆ berry_dipole()

real(real64) function, public berry_oct_m::berry_dipole ( type(states_elec_t), intent(in)  st,
type(namespace_t), intent(in)  namespace,
class(mesh_t), intent(in)  mesh,
type(lattice_vectors_t), intent(in)  latt,
class(space_t), intent(in)  space,
integer, intent(in)  dir 
)

Use the single-point Berry-phase method to calculate a periodic dipole.

This is only accurate in the limit of a large supercell. It is implemented only for an orthogonal unit cell.

\[ \mu = - eL/2*\pi Im ln <\Psi|exp(-i(2*\pi/L)x)|\Psi> \]

E Yaschenko, L Fu, L Resca, R Resta, Phys. Rev. B 58, 1222-1229 (1998) The single-point Berry-phase method for dipoles should not be used when there is more than one k-point. In that case, finite differences should be used to construct derivatives with respect to k.

Definition at line 972 of file berry.F90.

◆ berry_phase_det()

complex(real64) function berry_oct_m::berry_phase_det ( type(states_elec_t), intent(in)  st,
type(namespace_t), intent(in)  namespace,
class(mesh_t), intent(in)  mesh,
type(lattice_vectors_t), intent(in)  latt,
class(space_t), intent(in)  space,
integer, intent(in)  dir,
integer, intent(in)  ik 
)
private

Determinant entering the single-point Berry-phase dipole.

This forms the occupied-state matrix for

\[ det <\psi_i|exp(-i(2*\pi/L)x)|\psi_j> \]

E Yaschenko, L Fu, L Resca, R Resta, Phys. Rev. B 58, 1222-1229 (1998)

Definition at line 1012 of file berry.F90.

◆ berry_potential()

subroutine, public berry_oct_m::berry_potential ( type(states_elec_t), intent(in)  st,
type(namespace_t), intent(in)  namespace,
class(space_t), intent(in)  space,
class(mesh_t), intent(in)  mesh,
type(lattice_vectors_t), intent(in)  latt,
real(real64), dimension(:), intent(in), contiguous  e_field,
real(real64), dimension(:,:), intent(out), contiguous  pot 
)

Local potential for electric enthalpy of a uniform field.

This is the single-point Berry-phase finite-field potential used by the internal Berry SCF loop.

P Umari et al., Phys Rev Lett 95, 207602 (2005) eqs (3), (7)

\[ E * (e L / 2 \pi) Im e^{i 2 \pi r / L} / z \]

Parameters
[in]e_field(spacedim)
[out]pot(meshnp, stdnspin)

Definition at line 1049 of file berry.F90.

◆ berry_energy_correction()

real(real64) function, public berry_oct_m::berry_energy_correction ( type(states_elec_t), intent(in)  st,
type(namespace_t), intent(in)  namespace,
class(space_t), intent(in)  space,
class(mesh_t), intent(in)  mesh,
type(lattice_vectors_t), intent(in)  latt,
real(real64), dimension(:), intent(in), contiguous  e_field,
real(real64), dimension(:,:), intent(in)  vberry 
)

Return the Berry electric-enthalpy correction for the active field.

The correction subtracts the expectation value of the local Berry potential and adds the real dipole-field term, giving the contribution used in the finite-field SCF loop.

Parameters
[in]e_field(spaceperiodic_dim)
[in]vberry(meshnp, stdnspin)

Definition at line 1108 of file berry.F90.