surface-construct 0.12.5__tar.gz → 0.12.7__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 (39) hide show
  1. {surface_construct-0.12.5/surface_construct.egg-info → surface_construct-0.12.7}/PKG-INFO +1 -1
  2. {surface_construct-0.12.5 → surface_construct-0.12.7}/setup.py +1 -1
  3. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/sg_sampler.py +27 -7
  4. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/structures/surface_grid.py +13 -7
  5. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/tasks/sitesampling.py +5 -0
  6. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/tasks/vipsitetask.py +28 -27
  7. {surface_construct-0.12.5 → surface_construct-0.12.7/surface_construct.egg-info}/PKG-INFO +1 -1
  8. {surface_construct-0.12.5 → surface_construct-0.12.7}/tests/test_task.py +8 -3
  9. {surface_construct-0.12.5 → surface_construct-0.12.7}/LICENSE +0 -0
  10. {surface_construct-0.12.5 → surface_construct-0.12.7}/README.md +0 -0
  11. {surface_construct-0.12.5 → surface_construct-0.12.7}/setup.cfg +0 -0
  12. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/__init__.py +0 -0
  13. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/db.py +0 -0
  14. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/default_parameter.py +0 -0
  15. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/structures/__init__.py +0 -0
  16. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/structures/adsorbate.py +0 -0
  17. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/structures/combiner.py +0 -0
  18. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/structures/pymsym_test.py +0 -0
  19. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/structures/surface.py +0 -0
  20. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/tasks/__init__.py +0 -0
  21. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/tasks/afm.py +0 -0
  22. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/tasks/taskbase.py +0 -0
  23. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/tasks/terminations.py +0 -0
  24. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/utils/__init__.py +0 -0
  25. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/utils/atoms.py +0 -0
  26. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/utils/geometry.py +0 -0
  27. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/utils/pymsym_wrapper.py +0 -0
  28. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/utils/spglib_wrapper.py +0 -0
  29. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct/utils/weight_functions.py +0 -0
  30. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct.egg-info/SOURCES.txt +0 -0
  31. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct.egg-info/dependency_links.txt +0 -0
  32. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct.egg-info/requires.txt +0 -0
  33. {surface_construct-0.12.5 → surface_construct-0.12.7}/surface_construct.egg-info/top_level.txt +0 -0
  34. {surface_construct-0.12.5 → surface_construct-0.12.7}/tests/test_adsorbate.py +0 -0
  35. {surface_construct-0.12.5 → surface_construct-0.12.7}/tests/test_combiner.py +0 -0
  36. {surface_construct-0.12.5 → surface_construct-0.12.7}/tests/test_sampling1.py +0 -0
  37. {surface_construct-0.12.5 → surface_construct-0.12.7}/tests/test_sampling2.py +0 -0
  38. {surface_construct-0.12.5 → surface_construct-0.12.7}/tests/test_simple_surface.py +0 -0
  39. {surface_construct-0.12.5 → surface_construct-0.12.7}/tests/test_surface_grid.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: surface_construct
3
- Version: 0.12.5
3
+ Version: 0.12.7
4
4
  Summary: Surface construction and surface reaction sampling tools.
5
5
  Home-page: https://gitee.com/pjren/surface_construct/
6
6
  Author: ren
@@ -15,7 +15,7 @@ install_requires = [
15
15
 
16
16
  setup(
17
17
  name='surface_construct',
18
- version='0.12.5',
18
+ version='0.12.7',
19
19
  packages=find_packages(),
20
20
  url='https://gitee.com/pjren/surface_construct/',
21
21
  license='GPL',
@@ -165,11 +165,22 @@ class MaxSigmaSGSampler(SGSamplerBase):
165
165
  def _samples(self, size, **kwargs):
166
166
  if 'energy' in self.sg_obj.grid_property:
167
167
  # 如果已经读入了一些能量,则返回误差最大的点
168
- sigma_array = self.sg_obj.grid_property['energy']
168
+ sigma_array = self.sg_obj.grid_property_sigma['energy']
169
169
  sigma0 = sigma_array.max()
170
- idx_list = np.argwhere(sigma_array <= sigma0-0.1).flatten().tolist()
171
- idx = random.sample(idx_list, size)
172
- return idx
170
+ if len(sigma_array) < size:
171
+ raise ValueError("Number of points should greater than sample!")
172
+ elif len(sigma_array) == size:
173
+ return np.asarray(range(len(sigma_array)))
174
+ else:
175
+ delta = 0.01
176
+ idx_list = []
177
+ while len(idx_list) < size:
178
+ idx_list = np.argwhere(sigma_array > sigma0-delta).flatten().tolist()
179
+ # 排除掉已经采过的点
180
+ idx_list = [i for i in idx_list if i not in self.sg_obj.calculated_sample]
181
+ delta += 0.01
182
+ idx = random.sample(idx_list, min(size, len(idx_list)))
183
+ return idx
173
184
  else:
174
185
  raise "No energy for all population, pls do initial sampling first!"
175
186
 
@@ -181,10 +192,19 @@ class MinEnergySGSampler(SGSamplerBase):
181
192
  def _samples(self, size, **kwargs):
182
193
  if 'energy' in self.sg_obj.grid_property:
183
194
  E_array = self.sg_obj.grid_property['energy']
184
- # 如果已经读入了一些能量,则返回能量最低的点 (<0.1eV 以内,然后随机选一个)
195
+ if len(E_array) < size:
196
+ raise ValueError("Number of points should greater than sample!")
197
+ elif len(E_array) == size:
198
+ return np.asarray(range(len(E_array)))
185
199
  E0 = E_array.min()
186
- idx_list = np.argwhere(E_array <= E0+0.1).flatten().tolist()
187
- idx = random.sample(idx_list, size)
200
+ delta = 0.1
201
+ idx_list = []
202
+ while len(idx_list) < size:
203
+ # 如果已经读入了一些能量,则返回能量最低的点 (<delta eV 以内,然后随机选一个)
204
+ idx_list = np.argwhere(E_array <= E0+0.1).flatten().tolist()
205
+ idx_list = [i for i in idx_list if i not in self.sg_obj.calculated_sample]
206
+ delta += 0.1
207
+ idx = random.sample(idx_list, min(size, len(idx_list)))
188
208
  return idx
189
209
  else:
190
210
  raise "No energy for all population, pls do initial sampling first!"
@@ -770,13 +770,19 @@ class SurfaceGrid:
770
770
  :return:
771
771
  """
772
772
  if self._vector_interval is None:
773
- nsample = 100
773
+ nsample = min(100, len(self.points)-1) # 如果 points 被过滤了,就需要修改了。
774
774
  rng = np.random.default_rng()
775
- idx_0 = rng.choice(range(len(self.points)-1), size=nsample)
775
+ if nsample < 10:
776
+ comb = itertools.combinations(range(len(self.points)-1), nsample)
777
+ idx_0 = rng.choice(list(comb))
778
+ else:
779
+ idx_0 = rng.choice(range(len(self.points)-1), size=nsample)
776
780
  idx_1 = idx_0+1
777
- idx = np.asarray([[i,j] for i,j in zip(idx_0, idx_1) if (i not in idx_1 and j not in idx_0)])
781
+ idx = np.asarray([[i,j] for i,j in zip(idx_0, idx_1)])
778
782
  d_grid = np.linalg.norm(self.points[idx[:, 0]] - self.points[idx[:, 1]], axis=1)
779
- idx = idx[d_grid<1.2 * self.interval]
783
+ tol = 1.2 * self.interval
784
+ if np.any(d_grid<tol):
785
+ idx = idx[d_grid<tol]
780
786
  d_vector = np.linalg.norm(self.vector[idx[:,0]]-self.vector[idx[:,1]], axis=1).mean()
781
787
  k = d_vector / self.interval
782
788
  self._vector_interval = np.min(k)
@@ -917,11 +923,11 @@ class SurfaceGrid:
917
923
  try:
918
924
  length_scale_grid = 1.0 # 实空间的length scale, 1 angstrom
919
925
  length_scale_vector = length_scale_grid * self.vector_interval
920
- length_scale_bounds = (length_scale_vector/2.0, length_scale_vector*2.0)
926
+ length_scale_bounds = (length_scale_vector/10.0, length_scale_vector*10.0)
921
927
  length_scale = length_scale_vector # 向量空间的 length_scale, isotropic
922
928
  except IndexError:
923
929
  length_scale = 1.0
924
- length_scale_bounds = (1e-5, 1e5)
930
+ length_scale_bounds = (1e-3, 1e3)
925
931
  rbf_kernel = RBF(length_scale=length_scale, length_scale_bounds=length_scale_bounds)
926
932
  # noise kernel
927
933
  noise_level_dict = {
@@ -935,7 +941,7 @@ class SurfaceGrid:
935
941
  noise_level_norm = np.abs(noise_level / scaler.scale_[0]) # 标准化缩放
936
942
  white_kernel = WhiteKernel(noise_level=noise_level_norm, noise_level_bounds='fixed')
937
943
  # 总的 kernel
938
- constant_kernel = ConstantKernel(constant_value=1.0, constant_value_bounds='fixed')
944
+ constant_kernel = ConstantKernel(constant_value=1.0, constant_value_bounds=(0.1,10))
939
945
  kernel = constant_kernel * rbf_kernel + white_kernel
940
946
  gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=9, alpha=noise_level_norm*0.01)
941
947
  print(f"Kernel parameters before fit:{kernel})")
@@ -171,6 +171,11 @@ class SurfaceSiteSampleTask(TaskBase):
171
171
  self.sg_obj.del_sample(grid_idx)
172
172
 
173
173
  def run(self):
174
+ # 在新的采样之前先进行已经采到但是未计算的点
175
+ uncalc_samples = [idx for idx in self.sg_obj.sample_idx if not self.sg_obj.sample_dct[idx]['calculated']]
176
+ for grid_idx in uncalc_samples:
177
+ self.irun(grid_idx, fit=False)
178
+
174
179
  for isampler in self.sampler:
175
180
  size = isampler.get("size", 1)
176
181
  sg_sampler = isampler.get("surface")
@@ -1,7 +1,5 @@
1
- import random
1
+ import os
2
2
 
3
- import ase.data
4
- import numpy as np
5
3
  from matplotlib import pyplot as plt
6
4
  from matplotlib.patches import Circle
7
5
 
@@ -10,40 +8,43 @@ from .sitesampling import SurfaceSiteSampleTask
10
8
  class VIPSiteTask(SurfaceSiteSampleTask):
11
9
  def __init__(self, exclude=None, include=None, **kwargs):
12
10
  super().__init__(**kwargs)
11
+ if not os.path.isfile(self.hist_pkl):
12
+ vip_id = self.sg_obj.vip_id
13
+ grid_site_type, site_type_dict = self.sg_obj.get_grid_site_type()
14
+ if exclude is None and include is None:
15
+ msg = [f"Either exclude or include must be specified"]
16
+ msg += [f"Possible site types are {len(site_type_dict)} in total:"]
17
+ msg += [f"{k}: {v}" for k,v in site_type_dict.items() if type(k) in (int,)]
18
+ raise ValueError('\n'.join(msg))
19
+ elif exclude is not None and include is not None:
20
+ raise ValueError("Can not specified exclude and include at the same time")
21
+ elif exclude is not None and include is None:
22
+ filtered = [i for i in vip_id if site_type_dict[grid_site_type[i]] not in exclude]
23
+ else:
24
+ filtered = [i for i in vip_id if site_type_dict[grid_site_type[i]] in include]
13
25
 
14
- vip_id = self.sg_obj.vip_id
15
- grid_site_type, site_type_dict = self.sg_obj.get_grid_site_type()
16
- if exclude is None and include is None:
17
- msg = [f"Either exclude or include must be specified"]
18
- msg += [f"Possible site types are {len(site_type_dict)} in total:"]
19
- msg += [f"{k}: {v}" for k,v in site_type_dict.items() if type(k) in (int,)]
20
- raise ValueError('\n'.join(msg))
21
- elif exclude is not None and include is not None:
22
- raise ValueError("Can not specified exclude and include at the same time")
23
- elif exclude is not None and include is None:
24
- filtered = [i for i in vip_id if site_type_dict[grid_site_type[i]] not in exclude]
25
- else:
26
- filtered = [i for i in vip_id if site_type_dict[grid_site_type[i]] in include]
27
-
28
- points = self.sg_obj.points[filtered]
29
- vector = self.sg_obj.vector[filtered]
30
- raw_vector = self.sg_obj._raw_vector[filtered]
31
- self.sg_obj.points = points
32
- self.sg_obj.vector = vector
33
- self.sg_obj._raw_vector = raw_vector
34
- self.sg_obj.vectorgen = None
26
+ points = self.sg_obj.points[filtered]
27
+ vector = self.sg_obj.vector[filtered]
28
+ raw_vector = self.sg_obj._raw_vector[filtered]
29
+ _ = self.sg_obj.vector_interval # 此处call 一下,用于后面的 fit 中的参数
30
+ self.sg_obj.points = points
31
+ self.sg_obj.vector = vector
32
+ self.sg_obj._raw_vector = raw_vector
33
+ self.sg_obj.vectorgen = None
35
34
 
36
- sampler_size = 0
35
+ sampler_size = len(self.sg_obj.calculated_sample)
37
36
  new_sampler = []
38
37
  for isampler in self.sampler: # 不需要初始采样和key 点采样
39
38
  if isampler['surface'] not in ('InitialSGSampler', 'KeyPointSGSampler'):
40
39
  sampler_size += isampler.get('size', 0)
41
40
  new_sampler.append(isampler)
41
+ else:
42
+ print("Warning: InitialSGSampler or KeyPointSGSampler should not applied in VIP sampling.")
42
43
 
43
44
  # 如果 filter 之后的点小于等于 self.sampler['size'], 重新定义sampler
44
- if sampler_size >= len(points):
45
+ if sampler_size >= len(self.sg_obj.points):
45
46
  self.sampler = [{
46
- 'size': len(points), # 采样大小
47
+ 'size': len(self.sg_obj.points)-len(self.sg_obj.calculated_sample), # 采样大小
47
48
  'surface': "RandomSGSampler", # 表面采样方法
48
49
  }]
49
50
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: surface_construct
3
- Version: 0.12.5
3
+ Version: 0.12.7
4
4
  Summary: Surface construction and surface reaction sampling tools.
5
5
  Home-page: https://gitee.com/pjren/surface_construct/
6
6
  Author: ren
@@ -3,6 +3,7 @@ import shutil
3
3
  from random import randint
4
4
 
5
5
  import ase.io
6
+ import numpy as np
6
7
  import pytest
7
8
  from ase import Atom, Atoms
8
9
  from ase.constraints import FixAtoms
@@ -175,7 +176,7 @@ class TestTask:
175
176
  'weight': (0.5, 0.5), # 表面采样方法的权重
176
177
  } # 第二步采样
177
178
  ]
178
- task_obj = AFMTask(combiner=com_obj, sampler=sampler, optimizer=LBFGS, nz=10) # nz 定义 z方向采多少样
179
+ task_obj = AFMTask(combiner=com_obj, sampler=sampler, optimizer=None, nz=3) # nz 定义 z方向采多少样
179
180
  task_obj.print_task_info()
180
181
  task_obj.run()
181
182
  print('Done')
@@ -195,12 +196,12 @@ class TestTask:
195
196
  ads_grid_comb = AdsGridCombiner(sg_obj, ads_obj)
196
197
  sampler =[
197
198
  {
199
+ 'surface': "RandomSGSampler", # 第一步,随机表面采样方法。
198
200
  'size': 2, # 采样大小
199
- 'surface': "RandomSGSampler", # 表面采样方法
200
201
  },
201
202
  {
202
- 'size': 4, # 采样大小
203
203
  'surface': ("MaxDiversitySGSampler", "MinEnergySGSampler", "MaxSigmaSGSampler"), # 表面采样方法
204
+ 'size': 4, # 采样大小
204
205
  'weight': (0.4, 0.3, 0.3), # 表面采样方法的权重
205
206
  } # 第二步采样
206
207
  ]
@@ -208,4 +209,8 @@ class TestTask:
208
209
  task_obj.print_task_info()
209
210
  task_obj.run()
210
211
  task_obj.plot()
212
+ energies = task_obj.sg_obj.grid_property['energy']
213
+ np.savetxt('energies.csv', np.column_stack((sg_obj.points, energies)),
214
+ header='x, y ,z , energy/eV',
215
+ delimiter=',', fmt='%f')
211
216
  print('Done')