Skip to content

Commit

Permalink
Store kwargs in calc_kwargs
Browse files Browse the repository at this point in the history
  • Loading branch information
gmatteo committed Aug 8, 2024
1 parent c84b792 commit 4aab7cb
Show file tree
Hide file tree
Showing 16 changed files with 409 additions and 418 deletions.
2 changes: 1 addition & 1 deletion abipy/abilab.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ def abiopen(filepath: str):
# Assume Abinit log file.
return AbinitLogFile.from_file(filepath)

if os.path.basename(filepath) == "phonopy_params.yaml":
if os.path.basename(filepath).endswith("phonopy_params.yaml"):
# Handle phonopy object.
import phonopy
return phonopy.load(filepath)
Expand Down
5 changes: 2 additions & 3 deletions abipy/dfpt/qha.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,7 @@ def get_phonopy_qha(self, tstart=0, tstop=2100, num=211, eos='vinet', t_max=None

class QHA(AbstractQHA):
"""
Object to extract results in the quasi-harmonic approximation from electronic and phonon calculations
at different volumes.
Object to extract results in the quasi-harmonic approximation from electronic and phonon calculations at different volumes.
Provides some basic methods and plotting utils, plus a converter to write input files for phonopy-qha or to
generate an instance of phonopy.qha.core.QHA. These can be used to obtain other quantities and plots.
Does not include electronic entropic contributions for metals.
Expand Down Expand Up @@ -938,7 +937,7 @@ def get_entropy(w, weights, t):

class AbstractQmeshAnalyzer(metaclass=abc.ABCMeta):
"""
Abstract class for the analysis of the convergence wrt to the q-mesh used to compute the phonon DOS.
Abstract class for the analysis of the convergence wrt to the q-mesh used to compute the phonon DOS.
Relies on abstract methods implemented in AbstractQHA.
"""

Expand Down
22 changes: 8 additions & 14 deletions abipy/electrons/ebands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1830,7 +1830,7 @@ def plot_dos(method, step, width):
width=ipw.FloatSlider(value=0.2, min=1e-6, max=1, step=0.05, description="Gaussian broadening (eV)"),
)

def get_edos(self, method="gaussian", step=0.1, width=0.2) -> ElectronDos:
def get_edos(self, method: str="gaussian", step: float=0.05, width: float=0.1) -> ElectronDos:
"""
Compute the electronic DOS on a linear mesh.
Expand Down Expand Up @@ -1861,7 +1861,7 @@ def get_edos(self, method="gaussian", step=0.1, width=0.2) -> ElectronDos:
dos[spin] += weight * gaussian(mesh, width, center=e)

else:
raise NotImplementedError(f"{method} method is not supported")
raise NotImplementedError(f"{method=} is not supported")

# Use fermie from Abinit if we are not using metallic scheme for occopt.
fermie = None
Expand Down Expand Up @@ -1907,8 +1907,6 @@ def plot_transitions(self, omega_ev, qpt=(0, 0, 0), atol_ev=0.1, atol_kdiff=1e-4
or scalar e.g. `left`. If left (right) is None, default values are used
alpha: The alpha blending value, between 0 (transparent) and 1 (opaque)
ax: |matplotlib-Axes| or None if a new figure should be created.
Returns: |matplotlib-Figure|
"""
ax, fig, plt = get_ax_fig_plt(ax=ax)
e0 = self.get_e0("fermie")
Expand Down Expand Up @@ -1949,8 +1947,8 @@ def plot_transitions(self, omega_ev, qpt=(0, 0, 0), atol_ev=0.1, atol_kdiff=1e-4
y = self.eigens[spin, ik, v_k] - e0
# http://matthiaseisen.com/matplotlib/shapes/arrow/
p = FancyArrowPatch((ik, y), (ik + dx, y + dy),
connectionstyle='arc3', mutation_scale=20,
alpha=alpha, **arrow_opts)
connectionstyle='arc3', mutation_scale=20,
alpha=alpha, **arrow_opts)
ax.add_patch(p)
return fig

Expand Down Expand Up @@ -2919,8 +2917,6 @@ def plot_lws_vs_e0(self, ax=None, e0="fermie", function=lambda x: x, exchange_xy
e0mesh = np.array(e0mesh) - e0

kw_linestyle = kwargs.pop("linestyle", "o")
#kw_lw = kwargs.pop("lw", 1)
#kw_lw = kwargs.pop("markersize", 5)
kw_color = kwargs.pop("color", "red")
kw_label = kwargs.pop("label", None)

Expand Down Expand Up @@ -3021,7 +3017,7 @@ def w(s):
f.close()

@memoized_method(maxsize=5, typed=False)
def get_ifermi_dense_bs(self, interpolation_factor, with_velocities):
def get_ifermi_dense_bs(self, interpolation_factor, with_velocities, nworkers=1):
"""
Use ifermi and BoltzTraP2 to interpolate KS energies (assumes ebands in the IBZ).
Expand All @@ -3047,7 +3043,7 @@ def get_ifermi_dense_bs(self, interpolation_factor, with_velocities):
bs = self.to_pymatgen()
interpolator = FourierInterpolator(bs)

nworkers = 1 # Use 1 worker because it does not seem to scale well on my Mac.
#nworkers = 1 # Use 1 worker because it does not seem to scale well on my Mac.
with Timer(footer=f"BoltzTraP2 interpolation with {interpolation_factor=} and {with_velocities=}"):
if with_velocities:
dense_bs, velocities = interpolator.interpolate_bands(interpolation_factor=interpolation_factor,
Expand All @@ -3062,7 +3058,7 @@ def get_ifermi_dense_bs(self, interpolation_factor, with_velocities):
return dict2namedtuple(dense_bs=dense_bs, velocities=velocities, interpolator=interpolator)

def get_ifermi_fs(self, interpolation_factor=8, mu=0.0, eref="fermie", wigner_seitz=True,
calculate_dimensionality=False, with_velocities=False):
calculate_dimensionality=False, with_velocities=False, nworkers=1):
"""
Use ifermi package to visualize the (interpolated) Fermi surface.
Requires netcdf file with energies in the IBZ.
Expand All @@ -3086,7 +3082,7 @@ def get_ifermi_fs(self, interpolation_factor=8, mu=0.0, eref="fermie", wigner_se
r = ebands.get_ifermi_fs()
r.fs_plotter.get_plot(plot_type="plotly").show()
"""
r = self.get_ifermi_dense_bs(interpolation_factor, with_velocities)
r = self.get_ifermi_dense_bs(interpolation_factor, with_velocities, nworkers=nworkers)

from ifermi.surface import FermiSurface
from ifermi.plot import FermiSurfacePlotter #, save_plot, show_plot FermiSlicePlotter,
Expand Down Expand Up @@ -3610,8 +3606,6 @@ def combiplot(self, e0="fermie", ylims=None, width_ratios=(2, 1), fontsize=8,
Used when there are DOS stored in the plotter.
fontsize: fontsize for legend.
linestyle_dict: Dictionary mapping labels to matplotlib linestyle options.
Returns: |matplotlib-Figure|.
"""
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
Expand Down
66 changes: 28 additions & 38 deletions abipy/electrons/effmass_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from abipy.tools.printing import print_dataframe
from abipy.tools.typing import Figure
from abipy.electrons.ebands import ElectronBands
from abipy.tools.plotting import add_fig_kwargs, get_ax_fig_plt, get_axarray_fig_plt, set_visible
from abipy.tools.plotting import add_fig_kwargs, get_ax_fig_plt, get_axarray_fig_plt, set_visible, set_grid_legend


class EffMassAnalyzer(Has_Structure, Has_ElectronBands):
Expand All @@ -35,16 +35,19 @@ class EffMassAnalyzer(Has_Structure, Has_ElectronBands):
print(emana)
emana.select_vbm()
emana.summarize()
emana.plot_emass()
# Alternatively, one can use:
#emana.select_cbm()
#emana.select_band_edges()
emana.select_cbm()
emana.select_band_edges()
emana.summarize()
emana.plot_emass()
or the most flexible API:
#emana.select_kpoint_band(kpoint=[0, 0, 0], band=3)
#emana.summarize()
emana.select_kpoint_band(kpoint=[0, 0, 0], band=3)
emana.summarize()
emana.plot_emass()
.. rubric:: Inheritance Diagram
Expand All @@ -56,9 +59,8 @@ def from_file(cls, filepath: str) -> EffMassAnalyzer:
"""
Initialize the object from a netcdf file providing an |ElectronBands| object, usually a GSR file.
"""
from abipy.abilab import abiopen
with abiopen(filepath) as ncfile:
return cls(ncfile.ebands, copy=False)
ebands = ElectronBands.as_ebands(filepath)
return cls(ebands, copy=False)

def __init__(self, ebands: ElectronBands, copy: bool = True):
"""
Expand Down Expand Up @@ -89,16 +91,16 @@ def to_string(self, verbose: int = 0) -> str:
"""
return self.ebands.to_string(with_structure=True, with_kpoints=True, verbose=verbose)

@property
def ebands(self) -> ElectronBands:
"""|ElectronBands| object."""
return self._ebands

@property
def structure(self) -> Structure:
"""|Structure| object."""
return self.ebands.structure

@property
def ebands(self) -> ElectronBands:
"""|ElectronBands| object."""
return self._ebands

def select_kpoint_band(self, kpoint, band: int, spin: int = 0, degtol_ev: float = 1e-3) -> int:
"""
Construct line segments based on the k-point ``kpoint`` and the band index ``band``.
Expand Down Expand Up @@ -126,32 +128,29 @@ def select_kpoint_band(self, kpoint, band: int, spin: int = 0, degtol_ev: float

def select_cbm(self, spin: int = 0, degtol_ev: float = 1e-3) -> int:
"""
Select the conduction band minimum for the given spin.
Return: Number of segments.
Select the conduction band minimum for the given spin. Return: Number of segments.
"""
ik_indices, band_inds_k = self._select(["cbm"], spin, degtol_ev)
return self._build_segments(spin, ik_indices, band_inds_k)

def select_vbm(self, spin: int = 0, degtol_ev: float = 1e-3) -> int:
"""
Select the valence band maximum for the given spin
Return: Number of segments.
Select the valence band maximum for the given spin, Return: Number of segments.
"""
ik_indices, band_inds_k = self._select(["vbm"], spin, degtol_ev)
return self._build_segments(spin, ik_indices, band_inds_k)

def select_band_edges(self, spin: int = 0, degtol_ev: float = 1e-3) -> int:
"""
Select conduction band minimum and valence band maximum.
Return: Number of segments.
Select conduction band minimum and valence band maximum. Return: Number of segments.
"""
ik_indices, band_inds_k = self._select(["cbm", "vbm"], spin, degtol_ev)
return self._build_segments(spin, ik_indices, band_inds_k)

def _select(self, what_list, spin, degtol_ev):
"""
Low-level method to select the electronic states
"""
ik_indices, band_inds_k = [], []

if "vbm" in what_list:
Expand Down Expand Up @@ -230,7 +229,7 @@ def summarize(self, acc_list=None) -> None:
print_dataframe(df, title=title)

@add_fig_kwargs
def plot_emass(self, acc=4, units="eV", sharey=True, fontsize=6,
def plot_emass(self, acc=4, units="eV", sharey=False, fontsize=6,
colormap="viridis", verbose=0, **kwargs) -> Figure:
"""
Plot electronic dispersion and quadratic approximant based on the
Expand Down Expand Up @@ -260,6 +259,7 @@ def plot_emass(self, acc=4, units="eV", sharey=True, fontsize=6,
print(f"== SEGMENT NUMBER: {iseg}")
print(segment)
print(2 * "\n")

irow, icol = divmod(iseg, ncols)
segment.plot_emass(ax=ax, acc=acc, units=units, fontsize=fontsize, colormap=colormap, show=False)
if iseg != 0: set_visible(ax, False, "ylabel")
Expand All @@ -277,17 +277,13 @@ def plot_all_segments(self, ax=None, colormap="viridis", fontsize=8, **kwargs) -
Args:
colormap: matplotlib colormap
fontsize: legend and title fontsize.
Return: |matplotlib-Figure|
"""
self._consistency_check()

ax, fig, plt = get_ax_fig_plt(ax=ax)
cmap = plt.get_cmap(colormap)
markers = ["o", "s", "x", "D", "+", "v", ">", "<"] * 8

ax.grid(True)
ax.set_ylabel('Energy (eV)')
pad = 0
for iseg, segment in enumerate(self.segments):
color = cmap(float(iseg / len(self.segments)))
Expand All @@ -297,9 +293,8 @@ def plot_all_segments(self, ax=None, colormap="viridis", fontsize=8, **kwargs) -
label="direction: %s" % segment.kdir.tos(m="fracart", scale=True) if ib == 0 else None)
pad += 10

ax.legend(loc="best", fontsize=fontsize, shadow=True)
#title = "k: %s, spin: %s, nband: %d" % (repr(self.efm_kpoint), self.spin, segment.nb)
#ax.set_title(title, fontsize=fontsize)
set_grid_legend(ax, fontsize, ylabel='Energy (eV)', title=title)

return fig

Expand Down Expand Up @@ -358,8 +353,7 @@ def __str__(self) -> str:
return self.to_string()

def get_fd_emass_d2(self, enes_kline, acc: int) -> tuple:
# Note the use of self.kpos so that the stencil is centered on the kpos index
# if we have points of both sides.
# Note the use of self.kpos so that the stencil is centered on the kpos index if we have points of both sides.
d2 = finite_diff(enes_kline, self.dk, order=2, acc=acc, index=self.kpos)
emass = 1. / (d2.value * (abu.eV_Ha / abu.Bohr_Ang ** 2))
return emass, d2
Expand Down Expand Up @@ -403,11 +397,8 @@ def plot_emass(self, acc: int = 4, units="eV", ax=None, fontsize: int = 8,
ax: |matplotlib-Axes| or None if a new figure should be created.
fontsize: legend and title fontsize.
colormap: matplotlib colormap
Return: |matplotlib-Figure|
"""
ax, fig, plt = get_ax_fig_plt(ax=ax)
ax.grid(True)
cmap = plt.get_cmap(colormap)

ufact = {"ev": 1, "mev": 1000}[units.lower()]
Expand All @@ -432,10 +423,9 @@ def plot_emass(self, acc: int = 4, units="eV", ax=None, fontsize: int = 8,
ax.plot(xs, ys * ufact, linestyle="--", color=cmap(float(ib) / self.nb), label=label)

ax.axvline(self.kpos, c="r", ls=":", lw=2)
ax.legend(loc="best", fontsize=fontsize, shadow=True)
title = r"${\bf k}_0$: %s, direction: %s, step: %.3f $\AA^{-1}$" % (
repr(self.k0), self.kdir.tos(m="fracart", scale=True), self.dk)
ax.set_title(title, fontsize=fontsize)
ax.set_ylabel(f'Energy ({units})')

set_grid_legend(ax, fontsize, ylabel=f'Energy ({units})', title=title)

return fig
8 changes: 4 additions & 4 deletions abipy/electrons/tests/test_ebands.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def test_nickel_ebands_spin(self):
assert same.structure == ni_ebands_kmesh.structure
assert same.smearing.occopt == ni_ebands_kmesh.smearing.occopt

ni_edos = ni_ebands_kmesh.get_edos()
ni_edos = ni_ebands_kmesh.get_edos(step=0.1, width=0.2)
repr(ni_edos); str(ni_edos)
assert ni_edos.to_string(verbose=2)
self.assert_almost_equal(ni_ebands_kmesh.get_collinear_mag(), 0.6501439036904575)
Expand Down Expand Up @@ -283,7 +283,7 @@ def test_silicon_ebands(self):
with self.assertRaises(NotImplementedError):
si_ebands_kmesh.get_edos(method="tetrahedron")

si_edos = si_ebands_kmesh.get_edos()
si_edos = si_ebands_kmesh.get_edos(step=0.1, width=0.2)
repr(si_edos); str(si_edos)
assert ElectronDos.as_edos(si_edos, {}) is si_edos
assert si_edos == si_edos and not (si_edos != si_edos)
Expand Down Expand Up @@ -579,7 +579,7 @@ def test_from_mpid(self):
assert new_fermie == r.ebands_kpath.fermie
assert r.ebands_kpath.isnot_ibz_sampling()

edos = r.ebands_kmesh.get_edos()
edos = r.ebands_kmesh.get_edos(step=0.1, width=0.2)
new_fermie = r.ebands_kpath.set_fermie_from_edos(edos)
assert new_fermie == edos.fermie

Expand Down Expand Up @@ -675,7 +675,7 @@ def test_api(self):
same_gsr_bands = ElectronBands.from_binary_string(fh.read())
assert same_gsr_bands.structure == gs_bands.structure

si_edos = gs_bands.get_edos()
si_edos = gs_bands.get_edos(step=0.1, width=0.2)

plotter = ElectronDosPlotter()
plotter.add_edos("edos1", si_edos)
Expand Down
18 changes: 17 additions & 1 deletion abipy/eph/gstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,23 @@ def to_string(self, verbose=0) -> str:

return "\n".join(lines)

#def write_epw_hdf5(self, filepath: PathLike) -> None:
def check_unfilled_entries_in_gvals(self):
"""
"""
r = self.r
cplex = r.cplex
for spin in range(self.nsppol):
# nctkarr_t("gvals", "dp", "gstore_cplex, nb_kq, nb_k, natom3, glob_nk, glob_nq)
variable = r.read_variable("gvals", path=f"gqk_spin{spin+1}")
fill_value = variable._FillValue
# Read the data
data = variable[:]
missing_entries = np.where(data == fill_value)
# Print the indices of missing entries
print("Missing entries found at indices:", missing_entries)

if self.r.kfilter == "none":
raise ValueError("when kfilter == 'none' all the entries in gvals should have been written!")


@dataclasses.dataclass(kw_only=True)
Expand Down
Loading

0 comments on commit 4aab7cb

Please sign in to comment.