Beispiel #1
0
def band_raw(primitive,
             bandfiles=None,
             pots=None,
             supercell=None,
             npts=100,
             title="{} Phonon Spectrum",
             save=None,
             figsize=(10, 8),
             nbands=4,
             line_names=None,
             delta=0.01,
             quick=True,
             **kwargs):
    """Plots the phonon bands from raw `band.yaml` files.

    Args:
        primitive (str): path to the atoms file for the *primitive* to plot
          bands for. Use the ASE format string as a prefix,
          e.g. `vasp-xml:vasprun.xml` or `extxyz:atoms.xyz`. Default assumes
          `vasp:{}` if no format is specified.
        bandfiles (list): list of `str` file paths to the plain `band.yaml` files.
        supercell (list): list of `int`; supercell dimensions for the phonon
          calculations.
        npts (int): number of points to sample along the special path in
          k-space.
        title (str): Override the default title for plotting; use `{}` for
          formatting chemical formula.
        save (str): name of a file to save the plot to; otherwise the plot is
          shown in a window.
        figsize (tuple): tuple of `float`; the size of the figure in inches.
        nbands (int): number of bands to plot.
        delta (float): size of displacement for finite difference derivative.
        quick (bool): when True, use symmetry to speed up the Hessian
          calculation for the specified potentials.
        kwargs (dict): additional "dummy" arguments so that this method can be
          called with arguments to other functions.
    """
    nlines = len(bandfiles) + (0 if pots is None else len(pots))
    colors = plt.cm.nipy_spectral(np.linspace(0, 1, nlines))
    bands, style = {}, {}

    #Handle DSL format import on the file path for the primitive cell.
    if ':' not in primitive:
        atoms = Atoms(primitive, format="vasp")
    else:
        fmt, atpath = primitive.split(':')
        atoms = Atoms(atpath, format=fmt)

    names, kpath = parsed_kpath(atoms)

    #matplotlib needs the $ signs for latex if we are using special
    #characters. We only get names out from the first configuration; all
    #the others have to use the same one.
    names = ["${}$".format(n) if '\\' in n or '_' in n else n for n in names]

    for ifile, fpath in enumerate(bandfiles):
        if line_names is not None:
            key = line_names[ifile]
        else:
            key = "File {}".format(ifile)

        bands[key] = from_yaml(fpath)
        style[key] = {"color": colors[ifile], "lw": 2}

    if pots is not None:
        for fiti, fit in enumerate(tqdm(pots)):
            gi = len(bandfiles) + fiti
            atoms.set_calculator(fit)
            H = phon_calc(atoms, supercell=supercell, delta=delta, quick=quick)
            bands[line_names[gi]] = _calc_bands(atoms, H, supercell)
            style[line_names[gi]] = {"color": colors[gi], "lw": 2}

    title = title.format(atoms.get_chemical_formula())
    savefile = None
    if save:
        savefile = save

    bandplot(bands,
             names,
             title=title,
             outfile=savefile,
             figsize=figsize,
             style=style,
             nbands=nbands)
Beispiel #2
0
def trimer(pot,
           atoms,
           elements,
           folder=None,
           base64=False,
           index=None,
           nsamples=50):
    """Plots the potential behavior as the angle between three atoms changes in a
    trimer.

    .. note:: This produces a *dict* of all possible 3-body interactions between
      distinct element types.

    Args:
        elements (list): list of chemical symbols in the system.
        pot (matdb.calculators.basic.AsyncCalculator): IP to calculate properties with.
        atoms (matdb.atoms.AtomsList): list of atoms from which to calculate correlations.
        folder (str): path to the folder where the saved image should be stored.
        base64 (bool): when True, use a base-64 encoded `src` for the output of
          this image; otherwise, the image is saved to `folder` and only its
          name is returned.
        index (int): integer index of this plot in the parent
          collection.
        nsamples (int): number of samples to take along the trajectory.

    Returns:

        dict: keys are concatenated element names (e.g. `AgPd`) and values are
        :class:`PointDetailImage` instances.
    """
    #First, determine the set of unique element pairs in the list.
    from itertools import product
    possible = list(product(elements, repeat=3))
    target = list(set(map(lambda l: tuple(sorted(l)), possible)))

    subplot_kw = {"xlabel": "Angle (Rad)", "ylabel": "IP Energy (eV)"}

    result = {}
    for elements in target:
        #Look up the lattice parameters for each of the elements. Use Vegard's
        #law to get a decent domain to plot the energy over.
        from matdb.data import vegard
        uelements = list(set(elements))
        concdict = [elements.count(e) / 3. for e in uelements]
        rvegard = vegard(uelements, concdict)

        trimer = Atoms(positions=np.zeros((3, 3)), cell=np.eye(3) * 100)
        trimer.positions = 0.
        trimer.set_chemical_symbols(elements)
        trimer.set_calculator(pot)
        #Set the position of the second atom to be at equilibrium with respect
        #to the Vegard's law calculation.
        trimer.positions[1, 2] = rvegard

        #Now, vary the angle of the third atom with respect to the original two
        #and see how the angle changes.
        theta = np.linspace(np.pi / 6, np.pi, nsamples)
        energy = []
        for t in theta:
            x = rvegard * np.cos(t)
            y = rvegard * np.sin(t)
            trimer.positions[1, 2] = x
            trimer.positions[1, 2] = y
            energy.append(trimer.get_potential_energy())

        elemstr = trimer.get_chemical_formula()
        img = PDI(theta,
                  np.array(energy),
                  "plot",
                  subplot_kw=subplot_kw,
                  index=index,
                  base64=base64,
                  name=elemstr,
                  imgtype=elemstr,
                  folder=folder)
        result[elemstr] = img

    return result