bandu 1.3.6__py3-none-any.whl → 1.3.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bandu/abinit_reader.py +1094 -1094
- bandu/bandu.py +320 -313
- bandu/brillouin_zone.py +185 -185
- bandu/colors.py +46 -46
- bandu/isosurface_class.py +235 -235
- bandu/plotter.py +599 -599
- bandu/translate.py +37 -37
- bandu/wfk_class.py +557 -556
- bandu/xsf_reader.py +91 -91
- {bandu-1.3.6.dist-info → bandu-1.3.7.dist-info}/METADATA +192 -192
- bandu-1.3.7.dist-info/RECORD +14 -0
- {bandu-1.3.6.dist-info → bandu-1.3.7.dist-info}/WHEEL +1 -1
- {bandu-1.3.6.dist-info → bandu-1.3.7.dist-info}/licenses/LICENSE +21 -21
- bandu-1.3.6.dist-info/RECORD +0 -14
- {bandu-1.3.6.dist-info → bandu-1.3.7.dist-info}/top_level.txt +0 -0
bandu/isosurface_class.py
CHANGED
|
@@ -1,236 +1,236 @@
|
|
|
1
|
-
import pyvista as pv
|
|
2
|
-
import numpy as np
|
|
3
|
-
from . import translate as trnslt
|
|
4
|
-
from . import abinit_reader as ar
|
|
5
|
-
from . import wfk_class as wc
|
|
6
|
-
from . import brillouin_zone as brlzn
|
|
7
|
-
|
|
8
|
-
# object for creating reciprocal space energy isosurfaces
|
|
9
|
-
class Isosurface():
|
|
10
|
-
'''
|
|
11
|
-
Class for constructing contours from WFK eigenvalues
|
|
12
|
-
|
|
13
|
-
Parameters
|
|
14
|
-
----------
|
|
15
|
-
points : np.ndarray
|
|
16
|
-
Array of reciprocal space points to construct contour over
|
|
17
|
-
Shape (N,3)
|
|
18
|
-
values : np.ndarray
|
|
19
|
-
Array of eigenvalues for each reciprocal space point
|
|
20
|
-
Shape (N,1) or (N,#Bands)
|
|
21
|
-
nbands : list[int]
|
|
22
|
-
List of bands to create contours for, aka indices of bands that cross energy isosurface
|
|
23
|
-
rec_latt : np.ndarray
|
|
24
|
-
Reciprocal lattice vectors
|
|
25
|
-
wfk_name : str
|
|
26
|
-
If points and values arrays are not provided, then construct contours from reading in an ABINIT WFK file
|
|
27
|
-
Path to wfk file
|
|
28
|
-
grid_steps : tuple
|
|
29
|
-
Set fineness of grid that contours are interpolated on
|
|
30
|
-
Default (50,50,50)
|
|
31
|
-
fermi_energy : float
|
|
32
|
-
Fermi energy
|
|
33
|
-
Default 0.0
|
|
34
|
-
energy_level : float
|
|
35
|
-
Sets energy isosurface relative to the Fermi energy
|
|
36
|
-
Default 0.0 (this samples the Fermi energy)
|
|
37
|
-
width : float
|
|
38
|
-
Sets the range above and below the energy_level that eigenvalues are sampled from
|
|
39
|
-
Default 0.005 (Assumes units of Hartree)
|
|
40
|
-
radius : float
|
|
41
|
-
Radius of gaussian interpolation
|
|
42
|
-
Default 0.05, this scales inversely with kpoint grid size (larger grids require smaller radius)
|
|
43
|
-
sym_ops : np.ndarray
|
|
44
|
-
Array of symmetry operations for generating points in Brillouin Zone
|
|
45
|
-
grid_stretch : float
|
|
46
|
-
Value that stretches grid that is used to interpolate bands
|
|
47
|
-
If portions of Brillouin Zone are cropped off, increase this value
|
|
48
|
-
Default is 0.15
|
|
49
|
-
|
|
50
|
-
Methods
|
|
51
|
-
-------
|
|
52
|
-
Contour
|
|
53
|
-
Generates energy isosurface contours
|
|
54
|
-
'''
|
|
55
|
-
def __init__(
|
|
56
|
-
self, points:np.ndarray=np.zeros(1), values:np.ndarray=np.zeros(1), rec_latt:np.ndarray=np.zeros(1),
|
|
57
|
-
wfk_name:str='', grid_steps:tuple=(50,50,50), fermi_energy:float=0.0, energy_level:float=0.0,
|
|
58
|
-
width:float=0.005, radius:float=0.05, nbands:list[int]=[], sym_ops:np.ndarray=np.zeros(1),
|
|
59
|
-
grid_stretch:float=0.15
|
|
60
|
-
)->None:
|
|
61
|
-
# define attributes
|
|
62
|
-
self.points=points
|
|
63
|
-
self.values=values
|
|
64
|
-
self.wfk_name=wfk_name
|
|
65
|
-
self.rec_latt=rec_latt
|
|
66
|
-
self.fermi_energy=fermi_energy
|
|
67
|
-
self.energy_level=energy_level
|
|
68
|
-
self.width=width
|
|
69
|
-
self.radius=radius
|
|
70
|
-
self.nbands=nbands
|
|
71
|
-
self.sym_ops=sym_ops
|
|
72
|
-
self.grid_stretch=grid_stretch
|
|
73
|
-
# check if enough information is provided to class to construct isosurfaces
|
|
74
|
-
if self.points.shape == (1,) and self.values.shape == (1,):
|
|
75
|
-
if wfk_name == '':
|
|
76
|
-
raise ValueError((
|
|
77
|
-
'Either the points and the values attributes must be defined or the wfk_name attribute '
|
|
78
|
-
'must be defined'
|
|
79
|
-
))
|
|
80
|
-
else:
|
|
81
|
-
self.points, self.values, self.nbands, self.ir_kpts = self._ReadAbinit(wfk_name)
|
|
82
|
-
# check if information provided is in correct format
|
|
83
|
-
if len(self.values.shape) > 2:
|
|
84
|
-
raise ValueError((
|
|
85
|
-
f'Provided values have dimension {len(self.values.shape)}'
|
|
86
|
-
'Values must be 1 or 2 dimensional'
|
|
87
|
-
))
|
|
88
|
-
else:
|
|
89
|
-
self._valdim=len(self.values.shape)
|
|
90
|
-
# more attributes, these rely on points and values attributes
|
|
91
|
-
self.contours:list[pv.PolyData] = []
|
|
92
|
-
self.grid_steps=grid_steps
|
|
93
|
-
self.grid = self._MakeGrid()
|
|
94
|
-
#---------------------------------------------------------------------------------------------------------------------#
|
|
95
|
-
#------------------------------------------------------ METHODS ------------------------------------------------------#
|
|
96
|
-
#---------------------------------------------------------------------------------------------------------------------#
|
|
97
|
-
# method for creating grid to interplote on
|
|
98
|
-
def _MakeGrid(
|
|
99
|
-
self
|
|
100
|
-
)->pv.ImageData:
|
|
101
|
-
'''
|
|
102
|
-
Method for constructing PyVista grid used in interpolation prior to plotting
|
|
103
|
-
*This method assumes your points are in Cartesian format*
|
|
104
|
-
|
|
105
|
-
Parameters
|
|
106
|
-
----------
|
|
107
|
-
points : np.ndarry
|
|
108
|
-
Numpy array with shape (N, 3) where N is number of points\n
|
|
109
|
-
These are the points that lie within your energy range, generally from GetValAndKpt method\n
|
|
110
|
-
These are NOT the points of the grid
|
|
111
|
-
steps : tuple
|
|
112
|
-
Define the number of grid points along (x,y,z)\n
|
|
113
|
-
Default is 50 points along each axis\n
|
|
114
|
-
Spacing of grid is automatically calculated from steps and points
|
|
115
|
-
'''
|
|
116
|
-
# helper functions for finding grid origin and setting grid spacing
|
|
117
|
-
def _GetMax(pts:np.ndarray):
|
|
118
|
-
xmax = pts[:,0].max()
|
|
119
|
-
ymax = pts[:,1].max()
|
|
120
|
-
zmax = pts[:,2].max()
|
|
121
|
-
return xmax, ymax, zmax
|
|
122
|
-
def _GetMin(pts:np.ndarray):
|
|
123
|
-
xmin = pts[:,0].min()
|
|
124
|
-
ymin = pts[:,1].min()
|
|
125
|
-
zmin = pts[:,2].min()
|
|
126
|
-
return xmin, ymin, zmin
|
|
127
|
-
# begin method for making grid
|
|
128
|
-
xmax, ymax, zmax = _GetMax(self.points)
|
|
129
|
-
xmin, ymin, zmin = _GetMin(self.points)
|
|
130
|
-
dimx = self.grid_steps[0]
|
|
131
|
-
dimy = self.grid_steps[1]
|
|
132
|
-
dimz = self.grid_steps[2]
|
|
133
|
-
grid = pv.ImageData()
|
|
134
|
-
stretch_factor = self.grid_stretch
|
|
135
|
-
dim_stretch = [2*stretch_factor/dim for dim in self.grid_steps]
|
|
136
|
-
grid.origin = (
|
|
137
|
-
xmin - 0.5*stretch_factor,
|
|
138
|
-
ymin - 0.5*stretch_factor,
|
|
139
|
-
zmin - 0.5*stretch_factor
|
|
140
|
-
)
|
|
141
|
-
grid.spacing = (
|
|
142
|
-
2*xmax/dimx + dim_stretch[0],
|
|
143
|
-
2*ymax/dimy + dim_stretch[1],
|
|
144
|
-
2*zmax/dimz + dim_stretch[2]
|
|
145
|
-
)
|
|
146
|
-
grid.dimensions = (dimx, dimy, dimz)
|
|
147
|
-
return grid
|
|
148
|
-
#-----------------------------------------------------------------------------------------------------------------#
|
|
149
|
-
# method for selecting which contour to perform depending on if a single band or many bands are passed
|
|
150
|
-
def Contour(
|
|
151
|
-
self
|
|
152
|
-
):
|
|
153
|
-
if self._valdim == 1:
|
|
154
|
-
self._Contour(points=self.points, values=self.values)
|
|
155
|
-
else:
|
|
156
|
-
for band in self.values.T:
|
|
157
|
-
self._Contour(points=self.points, values=band)
|
|
158
|
-
#-----------------------------------------------------------------------------------------------------------------#
|
|
159
|
-
# method for drawing contour from list of values
|
|
160
|
-
def _Contour(
|
|
161
|
-
self, points:np.ndarray, values:np.ndarray
|
|
162
|
-
):
|
|
163
|
-
# setup grid interpolation
|
|
164
|
-
null_value = self.fermi_energy + self.energy_level + self.width/2 * 1.05
|
|
165
|
-
trans_pts, trans_vals = trnslt.TranslatePoints(
|
|
166
|
-
points=points,
|
|
167
|
-
values=values.reshape((values.shape[0],1)),
|
|
168
|
-
lattice_vecs=self.rec_latt
|
|
169
|
-
)
|
|
170
|
-
trans_pts = pv.PolyData(trans_pts)
|
|
171
|
-
trans_pts['values'] = trans_vals
|
|
172
|
-
inter_grid:pv.ImageData = self.grid.interpolate(
|
|
173
|
-
trans_pts,
|
|
174
|
-
radius=self.radius,
|
|
175
|
-
sharpness=2.0,
|
|
176
|
-
strategy='null_value',
|
|
177
|
-
null_value=null_value
|
|
178
|
-
)
|
|
179
|
-
# create contour
|
|
180
|
-
iso_range = [self.fermi_energy + self.energy_level, self.fermi_energy + self.energy_level]
|
|
181
|
-
contour:pv.PolyData = inter_grid.contour(
|
|
182
|
-
isosurfaces=2,
|
|
183
|
-
rng=iso_range,
|
|
184
|
-
method='contour'
|
|
185
|
-
)
|
|
186
|
-
self.contours.append(contour)
|
|
187
|
-
#-----------------------------------------------------------------------------------------------------------------#
|
|
188
|
-
# method for reading kpoints and eigenvalues from ABINIT WFK file
|
|
189
|
-
def _ReadAbinit(
|
|
190
|
-
self, filename:str
|
|
191
|
-
)->tuple[np.ndarray,np.ndarray, list, np.ndarray]:
|
|
192
|
-
# collect kpoints and eigenvalues from wfk file
|
|
193
|
-
wfk = ar.AbinitWFK(filename=filename)
|
|
194
|
-
eigs = []
|
|
195
|
-
syms = np.array(wfk.symrel)
|
|
196
|
-
nsym = wfk.nsym
|
|
197
|
-
kpoints = np.array(wfk.kpts)
|
|
198
|
-
ir_kpts = kpoints
|
|
199
|
-
nbands = wfk.bands[0]
|
|
200
|
-
nkpt = wfk.nkpt
|
|
201
|
-
self.fermi_energy = wfk.fermi
|
|
202
|
-
self.rec_latt = wc.WFK(lattice=wfk.real_lattice).
|
|
203
|
-
for wfk_obj in wfk.ReadEigenvalues():
|
|
204
|
-
eigs.append(wfk_obj.eigenvalues)
|
|
205
|
-
eigs = np.array(eigs).reshape((nkpt,nbands))
|
|
206
|
-
# look through eigenvalues to find which bands to contour
|
|
207
|
-
min_val = self.fermi_energy + self.energy_level - self.width/2
|
|
208
|
-
max_val = self.fermi_energy + self.energy_level + self.width/2
|
|
209
|
-
band_num = []
|
|
210
|
-
for i in range(nbands):
|
|
211
|
-
for eigval in eigs[:,i]:
|
|
212
|
-
if min_val <= eigval <= max_val:
|
|
213
|
-
band_num.append(i)
|
|
214
|
-
break
|
|
215
|
-
# return kpoints and bands of interest
|
|
216
|
-
bands = np.take(eigs, band_num, axis=1)
|
|
217
|
-
shifts = brlzn.BZ(self.rec_latt).GetShifts(kpoints)
|
|
218
|
-
kpoints = kpoints - shifts
|
|
219
|
-
ir_kpts -= shifts
|
|
220
|
-
ir_kpts = np.matmul(ir_kpts,self.rec_latt)
|
|
221
|
-
wfk = wc.WFK(symrel=syms, nsym=nsym, nbands=len(band_num), nkpt=nkpt)
|
|
222
|
-
all_kpts = np.zeros((1,3))
|
|
223
|
-
all_eigs = np.zeros((1,bands.shape[1]))
|
|
224
|
-
# symmetrize kpoints
|
|
225
|
-
for i, kpt in enumerate(kpoints):
|
|
226
|
-
unique_kpts, _ = wfk.Symmetrize(
|
|
227
|
-
points=kpt,
|
|
228
|
-
reciprocal=True,
|
|
229
|
-
)
|
|
230
|
-
all_kpts = np.concatenate((all_kpts, unique_kpts), axis=0)
|
|
231
|
-
new_eigs = np.repeat(bands[i,:].reshape((1,-1)), unique_kpts.shape[0], axis=0)
|
|
232
|
-
all_eigs = np.concatenate((all_eigs, new_eigs), axis=0)
|
|
233
|
-
kpoints = np.delete(all_kpts, 0, axis=0)
|
|
234
|
-
bands = np.delete(all_eigs, 0, axis=0)
|
|
235
|
-
kpoints = np.matmul(kpoints, self.rec_latt)
|
|
1
|
+
import pyvista as pv
|
|
2
|
+
import numpy as np
|
|
3
|
+
from . import translate as trnslt
|
|
4
|
+
from . import abinit_reader as ar
|
|
5
|
+
from . import wfk_class as wc
|
|
6
|
+
from . import brillouin_zone as brlzn
|
|
7
|
+
|
|
8
|
+
# object for creating reciprocal space energy isosurfaces
|
|
9
|
+
class Isosurface():
|
|
10
|
+
'''
|
|
11
|
+
Class for constructing contours from WFK eigenvalues
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
points : np.ndarray
|
|
16
|
+
Array of reciprocal space points to construct contour over
|
|
17
|
+
Shape (N,3)
|
|
18
|
+
values : np.ndarray
|
|
19
|
+
Array of eigenvalues for each reciprocal space point
|
|
20
|
+
Shape (N,1) or (N,#Bands)
|
|
21
|
+
nbands : list[int]
|
|
22
|
+
List of bands to create contours for, aka indices of bands that cross energy isosurface
|
|
23
|
+
rec_latt : np.ndarray
|
|
24
|
+
Reciprocal lattice vectors
|
|
25
|
+
wfk_name : str
|
|
26
|
+
If points and values arrays are not provided, then construct contours from reading in an ABINIT WFK file
|
|
27
|
+
Path to wfk file
|
|
28
|
+
grid_steps : tuple
|
|
29
|
+
Set fineness of grid that contours are interpolated on
|
|
30
|
+
Default (50,50,50)
|
|
31
|
+
fermi_energy : float
|
|
32
|
+
Fermi energy
|
|
33
|
+
Default 0.0
|
|
34
|
+
energy_level : float
|
|
35
|
+
Sets energy isosurface relative to the Fermi energy
|
|
36
|
+
Default 0.0 (this samples the Fermi energy)
|
|
37
|
+
width : float
|
|
38
|
+
Sets the range above and below the energy_level that eigenvalues are sampled from
|
|
39
|
+
Default 0.005 (Assumes units of Hartree)
|
|
40
|
+
radius : float
|
|
41
|
+
Radius of gaussian interpolation
|
|
42
|
+
Default 0.05, this scales inversely with kpoint grid size (larger grids require smaller radius)
|
|
43
|
+
sym_ops : np.ndarray
|
|
44
|
+
Array of symmetry operations for generating points in Brillouin Zone
|
|
45
|
+
grid_stretch : float
|
|
46
|
+
Value that stretches grid that is used to interpolate bands
|
|
47
|
+
If portions of Brillouin Zone are cropped off, increase this value
|
|
48
|
+
Default is 0.15
|
|
49
|
+
|
|
50
|
+
Methods
|
|
51
|
+
-------
|
|
52
|
+
Contour
|
|
53
|
+
Generates energy isosurface contours
|
|
54
|
+
'''
|
|
55
|
+
def __init__(
|
|
56
|
+
self, points:np.ndarray=np.zeros(1), values:np.ndarray=np.zeros(1), rec_latt:np.ndarray=np.zeros(1),
|
|
57
|
+
wfk_name:str='', grid_steps:tuple=(50,50,50), fermi_energy:float=0.0, energy_level:float=0.0,
|
|
58
|
+
width:float=0.005, radius:float=0.05, nbands:list[int]=[], sym_ops:np.ndarray=np.zeros(1),
|
|
59
|
+
grid_stretch:float=0.15
|
|
60
|
+
)->None:
|
|
61
|
+
# define attributes
|
|
62
|
+
self.points=points
|
|
63
|
+
self.values=values
|
|
64
|
+
self.wfk_name=wfk_name
|
|
65
|
+
self.rec_latt=rec_latt
|
|
66
|
+
self.fermi_energy=fermi_energy
|
|
67
|
+
self.energy_level=energy_level
|
|
68
|
+
self.width=width
|
|
69
|
+
self.radius=radius
|
|
70
|
+
self.nbands=nbands
|
|
71
|
+
self.sym_ops=sym_ops
|
|
72
|
+
self.grid_stretch=grid_stretch
|
|
73
|
+
# check if enough information is provided to class to construct isosurfaces
|
|
74
|
+
if self.points.shape == (1,) and self.values.shape == (1,):
|
|
75
|
+
if wfk_name == '':
|
|
76
|
+
raise ValueError((
|
|
77
|
+
'Either the points and the values attributes must be defined or the wfk_name attribute '
|
|
78
|
+
'must be defined'
|
|
79
|
+
))
|
|
80
|
+
else:
|
|
81
|
+
self.points, self.values, self.nbands, self.ir_kpts = self._ReadAbinit(wfk_name)
|
|
82
|
+
# check if information provided is in correct format
|
|
83
|
+
if len(self.values.shape) > 2:
|
|
84
|
+
raise ValueError((
|
|
85
|
+
f'Provided values have dimension {len(self.values.shape)}'
|
|
86
|
+
'Values must be 1 or 2 dimensional'
|
|
87
|
+
))
|
|
88
|
+
else:
|
|
89
|
+
self._valdim=len(self.values.shape)
|
|
90
|
+
# more attributes, these rely on points and values attributes
|
|
91
|
+
self.contours:list[pv.PolyData] = []
|
|
92
|
+
self.grid_steps=grid_steps
|
|
93
|
+
self.grid = self._MakeGrid()
|
|
94
|
+
#---------------------------------------------------------------------------------------------------------------------#
|
|
95
|
+
#------------------------------------------------------ METHODS ------------------------------------------------------#
|
|
96
|
+
#---------------------------------------------------------------------------------------------------------------------#
|
|
97
|
+
# method for creating grid to interplote on
|
|
98
|
+
def _MakeGrid(
|
|
99
|
+
self
|
|
100
|
+
)->pv.ImageData:
|
|
101
|
+
'''
|
|
102
|
+
Method for constructing PyVista grid used in interpolation prior to plotting
|
|
103
|
+
*This method assumes your points are in Cartesian format*
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
points : np.ndarry
|
|
108
|
+
Numpy array with shape (N, 3) where N is number of points\n
|
|
109
|
+
These are the points that lie within your energy range, generally from GetValAndKpt method\n
|
|
110
|
+
These are NOT the points of the grid
|
|
111
|
+
steps : tuple
|
|
112
|
+
Define the number of grid points along (x,y,z)\n
|
|
113
|
+
Default is 50 points along each axis\n
|
|
114
|
+
Spacing of grid is automatically calculated from steps and points
|
|
115
|
+
'''
|
|
116
|
+
# helper functions for finding grid origin and setting grid spacing
|
|
117
|
+
def _GetMax(pts:np.ndarray):
|
|
118
|
+
xmax = pts[:,0].max()
|
|
119
|
+
ymax = pts[:,1].max()
|
|
120
|
+
zmax = pts[:,2].max()
|
|
121
|
+
return xmax, ymax, zmax
|
|
122
|
+
def _GetMin(pts:np.ndarray):
|
|
123
|
+
xmin = pts[:,0].min()
|
|
124
|
+
ymin = pts[:,1].min()
|
|
125
|
+
zmin = pts[:,2].min()
|
|
126
|
+
return xmin, ymin, zmin
|
|
127
|
+
# begin method for making grid
|
|
128
|
+
xmax, ymax, zmax = _GetMax(self.points)
|
|
129
|
+
xmin, ymin, zmin = _GetMin(self.points)
|
|
130
|
+
dimx = self.grid_steps[0]
|
|
131
|
+
dimy = self.grid_steps[1]
|
|
132
|
+
dimz = self.grid_steps[2]
|
|
133
|
+
grid = pv.ImageData()
|
|
134
|
+
stretch_factor = self.grid_stretch
|
|
135
|
+
dim_stretch = [2*stretch_factor/dim for dim in self.grid_steps]
|
|
136
|
+
grid.origin = (
|
|
137
|
+
xmin - 0.5*stretch_factor,
|
|
138
|
+
ymin - 0.5*stretch_factor,
|
|
139
|
+
zmin - 0.5*stretch_factor
|
|
140
|
+
)
|
|
141
|
+
grid.spacing = (
|
|
142
|
+
2*xmax/dimx + dim_stretch[0],
|
|
143
|
+
2*ymax/dimy + dim_stretch[1],
|
|
144
|
+
2*zmax/dimz + dim_stretch[2]
|
|
145
|
+
)
|
|
146
|
+
grid.dimensions = (dimx, dimy, dimz)
|
|
147
|
+
return grid
|
|
148
|
+
#-----------------------------------------------------------------------------------------------------------------#
|
|
149
|
+
# method for selecting which contour to perform depending on if a single band or many bands are passed
|
|
150
|
+
def Contour(
|
|
151
|
+
self
|
|
152
|
+
):
|
|
153
|
+
if self._valdim == 1:
|
|
154
|
+
self._Contour(points=self.points, values=self.values)
|
|
155
|
+
else:
|
|
156
|
+
for band in self.values.T:
|
|
157
|
+
self._Contour(points=self.points, values=band)
|
|
158
|
+
#-----------------------------------------------------------------------------------------------------------------#
|
|
159
|
+
# method for drawing contour from list of values
|
|
160
|
+
def _Contour(
|
|
161
|
+
self, points:np.ndarray, values:np.ndarray
|
|
162
|
+
):
|
|
163
|
+
# setup grid interpolation
|
|
164
|
+
null_value = self.fermi_energy + self.energy_level + self.width/2 * 1.05
|
|
165
|
+
trans_pts, trans_vals = trnslt.TranslatePoints(
|
|
166
|
+
points=points,
|
|
167
|
+
values=values.reshape((values.shape[0],1)),
|
|
168
|
+
lattice_vecs=self.rec_latt
|
|
169
|
+
)
|
|
170
|
+
trans_pts = pv.PolyData(trans_pts)
|
|
171
|
+
trans_pts['values'] = trans_vals
|
|
172
|
+
inter_grid:pv.ImageData = self.grid.interpolate(
|
|
173
|
+
trans_pts,
|
|
174
|
+
radius=self.radius,
|
|
175
|
+
sharpness=2.0,
|
|
176
|
+
strategy='null_value',
|
|
177
|
+
null_value=null_value
|
|
178
|
+
) # type: ignore
|
|
179
|
+
# create contour
|
|
180
|
+
iso_range = [self.fermi_energy + self.energy_level, self.fermi_energy + self.energy_level]
|
|
181
|
+
contour:pv.PolyData = inter_grid.contour(
|
|
182
|
+
isosurfaces=2,
|
|
183
|
+
rng=iso_range,
|
|
184
|
+
method='contour'
|
|
185
|
+
) # type: ignore
|
|
186
|
+
self.contours.append(contour)
|
|
187
|
+
#-----------------------------------------------------------------------------------------------------------------#
|
|
188
|
+
# method for reading kpoints and eigenvalues from ABINIT WFK file
|
|
189
|
+
def _ReadAbinit(
|
|
190
|
+
self, filename:str
|
|
191
|
+
)->tuple[np.ndarray,np.ndarray, list, np.ndarray]:
|
|
192
|
+
# collect kpoints and eigenvalues from wfk file
|
|
193
|
+
wfk = ar.AbinitWFK(filename=filename)
|
|
194
|
+
eigs = []
|
|
195
|
+
syms = np.array(wfk.symrel)
|
|
196
|
+
nsym = wfk.nsym
|
|
197
|
+
kpoints = np.array(wfk.kpts)
|
|
198
|
+
ir_kpts = kpoints
|
|
199
|
+
nbands = wfk.bands[0]
|
|
200
|
+
nkpt = wfk.nkpt
|
|
201
|
+
self.fermi_energy = wfk.fermi
|
|
202
|
+
self.rec_latt = wc.WFK(lattice=wfk.real_lattice).rec_latt
|
|
203
|
+
for wfk_obj in wfk.ReadEigenvalues():
|
|
204
|
+
eigs.append(wfk_obj.eigenvalues)
|
|
205
|
+
eigs = np.array(eigs).reshape((nkpt,nbands))
|
|
206
|
+
# look through eigenvalues to find which bands to contour
|
|
207
|
+
min_val = self.fermi_energy + self.energy_level - self.width/2
|
|
208
|
+
max_val = self.fermi_energy + self.energy_level + self.width/2
|
|
209
|
+
band_num = []
|
|
210
|
+
for i in range(nbands):
|
|
211
|
+
for eigval in eigs[:,i]:
|
|
212
|
+
if min_val <= eigval <= max_val:
|
|
213
|
+
band_num.append(i)
|
|
214
|
+
break
|
|
215
|
+
# return kpoints and bands of interest
|
|
216
|
+
bands = np.take(eigs, band_num, axis=1)
|
|
217
|
+
shifts = brlzn.BZ(self.rec_latt).GetShifts(kpoints)
|
|
218
|
+
kpoints = kpoints - shifts
|
|
219
|
+
ir_kpts -= shifts
|
|
220
|
+
ir_kpts = np.matmul(ir_kpts,self.rec_latt)
|
|
221
|
+
wfk = wc.WFK(symrel=syms, nsym=nsym, nbands=len(band_num), nkpt=nkpt)
|
|
222
|
+
all_kpts = np.zeros((1,3))
|
|
223
|
+
all_eigs = np.zeros((1,bands.shape[1]))
|
|
224
|
+
# symmetrize kpoints
|
|
225
|
+
for i, kpt in enumerate(kpoints):
|
|
226
|
+
unique_kpts, _ = wfk.Symmetrize(
|
|
227
|
+
points=kpt,
|
|
228
|
+
reciprocal=True,
|
|
229
|
+
)
|
|
230
|
+
all_kpts = np.concatenate((all_kpts, unique_kpts), axis=0)
|
|
231
|
+
new_eigs = np.repeat(bands[i,:].reshape((1,-1)), unique_kpts.shape[0], axis=0)
|
|
232
|
+
all_eigs = np.concatenate((all_eigs, new_eigs), axis=0)
|
|
233
|
+
kpoints = np.delete(all_kpts, 0, axis=0)
|
|
234
|
+
bands = np.delete(all_eigs, 0, axis=0)
|
|
235
|
+
kpoints = np.matmul(kpoints, self.rec_latt)
|
|
236
236
|
return kpoints, bands, band_num, ir_kpts
|