surface-construct 0.8.1__tar.gz → 0.8.2__tar.gz

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.
Files changed (19) hide show
  1. {surface_construct-0.8.1/surface_construct.egg-info → surface_construct-0.8.2}/PKG-INFO +1 -1
  2. {surface_construct-0.8.1 → surface_construct-0.8.2}/setup.py +1 -1
  3. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/sampling.py +37 -14
  4. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/surface_grid.py +1 -1
  5. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/utils.py +33 -1
  6. {surface_construct-0.8.1 → surface_construct-0.8.2/surface_construct.egg-info}/PKG-INFO +1 -1
  7. {surface_construct-0.8.1 → surface_construct-0.8.2}/LICENSE +0 -0
  8. {surface_construct-0.8.1 → surface_construct-0.8.2}/README.md +0 -0
  9. {surface_construct-0.8.1 → surface_construct-0.8.2}/setup.cfg +0 -0
  10. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/__init__.py +0 -0
  11. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/atoms.py +0 -0
  12. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/db.py +0 -0
  13. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/default_parameter.py +0 -0
  14. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/structure.py +0 -0
  15. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct/surface.py +0 -0
  16. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct.egg-info/SOURCES.txt +0 -0
  17. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct.egg-info/dependency_links.txt +0 -0
  18. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct.egg-info/requires.txt +0 -0
  19. {surface_construct-0.8.1 → surface_construct-0.8.2}/surface_construct.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: surface_construct
3
- Version: 0.8.1
3
+ Version: 0.8.2
4
4
  Summary: Surface termination construction especially for complex model, such as oxides or carbides.
5
5
  Home-page: https://gitee.com/pjren/surface_construct/
6
6
  Author: ren
@@ -18,7 +18,7 @@ install_requires = [
18
18
 
19
19
  setup(
20
20
  name='surface_construct',
21
- version='0.8.1',
21
+ version='0.8.2',
22
22
  packages=['surface_construct'],
23
23
  url='https://gitee.com/pjren/surface_construct/',
24
24
  license='GPL',
@@ -1,17 +1,37 @@
1
1
  """
2
2
  TODO: 关键点采样:top 位置、hollow位,bridge 位等等。
3
3
  """
4
- from logging import warning
5
-
4
+ import itertools
6
5
  import numpy as np
7
6
  from ase.geometry import get_distances
8
7
  from scipy.spatial import ConvexHull
9
8
  from scipy.spatial.distance import cdist
9
+ from scipy.special import comb
10
10
  from sklearn.cluster import KMeans as Cluster
11
11
  import random
12
12
 
13
13
  from surface_construct.utils import furthest_sites
14
14
 
15
+ MIN_HULL_ANGLE_COS = np.cos(np.pi * 30 / 180)
16
+
17
+ def hull_vertices(hull):
18
+ hsimplices = hull.simplices
19
+ hvertices = hull.vertices
20
+ hnorms = hull.equations[:,0:-1]
21
+ ndim = hsimplices.shape[1]
22
+ vertices = []
23
+ # 去掉 hull 的 simplices 的角度较大的点
24
+ for i in hvertices:
25
+ p0_facets_idx = np.argwhere(hsimplices == i)[:,0]
26
+ p0_norms = hnorms[p0_facets_idx]
27
+ cosangle = lambda a,b: a.dot(b) / (np.linalg.norm(a) * np.linalg.norm(b))
28
+ # 求 i 凸点相邻的超平面的法向向量之间的夹角。如果存在夹角小于30度,即平面之间的夹角大于150度,则排除该点。反之,保留该点。
29
+ norm_angle_cos = np.absolute([cosangle(a,b) for a,b in itertools.combinations(p0_norms, 2)])
30
+ if np.sum(norm_angle_cos < MIN_HULL_ANGLE_COS) >= comb(ndim,2):
31
+ vertices.append(i)
32
+
33
+ return vertices
34
+
15
35
 
16
36
  def addition_samples(sg_obj, size=None, probability=None, **kwargs):
17
37
  if 'seed' in kwargs:
@@ -138,19 +158,20 @@ class InitialSampling(SamplingBase):
138
158
 
139
159
  def _samples(self, size, **kwargs):
140
160
  hull = ConvexHull(self.sg_obj.vector)
141
- vertices = []
161
+ #vertices = []
142
162
  # 去掉 hull 的 simplices 的角度较大的点
143
- for i in hull.vertices:
144
- p1_idx, p2_idx = np.argwhere(hull.simplices == i)
145
- p0 = hull.points[i]
146
- p1 = hull.points[hull.simplices[p1_idx[0],1-p1_idx[1]]]
147
- p2 = hull.points[hull.simplices[p2_idx[0],1-p2_idx[1]]]
148
- a = p1 - p0
149
- b = p2 - p0
150
- cosangle = a.dot(b)/(np.linalg.norm(a) * np.linalg.norm(b))
151
- if cosangle > np.cos(np.pi*150/180):
152
- vertices.append(i)
163
+ #for i in hull.vertices:
164
+ # p1_idx, p2_idx = np.argwhere(hull.simplices == i)
165
+ # p0 = hull.points[i]
166
+ # p1 = hull.points[hull.simplices[p1_idx[0],1-p1_idx[1]]]
167
+ # p2 = hull.points[hull.simplices[p2_idx[0],1-p2_idx[1]]]
168
+ # a = p1 - p0
169
+ # b = p2 - p0
170
+ # cosangle = a.dot(b)/(np.linalg.norm(a) * np.linalg.norm(b))
171
+ # if cosangle > MIN_HULL_ANGLE_COS:
172
+ # vertices.append(i)
153
173
  # 聚类,vector_mesh
174
+ vertices = hull_vertices(hull)
154
175
  n_vector_mesh = int(hull.volume / (self.sg_obj._vector_unit *
155
176
  self.sg_obj.interval)**self.sg_obj.vector.shape[1]) + 1
156
177
  cluster0 = Cluster(n_clusters=n_vector_mesh)
@@ -162,9 +183,11 @@ class InitialSampling(SamplingBase):
162
183
  self.sg_obj._clusters = cluster
163
184
  nvert = len(vertices)
164
185
  if nvert >= size:
165
- warning("Sample number better be larger than {nvert}!")
186
+ print(f"Warning: Sample number better be larger than {nvert}!")
166
187
  if size == 1:
167
188
  sample_idx = np.random.choice(vertices,1)
189
+ elif size==nvert:
190
+ sample_idx = vertices
168
191
  else:
169
192
  sample_idx = [vertices[i] for i in
170
193
  furthest_sites(self.sg_obj.vector[vertices], size)]
@@ -321,7 +321,7 @@ class SurfaceGrid:
321
321
  k = d_vector / self.interval
322
322
  return np.min(k)
323
323
 
324
- def grid_sample(self, probability=None, N=1, **kwargs):
324
+ def grid_sample(self, N=1, probability=None, **kwargs):
325
325
  """
326
326
  Warning: Obsoleted, replaced by Sampling class
327
327
  :param probability:
@@ -117,7 +117,7 @@ class GridGenerator:
117
117
  """
118
118
  self.atoms = atoms
119
119
  self._grid = None
120
- self.atoms_num_type = set(atoms.numbers)
120
+ self.atoms_num_type = sorted(set(atoms.numbers))
121
121
  self.interval = interval
122
122
 
123
123
  if subtype is None:
@@ -299,6 +299,38 @@ class GridGenerator:
299
299
  print("Too much grid number, it will be very slow.")
300
300
  view(self.atoms + ase.Atoms(symbols=['X'] * len(self.grid), positions=self.grid))
301
301
 
302
+ def get_grid_site_type(self, site_dict=None):
303
+ """
304
+ 根据第一近邻原子返回格点所对应的类型
305
+ :param site_dict: 格点的类型字典
306
+ example: {0:((atom_num, count),(atom_num, count),...), ..., 'next_idx':int}
307
+ :return: site label for each grid, site_dict
308
+ """
309
+
310
+ if site_dict is None:
311
+ site_dict = {'next_idx': 0}
312
+ _, Dga = get_distances(self.grid, self.atoms.positions, use_ase=True, cell=self.atoms.cell, pbc=self.atoms.pbc)
313
+ Lga = (Dga - (self.rsub+self.rads)*1.1 < 0) # 格点与原子的连接性。如果距离小于半径之和,则为不连接
314
+ LTga = np.asarray([(Lga & (self.atoms.numbers==n1)).sum(-1) for n1 in self.atoms_num_type]).T # 每个格点相连类矩阵
315
+ label_T_set = sorted(set(tuple(i) for i in LTga)) # 以原子类型区分,不同格点的类别集合
316
+ site_label = tuple(tuple((self.atoms_num_type[idx], l) for idx, l in enumerate(label)) for label in label_T_set)
317
+ if site_dict is None:
318
+ site_dict = {i:v for i,v in enumerate(site_label)}
319
+ site_dict['next_idx'] = len(site_label)
320
+ else:
321
+ # 比较新旧字典,如果有新的,就加入到 site_dict 中
322
+ old_site_label = tuple(v for k,v in site_dict.items() if type(k) == int)
323
+ new_site = [i for i in site_label if i not in old_site_label]
324
+ for ns in new_site:
325
+ idx = site_dict['next_idx']
326
+ site_dict[idx] = ns
327
+ site_dict['next_idx'] = idx + 1
328
+ site_dict_reverse = {tuple(iv[1] for iv in v):i for i,v in site_dict.items() if type(i)==int}
329
+ grid_T_label = [site_dict_reverse[tuple(i)] for i in LTga]
330
+ self.grid_site_type = grid_T_label
331
+ self.site_type_dict = site_dict
332
+ return grid_T_label, site_dict
333
+
302
334
 
303
335
  def rattle(positions, stdev=0.001, rng=None, seed=None):
304
336
  """Rattle the grid to make the vector distribution more smooth.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: surface_construct
3
- Version: 0.8.1
3
+ Version: 0.8.2
4
4
  Summary: Surface termination construction especially for complex model, such as oxides or carbides.
5
5
  Home-page: https://gitee.com/pjren/surface_construct/
6
6
  Author: ren