补充了通知模块
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
# param.yaml
|
||||
|
||||
project: "LGPS"
|
||||
project: "LYC_model1"
|
||||
|
||||
# 1. 初始文件定义 (对应 data/ 目录)
|
||||
files:
|
||||
poscar: "POSCAR"
|
||||
poscar: "model1.vasp"
|
||||
potcar: "POTCAR"
|
||||
initial_pot: "nep89.txt" # 第一轮 MD 用的势函数
|
||||
label: "Li Ge P S"
|
||||
label: "Li Y Cl"
|
||||
|
||||
# 2. 迭代流程控制
|
||||
iterations:
|
||||
@@ -37,9 +37,33 @@ iterations:
|
||||
# 逻辑:cp template/03.train/nep.in
|
||||
- name: "03.train"
|
||||
executor: "nep_local"
|
||||
|
||||
# --- 第二轮 ---
|
||||
- id: 1
|
||||
steps:
|
||||
# Step 1: MD (预热 + 采样)
|
||||
# 逻辑:会把 nep.txt (来自 initial_pot) 和 model.xyz 准备好
|
||||
- name: "00.md"
|
||||
sub_tasks:
|
||||
# 你提到可能有预热,也可能有加工,这里支持串行执行
|
||||
- template_sub: "preheat" # 使用 template/00.md/preheat/run.in
|
||||
- template_sub: "production" # 使用 template/00.md/production/run.in
|
||||
executor: "gpumd" # 对应 machine.yaml
|
||||
|
||||
# Step 2: 筛选
|
||||
- name: "01.select"
|
||||
method: "distance"
|
||||
params: [90, 120]
|
||||
|
||||
# Step 3: SCF (VASP)
|
||||
# 逻辑:cp template/02.scf/INCAR; check KPOINTS; cp data/POTCAR
|
||||
- name: "02.scf"
|
||||
executor: "vasp_std" # 对应 machine.yaml (可能调用 vasp_std.sh)
|
||||
|
||||
# Step 4: 训练
|
||||
# 逻辑:cp template/03.train/nep.in
|
||||
- name: "03.train"
|
||||
executor: "nep_local"
|
||||
# --- 第二轮 ---
|
||||
- id: 2
|
||||
steps:
|
||||
- name: "00.md"
|
||||
sub_tasks:
|
||||
@@ -57,11 +81,20 @@ iterations:
|
||||
- name: "03.train"
|
||||
executor: "nep_local"
|
||||
- name: "04.predict"
|
||||
# 定义温度和时间列表
|
||||
# [新增] 自定义模型文件 (位于 data/ 目录下),不填则使用当前训练结果
|
||||
# custom_nep: "nep_final_best.txt"
|
||||
|
||||
# [新增] 自定义预测结构 (位于 data/ 目录下),不填则使用 00.md 的结果
|
||||
# 注意:这里填写 .vasp 文件,程序会自动转化为 model.xyz
|
||||
custom_poscar: "model1_supercell.vasp"
|
||||
|
||||
conditions:
|
||||
- {T: 375, time: "15ns"}
|
||||
- { T: 400, time: "5ns" }
|
||||
- { T: 425, time: "2ns" }
|
||||
- { T: 450, time: "1ns" }
|
||||
- { T: 500, time: "1ns" }
|
||||
- {T: 600, time: "1ns"} # 支持不同温度不同时长
|
||||
- { T: 600, time: "1ns" }
|
||||
- { T: 700, time: "1ns" }
|
||||
- { T: 800, time: "1ns" }
|
||||
- {T: 900, time: "1ns"} # 支持不同温度不同时长
|
||||
- {T: 1000, time: "1ns"}
|
||||
- { T: 900, time: "1ns" }
|
||||
39
src/utils.py
39
src/utils.py
@@ -36,16 +36,43 @@ def setup_logger(work_dir, log_file="autonep.log"):
|
||||
return logger
|
||||
|
||||
|
||||
# src/utils.py 中的 Notifier 类
|
||||
|
||||
class Notifier:
|
||||
"""(预留) 通知模块"""
|
||||
def __init__(self, project_name="AutoNEP"):
|
||||
self.project_name = project_name
|
||||
|
||||
def __init__(self, url=None):
|
||||
self.url = url
|
||||
def send(self, title, message, priority=3):
|
||||
"""
|
||||
调用本地 'post' 命令发送通知
|
||||
Args:
|
||||
title: 标题
|
||||
message: 内容
|
||||
priority: 优先级 (0-3: Low/Log, 4-7: Med/Done, 8+: High/Err)
|
||||
"""
|
||||
import subprocess
|
||||
|
||||
def send(self, title, msg, priority=5):
|
||||
# 暂时只打印日志,不实际发送
|
||||
logging.info(f"[[Notification]] {title}: {msg}")
|
||||
# 自动加上项目前缀
|
||||
full_title = f"[{self.project_name}] {title}"
|
||||
|
||||
# 构造命令: post -a task -t "Title" -m "Msg" -p Priority
|
||||
cmd = [
|
||||
"post",
|
||||
"-a", "task", # 固定推送到 task 频道
|
||||
"-t", full_title,
|
||||
"-m", message,
|
||||
"-p", str(priority)
|
||||
]
|
||||
|
||||
try:
|
||||
# 执行命令,不输出到屏幕,防止干扰主程序日志
|
||||
subprocess.run(cmd, check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
# 同时在本地日志留档
|
||||
logging.info(f"[[Notification Sent]] P{priority} | {title}: {message}")
|
||||
except FileNotFoundError:
|
||||
logging.warning("Command 'post' not found. Notification skipped.")
|
||||
except Exception as e:
|
||||
logging.warning(f"Failed to send notification: {e}")
|
||||
|
||||
# src/utils.py 添加在最后
|
||||
|
||||
|
||||
162
src/workflow.py
162
src/workflow.py
@@ -25,14 +25,16 @@ class Workflow:
|
||||
# 初始化状态追踪
|
||||
os.makedirs(self.workspace, exist_ok=True)
|
||||
self.tracker = StateTracker(self.workspace)
|
||||
|
||||
project_name = self.param.get('project', 'AutoNEP')
|
||||
self.notifier = Notifier(project_name)
|
||||
self.notifier.send("Workflow Init", "AutoNEP framework initialized.", 1)
|
||||
# 初始变量
|
||||
self.current_nep_pot = os.path.join(self.data_dir, self.param['files']['initial_pot'])
|
||||
self.current_train_set = os.path.join(self.workspace, "accumulated_train.xyz")
|
||||
|
||||
def run(self):
|
||||
self.logger.info(f"Workflow Started: {self.param['project']}")
|
||||
|
||||
self.notifier.send("Workflow Start", f"Starting project: {self.param['project']}", 5)
|
||||
for iteration in self.param['iterations']:
|
||||
iter_id = iteration['id']
|
||||
iter_name = f"iter_{iter_id:02d}"
|
||||
@@ -73,6 +75,7 @@ class Workflow:
|
||||
cmd = f"{kit_path} -addlabel {std_poscar_name} {atom_labels}"
|
||||
|
||||
if run_cmd_with_log(cmd, step_dir, "init.log"):
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_init}", 2)
|
||||
self.tracker.mark_done(task_id_init)
|
||||
else:
|
||||
self.logger.error("Custom POSCAR initialization failed.")
|
||||
@@ -93,6 +96,7 @@ class Workflow:
|
||||
cmd = f"{kit_path} -addlabel {poscar_name} {atom_labels}"
|
||||
|
||||
if run_cmd_with_log(cmd, step_dir, "init.log"):
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_init}", 2)
|
||||
self.tracker.mark_done(task_id_init)
|
||||
else:
|
||||
self.logger.error("Initialization failed.")
|
||||
@@ -111,11 +115,13 @@ class Workflow:
|
||||
if os.path.exists(prev_model_src):
|
||||
self.logger.info(f"Copying model.xyz from {prev_iter_name}...")
|
||||
shutil.copy(prev_model_src, os.path.join(step_dir, "model.xyz"))
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_init}", 2)
|
||||
self.tracker.mark_done(task_id_init) # 标记完成
|
||||
else:
|
||||
self.logger.error(f"Previous model.xyz not found: {prev_model_src}")
|
||||
return
|
||||
else:
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_init}", 2)
|
||||
self.tracker.mark_done(task_id_init)
|
||||
# 确保 gpumdkit 路径可用
|
||||
kit_path = self.machine.config['paths'].get('gpumdkit', 'gpumdkit.sh')
|
||||
@@ -147,6 +153,7 @@ class Workflow:
|
||||
|
||||
if run_cmd_with_log(kit_path, preheat_dir, "step_exec.log", input_str=input_str_201):
|
||||
if os.path.exists(os.path.join(preheat_dir, "sampled_structures.xyz")):
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_preheat}", 2)
|
||||
self.tracker.mark_done(task_id_preheat)
|
||||
else:
|
||||
self.logger.error("sampled_structures.xyz not generated.")
|
||||
@@ -216,6 +223,7 @@ class Workflow:
|
||||
run_cmd_with_log("cat sample_*/dump.xyz > dump.xyz", prod_dir, "step_exec.log")
|
||||
|
||||
self.last_dump_path = os.path.join(prod_dir, "dump.xyz")
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_prod}", 2)
|
||||
self.tracker.mark_done(task_id_prod)
|
||||
else:
|
||||
self.logger.info("Skipping Production (Already Done).")
|
||||
@@ -395,7 +403,7 @@ class Workflow:
|
||||
src_png = os.path.join(step_dir, "select.png")
|
||||
if os.path.exists(src_png):
|
||||
shutil.copy(src_png, os.path.join(output_dir, "select.png"))
|
||||
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_select}", 2)
|
||||
self.tracker.mark_done(task_id_select)
|
||||
|
||||
# === 分支 B: 随机筛选 (保持不变) ===
|
||||
@@ -409,6 +417,7 @@ class Workflow:
|
||||
f.write(f"Random,{min_n},{max_n},Executed\n")
|
||||
src_png = os.path.join(step_dir, "select.png")
|
||||
if os.path.exists(src_png): shutil.copy(src_png, os.path.join(output_dir, "select.png"))
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_select}", 2)
|
||||
self.tracker.mark_done(task_id_select)
|
||||
else:
|
||||
self.logger.error("Random selection failed.")
|
||||
@@ -562,6 +571,7 @@ class Workflow:
|
||||
self.logger.info(f"VASP data collected: {res_file}")
|
||||
# 保存这个路径供 Train 使用
|
||||
self.new_data_chunk = res_file
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_scf}", 2)
|
||||
self.tracker.mark_done(task_id_scf)
|
||||
else:
|
||||
self.logger.error("NEP-dataset.xyz not found after collection.")
|
||||
@@ -683,7 +693,7 @@ class Workflow:
|
||||
dst_png = os.path.join(output_dir, file)
|
||||
shutil.copy(src_png, dst_png)
|
||||
self.logger.info(f"Archived plot: {file}")
|
||||
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_train}", 2)
|
||||
self.tracker.mark_done(task_id_train)
|
||||
|
||||
else:
|
||||
@@ -706,48 +716,108 @@ class Workflow:
|
||||
self.logger.info("=== Step: 04.predict (Arrhenius) ===")
|
||||
os.makedirs(step_dir, exist_ok=True)
|
||||
|
||||
# 准备输出目录
|
||||
output_dir = os.path.join(iter_path, "05.output")
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
# 1. 准备基础文件 (model.xyz, nep.txt)
|
||||
# 注意:预测通常使用最新的 nep.txt 和 原始/最新 model.xyz
|
||||
# 这里使用 current_nep_pot 和 初始 model.xyz (保证一致性)
|
||||
model_src = os.path.join(iter_path, "00.md", "model.xyz") # 假设 00.md 里有
|
||||
if not os.path.exists(model_src):
|
||||
# 如果没有,尝试从 data 目录拿
|
||||
model_src = os.path.join(self.data_dir, self.param['files']['poscar'])
|
||||
# 这里简化处理,最好确保 00.md 产生了 model.xyz
|
||||
# -------------------------------------------------
|
||||
# 1. 准备 NEP 势函数 (支持自定义)
|
||||
# -------------------------------------------------
|
||||
custom_nep_name = step_conf.get('custom_nep')
|
||||
nep_src = ""
|
||||
|
||||
# 2. 遍历温度点执行模拟
|
||||
if custom_nep_name:
|
||||
# 优先使用 data/ 下的自定义模型
|
||||
nep_src = os.path.join(self.data_dir, custom_nep_name)
|
||||
if not os.path.exists(nep_src):
|
||||
self.logger.error(f"Custom NEP file not found: {nep_src}")
|
||||
return
|
||||
self.logger.info(f"Using Custom NEP model: {custom_nep_name}")
|
||||
else:
|
||||
# 默认使用当前流程的训练结果
|
||||
nep_src = self.current_nep_pot
|
||||
self.logger.info("Using current training result for prediction.")
|
||||
|
||||
if not os.path.exists(nep_src):
|
||||
self.logger.error(f"NEP potential source missing: {nep_src}")
|
||||
return
|
||||
|
||||
# -------------------------------------------------
|
||||
# 2. 准备 model.xyz (支持自定义 VASP -> 转化)
|
||||
# -------------------------------------------------
|
||||
custom_poscar_name = step_conf.get('custom_poscar')
|
||||
final_model_xyz = os.path.join(step_dir, "model.xyz") # 统一存放在 step_dir 根目录备用
|
||||
|
||||
kit_path = self.machine.config['paths'].get('gpumdkit', 'gpumdkit.sh')
|
||||
|
||||
if custom_poscar_name:
|
||||
# === Case A: 使用自定义 VASP 结构 ===
|
||||
self.logger.info(f"Using Custom POSCAR for prediction: {custom_poscar_name}")
|
||||
poscar_src = os.path.join(self.data_dir, custom_poscar_name)
|
||||
|
||||
if os.path.exists(poscar_src):
|
||||
# 复制 VASP 文件到当前目录
|
||||
shutil.copy(poscar_src, os.path.join(step_dir, custom_poscar_name))
|
||||
|
||||
# 获取 label 并执行转化
|
||||
atom_labels = self.param['files'].get('label', '')
|
||||
if not atom_labels:
|
||||
self.logger.error("Labels missing in config (files.label), cannot convert POSCAR.")
|
||||
return
|
||||
|
||||
cmd = f"{kit_path} -addlabel {custom_poscar_name} {atom_labels}"
|
||||
self.logger.info(f"Converting POSCAR to model.xyz: {cmd}")
|
||||
|
||||
if not run_cmd_with_log(cmd, step_dir, "convert_model.log"):
|
||||
self.logger.error("Failed to convert custom POSCAR.")
|
||||
return
|
||||
|
||||
if not os.path.exists(final_model_xyz):
|
||||
self.logger.error("model.xyz not generated after conversion.")
|
||||
return
|
||||
else:
|
||||
self.logger.error(f"Custom POSCAR not found: {poscar_src}")
|
||||
return
|
||||
else:
|
||||
# === Case B: 使用流程默认结构 (00.md) ===
|
||||
self.logger.info("Using default structure from 00.md")
|
||||
default_src = os.path.join(iter_path, "00.md", "model.xyz")
|
||||
|
||||
if os.path.exists(default_src):
|
||||
shutil.copy(default_src, final_model_xyz)
|
||||
else:
|
||||
# 尝试兜底:用 data 里的初始 POSCAR
|
||||
self.logger.warning("00.md/model.xyz not found. Trying initial POSCAR...")
|
||||
# 这里省略复杂的再次转化逻辑,建议保证 00.md 跑通
|
||||
self.logger.error(f"Default model.xyz source missing: {default_src}")
|
||||
return
|
||||
|
||||
# -------------------------------------------------
|
||||
# 3. 遍历温度点执行模拟
|
||||
# -------------------------------------------------
|
||||
conditions = step_conf.get('conditions', [])
|
||||
if not conditions:
|
||||
self.logger.error("No conditions defined for 04.predict")
|
||||
continue
|
||||
|
||||
# 发送开始通知
|
||||
self.notifier.send("Predict Start", f"Starting {len(conditions)} tasks in {iter_name}", 5)
|
||||
self.notifier.send("Predict Start", f"Tasks: {len(conditions)}", 5)
|
||||
|
||||
for cond in conditions:
|
||||
temp = cond['T']
|
||||
time_str = cond['time']
|
||||
steps = parse_time_to_steps(time_str)
|
||||
|
||||
# [新增] 计算 MSD Window
|
||||
# 公式: 10 * window * 20 = steps => window = steps / 200
|
||||
# 自动计算 MSD Window (Steps / 200)
|
||||
msd_window = int(steps / 200)
|
||||
|
||||
sub_dir_name = f"{temp}K"
|
||||
sub_work_dir = os.path.join(step_dir, sub_dir_name)
|
||||
os.makedirs(sub_work_dir, exist_ok=True)
|
||||
|
||||
self.logger.info(
|
||||
f"-> Running Prediction: {temp}K, {time_str} ({steps} steps, MSD window={msd_window})")
|
||||
self.logger.info(f"-> Running Prediction: {temp}K, {time_str}")
|
||||
|
||||
# 分发文件
|
||||
if os.path.exists(model_src):
|
||||
shutil.copy(model_src, os.path.join(sub_work_dir, "model.xyz"))
|
||||
shutil.copy(self.current_nep_pot, os.path.join(sub_work_dir, "nep.txt"))
|
||||
# 分发准备好的 model.xyz 和 nep.txt
|
||||
shutil.copy(final_model_xyz, os.path.join(sub_work_dir, "model.xyz"))
|
||||
shutil.copy(nep_src, os.path.join(sub_work_dir, "nep.txt"))
|
||||
|
||||
# 生成 run.in
|
||||
template_path = os.path.join(self.template_dir, "04.predict", "run.in")
|
||||
@@ -755,7 +825,6 @@ class Workflow:
|
||||
with open(template_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# [修改] 替换参数,增加 MSD_WINDOW
|
||||
content = content.replace("{T}", str(temp))
|
||||
content = content.replace("{STEPS}", str(steps))
|
||||
content = content.replace("{MSD_WINDOW}", str(msd_window))
|
||||
@@ -766,34 +835,28 @@ class Workflow:
|
||||
self.logger.error(f"Template not found: {template_path}")
|
||||
continue
|
||||
|
||||
|
||||
# 执行 GPUMD
|
||||
# 这里不使用 nohup 模式,因为是串行跑,直接记录日志即可
|
||||
if not run_cmd_with_log("gpumd", sub_work_dir, "predict.log"):
|
||||
self.logger.error(f"Prediction failed at {temp}K")
|
||||
# 也可以选择 continue 或者 return
|
||||
|
||||
# 3. 后处理分析 (gpumdkit.sh -plt sigma)
|
||||
# -------------------------------------------------
|
||||
# 4. 后处理分析
|
||||
# -------------------------------------------------
|
||||
self.logger.info("Running Analysis (gpumdkit -plt sigma)...")
|
||||
kit_path = self.machine.config['paths'].get('gpumdkit', 'gpumdkit.sh')
|
||||
|
||||
# 捕获输出用于解析
|
||||
analysis_log = os.path.join(step_dir, "sigma_analysis.log")
|
||||
cmd_analyze = f"{kit_path} -plt sigma"
|
||||
|
||||
# 我们需要捕获 stdout 内容
|
||||
process = subprocess.Popen(
|
||||
cmd_analyze, shell=True, cwd=step_dir,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True
|
||||
)
|
||||
stdout, _ = process.communicate()
|
||||
|
||||
# 将输出写入日志文件备份
|
||||
with open(analysis_log, 'w') as f:
|
||||
f.write(stdout)
|
||||
|
||||
# 4. 解析输出并生成报告
|
||||
# 目标格式: CSV
|
||||
# 解析输出并生成报告 (Regex Logic)
|
||||
csv_data = []
|
||||
ea_val = "N/A"
|
||||
sigma_300k = "N/A"
|
||||
@@ -803,26 +866,16 @@ class Workflow:
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
# 解析 Ea
|
||||
if "Ea:" in line:
|
||||
# 格式: 04.predict, Ea: 0.305 eV
|
||||
match = re.search(r"Ea:\s+([\d\.]+)\s+eV", line)
|
||||
if match: ea_val = match.group(1)
|
||||
|
||||
# 解析 300K Sigma
|
||||
if "at 300K" in line:
|
||||
# 格式: at 300K, 04.predict: Sigma = 1.816e-03 S/cm
|
||||
match = re.search(r"Sigma\s*=\s*([\d\.eE\+\-]+)", line)
|
||||
if match: sigma_300k = match.group(1)
|
||||
|
||||
# 解析表格
|
||||
if "----------------" in line:
|
||||
in_table = not in_table # 切换状态
|
||||
in_table = not in_table
|
||||
continue
|
||||
|
||||
if in_table:
|
||||
# T (K) Sigma (S/cm) Sigma·T (K·S/cm)
|
||||
# 425 3.656e-02 1.554e+01
|
||||
parts = line.split()
|
||||
if len(parts) >= 3 and parts[0].isdigit():
|
||||
csv_data.append({
|
||||
@@ -831,30 +884,21 @@ class Workflow:
|
||||
"Sigma*T": parts[2]
|
||||
})
|
||||
|
||||
# 写入 CSV 到 output
|
||||
report_path = os.path.join(output_dir, "conductivity_report.csv")
|
||||
with open(report_path, 'w') as f:
|
||||
# 写头部汇总信息
|
||||
f.write(f"# Extracted from gpumdkit output\n")
|
||||
f.write(f"# Ea (eV):,{ea_val}\n")
|
||||
f.write(f"# Extrapolated Sigma@300K (S/cm):,{sigma_300k}\n")
|
||||
f.write("\n")
|
||||
# 写表格数据
|
||||
f.write(f"# Sigma@300K (S/cm):,{sigma_300k}\n\n")
|
||||
f.write("Temperature(K),Sigma(S/cm),Sigma*T(K*S/cm)\n")
|
||||
for row in csv_data:
|
||||
f.write(f"{row['T(K)']},{row['Sigma(S/cm)']},{row['Sigma*T']}\n")
|
||||
|
||||
self.logger.info(f"Report saved to {report_path}")
|
||||
self.notifier.send("Predict Done", f"Ea: {ea_val} eV, Sigma@300K: {sigma_300k}", 5)
|
||||
self.notifier.send("Predict Done", f"Ea: {ea_val} eV", 5)
|
||||
|
||||
# 5. 归档 Arrhenius.png
|
||||
src_png = os.path.join(step_dir, "Arrhenius.png")
|
||||
if os.path.exists(src_png):
|
||||
shutil.copy(src_png, os.path.join(output_dir, "Arrhenius.png"))
|
||||
self.logger.info("Archived Arrhenius.png")
|
||||
else:
|
||||
self.logger.warning("Arrhenius.png not found.")
|
||||
|
||||
self.notifier.send(f"Step Done: {step_name}", f"project {self.param['project']} Finished task {task_id_predict}", 2)
|
||||
self.tracker.mark_done(task_id_predict)
|
||||
else:
|
||||
self.logger.info("Skipping Predict (Already Done).")
|
||||
self.notifier.send("Workflow end", f"project {self.param['project']} success", 5)
|
||||
@@ -1,7 +1,7 @@
|
||||
potential ./nep.txt
|
||||
velocity 400
|
||||
velocity 350
|
||||
|
||||
ensemble npt_mttk temp 400 800 aniso 0 0
|
||||
ensemble npt_mttk temp 350 900 aniso 0 0
|
||||
dump_thermo 10
|
||||
dump_exyz 100
|
||||
run 500000
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
SYSTEM = LiGePS static SCF
|
||||
ISTART = 0
|
||||
ICHARG = 2
|
||||
ENCUT = 520
|
||||
NPAR = 8
|
||||
PREC = Normal
|
||||
GGA = PE
|
||||
EDIFF = 1E-6
|
||||
ALGO = Normal
|
||||
NELM = 120
|
||||
NSW = 0
|
||||
IBRION = -1
|
||||
ISPIN = 1
|
||||
ISMEAR = 0
|
||||
SIGMA = 0.05
|
||||
LASPH = .TRUE.
|
||||
LREAL = .FALSE.
|
||||
ADDGRID = .TRUE.
|
||||
ISYM = 2
|
||||
LCHARG = .FALSE.
|
||||
LWAVE = .FALSE.
|
||||
SYSTEM = Li3YCl6 Training Data Generation
|
||||
|
||||
KSPACING= 0.25
|
||||
KGAMMA = .TRUE.
|
||||
! --- 电子步基础设置 ---
|
||||
ENCUT = 520 ! [anie202215544-sup-0001-misc_information (1).pdf] 明确指定
|
||||
PREC = Accurate ! 保证力计算的精度
|
||||
ALGO = Normal ! 或者 Normal
|
||||
LREAL = .FALSE. ! 对于生成 Force training data,Projection 最好关掉(False)
|
||||
|
||||
! --- 电子收敛标准 ---
|
||||
! 文献提到能量收敛 1e-4,但为了训练势函数,建议稍微严一点
|
||||
EDIFF = 1E-6
|
||||
ISYM = 0 ! 关闭对称性,防止 MD/采样 过程中因为对称性导致力计算的人为约束
|
||||
|
||||
! --- 展宽设置 (绝缘体/半导体) ---
|
||||
ISMEAR = 0 ! Gaussian Smearing
|
||||
SIGMA = 0.05 ! 配合 ISMEAR=0 使用,文献常用值
|
||||
|
||||
! --- 关键:optB88-vdW 泛函设置 ---
|
||||
! [anie202215544-sup-0001-misc_information (1).pdf] 明确指出使用 optB88-vdW
|
||||
! 以下参数必须完全照抄,不能改动
|
||||
LUSE_VDW = .TRUE. ! 开启 vdW 修正
|
||||
AGGAC = 0.0000 ! 必须为 0
|
||||
GGA = BO ! optB88 基于 MK 交换泛函
|
||||
PARAM1 = 0.18333333 ! optB88 特有参数
|
||||
PARAM2 = 0.22000000 ! optB88 特有参数
|
||||
|
||||
! --- 输出控制 ---
|
||||
LWAVE = .FALSE. ! 训练数据不需要波函数,节省空间
|
||||
LCHARG = .FALSE. ! 不需要电荷密度
|
||||
|
||||
24
template/02.scf/INCAR_unifrom
Normal file
24
template/02.scf/INCAR_unifrom
Normal file
@@ -0,0 +1,24 @@
|
||||
SYSTEM = static SCF
|
||||
ISTART = 0
|
||||
ICHARG = 2
|
||||
ENCUT = 520
|
||||
NPAR = 8
|
||||
PREC = Normal
|
||||
GGA = PE
|
||||
EDIFF = 1E-6
|
||||
ALGO = Normal
|
||||
NELM = 120
|
||||
NSW = 0
|
||||
IBRION = -1
|
||||
ISPIN = 1
|
||||
ISMEAR = 0
|
||||
SIGMA = 0.05
|
||||
LASPH = .TRUE.
|
||||
LREAL = .FALSE.
|
||||
ADDGRID = .TRUE.
|
||||
ISYM = 2
|
||||
LCHARG = .FALSE.
|
||||
LWAVE = .FALSE.
|
||||
|
||||
KSPACING= 0.25
|
||||
KGAMMA = .TRUE.
|
||||
5
template/02.scf/KPOINTS
Normal file
5
template/02.scf/KPOINTS
Normal file
@@ -0,0 +1,5 @@
|
||||
Automatic Mesh for Training Data
|
||||
0 ! 0 表示自动生成
|
||||
Gamma ! 必须用 Gamma centered(六角/三角晶系推荐)
|
||||
3 3 3 ! 或者 3 3 3,取决于你的计算资源,2x2x2 通常够用
|
||||
0 0 0 ! shift (通常为0)
|
||||
BIN
template/02.scf/vdw_kernel.bindat
Normal file
BIN
template/02.scf/vdw_kernel.bindat
Normal file
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
type 4 Li Ge P S
|
||||
type 4 Li Y Cl
|
||||
zbl 2
|
||||
cutoff 6 5
|
||||
generation 100000
|
||||
|
||||
Reference in New Issue
Block a user