--- title: Structure IO keywords: fastai sidebar: home_sidebar summary: "This includes generating POSCAR form Materials Project. You need their API key to run functions in this module where required." description: "This includes generating POSCAR form Materials Project. You need their API key to run functions in this module where required." nb_path: "StructureIO.ipynb" ---
{% raw %}
{% endraw %} {% raw %}

  Index 
  XmlElementTree 
  StaticPlots 
  InteractivePlots 
  Utilities 
  StructureIO● 
  Widgets 
  MainAPI 

{% endraw %}

Note : To use materials project data frequently, you may need to save their api key into file. Run function below and it saves key to a file and every function will autoload it.

{% raw %}
{% endraw %} {% raw %}
{% endraw %} {% raw %}

class Arrow3D[source]

Arrow3D(x, y, z, u, v, w, *args, **kwargs) :: FancyArrowPatch

Draw 3D fancy arrow.

{% endraw %} {% raw %}

fancy_quiver3d[source]

fancy_quiver3d(X, Y, Z, U, V, W, ax=None, C='r', L=0.7, mutation_scale=10, **kwargs)

Plots 3D arrows on a given ax. See FancyArrowPatch.

  • Parameters
    • X, Y, Z : 1D arrays of coordinates of arrows' tail point.
    • U, V, W : 1D arrays of dx,dy,dz of arrows.
    • ax: 3D axes, if not given, auto created.
    • C : 1D colors array mapping for arrows. Could be one color.
    • L : 1D linwidths array mapping for arrows. Could be one linewidth.
    • mutation_scale: Arrow head width/size scale. Default is 10.
    • kwargs: FancyArrowPatch's keyword arguments excluding positions,color, lw and mutation_scale, shrinkA, shrinkB which are already used. An important keyword argument is arrowstyle which could be '->','-|>', their inverted forms and many more. See on matplotlib.
{% endraw %} {% raw %}
{% endraw %} {% raw %}
def field(x,y,z):
    u, v, w = y, -x , z
    norm = 5*(u*u + v*v + w*w)**(1/2)
    if norm == 0:
        return (x,y,z,0.01,0.01,0.01)
    return (x,y,z, u/norm, v/norm, w/norm)

X,Y,Z = np.mgrid[0:1:10j,0:1:10j,0:1:3j]
vs = np.concatenate([X.ravel(),Y.ravel(),Z.ravel()]).reshape((3,-1)).T

ef = np.array([field(*v) for v in vs]).T

C = np.abs(ef[3:,:].T)
C = C/np.max(C)

ax1, ax2 = sp.get_axes(ncols=2,figsize=(6,3),axes_3d=[0,1])
bz = get_bz([[1,0,0],[0,1,0],[0,0,1]],primitive=True)
splot_bz(bz,ax=ax1,vname='x',fill=False,color=(0.8,0.7,0.2,0.7))
splot_bz(bz,ax=ax2,vname='x',fill=False,color=(0.8,0.7,0.2,0.7))

fancy_quiver3d(*ef,C = C,ax=ax1,L=0.01,mutation_scale=7,capstyle='butt',arrowstyle='wedge').set_box_aspect((1,1,1))
ax1.set_axis_off()
ax1.set_title('Fancy Quiver 3D')

# Repeat for each body line and two head lines
C = np.concatenate([C,np.repeat(C, 2, axis=0)])
q = ax2.quiver(*ef,lw=1,colors=C)
ax2.set_title('Default Quiver 3D')
ax2.set_box_aspect((1,1,1))
ax2.set_axis_off()
2022-04-24T13:55:11.460521 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
{% endraw %} {% raw %}

export_poscar[source]

export_poscar(path=None, content=None)

Export POSCAR file to python objects.

  • Parameters
    • path: Path/to/POSCAR file. Auto picks in CWD.
    • contet: POSCAR content as string, This takes precedence to path.
{% endraw %} {% raw %}
{% endraw %} {% raw %}
{% endraw %} {% raw %}
{% endraw %} {% raw %}

class InvokeMaterialsProject[source]

InvokeMaterialsProject(api_key=None)

Connect to materials project and get data using api_key from their site. Usage:

>>> from pivotpyr.sio import InvokeMaterialsProject # or import pivotpy.InvokeMaterialsProject as InvokeMaterialsProject
>>> mp = InvokeMaterialsProject(api_key='your_api_key')
>>> mp.request(formula='NaCl') #returns nothing but saves response
>>> mp.poscars #returns poscars data
>>> mp.cifs #returns cifs data
{% endraw %} {% raw %}
{% endraw %} {% raw %}
mp = InvokeMaterialsProject()
mp.request('GaAs',max_sites=2,min_sites=2)
pc = mp.poscars
print("material_id: ",pc[1].mp_id)
print("spacegroup symbol: ",pc[1].symbol)
print("\n",pc[1].content)
material_id:  mp-2534
spacegroup symbol:  F-43m

 GaAs	# [F-43m] Generated by PivotPy using Materials Project Database.
  4.06599269
     1.0000000000000000     0.0000000000000000     0.0000000000000000
     0.5000000000490150     0.8660254037561398     0.0000000000000000
     0.5000000000490150     0.2886751346042458     0.8164965780265512
  Ga	As
  1	1
Direct
  0.00000000    0.00000000    0.00000000  Ga
  0.75000000    0.75000000    0.75000000  As

{% endraw %} {% raw %}

get_kpath[source]

get_kpath(hsk_list=[], labels=[], n=5, weight=None, ibzkpt=None, outfile=None)

Generate list of kpoints along high symmetry path. Options are write to file or return KPOINTS list. It generates uniformly spaced point with input n as just a scale factor of number of points per unit length. You can also specify custom number of kpoints in an interval by putting number of kpoints as 4th entry in left kpoint.

  • Parameters
    • hsk_list : N x 3 list of N high symmetry points, if broken path then [[N x 3],[M x 3],...].
            Optionally you can put a 4 values point where 4th entry will decide number of kpoints in current interval.
            Make sure that points in a connected path patch are at least two i.e. `[[x1,y1,z1],[x2,y2,z2]]` or `[[x1,y1,z1,N],[x2,y2,z2]]`.
    • n : int, number per unit length, this makes uniform steps based on distance between points.
    • weight : Float, if None, auto generates weights.
    • ibzkpt : Path to ibzkpt file, required for HSE calculations.
    • labels : Hight symmetry points labels. Good for keeping record of lables and points indices for later use.
            > Note: If you do not want to label a point, label it as 'skip' at its index and it will be removed.
    • outfile: Path/to/file to write kpoints.

If outfile = None, KPONITS file content is printed.

{% endraw %} {% raw %}

read_ticks[source]

read_ticks(kpoints_file_path)

Reads ticks values and labels in header of kpoint file. Returns dictionary of ktick_inds,ktick_vals,kseg_inds that can be unpacked to plotting functions. If not exist in header, returns empty values(still valid).

{% endraw %} {% raw %}
{% endraw %} {% raw %}
read_ticks('kpt.txt')
{'ktick_inds': [0, 29, -1],
 'ktick_vals': ['M', 'Γ|M', 'L|K', 'N'],
 'kseg_inds': [21, 29]}
{% endraw %}

In example below, the overall value of n = 5 is skipped and 4th entry in the point is used instead. In later example, a 'skipk' label removes high symmetry point index.

{% raw %}
get_kpath([[0.5,0.5,0.5,2],[0,0,0]],n=5,ibzkpt='IBZKPT',labels = ['M','Γ'])
Automatically generated using PivotPy with HSK-INDS = [0, -1], LABELS = ['M', 'Γ'], SEG-INDS = []
	2
Reciprocal Lattice
    0.5000000000    0.5000000000    0.5000000000    0.500000
    0.0000000000    0.0000000000    0.0000000000    0.500000
{% endraw %} {% raw %}
get_kpath([[[0.375,0.375,0.5,21],[0,0,0]],[[0.5,0.25,0.5],[0,0,0]],[[0.25,0.25,0.25],[0,0,0]]],n=11,labels = ['M','skip','Γ|M','L','K','N'],outfile='kpt.txt')
{% endraw %}
Automatically generated using PivotPy with HSK-INDS = [0, 29, -1], LABELS = ['M', 'Γ|M', 'L'], SEG-INDS = [21, 29]
    34

HSK-INDS = [0, 29, -1] should be [0,21,29,-1] but skip label removed it. Also after 21, it may have 32 as n=11, but distance smaller than 1 resulted in only 8 points there. This is pretty useful if you don't need to rescale kpoint axis later on based on distance.

{% raw %}

str2kpath[source]

str2kpath(kpath_str, n=5, weight=None, ibzkpt=None, outfile=None)

Get Kpath from a string of kpoints (Line-Mode like). Useful in Terminal.

  • Parameters

    • kpath_str: str, a multiline string similiar to line mode of KPOINTS, initial 4 lines are not required.
      • If you do not want to label a point, label it as 'skip' and it will be removed.
      • You can add an interger at end of a line to customize number of points in a given patch.
      • Each empty line breaks the path, so similar points before and after empty line are useless here.
    • n : int, number per unit length, this makes uniform steps based on distance between points.
    • weight : Float, if None, auto generates weights.
    • ibzkpt : Path to ibzkpt file, required for HSE calculations.
    • outfile: Path/to/file to write kpoints.
  • Example

    str2kpath('''0 0 0 !$\Gamma$ 3 0.25 0.25 0.25 !L''') Automatically generated using PivotPy with HSK-INDS = [0, -1], LABELS = ['$\Gamma$', 'L'], SEG-INDS = [] 3 Reciprocal Lattice 0.0000000000 0.0000000000 0.0000000000 0.333333 0.1250000000 0.1250000000 0.1250000000 0.333333 0.2500000000 0.2500000000 0.2500000000 0.333333

{% endraw %} {% raw %}
{% endraw %} {% raw %}
str2kpath('0 0 0 G 2\n 1 1 1 X\n1/2 1/2 1/2 L',n=4)
Automatically generated using PivotPy with HSK-INDS = [0, 2, -1], LABELS = ['G', 'X', 'L'], SEG-INDS = []
	5
Reciprocal Lattice
    0.0000000000    0.0000000000    0.0000000000    0.200000
    1.0000000000    1.0000000000    1.0000000000    0.200000
    1.0000000000    1.0000000000    1.0000000000    0.200000
    0.7500000000    0.7500000000    0.7500000000    0.200000
    0.5000000000    0.5000000000    0.5000000000    0.200000
{% endraw %} {% raw %}
{% endraw %} {% raw %}
_get_basis([[ 4.00771850e+00,  0.00000000e+00, -0.00000000e+00],
       [ 2.00385925e+00,  3.47078603e+00,  5.06700000e-13],
       [ 2.00385925e+00,  1.15692868e+00,  3.27228845e+00]]).inverted
array([[ 2.49518523e-01, -1.44059586e-01, -1.01865510e-01],
       [ 0.00000000e+00,  2.88119173e-01, -1.01865511e-01],
       [ 0.00000000e+00, -4.46140330e-14,  3.05596531e-01]])
{% endraw %}

KPOINTS Mesh for Fermi Surface Calculations

  • The command get_kmesh generates a uniform grid in first (primitive) Brillouin zone.
  • The POSCAR is used to get ratios of side lengths in first BZ. Use relaxed and same POSCAR you will use in actual calculations. If you use Vasp's auto generated mesh, use ISYM = -1 to list all points and points inside BZ will be filtered later on while plotting Fermi Surface.
  • KPOINTS are written on outfile provided, if outfile = None, thn BZ data object is returned.
  • IBZKPT file path could be given to argument ibzkpt to include it automatically, this is important to include for HSE calculations with weight = 0. If weight = None, weights are distributed uniformly.
  • If you provide n_xyz = integer,(recommended for auto uniform mesh), all sides have same number of points unless you provide path_pos too, in that case n_xyz is chosen for smallest side in reciprocal space and other sides are scaled based on their lengths according to given POSCAR.
{% raw %}

get_kmesh[source]

get_kmesh(n_xyz=[5, 5, 5], weight=None, ibzkpt=None, path_pos=None, outfile=None)

  • Generates uniform mesh of kpoints. Options are write to file, or return KPOINTS list.
  • Parameters
    • n_xyz : List of [nx ny nz] or integer. If integer given, it represents numbers of kpoints along smallest side in reciprocal space and kmesh is autoscaled.
    • weight : Float, if None, auto generates weights.
    • ibzkpt : Path to ibzkpt file, required for HSE calculations.
    • path_pos : POSCAR file path or real space lattice vectors, if None, cubic symmetry is used and it is fast.
    • outfile: Path/to/file to write kpoints.

If outfile = None, KPOINTS file content is printed.

{% endraw %} {% raw %}
{% endraw %} {% raw %}
get_kmesh(n_xyz=[2,2,2],path_pos=[[1,1,0],[0,1,1],[1,0,0.5]])
Automatically generated uniform mesh using PivotPy with 2x2x2 grid
	8
Reciprocal Lattice
    0.0000000000    0.0000000000    0.0000000000    0.125000
    1.0000000000    0.0000000000    0.0000000000    0.125000
    0.0000000000    1.0000000000    0.0000000000    0.125000
    1.0000000000    1.0000000000    0.0000000000    0.125000
    0.0000000000    0.0000000000    1.0000000000    0.125000
    1.0000000000    0.0000000000    1.0000000000    0.125000
    0.0000000000    1.0000000000    1.0000000000    0.125000
    1.0000000000    1.0000000000    1.0000000000    0.125000
{% endraw %} {% raw %}

order[source]

order(points, loop=True)

  • Returns indices of counterclockwise ordered vertices of a plane in 3D.
  • Parameters
    • points: numpy array of shape (N,3) or List[List(len=3)].
    • loop : Default is True and appends start point at end to make a loop.
  • Example

    pts = np.array([[1,0,3],[0,0,0],[0,1,2]]) inds = order(pts) pts[inds]

      array([[1, 2, 3],
             [0, 0, 0],
             [1, 0, 3]
             [0, 1, 2]])
{% endraw %} {% raw %}

rotation[source]

rotation(angle_deg, axis_vec)

Get a scipy Rotation object at given angle_deg around axis_vec. Usage: rot = rotation(60,[0,0,1]) rot.apply([1,1,1]) [-0.3660254 1.3660254 1.] #give this

{% endraw %} {% raw %}
{% endraw %} {% raw %}
import numpy as np
print("Interier Angle:",_rad_angle([0,0.1,0],[0,0.5,1]))
print("Angle with x-axis:",_tan_inv(1,0))
pts = np.array([[1,0,3],[0,0,0],[0,1,2]])
inds = order(pts)
pts[inds]
Interier Angle: 1.1071487177940433
Angle with x-axis: 1.5707963267948966
array([[0, 1, 2],
       [0, 0, 0],
       [1, 0, 3],
       [0, 1, 2]])
{% endraw %} {% raw %}

get_bz[source]

get_bz(path_pos=None, loop=True, digits=8, primitive=False)

  • Return required information to construct first Brillouin zone in form of tuple (basis, normals, vertices, faces).
  • Parameters
    • path_pos : POSCAR file path or list of 3 vectors in 3D aslist[list,list,list].
    • loop : If True, joins the last vertex of a BZ plane to starting vertex in order to complete loop.
    • digits : int, rounding off decimal places, no effect on intermediate calculations, just for pretty final results.
    • primitive: Defualt is False and returns Wigner-Seitz cell, If True returns parallelipiped in rec_basis.
  • Attributes
    • basis : get_bz().basis, recprocal lattice basis.
    • normals : get_bz().normals, all vertors that are perpendicular BZ faces/planes.
    • vertices: get_bz().vertices, all vertices of BZ, could be input into ConvexHull for constructing 3D BZ.
    • faces : get_bz().faces, vertices arranged into faces, could be input to Poly3DCollection of matplotlib for creating BZ from faces' patches.
    • specials : get_bz().specials, Data with attributes coords,kpoints and near in on-one correspondence for high symmetry KPOINTS in recirprocal coordinates space. near gives indices of nearest special points around a vertex. All vertices with z > 0 are included.
{% endraw %} {% raw %}
{% endraw %} {% raw %}
import numpy as np
bbya = 1.2
cbya = 0.8
ofco = [[1,bbya,0],[-1,bbya,0],[0,0,cbya]]
bco = [[1,bbya,cbya],[-1,bbya,cbya],[-1,-bbya,cbya]]
fco = [[1,0,cbya],[1,bbya,0],[0,bbya,cbya]]
bcc = [[1,1,1],[-1,1,1],[-1,-1,1]]
cube = [[1,0,0],[0,1,0],[0,0,1]]
hexa = [[1,0,0],[0.5,np.sqrt(3)/2,0],[0,0,1]]

ctg = [[1,1,cbya],[1,-1,cbya],[-1,-1,cbya]]
tgl = [[0.81915,-0.472937,0.94923],[0,0.94587,0.94923],[-0.81915,-0.472937,0.94923]]
fcc =[[0.0000000000000000,    0.5020149905223673,    0.5020149905223673],
    [0.5020149905223673,    0.0000000000000000,    0.5020149905223673],
     [0.5020149905223673,    0.5020149905223673,    0.0000000000000000]]

basis,normals,vertices,faces,specials = get_bz(fcc,digits=4)
print(basis)
for k,v in zip(specials.coords[:10],specials.kpoints[:10]):
    print(v,'-->',k)
[[-0.99598619  0.99598619  0.99598619]
 [ 0.99598619 -0.99598619  0.99598619]
 [ 0.99598619  0.99598619 -0.99598619]]
[-0.  0.  0.] --> [0. 0. 0.]
[-0.  -0.5 -0.5] --> [-0.996  0.     0.   ]
[-0.5 -0.5 -0.5] --> [-0.498 -0.498 -0.498]
[-0.  -0.5  0. ] --> [-0.498  0.498 -0.498]
[-0.   0.  -0.5] --> [-0.498 -0.498  0.498]
[0.5 0.  0. ] --> [-0.498  0.498  0.498]
[-0.5 -0.5  0. ] --> [ 0.     0.    -0.996]
[-0.5  0.  -0.5] --> [ 0.    -0.996  0.   ]
[-0.   0.5  0.5] --> [0.996 0.    0.   ]
[0.  0.5 0. ] --> [ 0.498 -0.498  0.498]
{% endraw %} {% raw %}

splot_bz[source]

splot_bz(path_pos_bz=None, ax=None, plane=None, color='blue', fill=True, vectors=True, v3=False, vname='b', colormap='plasma', light_from=(1, 1, 1), alpha=0.4)

  • Plots matplotlib's static figure.
  • Parameters
    • path_pos_bz: Path/to/POSCAR or List of 3 basis vectors or output of get_zb. Auto picks POSCAR from current directory.
    • fill : True by defult, determines whether to fill surface of BZ or not.
    • color : color to fill surface and stroke color.
    • vectors : Plots basis vectors, default is True.
    • v3 : Plots 3rd vector as well. Only works in 2D and when vectors=True.
    • plane : Default is None and plots 3D surface. Can take 'xy','yz','zx' to plot in 2D.
    • ax : Auto generated by default, 2D/3D axes, auto converts in 3D on demand as well.
    • vname : Default is b for reciprocal space, can set a for plotting cell as after get_bz(get_bz().basis) you get real space lattice back if primitive=True both times.
    • colormap : If None, single color is applied, only works in 3D and fill=True. Colormap is applied along z.
    • light_from: Point from where light is thrown on BZ planes, default is (1,1,1). Only works on plane in 3D.
    • alpha : Opacity of filling in range [0,1]. Increase for clear viewpoint.
  • Returns
    • ax : Matplotlib's 2D axes if plane=None.
    • ax3d : Matplotlib's 2D axes if plane is given.

Tip: splot_bz(rec_basis,primitive=True) will plot cell in real space.

{% endraw %} {% raw %}
{% endraw %} {% raw %}
import pivotpy.s_plots as sp
lat = hexa
bz = get_bz(lat,primitive=False,loop=True)
axs = sp.get_axes(ncols=4,figsize=(9,2))
ax2d = splot_bz(bz,plane='xy',ax=axs[0],vectors=True,color=(0.7,0,0.5))
ax3d = splot_bz(bz,ax=axs[1],color=(108/255,204/255,215/255,0),vectors=True,light_from=(10,10,30),alpha=0.5,colormap=None)
prim_bz = get_bz(lat,primitive=True)
ax3d_ = splot_bz(prim_bz,ax=axs[2],color=(212/255,175/255,55/255,0),vectors=True)
_ax3d = splot_bz(get_bz(prim_bz.basis,primitive=True),ax=axs[3],color=(212/255,175/255,55/255,0),vectors=True,vname='a',colormap='turbo_r',light_from=(0,1,1))
ps = bz.specials.coords[bz.specials.near[4]][[0,1,8,2,5,4]]
ax3d.scatter(ps[:,0],ps[:,1],ps[:,2],c='r',s=20)
ax2d.scatter(ps[:,0],ps[:,1],c='r',s=20)

ax3d.set_axis_off()
ax3d.set_title('Regular BZ')
ax3d_.set_axis_off()
ax3d_.set_title('Primitive BZ')
ax2d.set_axis_off()
_ax3d.set_title('Real lattice')
_ax3d.set_axis_off()
ax2d.set_title('XY Projection of Regular BZ')
sp.plt2html()
2022-04-24T13:55:13.128380 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
<Figure size 648x144 with 0 Axes>
{% endraw %} {% raw %}

iplot_bz[source]

iplot_bz(path_pos_bz=None, fill=True, color='rgba(168,204,216,0.4)', background='rgb(255,255,255)', vname='b', alpha=0.4, ortho3d=True, fig=None)

  • Plots interactive figure showing axes,BZ surface, special points and basis, each of which could be hidden or shown.
  • Parameters
    • path_pos_bz: Path/to/POSCAR or List of 3 basis vectors or output of get_zb. Auto picks POSCAR from current directory.
    • fill : True by defult, determines whether to fill surface of BZ or not.
    • color : color to fill surface 'rgba(168,204,216,0.4)` by default.
    • background : Plot background color, default is 'rgb(255,255,255)'.
    • vname : Default is b for reciprocal space, can set a for plotting cell as after get_bz(get_bz().basis) you get real space lattice back if primitive=True both times.
    • alpha : Opacity of BZ planes.
    • ortho3d : Default is True, decides whether x,y,z are orthogonal or perspective.
    • fig : (Optional) Plotly's go.Figure. If you want to plot on another plotly's figure, provide that.
  • Returns
    • fig : plotly.graph_object's Figure instance.

Tip: iplot_bz(rec_basis,primitive=True) will plot cell in real space.

{% endraw %} {% raw %}
{% endraw %}
  • Below is a BZ plot using command iplot_bz(). Same color points lie on a sphere, with radius decreasing as red to blue and gamma point in gold color. These color help distinguishing points but the points not always be equivalent, for example in FCC, there are two points on mid of edges connecting square-hexagon and hexagon-hexagon at equal distance from center but not the same points. {% include note.html content='iplot_bz includes special points only if vname = b, i.e. in recirpocal space. ' %}
{% raw %}
import pivotpy as pp
fig = iplot_bz([[1,0,1],[1,1,0],[0,1,1]],alpha=1)
pp.iplot2html(fig,modebar=False)
{% endraw %} {% raw %}

to_R3[source]

to_R3(basis, points)

Transforms coordinates of points (relative to non-othogonal basis) into orthogonal space.

  • Parameters
    • basis : Non-orthogonal basis of real or reciprocal space.
    • points: 3D points relative to basis, such as KPOINTS and Lattice Points.
{% endraw %} {% raw %}
{% endraw %} {% raw %}
to_R3(_get_basis(hexa).inverted,[[1,1,1],[0.333,0.333,0.5]])
array([[1.        , 0.57735027, 1.        ],
       [0.333     , 0.19225764, 0.5       ]])
{% endraw %} {% raw %}

kpoints2bz[source]

kpoints2bz(bz, kpoints, primitive=False)

Brings KPOINTS inside BZ. Applies to_R3 only if primitive=True.

  • Parameters
    • bz : Output of get_bz(), make sure use same value of primitive there and here.
    • kpoints : List or array of KPOINTS to transorm into BZ or R3.
    • primitive: Default is False and brings kpoints into regular BZ. If True, returns to_R3().
{% endraw %} {% raw %}
{% endraw %} {% raw %}
import pivotpy as pp, numpy as np

kpoints = get_kmesh(2)
fig = iplot_bz(get_bz(hexa))
prim_bz = get_bz(hexa,primitive=True)
iplot_bz(get_bz(prim_bz.basis,primitive=True),vname='a',fig=fig,color="rgba(200,220,10,0.4)")
pp.iplot2html(fig,modebar=False)
Automatically generated uniform mesh using PivotPy with 2x2x2 grid
	8
Reciprocal Lattice
    0.0000000000    0.0000000000    0.0000000000    0.125000
    1.0000000000    0.0000000000    0.0000000000    0.125000
    0.0000000000    1.0000000000    0.0000000000    0.125000
    1.0000000000    1.0000000000    0.0000000000    0.125000
    0.0000000000    0.0000000000    1.0000000000    0.125000
    1.0000000000    0.0000000000    1.0000000000    0.125000
    0.0000000000    1.0000000000    1.0000000000    0.125000
    1.0000000000    1.0000000000    1.0000000000    0.125000
{% endraw %}

Example: Showing Energy as Color on BZ

In below figure, left side of colorbar is tricontourf and right side is scatter plot with color based on energy value of VBM.

{% raw %}
import matplotlib.pyplot as plt , pivotpy as pp
import matplotlib.tri as tri
axs = pp.get_axes(ncols=5,figsize=(9,2.3),widths=[5,5,0.2,5,5])
evr = pp.Vasprun('../graphene_example/ISPIN_1/dos/vasprun.xml').data

kpoints = np.concatenate([evr.kpoints, -evr.kpoints]) # negative side
bz1 = get_bz(evr.poscar.basis,primitive=True)
bz2 = get_bz(evr.poscar.basis,primitive=False)
out1 = kpoints2bz(bz1,kpoints,primitive=True) + 0.002 #Just fun translate
out2 = kpoints2bz(bz2,kpoints,primitive=False)
splot_bz(bz1,plane='xy',ax = axs[0],color=(1,1,1,0)).set_axis_off()
splot_bz(bz2,plane='xy',ax = axs[1]).set_axis_off()
splot_bz(bz1,plane='xy',ax = axs[3]).set_axis_off()
splot_bz(bz2,plane='xy',ax = axs[4]).set_axis_off()

# Energy as color on BZ. 
en = evr.bands.evals[:,8].ravel()
en = np.concatenate([en,en])
s_en = (en-np.min(en))/(np.max(en)-np.min(en)) # bring to range [0,1] for colors
c = plt.cm.get_cmap('plasma')(s_en)
labels = [str(l) + ' eV' for l in np.round(np.min(en)+(np.max(en)-np.min(en))*np.array([1/6,3/5,5/6]),2)]
tri1 = tri.Triangulation(out1.T[0], out1.T[1])
tri2 = tri.Triangulation(out2.T[0], out2.T[1])
axs[0].tricontourf(tri1, en, levels=np.linspace(-2.6, 3.4, 8), cmap='plasma',shading='nearest')
axs[1].tricontour(tri2, en, levels=np.linspace(-2.6, 3.4, 8), cmap='plasma',linewidths=[0.8])
axs[3].scatter(out1[:,0],out1[:,1],s=4,c=c)
axs[4].scatter(out2[:,0],out2[:,1],s=4,c=c)

axs[2].add_colorbar(cmap_or_clist='plasma', ticklabels=labels,vertical=True)
c:\users\mass_\appdata\local\programs\python\python37\lib\site-packages\ipykernel_launcher.py:24: UserWarning:

The following kwargs were not used by contour: 'shading'

<matplotlib.axes._axes.Axes at 0x16ed5b7b048>
2022-04-24T13:55:17.194456 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
{% endraw %} {% raw %}

fix_sites[source]

fix_sites(poscar, tol=0.01, eqv_sites=True, translate=None)

Add equivalent sites to make a full data shape of lattice. Returns same data after fixing.

  • Parameters
    • poscar: Output of export_poscar or export_vasprun().poscar.
    • tol : Tolerance value. Default is 0.01.
    • eqv_sites: If True, add sites on edges and faces. If False, just fix coordinates, i.e. pos > 1 - tol -> pos - 1, useful for merging poscars to make slabs.
    • translate: A number(+/-) or list of three numbers to translate in x,y,z directions.
{% endraw %} {% raw %}

get_pairs[source]

get_pairs(basis, positions, r, eps=0.01)

Returns a tuple of Lattice (coords,pairs), so coords[pairs] given nearest site bonds.

  • Parameters
    • basis: Real space lattice basis.
    • positions: Array(N,3) of fractional positions of lattice sites. If coordinates positions, provide unity basis.
    • r : Cartesian distance between the pairs in units of Angstrom e.g. 1.2 -> 1.2E-10.
    • eps : Tolerance value. Default is 10^-2.
{% endraw %} {% raw %}
{% endraw %}

Lattice Plotting

{% raw %}

iplot_lat[source]

iplot_lat(poscar, sizes=10, colors='blue', bond_length=None, tol=0.1, eps=0.01, eqv_sites=True, translate=None, line_width=4, edge_color='black', fill=False, alpha=0.4, ortho3d=True, fig=None)

Interactive plot of lattice.

  • Main Parameters
    • poscar : Output of export_poscar or export_vasprun().poscar.
    • sizes : Size of sites. Either one int/float or list equal to type of ions.
    • colors : Colors of sites. Either one colors or list equal to type of ions.
    • bond_length: Length of bond in fractional unit [0,1]. It is scaled to V^1/3 and auto calculated if not provides. Other parameters just mean what they seem to be.
{% endraw %} {% raw %}
{% endraw %} {% raw %}
import pivotpy as pp
fig=iplot_lat(evr.poscar,sizes=10,colors=['blue','red','green'],line_width=4,fill=False)
pp.iplot2html(fig,modebar=False)
{% endraw %} {% raw %}

splot_lat[source]

splot_lat(poscar, sizes=50, colors=[], colormap=None, bond_length=None, tol=0.1, eps=0.01, eqv_sites=True, translate=None, line_width=1, edge_color=(1, 0.5, 0, 0.4), vectors=True, v3=False, plane=None, light_from=(1, 1, 1), fill=False, alpha=0.4, ax=None)

Static plot of lattice.

  • Main Parameters
    • poscar : Output of export_poscar or export_vasprun().poscar.
    • sizes : Size of sites. Either one int/float or list equal to type of ions.
    • bond_length: Length of bond in fractional unit [0,1]. It is scaled to V^1/3 and auto calculated if not provides.
    • colors: List of colos. If given, preffered over colormap, should have same length as type of ions. Other parameters just mean what they seem to be.

Tip: Use plt.style.use('ggplot') for better 3D perception.

{% endraw %} {% raw %}
{% endraw %} {% raw %}
plt.style.use('ggplot')
axs = pp.get_axes((6,6),ncols=2,axes_3d=[0,])
splot_lat(evr.poscar,sizes=40,plane=None,fill=True,tol=1,alpha=0.4,light_from=(1,-0.1,0),vectors=False,ax=axs[0],edge_color=(0.5,0.5,0,0.4))
splot_lat(evr.poscar,sizes=40,plane='xy',fill=True,tol=1,alpha=0.4,light_from=(1,-0.1,0),vectors=False,ax=axs[1],colors=['red'],translate=[-2/3,-1/3,0]).set_axis_on()
axs[0].view_init(70,75)
2022-04-24T13:55:18.133007 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
{% endraw %}

Joining Multiple POSCARS

This is useful to create slabs for interface calculations or even to make supercell in a straightforward way.

{% raw %}

join_poscars[source]

join_poscars(poscar1, poscar2, direction='z', tol=0.01)

Joins two POSCARs in a given direction. In-plane lattice parameters are kept from poscar1 and basis of poscar2 parallel to direction is modified while volume is kept same.

  • Parameters
    • poscar1, poscar2: Base and secondary POSCARs respectivly. Output of export_poscar or similar object from other functions.
    • direction: The joining direction. It is general and can join in any direction along basis. Expect one of ['a','b','c','x','y','z'].
    • tol: Default is 0.01. It is used to bring sites near 1 to near zero in order to complete sites in plane. Vasp relaxation could move a point, say at 0.00100 to 0.99800 which is not useful while merging sites.
{% endraw %} {% raw %}
{% endraw %} {% raw %}

write_poscar[source]

write_poscar(poscar, sd_list=None, outfile=None, overwrite=False)

Writes poscar data object to a file or returns string

  • Parameters
    • poscar : Output of export_poscar,join_poscars etc.
    • sd_list : A list ['T T T','F F F',...] strings to turn on selective dynamics at required sites. len(sd_list)==len(sites) should hold.
    • outfile : str,file path to write on.
    • overwrite: bool, if file already exists, overwrite=True changes it.
{% endraw %} {% raw %}
{% endraw %} {% raw %}
print(write_poscar(evr.poscar))
print("===================================================")
write_poscar(evr.poscar,sd_list=['T T T','F F F'],outfile='POSCAR')
print("===================================================")
print(write_poscar(evr.poscar,sd_list=['T T T','F F F']))
C2  # Created by Pivotpy
  2.46803100000000    
    1.0000000000000000    0.0000000000000000    0.0000000000000000
   -0.4999997974093519    0.8660251836382931    0.0000000000000000
    0.0000000000000000    0.0000000000000000    8.1029342824300024
  C
  2
Direct
   0.3333330000000000   0.6666670000000000   0.0000000000000000
   0.6666670000000000   0.3333330000000000   0.0000000000000000
===================================================
'POSCAR' exists, can not overwrite, 
use overwrite=True if you want to chnage.
===================================================
C2  # Created by Pivotpy
  2.46803100000000    
    1.0000000000000000    0.0000000000000000    0.0000000000000000
   -0.4999997974093519    0.8660251836382931    0.0000000000000000
    0.0000000000000000    0.0000000000000000    8.1029342824300024
  C
  2
Selective Dynamics
Direct
   0.3333330000000000   0.6666670000000000   0.0000000000000000   T T T
   0.6666670000000000   0.3333330000000000   0.0000000000000000   F F F
{% endraw %} {% raw %}

scale_poscar[source]

scale_poscar(path_poscar, scale=(1, 1, 1), tol=0.01)

Create larger/smaller cell from a given POSCAR.

  • Parameters
    • path_poscar: Path/to/POSCAR or poscar data object.
    • scale: Tuple of three values along (a,b,c) vectors. int or float values. If number of sites are not as expected in output, tweak tol instead of scale. You can put a minus sign with tol to get more sites and plus sign to reduce sites.
    • tol: It is used such that site positions are blow 1 - tol, as 1 belongs to next cell, not previous one.

      Tip: scale = (2,2,2) enlarges a cell and next operation of (1/2,1/2,1/2) should bring original cell back.

{% endraw %} {% raw %}

rotate_poscar[source]

rotate_poscar(path_poscar, angle_deg, axis_vec)

Rotate a given POSCAR.

  • Parameters
    • path_poscar: Path/to/POSCAR or poscar data object.
    • angle_deg: Rotation angle in degrees.
    • axis_vec : (x,y,z) of axis about which rotation takes place. Axis passes through origin.
{% endraw %} {% raw %}
{% endraw %} {% raw %}
import pivotpy as pp 
import numpy as np
import pivotpy.vr_parser as vp
poscar = pp.POSCAR('POSCAR')
ax = poscar.splot_lat(plane='xy',colormap='RGB',sizes=100,line_width=5)
scaled = poscar.scale(scale=[3,3,3])
scaled.splot_lat(ax=ax,plane='xy',bond_length=0.1,tol=1e-5,line_width=2)
scaled.scale(scale=[1/3,1/3,1/3],tol=1e-3).splot_lat(ax=ax,plane='xy',colormap='viridis_r',sizes=15,line_width=0.5)
<AxesSubplot:xlabel='x', ylabel='y'>
2022-04-24T13:55:18.836818 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
{% endraw %} {% raw %}

  Index 
  XmlElementTree 
  StaticPlots 
  InteractivePlots 
  Utilities 
  StructureIO● 
  Widgets 
  MainAPI 

{% endraw %}