def eval_line(self, point1, point2, num=200, cartesian=False, kpoint=None): """ Interpolate values along a line. Args: point1: First point of the line. Accepts 3d vector or integer. The vector is in reduced coordinates unless `cartesian == True`. If integer, the first point of the line is given by the i-th site of the structure e.g. `point1=0, point2=1` gives the line passing through the first two atoms. point2: Second point of the line. Same API as `point1`. num: Number of points sampled along the line. cartesian: By default, `point1` and `point1` are interpreted as points in fractional coordinates (if not integers). Use True to pass points in cartesian coordinates. kpoint: k-point in reduced coordinates. If not None, the phase-factor e^{ikr} is included. Return: named tuple with site1, site2: None if the points do not represent atomic sites. points: Points in fractional coords. dist: the distance of points along the line in Ang. values: numpy array of shape [ndt, num] with interpolated values. """ site1 = None if duck.is_intlike(point1): if point1 > len(self.structure): raise ValueError("point1: %s > natom: %s" % (point1, len(self.structure))) site1 = self.structure[point1] point1 = site1.coords if cartesian else site1.frac_coords site2 = None if duck.is_intlike(point2): if point2 > len(self.structure): raise ValueError("point2: %s > natom: %s" % (point2, len(self.structure))) site2 = self.structure[point2] point2 = site2.coords if cartesian else site2.frac_coords point1 = np.reshape(point1, (3, )) point2 = np.reshape(point2, (3, )) if cartesian: red_from_cart = self.structure.lattice.inv_matrix.T point1 = np.dot(red_from_cart, point1) point2 = np.dot(red_from_cart, point2) p21 = point2 - point1 line_points = np.reshape( [alpha * p21 for alpha in np.linspace(0, 1, num=num)], (-1, 3)) dist = self.structure.lattice.norm(line_points) line_points += point1 return dict2namedtuple(site1=site1, site2=site2, points=line_points, dist=dist, values=self.eval_points(line_points, kpoint=kpoint))
def eval_line(self, point1, point2, num=200, cartesian=False, kpoint=None): """ Interpolate values along a line. Args: point1: First point of the line. Accepts 3d vector or integer. The vector is in reduced coordinates unless `cartesian == True`. If integer, the first point of the line is given by the i-th site of the structure e.g. `point1=0, point2=1` gives the line passing through the first two atoms. point2: Second point of the line. Same API as `point1`. num: Number of points sampled along the line. cartesian: By default, `point1` and `point1` are interpreted as points in fractional coordinates (if not integers). Use True to pass points in cartesian coordinates. kpoint: k-point in reduced coordinates. If not None, the phase-factor e^{ikr} is included. Return: named tuple with site1, site2: None if the points do not represent atomic sites. points: Points in fractional coords. dist: the distance of points along the line in Ang. values: numpy array of shape [ndt, num] with interpolated values. """ site1 = None if duck.is_intlike(point1): if point1 > len(self.structure): raise ValueError("point1: %s > natom: %s" % (point1, len(self.structure))) site1 = self.structure[point1] point1 = site1.coords if cartesian else site1.frac_coords site2 = None if duck.is_intlike(point2): if point2 > len(self.structure): raise ValueError("point2: %s > natom: %s" % (point2, len(self.structure))) site2 = self.structure[point2] point2 = site2.coords if cartesian else site2.frac_coords point1 = np.reshape(point1, (3,)) point2 = np.reshape(point2, (3,)) if cartesian: red_from_cart = self.structure.lattice.inv_matrix.T point1 = np.dot(red_from_cart, point1) point2 = np.dot(red_from_cart, point2) p21 = point2 - point1 line_points = np.reshape([alpha * p21 for alpha in np.linspace(0, 1, num=num)], (-1, 3)) dist = self.structure.lattice.norm(line_points) line_points += point1 return dict2namedtuple(site1=site1, site2=site2, points=line_points, dist=dist, values=self.eval_points(line_points, kpoint=kpoint))
def plot_ax(self, ax, qpoint=None, **kwargs): """ Helper function to plot data on the axis ax. Args: ax: |matplotlib-Axes| qpoint: index of the q-point or |Kpoint| object or None to plot emacro_avg. kwargs: Keyword arguments passed to matplotlib. Accepts also: cplx_mode: string defining the data to print (case-insensitive). Possible choices are - "re" for real part - "im" for imaginary part only. - "abs' for the absolute value Options can be concated with "-". """ # Extract the function to plot according to qpoint. if duck.is_intlike(qpoint): f = self.emacros_q[int(qpoint)] elif isinstance(qpoint, Kpoint): iq = self.qpoints.index(qpoint) f = self.emacros_q[iq] elif qpoint is None: f = self.emacro_avg else: raise ValueError("Don't know how to handle %s" % str(qpoint)) return f.plot_ax(ax, **kwargs)
def plot_ax(self, ax, what, red_coords, *args, **kwargs): """ Helper function to plot data on the axis ax. Args: ax: |matplotlib-Axes| what: Sequential index of the tensor matrix element. args: Positional arguments passed to ``ax.plot`` kwargs: Keyword arguments passed to matplotlib. Accepts also: ============== ============================================================== kwargs Meaning ============== ============================================================== cplx_mode: string defining the data to print (case-insensitive). Possible choices are: - "re" for real part - "im" for imaginary part only. - "abs' for the absolute value Options can be concated with "-". ============== ============================================================== """ # Extract the function to plot according to qpoint. if duck.is_intlike(what): f = self.to_func1d(red_coords)[int(what)] else: raise ValueError("Don't know how to handle %s" % str(what)) return f.plot_ax(ax, *args, **kwargs)
def plot_gg(self, cplx_mode="abs", wpos=None, **kwargs): r""" Use matplotlib imshow to plot :math:`W_{GG'}` matrix Args: cplx_mode: string defining the data to print. Possible choices are (case-insensitive): ``re`` for the real part ``im`` for the imaginary part, ``abs`` for the absolute value. ``angle`` will display the phase of the complex number in radians. wpos: List of frequency indices to plot. If None, the first frequency is used (usually w=0). If wpos == "all" all frequencies are shown (use it carefully) Other possible values: "real" if only real frequencies are wanted. "imag" for imaginary frequencies only. Returns: |matplotlib-Figure| """ # Get wpos indices. choice_wpos = {None: [0], "all": range(self.nw), "real": range(self.nrew), "imag": range(self.nrew, self.nw)} if any(wpos == k for k in choice_wpos): wpos = choice_wpos[wpos] else: if duck.is_intlike(wpos): wpos = [int(wpos)] wpos = np.array(wpos) # Build plotter. plotter = ArrayPlotter() for iw in wpos: label = r"%s $\omega=%s$" % (self.latex_label(cplx_mode), self.wpoints[iw]) data = data_from_cplx_mode(cplx_mode, self.wggmat[iw]) plotter.add_array(label, data) return plotter.plot(show=False, **kwargs)
def plot_ax(self, ax, what, red_coords, *args, **kwargs): """ Helper function to plot data on the axis ax. Args: ax: |matplotlib-Axes| what: Sequential index of the tensor matrix element. args: Positional arguments passed to ``ax.plot`` kwargs: Keyword arguments passed to matplotlib. Accepts also: ============== ============================================================== kwargs Meaning ============== ============================================================== cplx_mode: string defining the data to print (case-insensitive). Possible choices are: - "re" for real part - "im" for imaginary part only. - "abs' for the absolute value Options can be concated with "-". ============== ============================================================== """ # Extract the function to plot according to qpoint. if duck.is_intlike(what): f = self.to_func1d(red_coords)[int(what)] else: raise ValueError("Don't know how to handle %s" % str(what)) return f.plot_ax(ax, *args, **kwargs)
def plot_ax(self, ax, qpoint=None, **kwargs): """ Helper function to plot data on the axis ax. Args: ax: |matplotlib-Axes| qpoint: index of the q-point or |Kpoint| object or None to plot emacro_avg. kwargs: Keyword arguments passed to matplotlib. Accepts also: cplx_mode: string defining the data to print (case-insensitive). Possible choices are - "re" for real part - "im" for imaginary part only. - "abs' for the absolute value Options can be concated with "-". """ # Extract the function to plot according to qpoint. if duck.is_intlike(qpoint): f = self.emacros_q[int(qpoint)] elif isinstance(qpoint, Kpoint): iq = self.qpoints.index(qpoint) f = self.emacros_q[iq] elif qpoint is None: f = self.emacro_avg else: raise ValueError("Don't know how to handle %s" % str(qpoint)) return f.plot_ax(ax, **kwargs)
def plot_gg(self, cplx_mode="abs", wpos=None, **kwargs): r""" Use matplotlib imshow to plot :math:`W_{GG'}` matrix Args: cplx_mode: string defining the data to print. Possible choices are (case-insensitive): ``re`` for the real part ``im`` for the imaginary part, ``abs`` for the absolute value. ``angle`` will display the phase of the complex number in radians. wpos: List of frequency indices to plot. If None, the first frequency is used (usually w=0). If wpos == "all" all frequencies are shown (use it carefully) Other possible values: "real" if only real frequencies are wanted. "imag" for imaginary frequencies only. Returns: |matplotlib-Figure| """ # Get wpos indices. choice_wpos = {None: [0], "all": range(self.nw), "real": range(self.nrew), "imag": range(self.nrew, self.nw)} if any(wpos == k for k in choice_wpos): wpos = choice_wpos[wpos] else: if duck.is_intlike(wpos): wpos = [int(wpos)] wpos = np.array(wpos) # Build plotter. plotter = ArrayPlotter() for iw in wpos: label = r"%s $\omega=%s$" % (self.latex_label(cplx_mode), self.wpoints[iw]) data = data_from_cplx_mode(cplx_mode, self.wggmat[iw]) plotter.add_array(label, data) return plotter.plot(show=False, **kwargs)
def gindex(self, gvec): """ Find the index of gvec. If ``gvec`` is an integer, gvec is returned. Raises: `ValueError` if gvec is not found. """ if duck.is_intlike(gvec): return int(gvec) return self.gsphere.index(gvec)
def gindex(self, gvec): """ Find the index of gvec. If ``gvec`` is an integer, gvec is returned. Raises: `ValueError` if gvec is not found. """ if duck.is_intlike(gvec): return int(gvec) return self.gsphere.index(gvec)
def test_is_intlike(self): """Testing is_intlike.""" assert duck.is_intlike(1) assert duck.is_intlike(1.0) assert not duck.is_intlike(1.3) assert not duck.is_intlike("1") assert not duck.is_intlike([1, 2, 3]) for t in (np.int32, np.int64, np.float64): assert duck.is_intlike(t(123)) assert duck.is_intlike(np.complex(123)) assert not duck.is_intlike(np.complex(123.2)) assert not duck.is_intlike(123 + 1j * 2)
def _find_iqpt_qpoint(self, qpoint): if duck.is_intlike(qpoint): iq = qpoint qpoint = self.qpoints[iq] else: qpoint = Kpoint.as_kpoint(qpoint, self.structure.reciprocal_lattice) iq = self.qpoints.index(qpoint) return iq, qpoint
def kindex(self, kpoint): """ Index of the k-point in the internal tables. Accepts: :class:`Kpoint` instance or integer. """ if duck.is_intlike(kpoint): return int(kpoint) else: return self.kpoints.index(kpoint)
def kindex(self, kpoint): """ Index of the k-point in the internal tables. Accepts: :class:`Kpoint` instance or integer. """ if duck.is_intlike(kpoint): return int(kpoint) else: return self.kpoints.index(kpoint)
def find_kpoint_fileindex(self, kpoint): """ Returns the k-point and the index of the k-point in the netcdf file. Accepts |Kpoint| instance or integer. """ if duck.is_intlike(kpoint): ik = int(kpoint) else: ik = self.kpoints.index(kpoint) return self.kpoints[ik], ik
def find_kpoint_fileindex(self, kpoint): """ Returns the k-point and the index of the k-point in the netcdf file. Accepts |Kpoint| instance or integer. """ if duck.is_intlike(kpoint): ik = int(kpoint) else: ik = self.kpoints.index(kpoint) return self.kpoints[ik], ik
def _new_array(self, dtype=np.float, zero=True, extra_dims=()): shape = self.shape if duck.is_intlike(extra_dims): extra_dims = (extra_dims,) shape = extra_dims + tuple(shape) if zero: return np.zeros(shape, dtype) else: return np.empty(shape, dtype)
def _new_array(self, dtype=np.float, zero=True, extra_dims=()): shape = self.shape if duck.is_intlike(extra_dims): extra_dims = (extra_dims, ) shape = extra_dims + tuple(shape) if zero: return np.zeros(shape, dtype) else: return np.empty(shape, dtype)
def _new_array(self, dtype=np.float, zero=True, extra_dims=()): """Returns a numpy array defined on the sphere.""" shape = (self.npw,) if duck.is_intlike(extra_dims): extra_dims = (extra_dims,) shape = extra_dims + tuple(shape) if zero: return np.zeros(shape, dtype) else: return np.empty(shape, dtype)
def random(self, dtype=np.float, extra_dims=()): """Returns random real |numpy-array| for this domain with val in [0.0, 1.0).""" shape = self.shape if duck.is_intlike(extra_dims): extra_dims = (extra_dims,) shape = extra_dims + tuple(shape) re = np.random.random(shape) if dtype == np.float: return re elif dtype == np.complex: im = self.random(extra_dims=extra_dims) return re + 1j*im else: raise ValueError("Wrong dtype: %s" % str(dtype))
def random(self, dtype=np.float, extra_dims=()): """Returns random real |numpy-array| for this domain with val in [0.0, 1.0).""" shape = self.shape if duck.is_intlike(extra_dims): extra_dims = (extra_dims, ) shape = extra_dims + tuple(shape) re = np.random.random(shape) if dtype == np.float: return re elif dtype == np.complex: im = self.random(extra_dims=extra_dims) return re + 1j * im else: raise ValueError("Wrong dtype: %s" % str(dtype))
def plot_gkq2_qpath(self, band_kq, band_k, kpoint=0, with_glr=False, qdamp=None, nu_list=None, # spherical_average=False, ax=None, fontsize=8, eph_wtol=EPH_WTOL, **kwargs): r""" Plot the magnitude of the electron-phonon matrix elements <k+q, band_kq| Delta_{q\nu} V |k, band_k> for a given set of (band_kq, band, k) as a function of the q-point. Args: band_ks: Band index of the k+q states (starts at 0) band_k: Band index of the k state (starts at 0) kpoint: |Kpoint| object or index. with_glr: True to plot the long-range component estimated from Verdi's model. qdamp: nu_list: List of phonons modes to be selected (starts at 0). None to select all modes. ax: |matplotlib-Axes| or None if a new figure should be created. fontsize: Label and title fontsize. Return: |matplotlib-Figure| """ if duck.is_intlike(kpoint): ik = kpoint kpoint = self.kpoints[ik] else: kpoint = Kpoint.as_kpoint(kpoint, self.abifiles[0].structure.reciprocal_lattice) ik = self.kpoints.index(kpoint) # Assume abifiles are already ordered according to q-path. xs = list(range(len(self.abifiles))) natom3 = len(self.abifiles[0].structure) * 3 nsppol = self.abifiles[0].nsppol nqpt = len(self.abifiles) gkq_snuq = np.empty((nsppol, natom3, nqpt), dtype=np.complex) if with_glr: gkq_lr = np.empty((nsppol, natom3, nqpt), dtype=np.complex) # TODO: Should take into account possible degeneracies in k and kq... xticks, xlabels = [], [] for iq, abifile in enumerate(self.abifiles): qpoint = abifile.qpoint #d3q_fact = one if not spherical_average else np.sqrt(4 * np.pi) * qpoint.norm name = qpoint.name if qpoint.name is not None else abifile.structure.findname_in_hsym_stars(qpoint) if qpoint.name is not None: xticks.append(iq) xlabels.append(name) phfreqs_ha, phdispl_red = abifile.phfreqs_ha, abifile.phdispl_red ncvar = abifile.reader.read_variable("gkq") for spin in range(nsppol): gkq_atm = ncvar[spin, ik, :, band_k, band_kq] gkq_atm = gkq_atm[:, 0] + 1j * gkq_atm[:, 1] # Transform the gkk matrix elements from (atom, red_direction) basis to phonon-mode basis. gkq_snuq[spin, :, iq] = 0.0 for nu in range(natom3): if phfreqs_ha[nu] < eph_wtol: continue gkq_snuq[spin, nu, iq] = np.dot(phdispl_red[nu], gkq_atm) / np.sqrt(2.0 * phfreqs_ha[nu]) if with_glr: # Compute long range part with (simplified) generalized Frohlich model. gkq_lr[spin, :, iq] = glr_frohlich(qpoint, abifile.becs_cart, abifile.epsinf_cart, abifile.phdispl_cart_bohr, phfreqs_ha, abifile.structure, qdamp=qdamp) ax, fig, plt = get_ax_fig_plt(ax=ax) nu_list = list(range(natom3)) if nu_list is None else list(nu_list) for spin in range(nsppol): for nu in nu_list: ys = np.abs(gkq_snuq[spin, nu]) * abu.Ha_meV pre_label = kwargs.pop("pre_label",r"$g_{\bf q}$") if nsppol == 1: label = r"%s $\nu$: %s" % (pre_label, nu) if nsppol == 2: label = r"%s $\nu$: %s, spin: %s" % (pre_label, nu, spin) ax.plot(xs, ys, linestyle="--", label=label) if with_glr: # Plot model with G = 0 and delta_nn' ys = np.abs(gkq_lr[spin, nu]) * abu.Ha_meV label = r"$g_{\bf q}^{\mathrm{lr0}}$ $\nu$: %s" % nu ax.plot(xs, ys, linestyle="", marker="o", label=label) ax.grid(True) ax.set_xlabel("Wave Vector") ax.set_ylabel(r"$|g_{\bf q}|$ (meV)") if xticks: ax.set_xticks(xticks, minor=False) ax.set_xticklabels(xlabels, fontdict=None, minor=False, size=kwargs.pop("klabel_size", "large")) ax.legend(loc="best", fontsize=fontsize, shadow=True) title = r"$band_{{\bf k} + {\bf q}: %s, band_{\bf{k}}: %s, kpoint: %s" % (band_kq, band_k, repr(kpoint)) ax.set_title(title, fontsize=fontsize) return fig