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/brillouin_zone.py CHANGED
@@ -1,186 +1,186 @@
1
- import numpy as np
2
- from scipy.spatial import Voronoi, KDTree, Delaunay
3
- from . import translate as trnslt
4
-
5
- # Brillouin Zone object
6
- class BZ():
7
- def __init__(
8
- self, rec_latt:np.ndarray
9
- )->None:
10
- self.rec_latt = rec_latt
11
- _3xgrid, _ = trnslt.TranslatePoints(np.zeros((1,3)), np.zeros(1), self.rec_latt)
12
- self._3xgrid = _3xgrid
13
- self.vertices = self._BZpts()
14
- #---------------------------------------------------------------------------------------------------------------------#
15
- #------------------------------------------------------ METHODS ------------------------------------------------------#
16
- #---------------------------------------------------------------------------------------------------------------------#
17
- # Method used to check if nearest points all occur in same plane
18
- def _CheckPts(
19
- self, pts:np.ndarray, verts:np.ndarray
20
- )->bool:
21
- # get cartesian coordinates
22
- verts = np.take(verts, pts, axis=0)
23
- # rounding avoids floating point errors in if comparison below
24
- verts = np.round(verts, decimals=8)
25
- # last point is the furthest, check if it is in same plane as other points
26
- pt = verts[-1,:]
27
- check = False
28
- # check if points are in same plane
29
- if pt[0] == verts[0,:][0] and pt[0] == verts[1,:][0] and pt[0] == verts[2,:][0]:
30
- check = True
31
- if pt[1] == verts[0,:][1] and pt[1] == verts[1,:][1] and pt[1] == verts[2,:][1]:
32
- check = True
33
- if pt[2] == verts[0,:][2] and pt[2] == verts[1,:][2] and pt[2] == verts[2,:][2]:
34
- check = True
35
- return check
36
- #-----------------------------------------------------------------------------------------------------------------#
37
- def _BZpts(
38
- self
39
- )->np.ndarray:
40
- # Voronoi tessallate the lattice points
41
- vor_tessellation = Voronoi(self._3xgrid)
42
- # find Voronoi region that encapsulates Brillouin zone
43
- vor_cell = -1
44
- for i, region in enumerate(vor_tessellation.regions):
45
- if -1 not in region and region != []:
46
- vor_cell = i
47
- break
48
- if vor_cell < 0:
49
- raise ValueError(
50
- 'Unable to construct Brillouin Zone from reciprocal lattice, check lattice parameters.'
51
- )
52
- # get vertices of BZ Voronoi region
53
- vor_cell_verts = vor_tessellation.regions[vor_cell]
54
- vor_verts = np.take(vor_tessellation.vertices, vor_cell_verts, axis=0)
55
- # find which vertices are closest to each other
56
- point_cloud = KDTree(vor_verts)
57
- vert_inds = []
58
- for i, vert in enumerate(vor_verts):
59
- _, nearest_pts = point_cloud.query(vert, k=4)
60
- c = 4
61
- # iterate check until points are no longer in same plane
62
- while self._CheckPts(nearest_pts, vor_verts):
63
- c += 1
64
- _, nearest_pts = point_cloud.query(vert, k=c)
65
- len_arr = c - 4
66
- arr = -1*np.arange(len_arr) - 2
67
- nearest_pts = np.delete(nearest_pts, arr, axis=0)
68
- # current index is a repeated entry every other point since this is how PyVista interprets lines
69
- nearest_pts = np.insert(nearest_pts, [2,4], [i,i])
70
- vert_inds.append(nearest_pts)
71
- # convert nested list to flat list
72
- vert_inds = [int(ind) for verts in vert_inds for ind in verts]
73
- # get cartesian coordinates
74
- vor_verts = np.take(vor_verts, vert_inds, axis=0)
75
- return vor_verts
76
- #-----------------------------------------------------------------------------------------------------------------#
77
- # method for determining shifts required to translate points outside BZ back into BZ
78
- def GetShifts(
79
- self, points:np.ndarray, cart:bool=True
80
- )->np.ndarray:
81
- '''
82
- Method for calculating necessary reciprocal lattice shift to move point into Brillouin Zone.
83
-
84
- Parameters
85
- ----------
86
- points : np.ndarray
87
- List of points to calculate shifts for.
88
- cart : bool
89
- Convert points from reduced to Cartesian coordinates.
90
- Default will apply conversion (True).
91
- '''
92
- # make points mulitdimensional if not already
93
- if len(points.shape) == 1:
94
- points = points.reshape((1,points.shape[0]))
95
- # convert to cartesian
96
- if cart:
97
- points = self.MakeCart(points=points)
98
- # find points outside of BZ
99
- outside_pts = self.PointLocate(points)
100
- # calculate shifts to move outside points back into BZ
101
- shifts = np.zeros((outside_pts[outside_pts < 0].shape[0],3))
102
- rec_grid = KDTree(self._3xgrid)
103
- shift_grid, _ = trnslt.TranslatePoints(np.zeros((1,3)), np.zeros(1), np.identity(3))
104
- for i, pt in enumerate(points[outside_pts < 0]):
105
- _, closest_pt = rec_grid.query(pt, k=1)
106
- shifts[i,:] = shift_grid[closest_pt, :]
107
- all_shifts = np.zeros((points.shape[0],3))
108
- all_shifts[outside_pts < 0] = shifts
109
- return all_shifts.astype(int)
110
- #-----------------------------------------------------------------------------------------------------------------#
111
- # method for finding if points are outside or inside of BZ
112
- def PointLocate(
113
- self, points:np.ndarray, cart:bool=True
114
- )->np.ndarray:
115
- '''
116
- Method for finding which points are outside, on the edge, and inside the Brillouin Zone.
117
-
118
- Parameters
119
- ----------
120
- points : np.ndarray
121
- Array of points to be checked against the Brillouin Zone, must be in cartesian format
122
- Shape (N,3)
123
-
124
- Returns
125
- -------
126
- np.ndarray
127
- elements < 0 correspond to points outside the Brillouin Zone
128
- elements > 0 correspond to points inside
129
- '''
130
- if cart:
131
- points = self.MakeCart(points=points)
132
- outside_pts = Delaunay(self.vertices).find_simplex(points)
133
- return outside_pts
134
- #-----------------------------------------------------------------------------------------------------------------#
135
- # method for finding if point is on BZ edge/face
136
- # not working
137
- def _BZEdgePt(
138
- self, points:np.ndarray, cart:bool=True
139
- )->np.ndarray:
140
- shift_grid, _ = trnslt.TranslatePoints(np.zeros((1,3)), np.zeros(1), np.identity(3))
141
- test_point = self.PointLocate(shift_grid + points, cart=cart)
142
- return test_point
143
- #-----------------------------------------------------------------------------------------------------------------#
144
- # method for converting points to cartesian format
145
- def MakeCart(
146
- self, points:np.ndarray
147
- )->np.ndarray:
148
- '''
149
- Method for converting points from reduced to cartesian format
150
-
151
- Parameters
152
- ----------
153
- points : np.ndarray
154
- Array of points to be converted
155
- Shape (N,3)
156
-
157
- Returns
158
- -------
159
- np.ndarray
160
- points in cartesian format
161
- Shape (N,3)
162
- '''
163
- cart_pts = np.matmul(points, self.rec_latt)
164
- return cart_pts
165
- #-----------------------------------------------------------------------------------------------------------------#
166
- # method for converting points to reduced format
167
- def MakeRed(
168
- self, points:np.ndarray
169
- )->np.ndarray:
170
- '''
171
- Method for converting points from cartesian to reduced format
172
-
173
- Parameters
174
- ----------
175
- points : np.ndarray
176
- Array of points to be converted
177
- Shape (N,3)
178
-
179
- Returns
180
- -------
181
- np.ndarray
182
- points in reduced format
183
- Shape (N,3)
184
- '''
185
- red_pts = np.matmul(points, np.linalg.inv(self.rec_latt))
1
+ import numpy as np
2
+ from scipy.spatial import Voronoi, KDTree, Delaunay
3
+ from . import translate as trnslt
4
+
5
+ # Brillouin Zone object
6
+ class BZ():
7
+ def __init__(
8
+ self, rec_latt:np.ndarray
9
+ )->None:
10
+ self.rec_latt = rec_latt
11
+ _3xgrid, _ = trnslt.TranslatePoints(np.zeros((1,3)), np.zeros(1), self.rec_latt)
12
+ self._3xgrid = _3xgrid
13
+ self.vertices = self._BZpts()
14
+ #---------------------------------------------------------------------------------------------------------------------#
15
+ #------------------------------------------------------ METHODS ------------------------------------------------------#
16
+ #---------------------------------------------------------------------------------------------------------------------#
17
+ # Method used to check if nearest points all occur in same plane
18
+ def _CheckPts(
19
+ self, pts:np.ndarray, verts:np.ndarray
20
+ )->bool:
21
+ # get cartesian coordinates
22
+ verts = np.take(verts, pts, axis=0)
23
+ # rounding avoids floating point errors in if comparison below
24
+ verts = np.round(verts, decimals=8)
25
+ # last point is the furthest, check if it is in same plane as other points
26
+ pt = verts[-1,:]
27
+ check = False
28
+ # check if points are in same plane
29
+ if pt[0] == verts[0,:][0] and pt[0] == verts[1,:][0] and pt[0] == verts[2,:][0]:
30
+ check = True
31
+ if pt[1] == verts[0,:][1] and pt[1] == verts[1,:][1] and pt[1] == verts[2,:][1]:
32
+ check = True
33
+ if pt[2] == verts[0,:][2] and pt[2] == verts[1,:][2] and pt[2] == verts[2,:][2]:
34
+ check = True
35
+ return check
36
+ #-----------------------------------------------------------------------------------------------------------------#
37
+ def _BZpts(
38
+ self
39
+ )->np.ndarray:
40
+ # Voronoi tessallate the lattice points
41
+ vor_tessellation = Voronoi(self._3xgrid)
42
+ # find Voronoi region that encapsulates Brillouin zone
43
+ vor_cell = -1
44
+ for i, region in enumerate(vor_tessellation.regions):
45
+ if -1 not in region and region != []:
46
+ vor_cell = i
47
+ break
48
+ if vor_cell < 0:
49
+ raise ValueError(
50
+ 'Unable to construct Brillouin Zone from reciprocal lattice, check lattice parameters.'
51
+ )
52
+ # get vertices of BZ Voronoi region
53
+ vor_cell_verts = vor_tessellation.regions[vor_cell]
54
+ vor_verts = np.take(vor_tessellation.vertices, vor_cell_verts, axis=0)
55
+ # find which vertices are closest to each other
56
+ point_cloud = KDTree(vor_verts)
57
+ vert_inds = []
58
+ for i, vert in enumerate(vor_verts):
59
+ _, nearest_pts = point_cloud.query(vert, k=4)
60
+ c = 4
61
+ # iterate check until points are no longer in same plane
62
+ while self._CheckPts(nearest_pts, vor_verts):
63
+ c += 1
64
+ _, nearest_pts = point_cloud.query(vert, k=c)
65
+ len_arr = c - 4
66
+ arr = -1*np.arange(len_arr) - 2
67
+ nearest_pts = np.delete(nearest_pts, arr, axis=0)
68
+ # current index is a repeated entry every other point since this is how PyVista interprets lines
69
+ nearest_pts = np.insert(nearest_pts, [2,4], [i,i])
70
+ vert_inds.append(nearest_pts)
71
+ # convert nested list to flat list
72
+ vert_inds = [int(ind) for verts in vert_inds for ind in verts]
73
+ # get cartesian coordinates
74
+ vor_verts = np.take(vor_verts, vert_inds, axis=0)
75
+ return vor_verts
76
+ #-----------------------------------------------------------------------------------------------------------------#
77
+ # method for determining shifts required to translate points outside BZ back into BZ
78
+ def GetShifts(
79
+ self, points:np.ndarray, cart:bool=True
80
+ )->np.ndarray:
81
+ '''
82
+ Method for calculating necessary reciprocal lattice shift to move point into Brillouin Zone.
83
+
84
+ Parameters
85
+ ----------
86
+ points : np.ndarray
87
+ List of points to calculate shifts for.
88
+ cart : bool
89
+ Convert points from reduced to Cartesian coordinates.
90
+ Default will apply conversion (True).
91
+ '''
92
+ # make points mulitdimensional if not already
93
+ if len(points.shape) == 1:
94
+ points = points.reshape((1,points.shape[0]))
95
+ # convert to cartesian
96
+ if cart:
97
+ points = self.MakeCart(points=points)
98
+ # find points outside of BZ
99
+ outside_pts = self.PointLocate(points)
100
+ # calculate shifts to move outside points back into BZ
101
+ shifts = np.zeros((outside_pts[outside_pts < 0].shape[0],3))
102
+ rec_grid = KDTree(self._3xgrid)
103
+ shift_grid, _ = trnslt.TranslatePoints(np.zeros((1,3)), np.zeros(1), np.identity(3))
104
+ for i, pt in enumerate(points[outside_pts < 0]):
105
+ _, closest_pt = rec_grid.query(pt, k=1)
106
+ shifts[i,:] = shift_grid[closest_pt, :]
107
+ all_shifts = np.zeros((points.shape[0],3))
108
+ all_shifts[outside_pts < 0] = shifts
109
+ return all_shifts.astype(int)
110
+ #-----------------------------------------------------------------------------------------------------------------#
111
+ # method for finding if points are outside or inside of BZ
112
+ def PointLocate(
113
+ self, points:np.ndarray, cart:bool=True
114
+ )->np.ndarray:
115
+ '''
116
+ Method for finding which points are outside, on the edge, and inside the Brillouin Zone.
117
+
118
+ Parameters
119
+ ----------
120
+ points : np.ndarray
121
+ Array of points to be checked against the Brillouin Zone, must be in cartesian format
122
+ Shape (N,3)
123
+
124
+ Returns
125
+ -------
126
+ np.ndarray
127
+ elements < 0 correspond to points outside the Brillouin Zone
128
+ elements > 0 correspond to points inside
129
+ '''
130
+ if cart:
131
+ points = self.MakeCart(points=points)
132
+ outside_pts = Delaunay(self.vertices).find_simplex(points)
133
+ return outside_pts
134
+ #-----------------------------------------------------------------------------------------------------------------#
135
+ # method for finding if point is on BZ edge/face
136
+ # not working
137
+ def _BZEdgePt(
138
+ self, points:np.ndarray, cart:bool=True
139
+ )->np.ndarray:
140
+ shift_grid, _ = trnslt.TranslatePoints(np.zeros((1,3)), np.zeros(1), np.identity(3))
141
+ test_point = self.PointLocate(shift_grid + points, cart=cart)
142
+ return test_point
143
+ #-----------------------------------------------------------------------------------------------------------------#
144
+ # method for converting points to cartesian format
145
+ def MakeCart(
146
+ self, points:np.ndarray
147
+ )->np.ndarray:
148
+ '''
149
+ Method for converting points from reduced to cartesian format
150
+
151
+ Parameters
152
+ ----------
153
+ points : np.ndarray
154
+ Array of points to be converted
155
+ Shape (N,3)
156
+
157
+ Returns
158
+ -------
159
+ np.ndarray
160
+ points in cartesian format
161
+ Shape (N,3)
162
+ '''
163
+ cart_pts = np.matmul(points, self.rec_latt)
164
+ return cart_pts
165
+ #-----------------------------------------------------------------------------------------------------------------#
166
+ # method for converting points to reduced format
167
+ def MakeRed(
168
+ self, points:np.ndarray
169
+ )->np.ndarray:
170
+ '''
171
+ Method for converting points from cartesian to reduced format
172
+
173
+ Parameters
174
+ ----------
175
+ points : np.ndarray
176
+ Array of points to be converted
177
+ Shape (N,3)
178
+
179
+ Returns
180
+ -------
181
+ np.ndarray
182
+ points in reduced format
183
+ Shape (N,3)
184
+ '''
185
+ red_pts = np.matmul(points, np.linalg.inv(self.rec_latt))
186
186
  return red_pts
bandu/colors.py CHANGED
@@ -1,47 +1,47 @@
1
- import numpy as np
2
- from matplotlib.colors import ListedColormap
3
-
4
- # class for creating custom colormaps for isosurface
5
- class Colors():
6
- #-----------------------------------------------------------------------------------------------------------------#
7
- # define a few colormaps for easy plotting
8
- def __init__(self):
9
- self.reds = self.Colormap([np.array([125, 125, 125])/255,
10
- np.array([255, 46, 31])/255
11
- ])
12
- self.stoplight = self.Colormap([np.array([255, 46, 31])/255,
13
- np.array([255, 180, 31])/255,
14
- np.array([26, 209, 23])/255
15
- ])
16
- self.WhBlRd = self.Colormap([np.array([240, 240, 240])/255,
17
- np.array([0, 0, 255])/255,
18
- np.array([255, 0, 0])/255
19
- ])
20
- self.PlTlPk = self.Colormap([np.array([74, 2, 115])/255,
21
- np.array([11, 217, 210])/255,
22
- np.array([255, 0, 255])/255
23
- ])
24
- self.blues = self.Colormap([np.array([240, 240, 240])/255,
25
- np.array([75, 222, 222])/255,
26
- np.array([5, 47, 255])/255
27
- ])
28
- #-----------------------------------------------------------------------------------------------------------------#
29
- # method to create custom colormap from list of rgb codes
30
- def Colormap(self, colorlist:list)->ListedColormap:
31
- num = 250*(len(colorlist)-1)
32
- parts = 250
33
- colors = np.empty((num, 4))
34
- reds = np.zeros(num)
35
- greens = np.zeros(num)
36
- blues = np.zeros(num)
37
- for i, color in enumerate(colorlist):
38
- if i == len(colorlist) - 1:
39
- break
40
- reds[i*parts:(i+1)*parts] += np.linspace(color[0], colorlist[i+1][0], parts)
41
- greens[i*parts:(i+1)*parts] += np.linspace(color[1], colorlist[i+1][1], parts)
42
- blues[i*parts:(i+1)*parts] += np.linspace(color[2], colorlist[i+1][2], parts)
43
- colors[:,0] = reds
44
- colors[:,1] = greens
45
- colors[:,2] = blues
46
- colors[:,3] = np.ones(num)
1
+ import numpy as np
2
+ from matplotlib.colors import ListedColormap
3
+
4
+ # class for creating custom colormaps for isosurface
5
+ class Colors():
6
+ #-----------------------------------------------------------------------------------------------------------------#
7
+ # define a few colormaps for easy plotting
8
+ def __init__(self):
9
+ self.reds = self.Colormap([np.array([125, 125, 125])/255,
10
+ np.array([255, 46, 31])/255
11
+ ])
12
+ self.stoplight = self.Colormap([np.array([255, 46, 31])/255,
13
+ np.array([255, 180, 31])/255,
14
+ np.array([26, 209, 23])/255
15
+ ])
16
+ self.WhBlRd = self.Colormap([np.array([240, 240, 240])/255,
17
+ np.array([0, 0, 255])/255,
18
+ np.array([255, 0, 0])/255
19
+ ])
20
+ self.PlTlPk = self.Colormap([np.array([74, 2, 115])/255,
21
+ np.array([11, 217, 210])/255,
22
+ np.array([255, 0, 255])/255
23
+ ])
24
+ self.blues = self.Colormap([np.array([240, 240, 240])/255,
25
+ np.array([75, 222, 222])/255,
26
+ np.array([5, 47, 255])/255
27
+ ])
28
+ #-----------------------------------------------------------------------------------------------------------------#
29
+ # method to create custom colormap from list of rgb codes
30
+ def Colormap(self, colorlist:list)->ListedColormap:
31
+ num = 250*(len(colorlist)-1)
32
+ parts = 250
33
+ colors = np.empty((num, 4))
34
+ reds = np.zeros(num)
35
+ greens = np.zeros(num)
36
+ blues = np.zeros(num)
37
+ for i, color in enumerate(colorlist):
38
+ if i == len(colorlist) - 1:
39
+ break
40
+ reds[i*parts:(i+1)*parts] += np.linspace(color[0], colorlist[i+1][0], parts)
41
+ greens[i*parts:(i+1)*parts] += np.linspace(color[1], colorlist[i+1][1], parts)
42
+ blues[i*parts:(i+1)*parts] += np.linspace(color[2], colorlist[i+1][2], parts)
43
+ colors[:,0] = reds
44
+ colors[:,1] = greens
45
+ colors[:,2] = blues
46
+ colors[:,3] = np.ones(num)
47
47
  return ListedColormap(colors)