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.
- ion_CSP/__init__.py +16 -5
- ion_CSP/log_and_time.py +10 -4
- ion_CSP/read_mlp_density.py +2 -2
- ion_CSP/task_manager.py +15 -4
- ion_CSP/vasp_processing.py +382 -15
- {ion_csp-2.0.8.dist-info → ion_csp-2.1.3.dist-info}/METADATA +19 -11
- ion_csp-2.1.3.dist-info/RECORD +28 -0
- {ion_csp-2.0.8.dist-info → ion_csp-2.1.3.dist-info}/WHEEL +1 -1
- {ion_csp-2.0.8.dist-info → ion_csp-2.1.3.dist-info}/top_level.txt +1 -0
- run/__init__.py +8 -0
- run/main_CSP.py +133 -0
- run/main_EE.py +133 -0
- run/run_convert_SMILES.py +49 -0
- run/run_empirical_estimate.py +55 -0
- run/run_gen_opt.py +65 -0
- run/run_read_mlp_density.py +42 -0
- run/run_upload_download.py +66 -0
- run/run_vasp_processing.py +42 -0
- ion_csp-2.0.8.dist-info/RECORD +0 -19
- {ion_csp-2.0.8.dist-info → ion_csp-2.1.3.dist-info}/entry_points.txt +0 -0
- {ion_csp-2.0.8.dist-info → ion_csp-2.1.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,12 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ion_CSP
|
3
|
-
Version: 2.
|
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
|
9
|
-
Keywords:
|
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.
|
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
|
-
|
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
|
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.
|
141
|
+
# Crystal Structure Design Software V2.1
|
136
142
|
|
137
143
|
## Project Overview
|
138
|
-
This software enables efficient crystal structure
|
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
|
-
|
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
|
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,,
|
run/__init__.py
ADDED
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)
|