ion-CSP 2.1.9__py3-none-any.whl → 2.2.0__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,7 +1,7 @@
1
1
  __author__ = "Ze Yang"
2
2
  __contact__ = "yangze1995007@163.com"
3
3
  __license__ = "MIT"
4
- __version__ = "2.1.9"
4
+ __version__ = "2.2.0"
5
5
  __date__ = "2025-06-27"
6
6
 
7
7
 
@@ -79,11 +79,11 @@ class EmpiricalEstimation:
79
79
  self.folders = folders
80
80
  self.ratios = ratios
81
81
  self.sort_by = sort_by
82
- if sort_by not in ("density", "nitrogen"):
83
- raise ValueError(f"The sort_by parameter must be either 'density' or 'nitrogen', but got '{sort_by}'")
82
+ if sort_by not in ("density", "nitrogen", "NC_ratio"):
83
+ raise ValueError(f"The sort_by parameter must be either 'density' 'nitrogen' or 'NC_ratio', but got '{sort_by}'")
84
84
  self.density_csv = "sorted_density.csv"
85
85
  self.nitrogen_csv = "sorted_nitrogen.csv"
86
- self.carbon_nitrogen_csv = "specific_C_N_ratio.csv"
86
+ self.NC_ratio_csv = "specific_NC_ratio.csv"
87
87
  # 检查Multiwfn可执行文件是否存在
88
88
  self.multiwfn_path = self._check_multiwfn_executable()
89
89
 
@@ -487,7 +487,7 @@ class EmpiricalEstimation:
487
487
  filtered_data.sort(key=lambda x: (-x[1], -x[2]))
488
488
 
489
489
  # 写入排序后的 .csv 文件
490
- with open(self.carbon_nitrogen_csv, "w", newline="", encoding="utf-8") as csv_file:
490
+ with open(self.NC_ratio_csv, "w", newline="", encoding="utf-8") as csv_file:
491
491
  writer = csv.writer(csv_file)
492
492
  # 动态生成表头
493
493
  num_components = len(combinations[0]) if combinations else 0
@@ -642,6 +642,8 @@ class EmpiricalEstimation:
642
642
  base_csv = self.density_csv
643
643
  elif self.sort_by == 'nitrogen':
644
644
  base_csv = self.nitrogen_csv
645
+ elif self.sort_by == "NC_ratio":
646
+ base_csv = self.NC_ratio_csv
645
647
  if not target_dir:
646
648
  target_dir = f'../2_{self.sort_by}_combos'
647
649
  with open(base_csv, mode='r', newline='') as file:
@@ -140,9 +140,7 @@ class VaspProcessing:
140
140
  task_dir = os.path.join(self.for_vasp_opt_dir, f"{parent}pop{pop}")
141
141
  for job_i in node_jobs[pop]:
142
142
  vasp_dir = mlp_contcar_files[job_i].split("CONTCAR_")[1]
143
- shutil.copytree(
144
- f"{task_dir}/{vasp_dir}", f"{self.vasp_optimized_dir}/{vasp_dir}"
145
- )
143
+ shutil.copytree(f"{task_dir}/{vasp_dir}", f"{self.vasp_optimized_dir}/{vasp_dir}", dirs_exist_ok=True)
146
144
  # 在成功完成 VASP 分步优化后,删除 3_for_vasp_opt/{parent}/pop{n} 文件夹以节省空间
147
145
  shutil.rmtree(task_dir)
148
146
  if machine_inform["context_type"] == "SSHContext":
@@ -256,10 +254,16 @@ class VaspProcessing:
256
254
  task_dir = os.path.join(self.vasp_optimized_dir, f"{parent}pop{pop}")
257
255
  for job_i in node_jobs[pop]:
258
256
  vasp_dir = vasp_optimized_folders[job_i]
259
- shutil.copytree(
260
- f"{task_dir}/{vasp_dir}/fine/final",
261
- f"{self.vasp_optimized_dir}/{vasp_dir}/fine/final",
262
- )
257
+ try:
258
+ shutil.copytree(
259
+ f"{task_dir}/{vasp_dir}/fine/final",
260
+ f"{self.vasp_optimized_dir}/{vasp_dir}/fine/final",
261
+ dirs_exist_ok=True,
262
+ )
263
+ except FileNotFoundError:
264
+ logging.error(
265
+ f"No final optimization results found for {vasp_dir} in {task_dir}"
266
+ )
263
267
  # 在成功完成 VASP 分步优化后,删除 4_vasp_optimized /{parent}/pop{n} 文件夹以节省空间
264
268
  shutil.rmtree(task_dir)
265
269
  if machine_inform["context_type"] == "SSHContext":
@@ -267,127 +271,6 @@ class VaspProcessing:
267
271
  shutil.rmtree(os.path.join(self.vasp_optimized_dir, parent))
268
272
  logging.info("Batch VASP optimization completed!!!")
269
273
 
270
- def dpdisp_vasp_complete_tasks(
271
- self,
272
- machine: str,
273
- resources: str,
274
- nodes: int = 1,
275
- ):
276
- """
277
- Based on the dpdispatcher module, prepare and submit files for optimization on remote server or local machine.
278
- """
279
- # 调整工作目录,减少错误发生
280
- os.chdir(self.for_vasp_opt_dir)
281
- # 读取machine.json和resources.json的参数
282
- if machine.endswith(".json"):
283
- machine = Machine.load_from_json(machine)
284
- elif machine.endswith(".yaml"):
285
- machine = Machine.load_from_yaml(machine)
286
- else:
287
- raise KeyError("Not supported machine file type")
288
- if resources.endswith(".json"):
289
- resources = Resources.load_from_json(resources)
290
- elif resources.endswith(".yaml"):
291
- resources = Resources.load_from_yaml(resources)
292
- else:
293
- raise KeyError("Not supported resources file type")
294
- # 由于dpdispatcher对于远程服务器以及本地运行的forward_common_files的默认存放位置不同,因此需要预先进行判断,从而不改动优化脚本
295
- machine_inform = machine.serialize()
296
- if machine_inform["context_type"] == "SSHContext":
297
- # 如果调用远程服务器,则创建二级目录
298
- parent = "data/"
299
- elif machine_inform["context_type"] == "LocalContext":
300
- # 如果在本地运行作业,则只在后续创建一级目录
301
- parent = ""
302
-
303
- # 获取dir文件夹中所有以prefix_name开头的文件,在此实例中为POSCAR_
304
- mlp_contcar_files = [
305
- f for f in os.listdir(self.for_vasp_opt_dir) if f.startswith("CONTCAR_")
306
- ]
307
- # 创建一个嵌套列表来存储每个节点的任务并将文件平均依次分配给每个节点
308
- # 例如:对于10个结构文件任务分发给4个节点的情况,则4个节点领到的任务分别[0, 4, 8], [1, 5, 9], [2, 6], [3, 7]
309
- node_jobs = [[] for _ in range(nodes)]
310
- for index, file in enumerate(mlp_contcar_files):
311
- node_index = index % nodes
312
- node_jobs[node_index].append(index)
313
- task_list = []
314
- for pop in range(nodes):
315
- forward_files = [
316
- "INCAR_1",
317
- "INCAR_2",
318
- "INCAR_3",
319
- "POTCAR_H",
320
- "POTCAR_C",
321
- "POTCAR_N",
322
- "POTCAR_O",
323
- "sub_final.sh",
324
- ]
325
- backward_files = ["log", "err"]
326
- # 将所有参数文件各复制一份到每个 task_dir 目录下
327
- task_dir = os.path.join(self.for_vasp_opt_dir, f"{parent}pop{pop}")
328
- os.makedirs(task_dir, exist_ok=True)
329
- for file in forward_files:
330
- shutil.copyfile(self.param_dir.joinpath(file), f"{task_dir}/{file}")
331
- for job_i in node_jobs[pop]:
332
- # 将分配好的POSCAR文件添加到对应的上传文件中
333
- forward_files.append(mlp_contcar_files[job_i])
334
- vasp_dir = mlp_contcar_files[job_i].split("CONTCAR_")[1]
335
- # 每个POSCAR文件在优化后都取回对应的CONTCAR和OUTCAR输出文件
336
- backward_files.append(f"{vasp_dir}/*")
337
- backward_files.append(f"{vasp_dir}/fine/*")
338
- backward_files.append(f"{vasp_dir}/fine/final/*")
339
- shutil.copyfile(
340
- f"{self.for_vasp_opt_dir}/{mlp_contcar_files[job_i]}",
341
- f"{task_dir}/{mlp_contcar_files[job_i]}",
342
- )
343
-
344
- remote_task_dir = f"{parent}pop{pop}"
345
- command = "chmod +x sub_final.sh && ./sub_final.sh"
346
- task = Task(
347
- command=command,
348
- task_work_path=remote_task_dir,
349
- forward_files=forward_files,
350
- backward_files=backward_files,
351
- )
352
- task_list.append(task)
353
-
354
- submission = Submission(
355
- work_base=self.for_vasp_opt_dir,
356
- machine=machine,
357
- resources=resources,
358
- task_list=task_list,
359
- )
360
- submission.run_submission()
361
-
362
- # 创建用于存放优化后文件的 4_vasp_optimized 目录
363
- os.makedirs(self.vasp_optimized_dir, exist_ok=True)
364
- mlp_outcar_files = [
365
- f for f in os.listdir(self.for_vasp_opt_dir) if f.startswith("OUTCAR_")
366
- ]
367
- for mlp_contcar, mlp_outcar in zip(mlp_contcar_files, mlp_outcar_files):
368
- shutil.copyfile(
369
- f"{self.for_vasp_opt_dir}/{mlp_contcar}",
370
- f"{self.vasp_optimized_dir}/{mlp_contcar}",
371
- )
372
- shutil.copyfile(
373
- f"{self.for_vasp_opt_dir}/{mlp_outcar}",
374
- f"{self.vasp_optimized_dir}/{mlp_outcar}",
375
- )
376
- for pop in range(nodes):
377
- # 从传回的 pop 文件夹中将结果文件取到 4_vasp_optimized 目录
378
- task_dir = os.path.join(self.for_vasp_opt_dir, f"{parent}pop{pop}")
379
- for job_i in node_jobs[pop]:
380
- vasp_dir = mlp_contcar_files[job_i].split("CONTCAR_")[1]
381
- shutil.copytree(
382
- f"{task_dir}/{vasp_dir}", f"{self.vasp_optimized_dir}/{vasp_dir}"
383
- )
384
- # 在成功完成 VASP 分步优化后,删除 3_for_vasp_opt/{parent}/pop{n} 文件夹以节省空间
385
- shutil.rmtree(task_dir)
386
- if machine_inform["context_type"] == "SSHContext":
387
- # 如果调用远程服务器,则删除data级目录
388
- shutil.rmtree(os.path.join(self.for_vasp_opt_dir, parent))
389
- logging.info("Batch VASP optimization completed!!!")
390
-
391
274
  def read_vaspout_save_csv(self, molecules_prior: bool, relaxation: bool = False):
392
275
  """
393
276
  Read VASP output files in batches and save energy and density to corresponding CSV files in the directory
@@ -626,6 +509,17 @@ class VaspProcessing:
626
509
  writer.writerow(header)
627
510
  for data in datas:
628
511
  writer.writerow(data)
512
+
513
+ logging.info(
514
+ f"Maximum MLP Density: {max(mlp_densities)}, Structure Number: {numbers[mlp_densities.index(max(mlp_densities))]}"
515
+ )
516
+ logging.info(
517
+ f"Maximum Fine Density: {max(fine_densities)}, Structure Number: {numbers[fine_densities.index(max(fine_densities))]}"
518
+ )
519
+ if relaxation:
520
+ logging.info(
521
+ f"Maximum Final Density: {max(final_densities)}, Structure Number: {numbers[final_densities.index(max(final_densities))]}"
522
+ )
629
523
 
630
524
  def export_max_density_structure(self):
631
525
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ion_CSP
3
- Version: 2.1.9
3
+ Version: 2.2.0
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
@@ -28,7 +28,7 @@ Dynamic: home-page
28
28
  Dynamic: license-file
29
29
  Dynamic: requires-python
30
30
 
31
- # 基于分子/离子构型的晶体结构设计软件 V2.1
31
+ # 基于分子/离子构型的晶体结构设计软件 V2.2
32
32
 
33
33
  ## 项目概述
34
34
 
@@ -1,7 +1,7 @@
1
- ion_CSP/__init__.py,sha256=3in4RkuAl_VL3kDHDz_CHQn3zEBtH1Z-H8aFniQbQI8,356
1
+ ion_CSP/__init__.py,sha256=1WGzlZrB669L2oFjKynPwf89qMUaSmlCttuR4864M_Y,356
2
2
  ion_CSP/__main__.py,sha256=XlNCx5eMSrL7yld9ddSYXhjXvg2ZYGD_uk9LdqNabvs,74
3
3
  ion_CSP/convert_SMILES.py,sha256=HAexqf6HXZAqRuMww5BKmU68MIO3d7XIaUtPKv_QwMs,15595
4
- ion_CSP/empirical_estimate.py,sha256=oqZ-yPbcFCgc0MkOu2PU7JWRNm3fXHm6YRq-bozCZoo,37776
4
+ ion_CSP/empirical_estimate.py,sha256=aSidH3jyoG39ky-kDNUY0ix8hPefeVVWmPABVjTmy0g,37866
5
5
  ion_CSP/gen_opt.py,sha256=F_gEopuOO-b-tHfS0V4OMeThktY2QvPGWCVRXOCemfk,21605
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
@@ -10,7 +10,7 @@ ion_CSP/read_mlp_density.py,sha256=KwVgniroT46uFQ7_HROd5Fk9YxJCMip1jnufWvHHEiw,1
10
10
  ion_CSP/steps_opt_monitor.sh,sha256=1klPjnK0gqkDbvI9PtjdK5qidJ5G0Mo8q1SfrlLW5xM,3330
11
11
  ion_CSP/task_manager.py,sha256=JglPNDKpsv-bjbCm42D4k6GegDkSylX4oDWAdFa-oSU,16569
12
12
  ion_CSP/upload_download.py,sha256=HXxVQMUydEoHe2vV89wR7De4Ut1lEte6pmp8Q82decI,23800
13
- ion_CSP/vasp_processing.py,sha256=YhZxEg03n2lwDtoYzpXdUn329QzfOvp4XXm-qTIIIMA,33337
13
+ ion_CSP/vasp_processing.py,sha256=Q4OotC5eK4RN4R3GZu5DnLk7wnkYSh-yC1oeGvrtT5U,28436
14
14
  ion_CSP/model/model.pt,sha256=5D9HTP5b7jUOv3kHltT71ORzhgt5p96awjbqC4oZVjQ,24649402
15
15
  ion_CSP/model/options/README.md,sha256=ifoeNXF2CfwqUjt3Xmh5qUl-e4hfP4eMV4EkqV7GU30,182
16
16
  ion_CSP/model/options/model.ckpt-4000000.pt,sha256=5D9HTP5b7jUOv3kHltT71ORzhgt5p96awjbqC4oZVjQ,24649402
@@ -35,9 +35,9 @@ ion_CSP/run/run_gen_opt.py,sha256=_Zcsu0FkuZTfiGKSWNaK17LiyQ3qrP30F66UN5QemCo,27
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.1.9.dist-info/licenses/LICENSE,sha256=yeL9PshY_rGAt3GKqn8U7NafHifpmZipb-Owu0DDrHo,1070
39
- ion_csp-2.1.9.dist-info/METADATA,sha256=OM9yIEVI-_77HaYxgA4qIfed2BRTs34mNgJbfLHYyFg,6314
40
- ion_csp-2.1.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
- ion_csp-2.1.9.dist-info/entry_points.txt,sha256=NexQJDs9f69kJA2DgoU6tsA3V8a66nadJRem1U_c_6g,54
42
- ion_csp-2.1.9.dist-info/top_level.txt,sha256=aYZa43dDebjLpWPN6bDIlBb6BVwA8gk4ajEjDDK9b9I,8
43
- ion_csp-2.1.9.dist-info/RECORD,,
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,,