ion-CSP 2.2.0__py3-none-any.whl → 2.2.2__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.
ion_CSP/__init__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  __author__ = "Ze Yang"
2
2
  __contact__ = "yangze1995007@163.com"
3
3
  __license__ = "MIT"
4
- __version__ = "2.2.0"
5
- __date__ = "2025-06-27"
4
+ __version__ = "2.2.2"
5
+ __date__ = "2025-07-02"
6
6
 
7
7
 
8
8
  try:
ion_CSP/convert_SMILES.py CHANGED
@@ -131,7 +131,7 @@ class SmilesProcessing:
131
131
  f"{self.converted_dir}/charge_{charge}"
132
132
  )
133
133
  os.makedirs(charge_dir, exist_ok=True)
134
- # 通过SMILE_to函数依次处理SMILES码
134
+ # 通过_convert_SMILES函数依次处理SMILES码
135
135
  for _, row in group.iterrows():
136
136
  result_code, basename = self._convert_SMILES(
137
137
  dir=charge_dir,
@@ -238,8 +238,10 @@ class SmilesProcessing:
238
238
  for folder in folders:
239
239
  folder_dir = os.path.join(self.converted_dir, folder)
240
240
  if not os.path.exists(folder_dir):
241
- logging.error(f'Provided folder {folder} is not in the directory {folder_dir}')
242
- continue
241
+ folder_dir = os.path.join(self.base_dir, folder)
242
+ if not os.path.exists(folder_dir):
243
+ logging.error(f'Provided folder {folder} is not either in the work directory or the converted directory.\n')
244
+ continue
243
245
  # 获取文件夹中所有以 .gjf 结尾的文件
244
246
  gjf_files = [
245
247
  f for f in os.listdir(folder_dir) if f.endswith(".gjf")
ion_CSP/gen_opt.py CHANGED
@@ -116,9 +116,8 @@ class CrystalGenerator:
116
116
  pyxtal_structure.to_file(POSCAR_path, fmt="poscar")
117
117
  total_count += 1
118
118
  group_count += 1
119
+ # 捕获对于某一空间群生成结构的运行时间过长、组成兼容性错误、对称性兼容性错误等异常,使结构生成能够完全进行而不中断
119
120
  except (RuntimeError, Comp_CompatibilityError, Symm_CompatibilityError) as e:
120
- # 捕获对于某一空间群生成结构的运行时间过长、组成兼容性错误、对称性兼容性错误等异常,使结构生成能够完全进行而不中断
121
- logging.error(f"Generating structure error: {e}")
122
121
  # 记录异常类型并跳出当前空间群的生成循环
123
122
  exception_message = type(e).__name__
124
123
  break
@@ -154,7 +153,11 @@ class CrystalGenerator:
154
153
  # 按顺序处理POSCAR文件,首先复制一份无数字后缀的POSCAR文件
155
154
  shutil.copy(f"{self.POSCAR_dir}/{filename}", f"{self.POSCAR_dir}/POSCAR")
156
155
  try:
157
- subprocess.run(["nohup", "phonopy", "--symmetry", "POSCAR"], check=True)
156
+ subprocess.run(
157
+ ["nohup", "phonopy", "--symmetry", "POSCAR"],
158
+ check=True,
159
+ stdout=subprocess.DEVNULL
160
+ )
158
161
  except subprocess.CalledProcessError as e:
159
162
  # 新增:捕获phonopy执行错误
160
163
  logging.error(f"Phonopy execution failed for {filename}: {str(e)}")
@@ -168,9 +171,6 @@ class CrystalGenerator:
168
171
 
169
172
  # 检查生成的POSCAR中的原子数,如果不匹配则删除该POSCAR并在日志中记录
170
173
  if cell_atoms != self.cell_atoms:
171
- error_message = f"Atom number mismatch ({cell_atoms} vs {self.cell_atoms})"
172
- print(f"{filename} - {error_message}")
173
-
174
174
  # 新增:回溯空间群归属
175
175
  poscar_index = int(filename.split('_')[1]) # 提取POSCAR编号
176
176
  space_group = self._find_space_group(poscar_index)
ion_CSP/mlp_opt.py CHANGED
@@ -1,23 +1,27 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  import os
4
+ os.environ["MKL_NUM_THREADS"] = "1"
5
+ os.environ["NUMEXPR_NUM_THREADS"] = "1"
6
+ os.environ["OMP_NUM_THREADS"] = "1"
7
+
4
8
  import time
5
9
  import numpy as np
6
10
  import multiprocessing
7
11
  from ase.io.vasp import read_vasp
8
12
  from ase.optimize import LBFGS
9
- from ase.constraints import UnitCellFilter
13
+ # from ase.constraints import UnitCellFilter
14
+ from ase.filters import ExpCellFilter
10
15
  from deepmd.calculator import DP
16
+ # from mattersim.forcefield import MatterSimCalculator
11
17
 
12
18
  # 根据脚本位置确定model.pt文件的位置, 减少错误发生
13
19
  base_dir = os.path.dirname(__file__)
14
20
  relative_path = './model.pt'
15
21
  file_path = os.path.join(base_dir, relative_path)
16
22
  calc = DP(file_path)
17
- """
18
- structure optimization with DP model and ASE
19
- PSTRESS and fmax should exist in input.dat
20
- """
23
+ # calc = MatterSimCalculator(device="cuda")
24
+
21
25
 
22
26
  def get_element_num(elements):
23
27
  """
@@ -51,7 +55,7 @@ def write_CONTCAR(element, ele, lat, pos, index):
51
55
  pos: atomic positions in direct coordinates
52
56
  index: index for the output file"""
53
57
  f = open(f'{base_dir}/CONTCAR_'+str(index),'w')
54
- f.write('ASE-DPKit-Optimization\n')
58
+ f.write('ASE-MLP-Optimization\n')
55
59
  f.write('1.0\n')
56
60
  for i in range(3):
57
61
  f.write('%15.10f %15.10f %15.10f\n' % tuple(lat[i]))
@@ -139,7 +143,7 @@ def get_indexes():
139
143
 
140
144
  def run_opt(index: int):
141
145
  """
142
- Using the ASE&DP to Optimize Configures
146
+ Using the ASE & MLP to Optimize Configures
143
147
  :params
144
148
  index: index of the POSCAR file to be optimized
145
149
  """
@@ -147,7 +151,7 @@ def run_opt(index: int):
147
151
  os.system(f'mv {base_dir}/OUTCAR {base_dir}/OUTCAR-last')
148
152
  fmax, pstress = 0.03, 0
149
153
 
150
- print('Start to Optimize Structures by DP----------')
154
+ print('Start to Optimize Structures by MLP----------')
151
155
 
152
156
  Opt_Step = 2000
153
157
  start = time.time()
@@ -158,7 +162,8 @@ def run_opt(index: int):
158
162
  aim_stress = 1.0 * pstress * 0.01 * 0.6242 / 10.0
159
163
  atoms = read_vasp('POSCAR_'+str(index))
160
164
  atoms.calc = calc
161
- ucf = UnitCellFilter(atoms, scalar_pressure=aim_stress)
165
+ # ucf = UnitCellFilter(atoms, scalar_pressure=aim_stress)
166
+ ucf = ExpCellFilter(atoms, scalar_pressure=aim_stress)
162
167
  # optimization
163
168
  opt = LBFGS(ucf)
164
169
  opt.run(fmax=fmax,steps=Opt_Step)
@@ -8,7 +8,7 @@ from ion_CSP.identify_molecules import identify_molecules, molecules_information
8
8
 
9
9
  class ReadMlpDensity:
10
10
 
11
- def __init__(self, work_dir:str):
11
+ def __init__(self, work_dir:str, folder:str = '2_mlp_optimized'):
12
12
  """
13
13
  This class is designed to read and process MLP optimized files, specifically CONTCAR files, to calculate and sort their densities.
14
14
  The class also provides functionality to process these files using phonopy for symmetry analysis and primitive cell generation.
@@ -20,7 +20,7 @@ class ReadMlpDensity:
20
20
  self.base_dir = work_dir
21
21
  os.chdir(self.base_dir)
22
22
  # 寻找同一目录下的2_mlp_optimized文件夹
23
- self.folder_dir = os.path.join(self.base_dir, '2_mlp_optimized')
23
+ self.folder_dir = os.path.join(self.base_dir, folder)
24
24
  self.max_density_dir = os.path.join(self.folder_dir, 'max_density')
25
25
  self.primitive_cell_dir = os.path.join(self.folder_dir, 'primitive_cell')
26
26
  print(f"Processing MLP CONTCARs in {self.folder_dir}")
@@ -174,7 +174,11 @@ class ReadMlpDensity:
174
174
  # 使用phonopy模块处理POSCAR结构文件,获取对称化的原胞和常规胞。
175
175
  # 应用晶体的对称操作优化后的原胞可以最好地符合晶体的对称性,减少后续优化计算的复杂性。
176
176
  log.write(f'\nProcessing file: {new_CONTCAR_filename}\n')
177
- result = subprocess.run(['nohup', 'phonopy', '--symmetry', 'POSCAR'], stderr=subprocess.STDOUT)
177
+ result = subprocess.run(
178
+ ["nohup", "phonopy", "--symmetry", "POSCAR"],
179
+ check=True,
180
+ stdout=subprocess.DEVNULL
181
+ )
178
182
  log.write(f'Finished processing file: {new_CONTCAR_filename} with return code: {result.returncode}\n')
179
183
  # 将phonopy生成的PPOSCAR(对称化原胞)和BPOSCAR(对称化常规胞)放到对应的文件夹中,并将文件名改回POSCAR_index
180
184
  shutil.move(f'{self.phonopy_dir}/PPOSCAR', f'{self.primitive_cell_dir}/{new_CONTCAR_filename}')
ion_CSP/run/main_EE.py CHANGED
@@ -109,6 +109,8 @@ def combination_task(work_dir, config):
109
109
  elif config["empirical_estimate"]["sort_by"] == "nitrogen":
110
110
  # 最终将预测的离子晶体氮含量以及对应的组分输出到 .csv 文件并根据氮含量从大到小排序
111
111
  combination.nitrogen_content_estimate()
112
+ elif config["empirical_estimate"]["sort_by"] == "NC_ratio":
113
+ combination.carbon_nitrogen_ratio_estimate()
112
114
  # 基于排序依据 sort_by 对应的 .csv 文件创建 combo_n 文件夹,并复制相应的 .gjf 结构文件。
113
115
  if config["empirical_estimate"]["make_combo_dir"]:
114
116
  combination.make_combo_dir(
ion_CSP/task_manager.py CHANGED
@@ -219,7 +219,9 @@ class TaskManager:
219
219
  def task_runner(self, module: str, work_dir: str):
220
220
  """任务执行器 - Task execution handler"""
221
221
  work_dir = Path(work_dir)
222
- work_dir.mkdir(exist_ok=True)
222
+ if not os.path.exists(work_dir):
223
+ print(f"Work directory {work_dir} does not exist")
224
+ return
223
225
 
224
226
  console_log = work_dir / f"main_{module}_console.log"
225
227
  pid_file = work_dir / "pid.txt"
@@ -262,7 +264,7 @@ class TaskManager:
262
264
  std_log.symlink_to(output_log)
263
265
 
264
266
  print('Starting task ......')
265
- time.sleep(6)
267
+ time.sleep(3)
266
268
  logging.info(f"Started {module} module (PID: {process.pid})")
267
269
  print(f"Task started (PID: {process.pid})")
268
270
  print(f"Normalized log file: {std_log}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ion_CSP
3
- Version: 2.2.0
3
+ Version: 2.2.2
4
4
  Summary: Crystal Structure Design Software Based on Molecular/Ionic Configuration.
5
5
  Home-page: https://github.com/bagabaga007/ion_CSP
6
6
  Author: Ze Yang
@@ -14,7 +14,7 @@ Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Requires-Dist: ase==3.23.0
16
16
  Requires-Dist: scipy==1.15.2
17
- Requires-Dist: deepmd-kit==3.0.1
17
+ Requires-Dist: deepmd-kit>=3.0.1
18
18
  Requires-Dist: torch==2.5.0
19
19
  Requires-Dist: dpdispatcher==0.6.7
20
20
  Requires-Dist: numpy==1.26.4
@@ -1,14 +1,14 @@
1
- ion_CSP/__init__.py,sha256=1WGzlZrB669L2oFjKynPwf89qMUaSmlCttuR4864M_Y,356
1
+ ion_CSP/__init__.py,sha256=X870lzd7xUyDvBsUfjnDBqMJbCXtUlGh1hbxqI7coX0,356
2
2
  ion_CSP/__main__.py,sha256=XlNCx5eMSrL7yld9ddSYXhjXvg2ZYGD_uk9LdqNabvs,74
3
- ion_CSP/convert_SMILES.py,sha256=HAexqf6HXZAqRuMww5BKmU68MIO3d7XIaUtPKv_QwMs,15595
3
+ ion_CSP/convert_SMILES.py,sha256=i_f9cbCAr6SpZUvClZRAPGjK-_v9U9lFGA-06i041Tk,15755
4
4
  ion_CSP/empirical_estimate.py,sha256=aSidH3jyoG39ky-kDNUY0ix8hPefeVVWmPABVjTmy0g,37866
5
- ion_CSP/gen_opt.py,sha256=F_gEopuOO-b-tHfS0V4OMeThktY2QvPGWCVRXOCemfk,21605
5
+ ion_CSP/gen_opt.py,sha256=EEMIPZ7oEOR9iGLRL-eJleHaWBiOK90o4a8_go9f-9o,21468
6
6
  ion_CSP/identify_molecules.py,sha256=GxDWq815Bk_Fq_SR8fe-dbrbEi1YgATVa7UINw3hAu4,5535
7
7
  ion_CSP/log_and_time.py,sha256=Db53LAM2KH_ty6M9_5FF8xDGiULgExh7pcKOvFtS7DQ,11697
8
- ion_CSP/mlp_opt.py,sha256=uJaqjNYLzc4dRogNcGIP_Ukta_fMd5YdYVf9cNweOA4,7029
9
- ion_CSP/read_mlp_density.py,sha256=KwVgniroT46uFQ7_HROd5Fk9YxJCMip1jnufWvHHEiw,12104
8
+ ion_CSP/mlp_opt.py,sha256=NoUSYoGVNVbijsB37xkOy7hwSFIhFTFD6gCB7UVloj0,7249
9
+ ion_CSP/read_mlp_density.py,sha256=0fymqrpqoAmWosnyoNwH3GAvml42skZp_6SLvrXN0SI,12232
10
10
  ion_CSP/steps_opt_monitor.sh,sha256=1klPjnK0gqkDbvI9PtjdK5qidJ5G0Mo8q1SfrlLW5xM,3330
11
- ion_CSP/task_manager.py,sha256=JglPNDKpsv-bjbCm42D4k6GegDkSylX4oDWAdFa-oSU,16569
11
+ ion_CSP/task_manager.py,sha256=62E5s2bkVkRJiKroSGWVfTNYBRbzVcMPqTfZ1FPN61A,16654
12
12
  ion_CSP/upload_download.py,sha256=HXxVQMUydEoHe2vV89wR7De4Ut1lEte6pmp8Q82decI,23800
13
13
  ion_CSP/vasp_processing.py,sha256=Q4OotC5eK4RN4R3GZu5DnLk7wnkYSh-yC1oeGvrtT5U,28436
14
14
  ion_CSP/model/model.pt,sha256=5D9HTP5b7jUOv3kHltT71ORzhgt5p96awjbqC4oZVjQ,24649402
@@ -28,16 +28,16 @@ ion_CSP/param/sub_ori.sh,sha256=JBERlc-VOVCNaKGwiJR8oq7Nyf0KV4JpHEVT5sE5s8E,2497
28
28
  ion_CSP/param/sub_supple.sh,sha256=23cam7WyW7-80J8O-Bs45qYkabk3mxZDgiHZvf48KBM,1887
29
29
  ion_CSP/run/__init__.py,sha256=_9EAXp4cv41ARbxahCkihwqY4F00Y18tBeTauWeD9mw,186
30
30
  ion_CSP/run/main_CSP.py,sha256=UaYHlh7BSxar4uGppPi-V0cFDpB14212Oy6gta59LfA,5898
31
- ion_CSP/run/main_EE.py,sha256=8TFlJx7QhJKGc4qZ2O0ESRYrlySp3r1WjeGLkUBeL5k,6217
31
+ ion_CSP/run/main_EE.py,sha256=rX02_752odK16VTLK2qSHcxPCooPviy27DOlAtOYgpc,6334
32
32
  ion_CSP/run/run_convert_SMILES.py,sha256=85a8-UXPxPo3Yw_iYED_QF47yNTvYRnJHm3PC1d-d_Q,2056
33
33
  ion_CSP/run/run_empirical_estimate.py,sha256=U_yvQ5gMiBkDEabHXLJSAEm0EzGHhSKs6xmWoEC_gjc,2831
34
34
  ion_CSP/run/run_gen_opt.py,sha256=_Zcsu0FkuZTfiGKSWNaK17LiyQ3qrP30F66UN5QemCo,2727
35
35
  ion_CSP/run/run_read_mlp_density.py,sha256=aSJjWS1jH-D7qzx7RnpMPSTH7KEZp2b35dg1b2OQSCM,1864
36
36
  ion_CSP/run/run_upload_download.py,sha256=wuTAdy4bgdduD7TJtgHwo_fTpHKlkAwmgRknClDLYDo,2436
37
37
  ion_CSP/run/run_vasp_processing.py,sha256=hziE4cZwmIWvVaZtwHn9Dl35apYSLlMvSVIbCyd5mFg,1612
38
- ion_csp-2.2.0.dist-info/licenses/LICENSE,sha256=yeL9PshY_rGAt3GKqn8U7NafHifpmZipb-Owu0DDrHo,1070
39
- ion_csp-2.2.0.dist-info/METADATA,sha256=7vO9oy9g9NEA_XQWdWBZSXda1VxTcE8NzuyCvr06VQ8,6314
40
- ion_csp-2.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
- ion_csp-2.2.0.dist-info/entry_points.txt,sha256=NexQJDs9f69kJA2DgoU6tsA3V8a66nadJRem1U_c_6g,54
42
- ion_csp-2.2.0.dist-info/top_level.txt,sha256=aYZa43dDebjLpWPN6bDIlBb6BVwA8gk4ajEjDDK9b9I,8
43
- ion_csp-2.2.0.dist-info/RECORD,,
38
+ ion_csp-2.2.2.dist-info/licenses/LICENSE,sha256=yeL9PshY_rGAt3GKqn8U7NafHifpmZipb-Owu0DDrHo,1070
39
+ ion_csp-2.2.2.dist-info/METADATA,sha256=C35tKmC9pWPtn5ta5Q0ndJVheskSG_kHWhHC4fVcr6Q,6314
40
+ ion_csp-2.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
+ ion_csp-2.2.2.dist-info/entry_points.txt,sha256=NexQJDs9f69kJA2DgoU6tsA3V8a66nadJRem1U_c_6g,54
42
+ ion_csp-2.2.2.dist-info/top_level.txt,sha256=aYZa43dDebjLpWPN6bDIlBb6BVwA8gk4ajEjDDK9b9I,8
43
+ ion_csp-2.2.2.dist-info/RECORD,,