ion-CSP 2.0.8__py3-none-any.whl → 2.1.3__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.
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ion_CSP
3
- Version: 2.0.8
3
+ Version: 2.1.3
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
7
7
  Author-email: Ze Yang <yangze1995007@163.com>
8
- License-Expression: MIT
9
- Keywords: ion_crystal, crystal_structure_prediction
8
+ License: MIT
9
+ Keywords: Ion_Crystal, Crystal_Structure_Prediction
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Operating System :: OS Independent
12
12
  Requires-Python: >=3.11
@@ -27,10 +27,10 @@ Dynamic: home-page
27
27
  Dynamic: license-file
28
28
  Dynamic: requires-python
29
29
 
30
- # Crystal Structure Design Software V2.0
30
+ # Crystal Structure Design Software V2.1
31
31
 
32
32
  ## 项目概述
33
- 基于分子/离子构型的晶体结构设计软件通过结合经验公式、机器学习势函数微调、第一性原理分步优化和分子/离子识别技术,实现了从分子/离子构型出发的高效晶体结构筛选。该软件采用模块化设计,支持全流程自动化材料筛选,在保证预测精度的同时显著提升计算效率。
33
+ 基于分子/离子构型的晶体结构设计软件通过结合经验公式、机器学习势函数微调、第一性原理分步优化和分子/离子识别技术,实现了从分子/离子构型出发的高效晶体结构设计。该软件采用模块化设计,支持全流程自动化材料筛选,在保证预测精度的同时显著提升计算效率。
34
34
 
35
35
  ## 功能特性
36
36
  ### 核心功能
@@ -71,12 +71,18 @@ Dynamic: requires-python
71
71
 
72
72
  ### 安装步骤
73
73
  ```bash
74
+ pip install ion-csp
75
+ ```
76
+
77
+ ```bash
74
78
  # 创建虚拟环境
75
79
  python -m venv venv
76
80
  source venv/bin/activate # Linux/Mac
77
81
 
78
82
  # 安装依赖
79
- pip install ion-csp
83
+ git clone https://github.com/Bagabaga007/ion_CSP.git
84
+ cd ion_CSP
85
+ pip install -e .
80
86
  ```
81
87
 
82
88
  ## 快速入门
@@ -127,15 +133,15 @@ graph TD
127
133
 
128
134
  ## 技术支持
129
135
  - **文档更新**:2025年5月
130
- - **最新版本**:v2.0.4
136
+ - **最新版本**:v2.1.0
131
137
  - **问题追踪**:https://github.com/bagabaga007/ion_CSP/issues
132
138
 
133
139
  ---
134
140
 
135
- # Crystal Structure Design Software V2.0
141
+ # Crystal Structure Design Software V2.1
136
142
 
137
143
  ## Project Overview
138
- This software enables efficient crystal structure screening from molecular/ion configurations by integrating empirical formulas, tuned machine learning potentials, stepwise first-principles optimization, and molecular/ion recognition techniques. The modular architecture ensures extensibility and maintainability while maintaining prediction accuracy.
144
+ This software enables efficient crystal structure design from molecular/ion configurations by integrating empirical formulas, tuned machine learning potentials, stepwise first-principles optimization, and molecular/ion recognition techniques. The modular architecture ensures extensibility and maintainability while maintaining prediction accuracy.
139
145
 
140
146
  ## Key Features
141
147
  ### Core Functionalities
@@ -181,7 +187,9 @@ python -m venv venv
181
187
  source venv/bin/activate # Linux/Mac
182
188
 
183
189
  # Install dependencies
184
- pip install ion-csp
190
+ git clone https://github.com/Bagabaga007/ion_CSP.git
191
+ cd ion_CSP
192
+ pip install -e .
185
193
  ```
186
194
 
187
195
  ## Quick Start
@@ -232,5 +240,5 @@ MIT License, see LICENSE file.
232
240
 
233
241
  ## Support
234
242
  - Documentation last updated: May 2025
235
- - Latest version: v2.0.4
243
+ - Latest version: v2.1.0
236
244
  - Issue tracker: https://github.com/bagabaga007/ion_CSP/issues
@@ -0,0 +1,28 @@
1
+ ion_CSP/__init__.py,sha256=axZa2cdqI7GY7iU5xGNsBIcYL4SqyozbGJ-76Blzf9I,374
2
+ ion_CSP/__main__.py,sha256=XlNCx5eMSrL7yld9ddSYXhjXvg2ZYGD_uk9LdqNabvs,74
3
+ ion_CSP/convert_SMILES.py,sha256=4fndMcuIEypYtkXWBoS7W7uEXkZXVLeMDshdXEIk5kY,13864
4
+ ion_CSP/empirical_estimate.py,sha256=_U5VRWSIAiJGcxnP3mnCHn8zKzviFEQhQwN7TjPTnCU,29089
5
+ ion_CSP/gen_opt.py,sha256=aVZmf2RqePCwZShgpNvzqfntNAW0I0yctWHGXoe3mgw,19463
6
+ ion_CSP/identify_molecules.py,sha256=hFKXS0Jjd7LyMsYGc9RmnoRPu1ibXF9fYO_9lR3wTfo,4634
7
+ ion_CSP/log_and_time.py,sha256=-RCycW1VB7sa3bjQZiF7c8i73iam8S41qgJxlHRqJaw,9406
8
+ ion_CSP/mlp_opt.py,sha256=ox4Qxg4D6WzrB8dxVnUWmAngnOA_wdcInP5UhBWsH4c,5535
9
+ ion_CSP/read_mlp_density.py,sha256=3N7kgM2RCe1gbP8QxpgtwYRaj77w4niNglWA5VDoQsk,11209
10
+ ion_CSP/steps_opt_monitor.sh,sha256=1klPjnK0gqkDbvI9PtjdK5qidJ5G0Mo8q1SfrlLW5xM,3330
11
+ ion_CSP/task_manager.py,sha256=TZPsbwUWoUIG_Kmsa-WcEh_rWx8WaKkj6SworG_qk9w,16733
12
+ ion_CSP/upload_download.py,sha256=Hiz5jKOy9x26hJJdcpt-owQdVUbzzGuGOelro6JozY8,23801
13
+ ion_CSP/vasp_processing.py,sha256=TshMNs7fA0zABvk4sKlVjofJFwGH9DVYcCGbcUpoH1s,31542
14
+ ion_csp-2.1.3.dist-info/licenses/LICENSE,sha256=2J6A8GT2iIf2LhuWO1_0ilgx7ijzzpQ2BXU7rHKe8Cc,1068
15
+ run/__init__.py,sha256=_9EAXp4cv41ARbxahCkihwqY4F00Y18tBeTauWeD9mw,186
16
+ run/main_CSP.py,sha256=UaYHlh7BSxar4uGppPi-V0cFDpB14212Oy6gta59LfA,5898
17
+ run/main_EE.py,sha256=4L0VbbgUaYaDJM-6EjffphxMoWAHaZchEaSCVJxsdls,6345
18
+ run/run_convert_SMILES.py,sha256=85a8-UXPxPo3Yw_iYED_QF47yNTvYRnJHm3PC1d-d_Q,2056
19
+ run/run_empirical_estimate.py,sha256=U_yvQ5gMiBkDEabHXLJSAEm0EzGHhSKs6xmWoEC_gjc,2831
20
+ run/run_gen_opt.py,sha256=_Zcsu0FkuZTfiGKSWNaK17LiyQ3qrP30F66UN5QemCo,2727
21
+ run/run_read_mlp_density.py,sha256=aSJjWS1jH-D7qzx7RnpMPSTH7KEZp2b35dg1b2OQSCM,1864
22
+ run/run_upload_download.py,sha256=wuTAdy4bgdduD7TJtgHwo_fTpHKlkAwmgRknClDLYDo,2436
23
+ run/run_vasp_processing.py,sha256=hziE4cZwmIWvVaZtwHn9Dl35apYSLlMvSVIbCyd5mFg,1612
24
+ ion_csp-2.1.3.dist-info/METADATA,sha256=_Ij1Ms_VyN0ZxGkw0FEs_3BcEaW-dvcaJKTakHeHsmQ,6524
25
+ ion_csp-2.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ ion_csp-2.1.3.dist-info/entry_points.txt,sha256=NexQJDs9f69kJA2DgoU6tsA3V8a66nadJRem1U_c_6g,54
27
+ ion_csp-2.1.3.dist-info/top_level.txt,sha256=Vp0RHefYscYU7uQ4Fu6bOKhC_ASrdGOzZxYfN5r0f2M,12
28
+ ion_csp-2.1.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.6.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
run/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ from importlib.metadata import version, PackageNotFoundError
2
+
3
+ try:
4
+ __version__ = version("binary4fun")
5
+ except PackageNotFoundError:
6
+ __version__ = "unknown version"
7
+
8
+ name = "run"
run/main_CSP.py ADDED
@@ -0,0 +1,133 @@
1
+ import logging
2
+ from ion_CSP.gen_opt import CrystalGenerator
3
+ from ion_CSP.read_mlp_density import ReadMlpDensity
4
+ from ion_CSP.vasp_processing import VaspProcessing
5
+ from ion_CSP.log_and_time import StatusLogger
6
+ from ion_CSP.log_and_time import log_and_time, merge_config, get_work_dir_and_config
7
+
8
+ # 默认配置
9
+ DEFAULT_CONFIG = {
10
+ "gen_opt": {
11
+ "num_per_group": 500, # 每个空间群要生成的晶体结构数量
12
+ "space_groups_limit": 230, # 空间群搜索的限制
13
+ "nodes": 1, # 机器学习势优化占用 GPU 节点数
14
+ },
15
+ "read_mlp_density": {
16
+ "n_screen": 10, # 筛选机器学习势优化后密度最大的n个CONTCAR与对应的OUTCAR
17
+ "molecules_screen": True, # 是否排除离子改变的晶体结构
18
+ "detail_log": False, # 是否额外生成详细的筛选日志文件
19
+ },
20
+ "vasp_processing": {
21
+ "nodes": 2, # VASP 分步优化占用 CPU 节点数
22
+ "molecules_prior": True, # 是否检查离子晶体结构中所有离子的结构
23
+ },
24
+ }
25
+
26
+
27
+ @log_and_time
28
+ def main(work_dir, config):
29
+ logging.info(f"Using config: {config}")
30
+ tasks = {
31
+ "1_generation": lambda: generation_task(work_dir, config),
32
+ "1_optimization": lambda: mlp_optimization_task(work_dir, config),
33
+ "2_read_mlp_density": lambda: read_mlp_density_task(work_dir, config),
34
+ "3_vasp_optimization": lambda: vasp_optimization_task(work_dir, config),
35
+ "3_vasp_relaxation": lambda: vasp_relaxation_task(work_dir, config),
36
+ }
37
+ for task_name, task_func in tasks.items():
38
+ task_logger = StatusLogger(work_dir=work_dir, task_name=task_name)
39
+ if not task_logger.is_successful():
40
+ try:
41
+ task_logger.set_running()
42
+ task_func()
43
+ task_logger.set_success()
44
+ except Exception:
45
+ task_logger.set_failure()
46
+ raise
47
+ logging.info(f"All tasks have been run successfully, including {tasks.keys()}")
48
+
49
+
50
+ def generation_task(work_dir, config):
51
+ generator = CrystalGenerator(
52
+ work_dir=work_dir,
53
+ ion_numbers=config["gen_opt"]["ion_numbers"],
54
+ species=config["gen_opt"]["species"],
55
+ )
56
+ # 根据提供的离子与对应的配比,使用 pyxtal 基于晶体空间群进行离子晶体结构的随机生成。
57
+ generator.generate_structures(
58
+ num_per_group=config["gen_opt"]["num_per_group"],
59
+ space_groups_limit=config["gen_opt"]["space_groups_limit"],
60
+ )
61
+ # 使用 phonopy 生成对称化的原胞另存于 primitive_cell 文件夹中,降低后续优化的复杂性,同时检查原子数以防止 pyxtal 生成双倍比例的超胞。
62
+ generator.phonopy_processing()
63
+
64
+
65
+ def mlp_optimization_task(work_dir, config):
66
+ generator = CrystalGenerator(
67
+ work_dir=work_dir,
68
+ ion_numbers=config["gen_opt"]["ion_numbers"],
69
+ species=config["gen_opt"]["species"],
70
+ )
71
+ # 基于 dpdispatcher 模块,在远程GPU服务器上批量准备并提交输入文件,并在任务结束后回收机器学习势优化的输出文件 OUTCAR 与 CONTCAR
72
+ generator.dpdisp_mlp_tasks(
73
+ machine=config["gen_opt"]["machine"],
74
+ resources=config["gen_opt"]["resources"],
75
+ nodes=config["gen_opt"]["nodes"],
76
+ )
77
+
78
+
79
+ def read_mlp_density_task(work_dir, config):
80
+ # 分析处理机器学习势优化得到的CONTCAR文件
81
+ mlp_result = ReadMlpDensity(work_dir=work_dir)
82
+ # 读取密度数据,根据离子是否成键进行筛选,并将前n个最大密度的文件保存到max_density文件夹
83
+ mlp_result.read_density_and_sort(
84
+ n_screen=config["read_mlp_density"]["n_screen"],
85
+ molecules_screen=config["read_mlp_density"]["molecules_screen"],
86
+ detail_log=config["read_mlp_density"]["detail_log"],
87
+ )
88
+ # 将max_density文件夹中的结构文件利用 phononpy 模块进行对称化处理,方便后续对于结构的查看,同时不影响晶胞性质
89
+ mlp_result.phonopy_processing_max_density()
90
+
91
+
92
+ def vasp_optimization_task(work_dir, config):
93
+ # VASP分步固定晶胞角度优化处理
94
+ vasp_result = VaspProcessing(work_dir=work_dir)
95
+ # 基于 dpdispatcher 模块,在远程CPU服务器上批量准备并提交VASP分步优化任务
96
+ vasp_result.dpdisp_vasp_optimization_tasks(
97
+ machine=config["vasp_processing"]["machine"],
98
+ resources=config["vasp_processing"]["resources"],
99
+ nodes=config["vasp_processing"]["nodes"],
100
+ )
101
+ # 批量读取 VASP 分步优化的输出文件,并将能量和密度等结果保存到目录中的相应CSV文件
102
+ vasp_result.read_vaspout_save_csv(
103
+ molecules_prior=config["vasp_processing"]["molecules_prior"]
104
+ )
105
+
106
+
107
+ def vasp_relaxation_task(work_dir, config):
108
+ # VASP无约束晶胞优化处理
109
+ vasp_result = VaspProcessing(work_dir=work_dir)
110
+ # 基于 dpdispatcher 模块,在远程CPU服务器上批量准备并提交VASP分步优化任务
111
+ vasp_result.dpdisp_vasp_relaxation_tasks(
112
+ machine=config["vasp_processing"]["machine"],
113
+ resources=config["vasp_processing"]["resources"],
114
+ nodes=config["vasp_processing"]["nodes"],
115
+ )
116
+ # 批量读取 VASP 分步优化的输出文件,并将能量和密度等结果保存到目录中的相应CSV文件
117
+ vasp_result.read_vaspout_save_csv(
118
+ molecules_prior=config["vasp_processing"]["molecules_prior"], relaxation=True
119
+ )
120
+ vasp_result.export_max_density_structure()
121
+
122
+
123
+ if __name__ == "__main__":
124
+ # 获取工作目录和配置
125
+ work_dir, config = get_work_dir_and_config()
126
+ # 合并配置(假设有merge_config函数)
127
+ modules = ["gen_opt", "read_mlp_density", "vasp_processing"]
128
+ for module in modules:
129
+ config[module] = merge_config(
130
+ default_config=DEFAULT_CONFIG, user_config=config, key=module
131
+ )
132
+ # 调用主函数
133
+ main(work_dir, config)
run/main_EE.py ADDED
@@ -0,0 +1,133 @@
1
+ import os
2
+ import logging
3
+ from ion_CSP.convert_SMILES import SmilesProcessing
4
+ from ion_CSP.empirical_estimate import EmpiricalEstimation
5
+ from ion_CSP.log_and_time import StatusLogger
6
+ from ion_CSP.log_and_time import log_and_time, merge_config, get_work_dir_and_config
7
+
8
+ # 默认配置
9
+ DEFAULT_CONFIG = {
10
+ "convert_SMILES": {
11
+ "csv_file": "", # 默认CSV文件名
12
+ "screen": False, # 默认不进行筛选
13
+ "charge_screen": "", # 默认电荷筛选为空
14
+ "group_screen": "", # 默认官能团筛选为空
15
+ "group_name": "", # 默认分组名称
16
+ "group_screen_invert": False, # 默认不进行反向筛选
17
+ },
18
+ "empirical_estimate": {
19
+ "folders": [], # 默认文件夹列表
20
+ "ratios": [], # 默认离子配比
21
+ "sort_by": "density", # 默认排序方式
22
+ "make_combo_dir": True, # 默认不创建组合目录
23
+ "target_dir": "", # 默认目标目录
24
+ "num_combos": 100, # 默认组合数量
25
+ "ion_numbers": [], # 默认离子数量
26
+ "update": True, # 默认每次运行都会更新组合文件夹
27
+ },
28
+ }
29
+
30
+
31
+ @log_and_time
32
+ def main(work_dir, config):
33
+ logging.info(f"Using config: {config}")
34
+ empirical_estimate_dir = os.path.join(work_dir, "1_2_Gaussian_optimized")
35
+ tasks = {
36
+ "0_convertion": lambda: convertion_task(work_dir, config),
37
+ "0_estimation": lambda: estimation_task(empirical_estimate_dir, config),
38
+ "0_update_combo": lambda: combination_task(empirical_estimate_dir, config),
39
+ }
40
+ for task_name, task_func in tasks.items():
41
+ task_logger = StatusLogger(work_dir=work_dir, task_name=task_name)
42
+ if not task_logger.is_successful():
43
+ try:
44
+ task_logger.set_running()
45
+ task_func()
46
+ task_logger.set_success()
47
+ except Exception:
48
+ task_logger.set_failure()
49
+ raise
50
+
51
+ if config["empirical_estimate"]["update"]:
52
+ task_logger = StatusLogger(work_dir=work_dir, task_name="0_update_combo")
53
+ try:
54
+ task_logger.set_running()
55
+ combination_task(empirical_estimate_dir, config)
56
+ task_logger.set_success()
57
+ except Exception:
58
+ task_logger.set_failure()
59
+ raise
60
+
61
+ def convertion_task(work_dir, config):
62
+ # 给定与脚本同目录的csv文件名
63
+ convertion = SmilesProcessing(
64
+ work_dir=work_dir, csv_file=config["convert_SMILES"]["csv_file"]
65
+ )
66
+ # 根据电荷进行分组创建文件夹并将SMILES码转换为对应的结构文件
67
+ convertion.charge_group()
68
+ if config["convert_SMILES"]["screen"]:
69
+ # 根据提供的官能团和电荷进行筛选, 在本数据集中硝基的SMILES码为[N+](=O)[O-]
70
+ convertion.screen(
71
+ charge_screen=config["convert_SMILES"]["charge_screen"],
72
+ group_screen=config["convert_SMILES"]["group_screen"],
73
+ group_name=config["convert_SMILES"]["group_name"],
74
+ group_screen_invert=config["convert_SMILES"]["group_screen_invert"],
75
+ )
76
+ # 基于 dpdispatcher 模块,在远程CPU服务器上批量准备并提交Gaussian优化任务
77
+ convertion.dpdisp_gaussian_tasks(
78
+ # 注意,此处需要人为指定文件夹以避免浪费计算资源,默认通过empirical_estimate中的folders来确定
79
+ folders=config["empirical_estimate"]["folders"],
80
+ machine=config["convert_SMILES"]["machine"],
81
+ resources=config["convert_SMILES"]["resources"],
82
+ nodes=config["convert_SMILES"]["nodes"],
83
+ )
84
+
85
+ def estimation_task(work_dir, config):
86
+ # 在工作目录下准备 Gaussian 优化处理后具有 .gjf、.fchk 和 .log 文件的文件夹, 并提供对应的离子配比
87
+ estimation = EmpiricalEstimation(
88
+ work_dir=work_dir,
89
+ folders=config["empirical_estimate"]["folders"],
90
+ ratios=config["empirical_estimate"]["ratios"],
91
+ sort_by=config["empirical_estimate"]["sort_by"],
92
+ )
93
+ # 对 .fchk 文件用 Multiwfn 进行静电势分析, 并将经验公式所需的分析结果保存到同名 JSON 文件中
94
+ estimation.multiwfn_process_fchk_to_json()
95
+ # 由于后续晶体生成不支持 .log 文件,需要将 Gaussian 优化得到的 .log 文件最后一帧转为 .gjf 结构文件
96
+ estimation.gaussian_log_to_optimized_gjf()
97
+ # 如果依据密度排序,则需要经验公式根据配比生成离子晶体组合,读取 .json 文件并将静电势分析得到的各离子性质代入经验公式
98
+ if config["empirical_estimate"]["sort_by"] == "density":
99
+ # 最终将预测的离子晶体密度以及对应的组分输出到 .csv 文件并根据密度从大到小排序
100
+ estimation.empirical_estimate()
101
+ # 如果依据氮含量排序,则调用另一套根据 .gjf 文件中化学分布信息
102
+ elif config["empirical_estimate"]["sort_by"] == "nitrogen":
103
+ # 最终将预测的离子晶体氮含量以及对应的组分输出到 .csv 文件并根据氮含量从大到小排序
104
+ estimation.nitrogen_content_estimate()
105
+
106
+ def combination_task(work_dir, config):
107
+ # 在工作目录下准备 Gaussian 优化处理后具有 .gjf、.fchk 和 .log 文件的文件夹, 并提供对应的离子配比
108
+ combination = EmpiricalEstimation(
109
+ work_dir=work_dir,
110
+ folders=config["empirical_estimate"]["folders"],
111
+ ratios=config["empirical_estimate"]["ratios"],
112
+ sort_by=config["empirical_estimate"]["sort_by"],
113
+ )
114
+ # 基于排序依据 sort_by 对应的 .csv 文件创建 combo_n 文件夹,并复制相应的 .gjf 结构文件。
115
+ if config["empirical_estimate"]["make_combo_dir"]:
116
+ combination.make_combo_dir(
117
+ target_dir=config["empirical_estimate"]["target_dir"],
118
+ num_combos=config["empirical_estimate"]["num_combos"],
119
+ ion_numbers=config["empirical_estimate"]["ion_numbers"],
120
+ )
121
+
122
+
123
+ if __name__ == "__main__":
124
+ # 获取工作目录和配置
125
+ work_dir, config = get_work_dir_and_config()
126
+ # 合并配置(假设有merge_config函数)
127
+ modules = ["convert_SMILES", "empirical_estimate"]
128
+ for module in modules:
129
+ config[module] = merge_config(
130
+ default_config=DEFAULT_CONFIG, user_config=config, key=module
131
+ )
132
+ # 调用主函数
133
+ main(work_dir, config)
@@ -0,0 +1,49 @@
1
+ from ion_CSP.convert_SMILES import SmilesProcessing
2
+ from ion_CSP.log_and_time import log_and_time, merge_config, get_work_dir_and_config
3
+
4
+ # 默认配置
5
+ DEFAULT_CONFIG = {
6
+ "convert_SMILES": {
7
+ "csv_file": "", # 默认CSV文件名
8
+ "screen": False, # 默认不进行筛选
9
+ "charge_screen": "", # 默认电荷筛选为空
10
+ "group_screen": "", # 默认官能团筛选为空
11
+ "group_name": "", # 默认分组名称
12
+ "group_screen_invert": False, # 默认不进行反向筛选
13
+ }
14
+ }
15
+
16
+ @log_and_time
17
+ def main(work_dir, config):
18
+ # 给定与脚本同目录的csv文件名
19
+ result = SmilesProcessing(
20
+ work_dir=work_dir,
21
+ csv_file=config["convert_SMILES"]["csv_file"]
22
+ )
23
+ # 根据电荷进行分组创建文件夹并将SMILES码转换为对应的结构文件
24
+ result.charge_group()
25
+ if config["convert_SMILES"]["screen"]:
26
+ # 根据提供的官能团和电荷进行筛选, 在本数据集中硝基的SMILES码为[N+](=O)[O-]
27
+ result.screen(
28
+ charge_screen=config["convert_SMILES"]["charge_screen"],
29
+ group_screen=config["convert_SMILES"]["group_screen"],
30
+ group_name=config["convert_SMILES"]["group_name"],
31
+ group_screen_invert=config["convert_SMILES"]["group_screen_invert"],
32
+ )
33
+ result.dpdisp_gaussian_tasks(
34
+ # 注意,此处需要人为指定文件夹以避免浪费计算资源,默认通过empirical_estimate中的folders来确定
35
+ folders=config["empirical_estimate"]["folders"],
36
+ machine=config["convert_SMILES"]["machine"],
37
+ resources=config["convert_SMILES"]["resources"],
38
+ nodes=config["convert_SMILES"]["nodes"],
39
+ )
40
+
41
+ if __name__ == "__main__":
42
+ # 获取工作目录和配置
43
+ work_dir, config = get_work_dir_and_config()
44
+ # 合并配置(假设有merge_config函数)
45
+ config["convert_SMILES"] = merge_config(
46
+ default_config=DEFAULT_CONFIG, user_config=config, key="convert_SMILES"
47
+ )
48
+ # 调用主函数
49
+ main(work_dir, config)
@@ -0,0 +1,55 @@
1
+ from ion_CSP.empirical_estimate import EmpiricalEstimation
2
+ from ion_CSP.log_and_time import log_and_time, merge_config, get_work_dir_and_config
3
+
4
+ # 默认配置
5
+ DEFAULT_CONFIG = {
6
+ "empirical_estimate": {
7
+ "folders": [], # 默认文件夹列表
8
+ "ratios": [], # 默认离子配比
9
+ "sort_by": "density", # 默认排序方式
10
+ "make_combo_dir": True, # 默认不创建组合目录
11
+ "target_dir": "", # 默认目标目录
12
+ "num_combos": 100, # 默认组合数量
13
+ "ion_numbers": [], # 默认离子数量
14
+ }
15
+ }
16
+
17
+ @log_and_time
18
+ def main(work_dir, config):
19
+ # 在工作目录下准备 Gaussian 优化处理后具有 .gjf、.fchk 和 .log 文件的文件夹, 并提供对应的离子配比
20
+ result = EmpiricalEstimation(
21
+ work_dir=work_dir,
22
+ folders=config["empirical_estimate"]["folders"],
23
+ ratios=config["empirical_estimate"]["ratios"],
24
+ sort_by=config["empirical_estimate"]["sort_by"],
25
+ )
26
+ # 对 .fchk 文件用 Multiwfn 进行静电势分析, 并将经验公式所需的分析结果保存到同名 JSON 文件中
27
+ result.multiwfn_process_fchk_to_json()
28
+ # 由于后续晶体生成不支持 .log 文件,需要将 Gaussian 优化得到的 .log 文件最后一帧转为 .gjf 结构文件
29
+ result.gaussian_log_to_optimized_gjf()
30
+ # 如果依据密度排序,则需要经验公式根据配比生成离子晶体组合,读取 .json 文件并将静电势分析得到的各离子性质代入经验公式
31
+ if config["empirical_estimate"]["sort_by"] == 'density':
32
+ # 最终将预测的离子晶体密度以及对应的组分输出到 .csv 文件并根据密度从大到小排序
33
+ result.empirical_estimate()
34
+ # 如果依据氮含量排序,则调用另一套根据 .gjf 文件中化学分布信息
35
+ elif config["empirical_estimate"]["sort_by"] == 'nitrogen':
36
+ # 最终将预测的离子晶体氮含量以及对应的组分输出到 .csv 文件并根据氮含量从大到小排序
37
+ result.nitrogen_content_estimate()
38
+ # 基于排序依据 sort_by 对应的 .csv 文件创建 combo_n 文件夹,并复制相应的 .gjf 结构文件。
39
+ if config["empirical_estimate"]["make_combo_dir"]:
40
+ result.make_combo_dir(
41
+ target_dir=config["empirical_estimate"]["target_dir"],
42
+ num_combos=config["empirical_estimate"]["num_combos"],
43
+ ion_numbers=config["empirical_estimate"]["ion_numbers"],
44
+ )
45
+
46
+
47
+ if __name__ == "__main__":
48
+ # 获取工作目录和配置
49
+ work_dir, config = get_work_dir_and_config()
50
+ # 合并配置(假设有merge_config函数)
51
+ config["empirical_estimate"] = merge_config(
52
+ default_config=DEFAULT_CONFIG, user_config=config, key="empirical_estimate"
53
+ )
54
+ # 调用主函数
55
+ main(work_dir, config)
run/run_gen_opt.py ADDED
@@ -0,0 +1,65 @@
1
+ from ion_CSP.gen_opt import CrystalGenerator
2
+ from ion_CSP.log_and_time import StatusLogger
3
+ from ion_CSP.log_and_time import log_and_time, merge_config, get_work_dir_and_config
4
+
5
+ # 默认配置
6
+ DEFAULT_CONFIG = {
7
+ "gen_opt": {
8
+ "num_per_group": 500, # 每个空间群要生成的晶体结构数量
9
+ "space_groups_limit": 230, # 空间群搜索的限制
10
+ "nodes": 1, # 机器学习势优化占用 GPU 节点数
11
+ }
12
+ }
13
+
14
+ @log_and_time
15
+ def main(work_dir, config):
16
+ generator = CrystalGenerator(
17
+ work_dir=work_dir,
18
+ ion_numbers=config["gen_opt"]["ion_numbers"],
19
+ species=config["gen_opt"]["species"],
20
+ )
21
+ task_name_1_1 = "1_generation"
22
+ task_1_1 = StatusLogger(work_dir=work_dir, task_name=task_name_1_1)
23
+ if not task_1_1.is_successful():
24
+ try:
25
+ task_1_1.set_running()
26
+ # 根据提供的离子与对应的配比,使用 pyxtal 基于晶体空间群进行离子晶体结构的随机生成。
27
+ generator.generate_structures(
28
+ num_per_group=config["gen_opt"]["num_per_group"],
29
+ space_groups_limit=config["gen_opt"]["space_groups_limit"],
30
+ )
31
+ # 使用 phonopy 生成对称化的原胞另存于 primitive_cell 文件夹中,降低后续优化的复杂性,同时检查原子数以防止 pyxtal 生成双倍比例的超胞。
32
+ generator.phonopy_processing()
33
+ task_1_1.set_success()
34
+ except Exception:
35
+ task_1_1.set_failure()
36
+ raise
37
+
38
+ if task_1_1.is_successful():
39
+ task_name_1_2 = "1_optimization"
40
+ task_1_2 = StatusLogger(work_dir=work_dir, task_name=task_name_1_2)
41
+ if not task_1_2.is_successful():
42
+ try:
43
+ task_1_2.set_running()
44
+ # 基于 dpdispatcher 模块,在远程服务器上批量准备并提交输入文件,并在任务结束后回收机器学习势优化的输出文件 OUTCAR 与 CONTCAR
45
+ generator.dpdisp_mlp_tasks(
46
+ machine=config["gen_opt"]["machine"],
47
+ resources=config["gen_opt"]["resources"],
48
+ python_path=config["gen_opt"]["python_path"],
49
+ nodes=config["gen_opt"]["nodes"],
50
+ )
51
+ task_1_2.set_success()
52
+ except Exception:
53
+ task_1_2.set_failure()
54
+ raise
55
+
56
+
57
+ if __name__ == "__main__":
58
+ # 获取工作目录和配置
59
+ work_dir, config = get_work_dir_and_config()
60
+ # 合并配置(假设有merge_config函数)
61
+ config["gen_opt"] = merge_config(
62
+ default_config=DEFAULT_CONFIG, user_config=config, key="gen_opt"
63
+ )
64
+ # 调用主函数
65
+ main(work_dir, config)
@@ -0,0 +1,42 @@
1
+ from ion_CSP.read_mlp_density import ReadMlpDensity
2
+ from ion_CSP.log_and_time import StatusLogger
3
+ from ion_CSP.log_and_time import log_and_time, merge_config, get_work_dir_and_config
4
+
5
+ # 默认配置
6
+ DEFAULT_CONFIG = {
7
+ "read_mlp_density": {
8
+ "n_screen": 10, # 筛选机器学习势优化后密度最大的n个CONTCAR与对应的OUTCAR
9
+ "molecules_screen": True, # 是否排除离子改变的晶体结构
10
+ "detail_log": False, # 是否额外生成详细的筛选日志文件
11
+ },
12
+ }
13
+
14
+
15
+ @log_and_time
16
+ def main(work_dir, config):
17
+ task_name = "2_read_mlp_density"
18
+ task = StatusLogger(work_dir=work_dir, task_name=task_name)
19
+ try:
20
+ task.set_running()
21
+ # 分析处理机器学习势优化得到的CONTCAR文件
22
+ result = ReadMlpDensity(work_dir=work_dir)
23
+ # 读取密度数据,根据离子是否成键进行筛选,并将前n个最大密度的文件保存到max_density文件夹
24
+ result.read_density_and_sort(n_screen=config["read_mlp_density"]["n_screen"],
25
+ molecules_screen=config["read_mlp_density"]["molecules_screen"],
26
+ detail_log=config["read_mlp_density"]["detail_log"],)
27
+ # 将max_density文件夹中的结构文件利用 phononpy 模块进行对称化处理,方便后续对于结构的查看,同时不影响晶胞性质
28
+ result.phonopy_processing_max_density()
29
+ task.set_success()
30
+ except Exception:
31
+ task.set_failure()
32
+ raise
33
+
34
+ if __name__ == "__main__":
35
+ # 获取工作目录和配置
36
+ work_dir, config = get_work_dir_and_config()
37
+ # 合并配置(假设有merge_config函数)
38
+ config["read_mlp_density"] = merge_config(
39
+ default_config=DEFAULT_CONFIG, user_config=config, key="read_mlp_density"
40
+ )
41
+ # 调用主函数
42
+ main(work_dir, config)