NEP框架重构

This commit is contained in:
2025-12-09 10:16:55 +08:00
parent 70068d4942
commit 99d7742c21

View File

@@ -48,59 +48,77 @@ class Workflow:
# Step: 00.md # Step: 00.md
# ========================== # ==========================
if step_name == "00.md": if step_name == "00.md":
# 1. 【修正点】先定义 step_dir确保后续都能访问到
step_dir = os.path.join(iter_path, "00.md") step_dir = os.path.join(iter_path, "00.md")
# --- 第一轮初始化POSCAR -> model.xyz --- # --- A. 第一轮初始化POSCAR -> model.xyz ---
if iter_id == 0: if iter_id == 0:
# 2. 现在使用 step_dir 是安全的
os.makedirs(step_dir, exist_ok=True) os.makedirs(step_dir, exist_ok=True)
# 获取文件名和路径
poscar_name = self.param['files']['poscar'] poscar_name = self.param['files']['poscar']
poscar_src = os.path.join(self.data_dir, poscar_name) poscar_src = os.path.join(self.data_dir, poscar_name)
# 复制原始 POSCAR if os.path.exists(poscar_src):
if not os.path.exists(poscar_src): shutil.copy(poscar_src, os.path.join(step_dir, poscar_name))
self.logger.error(f"Initial POSCAR not found: {poscar_src}")
return
shutil.copy(poscar_src, os.path.join(step_dir, poscar_name))
# 获取标签 atom_labels = self.param['files'].get('label', '')
atom_labels = self.param['files'].get('label', '') kit_path = self.machine.config['paths'].get('gpumdkit', 'gpumdkit.sh')
if not atom_labels:
self.logger.error("Missing 'label' in param.yaml files section.")
return
# 执行转换 cmd = f"{kit_path} -addlabel {poscar_name} {atom_labels}"
kit_path = self.machine.config['paths'].get('gpumdkit', 'gpumdkit.sh') self.logger.info(f"Initializing model.xyz: {cmd}")
# 确保使用绝对路径,防止 subprocess 找不到
if not os.path.isabs(kit_path):
# 假设相对于项目根目录,或者在 PATH 中
pass
cmd = f"{kit_path} -addlabel {poscar_name} {atom_labels}"
self.logger.info(f"Initializing model.xyz with command: {cmd}")
try:
subprocess.check_call(cmd, shell=True, cwd=step_dir) subprocess.check_call(cmd, shell=True, cwd=step_dir)
except subprocess.CalledProcessError as e:
self.logger.error(f"Failed to convert POSCAR: {e}")
return
if not os.path.exists(os.path.join(step_dir, "model.xyz")):
self.logger.error("model.xyz was not generated.")
return
else: else:
self.logger.info("Successfully generated model.xyz") self.logger.error(f"POSCAR missing: {poscar_src}")
continue # 跳过这一步
# --- 遍历子任务 (preheat, production...) --- # 检查 model.xyz 是否存在 (无论是刚生成的,还是上一轮传过来的)
for sub in step_conf.get('sub_tasks', []): # 注意:如果是 Iter > 0这里需要逻辑从上一轮获取目前先保证 Iter 0
template_sub_name = sub['template_sub'] current_model_xyz = os.path.join(step_dir, "model.xyz")
if not os.path.exists(current_model_xyz):
self.logger.error(f"Critical: model.xyz not found in {step_dir}")
continue
# --- B. 执行子任务 (Preheat / Production) ---
sub_tasks = step_conf.get('sub_tasks', [])
if not sub_tasks:
self.logger.warning("No sub_tasks defined for 00.md in param.yaml!")
for sub in sub_tasks:
template_sub_name = sub.get('template_sub')
if not template_sub_name: continue
# 1. 定义子目录 (e.g., iter_00/00.md/preheat)
sub_work_dir = os.path.join(step_dir, template_sub_name) sub_work_dir = os.path.join(step_dir, template_sub_name)
template_path = os.path.join(self.template_dir, "00.md", template_sub_name) os.makedirs(sub_work_dir, exist_ok=True)
# ========================== self.logger.info(f"--> Setup Sub-task: {template_sub_name}")
# 2. 【关键】将 model.xyz 分发到子目录
shutil.copy(current_model_xyz, os.path.join(sub_work_dir, "model.xyz"))
# 3. 准备 Template (run.in)
# 路径: template/00.md/preheat/
template_path = os.path.join(self.template_dir, "00.md", template_sub_name)
if not os.path.exists(template_path):
self.logger.error(f"Template not found: {template_path}")
continue
# 4. 实例化 MD 任务
# 这里的 name 仅仅是日志用的标识
md_task = MDStep(f"MD-{template_sub_name}", sub_work_dir, self.machine, self.config)
# 5. 运行 (传入势函数路径 和 模板路径)
# run() 方法内部会处理 nep.txt 的复制和 run.in 的复制
success = md_task.run(self.current_nep_pot, template_path)
if success:
# 记录最新的 dump.xyz 位置,供下一步 Select 使用
self.last_dump_path = os.path.join(sub_work_dir, "dump.xyz")
# 同时也把最新的 model.xyz (如果MD改变了结构) 或 dump 更新为下一次的起点?
# 目前逻辑Select 步会用 self.last_dump_path
else:
self.logger.error(f"MD Sub-task {template_sub_name} Failed.")
# 根据策略决定是否中断,这里暂时中断
break
# ==========================
# Step: 01.select # Step: 01.select
# ========================== # ==========================
elif step_name == "01.select": elif step_name == "01.select":