crystalbuilder 0.5.4__py2.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.

Potentially problematic release.


This version of crystalbuilder might be problematic. Click here for more details.

@@ -0,0 +1,22 @@
1
+ from crystalbuilder import convert
2
+ from crystalbuilder import lattice
3
+ from crystalbuilder import vectors
4
+ from crystalbuilder import bilbao
5
+ import numpy as np
6
+
7
+ def MonkhorstPack(size):
8
+ """
9
+ This is a direct copy of the Monkhorst-Pack k-space sampling method in ase (https://iopscience.iop.org/article/10.1088/1361-648X/aa680e)
10
+
11
+ This way there's no need to import ase.
12
+
13
+ Parameters
14
+ ----------
15
+ size : ndarray
16
+ number of points (kx, ky, kz) to sample reciprocal space. This should only be used in MPB, as it performs the necessary multiplication by the reciprocal lattice vectors
17
+
18
+ """
19
+ if np.less_equal(size, 0).any():
20
+ raise ValueError(f'Illegal size: {list(size)}')
21
+ kpts = np.indices(size).transpose((1, 2, 3, 0)).reshape((-1, 3))
22
+ return (kpts + 0.5) / size - 0.5
@@ -0,0 +1,279 @@
1
+ import numpy as np
2
+ from matplotlib import pyplot as plt
3
+
4
+ debug = 'off'
5
+
6
+ rounder = 50 #sets decimal rounding
7
+ #Needs Done
8
+
9
+
10
+ def flatten(list):
11
+ flat_list = [item for sublist in list for item in sublist]
12
+ return flat_list
13
+
14
+ def angle_check(theta, unit):
15
+ if unit == 'degrees' or 'deg' or 'd' or 'degree':
16
+ radthet = np.radians(theta)
17
+ elif unit == 'radians' or 'rad' or 'r' or 'radian':
18
+ radthet = theta
19
+ else:
20
+ print("Error: Units must be 'degrees' or 'radians'")
21
+ return radthet
22
+
23
+ def shift(point, shift_vector):
24
+ """
25
+ TO DO
26
+
27
+ shift point by the shift vector
28
+ """
29
+ point_arr = np.asarray(point)
30
+ shiftvec = np.asarray(shift_vector)
31
+ shiftedpoint = point_arr.reshape(3,) + shiftvec.reshape(3,)
32
+ return shiftedpoint
33
+
34
+ def get_shift_vector(point, newpoint):
35
+ point_arr = np.asarray(point)
36
+ newpoint = np.asarray(newpoint)
37
+ shiftvec = newpoint.reshape(3,) - point_arr.reshape(3,)
38
+ return shiftvec
39
+
40
+ def shift_angle(point, theta, distance, unit='degrees'):
41
+ """
42
+ Shifts in x-y plane a distance at angle theta
43
+ """
44
+ point_arr = np.asarray(point)
45
+ shiftvec = rotate([[distance, 0, 0]], theta, axis=2, unit=unit)
46
+ print(shiftvec.T)
47
+ print(point_arr)
48
+ shiftedpoint = point_arr.reshape(3,) + shiftvec.reshape(3,)
49
+ return shiftedpoint
50
+
51
+ def rotate(point, theta, relative_point=(0,0,0), axis=2, unit='degrees', toarray=True):
52
+ """
53
+ rotates counterclockwise a point or list of points about relative_point by theta in
54
+ This does a 2D rotation only, so string a few together to rotate in more than one axis
55
+
56
+ Parameters:
57
+ point (list of array_like)
58
+ theta (float)
59
+ relative_point (array_like)
60
+ axis (0,1,2)
61
+ unit (str): 'degrees' or 'radians'
62
+
63
+ Returns:
64
+ List of coordinate lists (3-list)
65
+
66
+ """
67
+
68
+ radthet = angle_check(theta, unit)
69
+
70
+
71
+ coordinatelist = []
72
+
73
+
74
+ for coord in point:
75
+
76
+ if axis==2:
77
+ newcoord = rotatez(coord, radthet, relative_point)
78
+
79
+ elif axis ==1:
80
+ newcoord = rotatey(coord, radthet, relative_point)
81
+
82
+ elif axis ==0:
83
+ newcoord = rotatex(coord, radthet, relative_point)
84
+
85
+ else:
86
+ print("Error: Check Axis Direction")
87
+
88
+ newcoord = newcoord.reshape(3,).tolist()
89
+ coordinatelist.append(newcoord)
90
+ if toarray==False:
91
+ new_coordinates=coordinatelist
92
+ else:
93
+ new_coordinates=np.asarray(coordinatelist)
94
+
95
+ if debug == 'on':
96
+ print('coordinates=\n', new_coordinates)
97
+ print('type= ', type(new_coordinates))
98
+ print('data type= ', type(new_coordinates[0][0]))
99
+
100
+
101
+ return new_coordinates
102
+
103
+ def rotatex(point, theta, relative_point):
104
+ """
105
+ rotates counterclockwise a point in x by theta radians about relative_point
106
+ """
107
+ x = point[0]
108
+ y = point[1]
109
+ z = point[2]
110
+
111
+ relx = relative_point[0]
112
+ rely = relative_point[1]
113
+ relz = relative_point[2]
114
+
115
+ tmat = np.array([
116
+ [1,0,0,0],
117
+ [0, 1, 0, 0],
118
+ [0,0,1,0],
119
+ [relx, rely, relz,1]])
120
+
121
+ tnmat = np.array([
122
+ [1,0,0,0],
123
+ [0,1,0,0],
124
+ [0,0,1,0],
125
+ [-relx, -rely, -relz, 1]])
126
+
127
+ rxmat = np.array([
128
+ [1, 0, 0, 0],
129
+ [0, np.cos(theta), -np.sin(theta), 0],
130
+ [0, np.sin(theta), np.cos(theta), 0],
131
+ [0,0,0,1]
132
+ ]).round(rounder)
133
+ if debug=='on':
134
+ print("rxmat", '= ', rxmat)
135
+
136
+ rt1mat = np.matmul(rxmat,tnmat)
137
+ if debug=='on':
138
+ print("rt1mat", '= ', rt1mat)
139
+
140
+ rt2mat = np.matmul(tmat,rt1mat)
141
+ if debug=='on':
142
+ print("rt2mat", '= ', rt2mat)
143
+
144
+ rotation = np.matmul(rt2mat, np.array([[x],[y],[z],[1]]))
145
+ return rotation[:3]
146
+
147
+ def rotatey(point, theta, relative_point):
148
+ """
149
+ rotates counterclockwise a point in y by theta radians about relative_point
150
+ """
151
+ x = point[0]
152
+ y = point[1]
153
+ z = point[2]
154
+
155
+ relx = relative_point[0]
156
+ rely = relative_point[1]
157
+ relz = relative_point[2]
158
+
159
+ tmat = np.array([
160
+ [1,0,0,0],
161
+ [0, 1, 0, 0],
162
+ [0,0,1,0],
163
+ [relx, rely, relz,1]])
164
+
165
+ tnmat = np.array([
166
+ [1,0,0,0],
167
+ [0,1,0,0],
168
+ [0,0,1,0],
169
+ [-relx, -rely, -relz, 1]])
170
+
171
+ rymat = np.array([
172
+ [np.cos(theta), 0, np.sin(theta), 0],
173
+ [0, 1, 0, 0],
174
+ [-np.sin(theta), 0, np.cos(theta), 0],
175
+ [0,0,0,1]
176
+ ]).round(rounder)
177
+ if debug=='on':
178
+ print("rymat", '= ', rymat)
179
+
180
+ rt1mat = np.matmul(rymat,tnmat)
181
+ if debug=='on':
182
+ print("rt1mat", '= ', rt1mat)
183
+
184
+ rt2mat = np.matmul(tmat,rt1mat)
185
+ if debug=='on':
186
+ print("rt2mat", '= ', rt2mat)
187
+
188
+ rotation = np.matmul(rt2mat, np.array([[x],[y],[z],[1]]))
189
+ return rotation[:3]
190
+
191
+ def rotatez(point, theta, relative_point):
192
+ """
193
+ rotates counterclockwise a point in z by theta radians about relative_point
194
+ """
195
+ x = point[0]
196
+ y = point[1]
197
+ z = point[2]
198
+
199
+ relx = relative_point[0]
200
+ rely = relative_point[1]
201
+ relz = relative_point[2]
202
+
203
+ tmat = np.array([
204
+ [1,0,0,relx],
205
+ [0,1,0,rely],
206
+ [0,0,1,relz],
207
+ [0,0,0,1]])
208
+
209
+
210
+ tnmat = np.array([
211
+ [1,0,0,-relx],
212
+ [0,1,0,-rely],
213
+ [0,0,1,-relz],
214
+ [0,0,0,1]])
215
+
216
+ rzmat = np.array([
217
+ [np.cos(theta), -np.sin(theta),0 , 0],
218
+ [np.sin(theta), np.cos(theta), 0, 0],
219
+ [0, 0, 1, 0],
220
+ [0,0,0,1]
221
+ ]).round(rounder)
222
+ if debug=='on':
223
+ print("translation matrix = \n", tmat)
224
+ print("negative translation matrix = \n", tnmat)
225
+ print("rzmat", '=\n', rzmat)
226
+
227
+
228
+ rt1mat = np.matmul(rzmat,tnmat)
229
+ if debug=='on':
230
+ print("rt1mat", '=\n', rt1mat)
231
+
232
+ rt2mat = np.matmul(tmat,rt1mat)
233
+ if debug=='on':
234
+ print("rt2mat", '=\n', rt2mat)
235
+
236
+ rotation = np.matmul(rt2mat, np.array([[x],[y],[z],[1]]))
237
+ return rotation[:3]
238
+
239
+ def basis_change(basis1, basis2, point_in_basis1):
240
+ """
241
+ makes column vectors from basis1 and basis2, then determines the change-of-basis matrix. Applies this to specified point and returns the coordinate in the other basis.
242
+
243
+ Both bases need to be defined in cartesian basis, but the output will be in terms of basis2
244
+
245
+
246
+ Parameters
247
+ ----------
248
+ basis1: basis in 3x3 list or array, or 'cartesian'
249
+ basis2: basis in 3x3 list or array, or 'cartesian'
250
+ point_in_basis1: 3-list point specified in units of basis 1
251
+
252
+ """
253
+ cartbasis = [[1,0,0], [0,1,0], [0,0,1]]
254
+ try:
255
+ if basis1 == 'cartesian': basis1=cartbasis
256
+ except ValueError:
257
+ pass
258
+
259
+ try:
260
+ if basis2 == 'cartesian': basis2=cartbasis
261
+ except ValueError:
262
+ pass
263
+
264
+
265
+ bas1_arr = np.transpose(np.asarray(basis1))
266
+ bas2_arr = np.transpose(np.asarray(basis2))
267
+ point_arr = np.asarray(point_in_basis1).reshape(3,1)
268
+
269
+ newpoint = np.matmul(bas1_arr, point_arr)
270
+ outpoint = np.matmul(bas2_arr, newpoint)
271
+ return outpoint.reshape(3,)
272
+
273
+ def cart_to_pol(point):
274
+ x = point[0]
275
+ y = point[1]
276
+ z = point[2]
277
+ r = np.sqrt((x**2 + y**2))
278
+ theta = np.arctan2(y, x)+np.pi
279
+ return [r, theta, z]
@@ -0,0 +1,82 @@
1
+ import vedo
2
+ import crystalbuilder
3
+ import crystalbuilder.geometry as geo
4
+
5
+ vedo.settings.default_backend='vtk'
6
+
7
+
8
+
9
+ def add_to_visualizer(structures, plot, **kwargs):
10
+ for object in structures:
11
+ if isinstance(object, geo.Cylinder):
12
+ plot += visualize_cylinder(object, **kwargs)
13
+ elif isinstance(object, geo.Sphere):
14
+ plot += visualize_sphere(object, **kwargs)
15
+ elif isinstance(object, geo.SuperCell):
16
+ plot += visualize_supercell(object, **kwargs)
17
+
18
+
19
+ def visualize(structures, plotter_style=9, **kwargs):
20
+ """
21
+
22
+ Parameters
23
+ -----------
24
+ structures : list of geo
25
+
26
+ """
27
+
28
+ plot = vedo.Plotter(axes=plotter_style)
29
+
30
+ add_to_visualizer(structures, plot)
31
+
32
+ # for object in structures:
33
+ # if isinstance(object, geo.Structure):
34
+ # if isinstance(object, geo.Cylinder):
35
+ # obj = visualize_cylinder(object, **kwargs)
36
+ # plot += obj
37
+ # elif isinstance(object, geo.SuperCell):
38
+ # obj = visualize_supercell(object, **kwargs)
39
+ # plot += obj
40
+ # elif isinstance(object, geo.Sphere):
41
+ # obj = visualize_sphere(object, **kwargs)
42
+ # plot += obj
43
+ # elif isinstance(object, list):
44
+ # for n in object:
45
+
46
+
47
+ return plot
48
+
49
+ def visualize_cylinder(cylinder, **kwargs):
50
+ center = cylinder.center
51
+ radius = cylinder.radius
52
+ height = cylinder.height
53
+ axis = cylinder.axis
54
+ name = str(cylinder.center)
55
+ obj = vedo.Cylinder(pos=center, r=radius, height=height, axis=axis, **kwargs).legend(name)
56
+ obj.name = name
57
+ return obj
58
+
59
+ def visualize_sphere(sphere, **kwargs):
60
+ center = sphere.center
61
+ radius = sphere.radius
62
+ name = str(sphere.center)
63
+ obj = vedo.Sphere(pos=center, r=radius, **kwargs).legend(name)
64
+ obj.name = name
65
+ return obj
66
+
67
+ def visualize_supercell(SuperCell, **kwargs):
68
+ objects = []
69
+ for structure in SuperCell:
70
+ if isinstance(structure, geo.Cylinder):
71
+ objects.append(visualize_cylinder(structure, **kwargs))
72
+ elif isinstance(structure, geo.Sphere):
73
+ objects.append(visualize_sphere(structure, **kwargs))
74
+ return objects
75
+
76
+
77
+
78
+
79
+ if __name__ == "__main__":
80
+ cylinder1 = geo.Cylinder(center=(0,0,0), radius=1, height=3, axis=2)
81
+ cylinder2 = geo.Cylinder(center=(5,5,0), radius=2, height=6, axis=1)
82
+ visualize([cylinder1, cylinder2])
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: crystalbuilder
3
+ Version: 0.5.4
4
+ Summary: A package for building 3D photonic crystals
5
+ Author: Brandon Hacha
6
+ License-File: LICENSE
7
+ Requires-Dist: beautifulsoup4
8
+ Requires-Dist: matplotlib
9
+ Requires-Dist: numpy
10
+ Requires-Dist: vedo
11
+ Provides-Extra: full
12
+ Requires-Dist: tidy3d; extra == 'full'
@@ -0,0 +1,14 @@
1
+ crystalbuilder/__init__.py,sha256=_Jc_rgu9WcSSuOs_uZw2NIFojARRBSU_EA59DY9vCzw,1368
2
+ crystalbuilder/bilbao.py,sha256=660d06o8I3NAqTSLHrOK7kTf-Lnr1rKhp2smw_giafA,10994
3
+ crystalbuilder/convert.py,sha256=2f8EcLg0SAyObjcdhL6m-j1N8qBLy_XIo-3MugLGYnM,12691
4
+ crystalbuilder/geometry.py,sha256=CPioM1OTVQUutJoX_XpVa3kYOXhJ9B3N4Vbmfjs5M1c,24647
5
+ crystalbuilder/lattice.py,sha256=1y8U9iJKbYIqTeX4qVR2k8E2lAjsbyx1zUz4ATswU7A,33555
6
+ crystalbuilder/utils.py,sha256=INkhGf8Jat_YH1K3TghL6mw5cS__CVILQgdo7u9g_SY,818
7
+ crystalbuilder/vectors.py,sha256=uf5StYewaQsY9R1hrtZtzg-5MkeN0DR7VPen2Tux_TU,7686
8
+ crystalbuilder/viewer.py,sha256=r37owd9kPre32D2zvIQUqImgySbR0CiuMFfdRfuDYVY,2474
9
+ crystalbuilder/conversions/lumc.py,sha256=WFJbt8Dgy5myWlIzdciHNMpmpeEV3TvmqB6SSvFZ3nw,1327
10
+ crystalbuilder/conversions/t3d.py,sha256=9QzRImME7muk7kG43Nnu7XUpjJi9um0zwWllKbBQM-s,6627
11
+ crystalbuilder-0.5.4.dist-info/METADATA,sha256=e1N8-PHxYERJpcdlnFEoNDFJdRmRyBm_96gdC2bNl40,312
12
+ crystalbuilder-0.5.4.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
13
+ crystalbuilder-0.5.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
+ crystalbuilder-0.5.4.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any