Skip to content

Commit

Permalink
Fix regressions in oncvpsp_gui.py
Browse files Browse the repository at this point in the history
  • Loading branch information
gmatteo committed Sep 12, 2024
1 parent 360eccd commit 747ef72
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 49 deletions.
9 changes: 8 additions & 1 deletion abipy/dfpt/phonons.py
Original file line number Diff line number Diff line change
Expand Up @@ -1553,7 +1553,14 @@ def _get_non_anal_freqs(self, frac_direction):
if np.allclose(cart_direction, d):
return self.non_anal_phfreqs[i]

raise ValueError("Non analytical contribution has not been calculated for reduced direction {0} ".format(frac_direction))
err_lines = [
f"Non analytical contribution has not been calculated for reduced direction: {frac_direction}",
"Available non_anal_directions:"
]
for i, d in enumerate(self.non_anal_directions):
err_lines.append(f"{i} {d}")

raise ValueError("\n".join(err_lines))

def _get_non_anal_phdispl(self, frac_direction):
# directions for the qph2l in anaddb are given in cartesian coordinates
Expand Down
38 changes: 23 additions & 15 deletions abipy/dfpt/phtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,36 @@ def __init__(self, structure, directions, phfreqs, phdispl_cart, amu=None):
@classmethod
def from_file(cls, filepath: str) -> NonAnalyticalPh:
"""
Reads the non analytical directions, frequencies and displacements from the anaddb.nc file specified.
Reads the non analytical directions, frequencies and displacements from the nc file specified (usually anaddb.nc)
Non existence of displacements is accepted for compatibility with abinit 8.0.6
Raises an error if the other values are not present in anaddb.nc.
Raises an error if the other values are not present in the netcdf file.
"""
with ETSF_Reader(filepath) as r:
directions = r.read_value("non_analytical_directions")
phfreq = r.read_value("non_analytical_phonon_modes")
return cls.from_ncreader(r)

# need a default as the first abinit version including IFCs in the netcdf doesn't have this attribute
phdispl_cart = r.read_value("non_analytical_phdispl_cart", cmode="c", default=None)
@classmethod
def from_ncreader(cls, nc_reader) -> NonAnalyticalPh:
"""
Build the object from a NetcdfReader.
"""
r = nc_reader
directions = r.read_value("non_analytical_directions")
phfreq = r.read_value("non_analytical_phonon_modes")

structure = r.read_structure()
# need a default as the first abinit version including IFCs in the netcdf doesn't have this attribute
phdispl_cart = r.read_value("non_analytical_phdispl_cart", cmode="c", default=None)
structure = r.read_structure()

amu_list = r.read_value("atomic_mass_units", default=None)
if amu_list is not None:
# ntypat arrays
atomic_numbers = r.read_value("atomic_numbers")
amu = {at: a for at, a in zip(atomic_numbers, amu_list)}
else:
amu = None
amu_list = r.read_value("atomic_mass_units", default=None)

if amu_list is not None:
# ntypat arrays
atomic_numbers = r.read_value("atomic_numbers")
amu = {at: a for at, a in zip(atomic_numbers, amu_list)}
else:
amu = None

return cls(structure=structure, directions=directions, phfreqs=phfreq, phdispl_cart=phdispl_cart, amu=amu)
return cls(structure=structure, directions=directions, phfreqs=phfreq, phdispl_cart=phdispl_cart, amu=amu)

@lazy_property
def dyn_mat_eigenvect(self) -> np.ndarray:
Expand Down
77 changes: 57 additions & 20 deletions abipy/eph/gpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@
from monty.termcolor import cprint
from abipy.core.structure import Structure
from abipy.core.kpoints import Kpath
from abipy.core.mixins import AbinitNcFile, Has_Structure, Has_ElectronBands, Has_Header #, NotebookWriter
from abipy.core.mixins import AbinitNcFile, Has_Structure, Has_ElectronBands, NotebookWriter
from abipy.tools.typing import PathLike
#from abipy.tools.numtools import BzRegularGridInterpolator, nparr_to_df
from abipy.tools.plotting import (add_fig_kwargs, get_ax_fig_plt, get_axarray_fig_plt, set_axlims, set_visible,
rotate_ticklabels, ax_append_title, set_ax_xylabels, linestyles, Marker, set_grid_legend)
#from abipy.tools import duck
from abipy.electrons.ebands import ElectronBands, RobotWithEbands
from abipy.dfpt.phonons import PhononBands
from abipy.dfpt.phtk import NonAnalyticalPh
from abipy.tools.typing import Figure
from abipy.abio.robots import Robot
from abipy.eph.common import BaseEphReader


class GpathFile(AbinitNcFile, Has_Structure): # , NotebookWriter):
#class GpathFile(AbinitNcFile, Has_Structure, Has_ElectronBands): # , NotebookWriter):
class GpathFile(AbinitNcFile, Has_Structure, NotebookWriter):
"""
This file stores the e-ph matrix elements along a k/q path
and provides methods to analyze and plot results.
Expand All @@ -37,12 +37,13 @@ class GpathFile(AbinitNcFile, Has_Structure): # , NotebookWriter):
.. code-block:: python
with GpathFile("out_GWAN.nc") as gpath:
print(gwan)
with GpathFile("out_GPATH.nc") as gpath:
print(gpath)
.. rubric:: Inheritance Diagram
.. inheritance-diagram:: GpathFile
"""

@classmethod
def from_file(cls, filepath: PathLike) -> GpathFile:
"""Initialize the object from a netcdf file."""
Expand Down Expand Up @@ -107,12 +108,13 @@ def to_string(self, verbose: int=0) -> str:
return "\n".join(lines)

@add_fig_kwargs
def plot_g_qpath(self, band_range, average_mode="all", ax_mat=None, fontsize=8, **kwargs) -> Figure:
def plot_g_qpath(self, band_range=None, with_q=False, average_mode="all", ax_mat=None, fontsize=8, **kwargs) -> Figure:
"""
Plot ...
Args:
band_range:
with_q
average_mode:
ax_mat: List of |matplotlib-Axes| or None if a new figure should be created.
fontsize: fontsize for legends and titles
Expand All @@ -122,24 +124,26 @@ def plot_g_qpath(self, band_range, average_mode="all", ax_mat=None, fontsize=8,
ax_mat, fig, plt = get_axarray_fig_plt(ax_mat, nrows=nrows, ncols=ncols,
sharex=False, sharey=False, squeeze=False)

qnorms = np.array([qpt.norm for qpt in self.phbands.qpoints]) if with_q else \
np.ones(len(self.phbands.qpoints))
#band_range = (self.r.bstart, self.r.bstop) if band_range is None else band_range

for spin in range(self.r.nsppol):
g2_nuq, g2_nuq_unsym = self.r.get_g2nuq_average_spin(spin, band_range, average_mode)

ax = ax_mat[0, spin]
#print(f"{g2_nuq_unsym.shape=}")
for nu in range(self.r.natom3):
ax.plot(g2_nuq[nu], label=f"sym {nu=}")
for mode in range(self.r.natom3):
ax.plot(g2_nuq[mode] * qnorms, label=f"sym {mode=}")

set_grid_legend(ax, fontsize, xlabel=r"$\mathbf{q}$ Wavevector", ylabel=r"$|g|$")
self.phbands.decorate_ax(ax, units="meV")
#ax.set_ylabel(abu.wlabel_from_units(units))
#ax.set_xlabel("Wave Vector")
set_grid_legend(ax, fontsize, xlabel=r"Wavevector $\mathbf{q}$", ylabel=r"$|g|$")

ax = ax_mat[1, spin]
for nu in range(self.r.natom3):
ax.plot(g2_nuq_unsym[nu], label=f"unsym {nu=}")
for mode in range(self.r.natom3):
ax.plot(g2_nuq_unsym[mode] * qnorms, label=f"unsym {mode=}")

self.phbands.decorate_ax(ax, units="meV")
set_grid_legend(ax, fontsize, xlabel=r"$\mathbf{q}$ Wavevector", ylabel=r"$|g|$")
set_grid_legend(ax, fontsize, xlabel=r"Wavevector $\mathbf{q}$", ylabel=r"$|g|$")

#ax.plot(self.r.phfreqs_ha * abu.Ha_meV) # , label=f"e_kq")
#set_grid_legend(ax, fontsize, xlabel=r"$\mathbf{q}$ wavevector", ylabel=r"$\omega_{\mathbf{q}\nu}$ (meV)")
Expand All @@ -152,6 +156,36 @@ def plot_g_qpath(self, band_range, average_mode="all", ax_mat=None, fontsize=8,

return fig

#@add_fig_kwargs
#def plot_g_kpath(self, band_range=None, with_q=False, average_mode="all", ax_mat=None, fontsize=8, **kwargs) -> Figure:

def yield_figs(self, **kwargs): # pragma: no cover
"""
This function *generates* a predefined list of matplotlib figures with minimal input from the user.
"""
yield self.ebands.plot(show=False)
if self.r.eph_fix_korq == "k":
yield self.phbands.plot(show=False)
yield self.plot_g_qpath()
#if self.r.eph_fix_korq == "q":
# yield self.plot_g_kpath()

def write_notebook(self, nbpath=None) -> str:
"""
Write a jupyter_ notebook to ``nbpath``. If nbpath is None, a temporay file in the current
working directory is created. Return path to the notebook.
"""
nbformat, nbv, nb = self.get_nbformat_nbv_nb(title=None)

nb.cells.extend([
nbv.new_code_cell("gpath = abilab.abiopen('%s')" % self.filepath),
nbv.new_code_cell("print(gpath)"),
nbv.new_code_cell("gpath.ebands.plot();"),
nbv.new_code_cell("gpath.phbands.plot();"),
])

return self._write_nb_nbpath(nb, nbpath)


class GpathReader(BaseEphReader):
"""
Expand Down Expand Up @@ -181,10 +215,11 @@ def __init__(self, filepath: PathLike):
self.eph_fix_wavec = self.read_value("eph_fix_wavevec")
#self.completed = self.read_value("gstore_completed")

# Note conversion Fortran --> C for the isym index.
# Note conversion Fortran --> C for the bstart index.
nband = self.read_dimvalue("nband")
self.bstart = self.read_value("bstart") - 1
self.band_range = [self.bstart, nband]
self.bstop = self.read_value("bstop")
self.band_range = [self.bstart, self.bstop]

def read_ebands(self):
"""
Expand Down Expand Up @@ -231,9 +266,11 @@ def read_phbands(self) -> PhononBands:

path_qq = Kpath(structure.lattice.reciprocal_lattice, qpath_frac_coords, weights=None, names=None, ksampling=None)

non_anal_ph = NonAnalyticalPh.from_ncreader(self) if "non_analytical_directions" in self.rootgrp.variables else None

return PhononBands(structure=structure, qpoints=path_qq, phfreqs=phfreqs, phdispl_cart=phdispl_cart, amu=amu,
# TODO
#non_anal_ph=non_anal_ph,
non_anal_ph=non_anal_ph,
# TODO ?
#epsinf=epsinf,
#zcart=zcart,
)
Expand All @@ -246,7 +283,7 @@ def get_g2nuq_average_spin(self, spin: int, band_range: list|tuple, average_mode
spin: Spin index
band_range:
average_mode:
eps_mev: Tolerance in mev used to detect degeneracies
eps_mev: Tolerance in meV used to detect degeneracies.
"""
# Consistency check
if self.nk_path != 1:
Expand Down
26 changes: 13 additions & 13 deletions abipy/panels/oncvpsp_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ class OncvGui(AbipyParameterized):
rcfact_dir = param.Selector(["centered", ">", "<"])

ace_theme = param.ObjectSelector(default="chrome",
objects=pnw.Ace.param.theme.objects,
objects=pnw.CodeEditor.param.theme.objects,
doc="Theme of the editor")

history_idx = param.Integer(default=-1, label="History index")
Expand All @@ -543,7 +543,7 @@ def __init__(self, oncv_input, plotlyFlag, in_filepath="", **params):
#max_length=150,
)

self.input_ace = pnw.Ace(value=str(oncv_input), **self.ace_kwargs)
self.input_ace = pnw.CodeEditor(value=str(oncv_input), **self.ace_kwargs)

# Add annotated example for documentation purposes.
self.annotated_example = pn.pane.HTML(f"<pre><code> {GE_ANNOTATED} </code></pre>")
Expand All @@ -566,7 +566,7 @@ def __init__(self, oncv_input, plotlyFlag, in_filepath="", **params):
#self.history_btn.on_click(self.on_history_btn)

self.rc_qcut_btn = pnw.Button(name="Execute", button_type='primary')

self.plotlyFlag = plotlyFlag

@param.depends("ace_theme")
Expand Down Expand Up @@ -661,7 +661,7 @@ def on_history_btn(self) -> pn.Column:
if hist_len == 0 or idx >= hist_len:
return pn.Column(f"hist_len == {hist_len}")

ace_hist = pnw.Ace(value=self.input_history[idx], **self.ace_kwargs)
ace_hist = pnw.CodeEditor(value=self.input_history[idx], **self.ace_kwargs)

fromlines = self.input_history[idx].splitlines()
tolines = self.input_ace.value.splitlines()
Expand Down Expand Up @@ -801,7 +801,7 @@ def on_change_qcut(self, event) -> None:
try:
for qcut in qcut_values:
oncv_input.lparams[i0].qcut = qcut
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type))
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False))
finally:
# Restore the initial value.
oncv_input.lparams[i0].qcut = qcut0
Expand Down Expand Up @@ -869,7 +869,7 @@ def on_change_debl(self, event) -> None:
try:
for debl in debl_values:
oncv_input.lparams[i0].debl = debl
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type))
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False))
finally:
# Restore the initial value.
oncv_input.lparams[i0].debl = debl0
Expand Down Expand Up @@ -910,7 +910,7 @@ def on_change_rc5(self, event) -> None:
try:
for new_rc in rc5_values:
oncv_input.rc5 = new_rc
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type))
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False))
finally:
# Restore the initial value.
oncv_input.rc5 = rc5
Expand Down Expand Up @@ -951,7 +951,7 @@ def on_change_dvloc0(self, event) -> None:
try:
for new_dvloc in dvloc_values:
oncv_input.dvloc0 = new_dvloc
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type))
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False))
finally:
# Restore the initial value.
oncv_input.dvloc0 = dvloc0
Expand Down Expand Up @@ -994,7 +994,7 @@ def on_change_rc(self, event) -> None:
try:
for rc in rc_values:
oncv_input.lparams[i0].rc = rc
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type))
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False))
finally:
# Restore the initial value.
oncv_input.lparams[i0].rc = rc0
Expand Down Expand Up @@ -1046,7 +1046,7 @@ def on_change_rhomodel(self, event) -> None:
try:
oncv_input.fcfact = fc
oncv_input.rcfact = rc
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type))
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False))
tasks.append((psgens[-1], {"fcfact": fc, "rcfact": rc}))
titles.append(f"fcfact: {fc}, rcfact: {rc}")
finally:
Expand All @@ -1059,7 +1059,7 @@ def on_change_rhomodel(self, event) -> None:
for fc in fcfact_values:
try:
oncv_input.fcfact = fc
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type))
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False))
tasks.append((psgens[-1], {"fcfact": fc}))
titles.append(f"fcfact: {fc}")
finally:
Expand Down Expand Up @@ -1137,7 +1137,7 @@ def rq_prod():
for rc, qcut in rq_prod():
oncv_input.lparams[i0].rc = rc
oncv_input.lparams[i0].qcut = qcut
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type))
psgens.append(OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False))
finally:
# Restore the initial value.
oncv_input.lparams[i0].rc = rc0
Expand Down Expand Up @@ -1171,7 +1171,7 @@ def on_execute_btn(self, event) -> None:
"""
with ButtonContext(event.obj), Loading(self.out_area):
oncv_input = self.get_oncv_input()
psgen = OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type)
psgen = OncvGenerator(input_str=str(oncv_input), calc_type=self.calc_type, use_mgga=False)
print("Running in workdir:", psgen.workdir)
psgen.start()
retcode = psgen.wait()
Expand Down

0 comments on commit 747ef72

Please sign in to comment.