Note
Go to the end to download the full example code.
Effective masses with finite diff
This example shows how to use finite differences to compute effective masses and plot the data.
Initialize the EffMassAnalyzer from a GSR file with energies computed along segments passing through the k-points of interest.
Clearly the accuracy of the finite difference results strongly depends on the spacing between the points along the path. The GSR file used in this example is not accurate enough!
import abipy.data as abidata
from abipy.electrons.effmass_analyzer import EffMassAnalyzer
emana = EffMassAnalyzer.from_file(abidata.ref_file("si_nscf_GSR.nc"))
print(emana)
================================= Structure =================================
Full Formula (Si2)
Reduced Formula: Si
abc : 3.866975 3.866975 3.866975
angles: 60.000000 60.000000 60.000000
pbc : True True True
Sites (2)
# SP a b c
--- ---- ---- ---- ----
0 Si 0 0 0
1 Si 0.25 0.25 0.25
Abinit Spacegroup: spgid: 227, num_spatial_symmetries: 48, has_timerev: True, symmorphic: True
Number of electrons: 8.0, Fermi level: 5.598 (eV)
nsppol: 1, nkpt: 14, mband: 8, nspinor: 1, nspden: 1
smearing scheme: none (occopt 1), tsmear_eV: 0.272, tsmear Kelvin: 3157.7
Direct gap:
Energy: 2.532 (eV)
Initial state: spin: 0, kpt: $\Gamma$ [+0.000, +0.000, +0.000], band: 3, eig: 5.598, occ: 2.000
Final state: spin: 0, kpt: $\Gamma$ [+0.000, +0.000, +0.000], band: 4, eig: 8.130, occ: 0.000
Fundamental gap:
Energy: 0.524 (eV)
Initial state: spin: 0, kpt: $\Gamma$ [+0.000, +0.000, +0.000], band: 3, eig: 5.598, occ: 2.000
Final state: spin: 0, kpt: [+0.000, +0.429, +0.429], band: 4, eig: 6.123, occ: 0.000
Bandwidth: 11.856 (eV)
Valence maximum located at kpt index 6:
spin: 0, kpt: $\Gamma$ [+0.000, +0.000, +0.000], band: 3, eig: 5.598, occ: 2.000
Conduction minimum located at kpt index 12:
spin: 0, kpt: [+0.000, +0.429, +0.429], band: 4, eig: 6.123, occ: 0.000
TIP: Use `--verbose` to print k-point coordinates with more digits
Before computing the effective masses, we have to select the k-points.
emana.select_vbm()
# Alternatively, one can use:
#emana.select_cbm()
#emana.select_band_edges()
# or the most flexible API:
#emana.select_kpoint_band((0, 0, 0), band=3, spin=0, degtol_ev=0.1)
Compute effective masses with different accuracies and print results in tabular format. Useful to understand if results are sensitive to the number of points in the finite difference. Note however that numerical differentiation is performed with the same delta_k step.
Centeral diff weights for order: 2, and accuracy: 1 are missing!
Centeral diff weights for order: 2, and accuracy: 1 are missing!
Centeral diff weights for order: 2, and accuracy: 1 are missing!
Centeral diff weights for order: 2, and accuracy: 3 are missing!
Centeral diff weights for order: 2, and accuracy: 3 are missing!
Centeral diff weights for order: 2, and accuracy: 3 are missing!
Centeral diff weights for order: 2, and accuracy: 5 are missing!
Centeral diff weights for order: 2, and accuracy: 5 are missing!
Centeral diff weights for order: 2, and accuracy: 5 are missing!
Don't have enough points for index: 6 in array of length: 7
to compute backward finite difference with order: 2, and acc: 6 (num_weights: 8)
Decrease acc or increase the number of sampling points.
Don't have enough points for index: 6 in array of length: 7
to compute backward finite difference with order: 2, and acc: 6 (num_weights: 8)
Decrease acc or increase the number of sampling points.
Don't have enough points for index: 6 in array of length: 7
to compute backward finite difference with order: 2, and acc: 6 (num_weights: 8)
Decrease acc or increase the number of sampling points.
Print the results to terminal with:
# extract segment.
segment = emana.segments[0]
#repr(segment); str(segment)
#assert segment.to_string(verbose=2)
df = segment.get_dataframe_with_accuracies(acc_list=(2, 4))
print(df)
#assert len(emana.segments) == 1
#for segment in emana.segments[0]:
# segment.get_effmass_line(acc=2)
npts effm_b0 effm_b1 effm_b2
accuracy
2 4 -0.163343 -0.633128 -0.633128
4 6 -0.098950 -0.470343 -0.470343
Plot electronic dispersion and quadratic approximant based on the effective masses computed along each segment.
emana.plot_emass(acc=4)
#emana.plot_all_segments()
#emana.segments[0].plot_emass()
Total running time of the script: (0 minutes 0.374 seconds)