Wannier localizationĀ¶
InĀ [1]:
import glob
import numpy as np
from eminus import Atoms, read, SCF
from eminus.extras import view
from eminus.localizer import get_wannier, wannier_cost
from eminus.orbitals import FLO, SCDM, WO
from eminus.tools import orbital_center
InĀ [2]:
# Run an initial calculation for methane
atoms = Atoms(*read("CH4.xyz"), ecut=15, center=True)
scf = SCF(atoms)
scf.run();
InĀ [3]:
# Calculate the SCDMs to have pre-localized orbitals
scdm = SCDM(scf)
InĀ [4]:
# Do the Wannier localization
# The resulting orbitals are equivalent to Foster-Boys orbitals, but with periodic boundary conditions
wannier = get_wannier(atoms, scdm)
InĀ [5]:
# Compare the initial SCDM spreads to the Wannier spreads
scdm_spreads = wannier_cost(atoms, scdm)
print(f"\nSCDM spreads = {scdm_spreads}")
print(f"SCDM spread = {np.sum(scdm_spreads)}")
InĀ [6]:
# The Wannier orbitals are a bit more localized, and all orbitals are evenly localized
wannier_spreads = wannier_cost(atoms, wannier)
print(f"Wannier spreads = {wannier_spreads}")
print(f"Wannier spread = {np.sum(wannier_spreads)}")
InĀ [7]:
# All of the above can be done with one function call, also save the orbitals
WO(scf, write_cubes=True);
InĀ [8]:
# Display the orbitals from the cube files
view(glob.glob("*.cube"));
InĀ [9]:
# One could calculate the center of masses from the Wannier orbitals...
coms = orbital_center(atoms, wannier[0])
atoms.view(coms)
InĀ [10]:
# ...and use them as an initial guess to create a set of FLOs
flo = FLO(scf, fods=coms)
flo_spreads = wannier_cost(atoms, flo)
print(f"FLO spreads = {flo_spreads}")
print(f"FLO spread = {np.sum(flo_spreads)}")