【零基础学智能仿真-61】DFT数值收敛与计算预算

课程摘要

++本节衔接体积---能量分析,区分电子自洽、基组与k点采样收敛,学习以能量、应力及最终物性共同判断数值可靠性。通过可运行的教学记录回放,识别首次通过与进一步确认的区别,比较8条和9条预算下的不同状态,并练习处理自洽失败、指标缺失和条件不一致。理解小应变下的误差放大,建立有阈值、有预算、有停止条件的检查计划,为下一节弹性常数计算做好准备。++


一、课程导入:曲线很光滑,为什么结果仍可能不可靠?

上一节,我们从构造的能量---体积数据中找回了160 GPa的体积模量。

但只把中心能量增加1 meV,中心差分结果就变成了约139.492 GPa。

这说明一个重要问题:

材料参数可能来自能量或应力的导数,小的点间误差可能被明显放大。

因此,本节不再只问"计算有没有结束",而要进一步问:

当前数值精度,是否足够支撑我们想得到的力学结论?

完成本节后,你应能够:

  • 区分SCF、基组和k点收敛;
  • 在固定条件下比较能量与应力变化;
  • 识别首次通过的候选设置;
  • 制定有限的计算预算;
  • 在证据不足时,明确报告尚未完成的检查。

本节不需要安装ABACUS。配套程序只回放构造的教学记录,不提交真实计算任务。

二、三种收敛,是三道不同的检查门

检查对象 改变什么 通过说明什么 不能说明什么
SCF电子自洽 电子密度及相关变量 当前结构与设置下满足自洽要求 基组、k点和物性已经可靠
基组与数值网格 截断能、轨道或积分相关设置 目标结果对相应数值表示足够稳定 倒空间采样已经足够
k点采样 倒空间采样密度与方案 目标结果对采样加密足够稳定 模型近似正确、所有应变状态均可靠

可以用拍照作一个不严格的类比:

SCF像把当前照片对好焦;基组与数值网格像检查分辨能力;k点则检查周期体系倒空间积分的采样是否充分。

但真正做计算时,必须分别检查,不能用一个"完成"标签代替全部判断。

插图一:收敛检查的层级与停止条件

图中是教学检查逻辑。SCF需要在每一次作业中检查,而不是整个流程只检查一次。

2.1 达到迭代上限,不等于达到自洽要求

例如,程序执行了规定的最大电子迭代次数后结束,不代表已经满足收敛判据。

本节继续锁定ABACUS v3.8.5文档解释参数:

  • scf_nmax控制电子迭代次数上限;
  • scf_thr涉及密度相关的收敛要求。

不能把后者直接理解成跨版本、跨基组通用的"总能量误差是多少eV"。官方参数说明

出现SCF振荡时,也不应只无限增加迭代次数。应先检查结构、电子态、占据和数值设置,再根据诊断考虑混合方法及相关参数。金属的展宽设置同样需要与研究目标保持一致,不能只为了让程序结束而随意改变。官方SCF收敛说明

2.2 基组收敛不等于"把一个参数调大"

在PW路径中,ecutwfc与平面波截断有关,单位是Ry。

LCAO路径还涉及有限的局域轨道基组及其他数值设置。仅提高ecutwfc,不能自动消除局域轨道基组的全部误差。ABACUS参数说明

本节练习固定为PW教学情境,不将结论直接推广到所有LCAO任务。

2.3 k点不是原子,也不是有限元单元

\(4\times4\times4\)描述的是一种倒空间采样网格:

  • 不表示64个原子;
  • 不表示64个有限元单元;
  • 也不保证实际使用64个不可约k点。

比较时应保持网格类型、偏移和相关约定一致。不同晶胞不能机械照搬同样的三个整数。官方KPT说明

三、先冻结比较条件,才能解释数值变化

假设你同时进行了以下修改:

复制代码
提高截断能
加密k点
更换赝势
改变晶格常数
调整展宽

随后能量发生变化。

这时,能否说变化来自截断能?

不能,因为多个条件同时变化,已经失去单变量解释的基础。

本节采用以下顺序:

复制代码
固定结构与物理模型
        ↓
固定k点等条件,扫描截断能
        ↓
识别候选,进一步加密检查
        ↓
暂时固定较严格的截断能,扫描k点
        ↓
回查最终组合设置与目标物性

比较时,还应保持或明确记录:

  • 组成、原子数与结构;
  • 赝势、泛函、磁态和占据约定;
  • 软件版本与基组路径;
  • 能量定义与归一化;
  • SCF要求;
  • 应力的单位、分量和符号。

如果使用每原子能量:

\ e_i=\\frac{E_i}{N}, \\

相邻变化为:

\ \\Delta e_i=\|e_i-e_{i-1}\|. \\

这里的 \(N\) 是这一固定结构比较中保持一致的原子数。

除以原子数,并不能让不同组成或不同物理约定自动变得可比。

另外,顺序筛查只是起点。在粗k点下看起来足够的截断能,在最终更密的k点下仍可能需要回查。

四、判据应该跟着目标物性走

4.1 本节使用两个教学指标

第一个指标是相邻每原子能量差:

\ \\Delta e_i\^{\\mathrm{meV/atom}} = 1000\|e_i-e_{i-1}\|. \\

第二个指标是一个应力分量的变化:

\ \\Delta s_i = \|\\sigma_{xx,i}-\\sigma_{xx,i-1}\|. \\

课堂要求两项同时满足:

\ \\Delta e_i\\leq2\\ \\mathrm{meV/atom}, \\\ \\Delta s_i\\leq0.05\\ \\mathrm{GPa}. \\

这些数值只是为了练习决策逻辑,不是ABACUS或任何材料的推荐精度。

代码只检查一个应力分量。真实弹性计算需要检查相关分量,必要时采用全张量指标,并直接检查最终弹性常数。

4.2 相邻变化小,不等于精确误差小

本节计算的是两个设置之间的变化,不是相对精确解的误差。

两个点可能共同受到系统偏差影响;k点加密的结果也未必单调变化。

因此:

\ \\text{相邻变化很小} \\neq \\text{已经知道严格误差上界}. \\

本节采用"连续两次相邻加密均通过"作为教学确认规则。它比首次通过更谨慎,但不是通用标准,更不是物理正确性的证明。

五、实战一:从截断能序列识别候选设置

沿用原课程目录中的五个教学点,再增加70 Ry作为进一步检查。

所有数据均为人为构造,不对应真实元素或ABACUS输出。

固定 \(4\times4\times4\) 网格:

截断能/Ry 能量/(eV/atom) \(\sigma_{xx}\)/GPa
20 -10.0000 2.000
30 -10.1000 0.600
40 -10.1200 0.160
50 -10.1230 0.100
60 -10.1234 0.090
70 -10.1235 0.088

5.1 50 Ry为什么没有通过?

相对40 Ry:

\ \\Delta e = 1000\|-10.1230+10.1200\| = 3\\ \\mathrm{meV/atom}, \\\ \\Delta s = \|0.100-0.160\| = 0.060\\ \\mathrm{GPa}. \\

两项都超出了教学阈值。

5.2 60 Ry为什么只是候选?

相对50 Ry:

\ \\Delta e=0.4\\ \\mathrm{meV/atom}, \\\ \\Delta s=0.010\\ \\mathrm{GPa}. \\

两项首次同时通过,所以60 Ry是候选设置。

但按照本节规则,还需要进一步加密检查。

5.3 70 Ry提供了什么证据?

相对60 Ry:

\ \\Delta e=0.1\\ \\mathrm{meV/atom}, \\\ \\Delta s=0.002\\ \\mathrm{GPa}. \\

再次通过,满足本节的两次连续规则。

为了后续直接复用已有记录,本节暂时固定70 Ry检查k点。这不是证明70 Ry成本最优,也不是向所有材料推荐70 Ry。

插图二:能量与应力的相邻变化

图由配套程序实际回放结果绘制。纵轴为对数坐标,展示相邻设置的变化,不是相对精确解的误差。

六、实战二:截断能检查完成,k点检查还没有

固定70 Ry,使用以下教学记录:

k点网格 能量/(eV/atom) \(\sigma_{xx}\)/GPa
\(4\times4\times4\) -10.1235 0.088
\(6\times6\times6\) -10.1265 0.120
\(8\times8\times8\) -10.1275 0.130
\(10\times10\times10\) -10.1277 0.133

第一行直接复用前一阶段70 Ry的记录,不额外计算一次。

结果为:

  • 从 \(4^3\) 到 \(6^3\):能量变化3 meV/atom,没有通过;
  • 从 \(6^3\) 到 \(8^3\):能量变化1 meV/atom,应力变化0.010 GPa,首次通过;
  • 从 \(8^3\) 到 \(10^3\):能量变化0.2 meV/atom,应力变化0.003 GPa,再次通过。

现在加入一个约束:

最多允许8条作业记录。

前面的截断能检查已经使用6条记录,只剩两条用于 \(6^3\) 和 \(8^3\)。

这时,k点只有一次通过,缺少后续确认。

正确状态应该是:

复制代码
NOT_CONVERGED_WITHIN_BUDGET

它表示:

"在这份计划和预算内,尚未完成规定的确认。"

不表示材料不存在收敛设置,也不等于已经证明结果错误。

七、配套程序:实际运行与预期输出

7.1 代码放在哪里?

复制代码
"""Replay synthetic convergence records under a job-count budget; no ABACUS calls."""
import argparse
import copy
import json
import math
from pathlib import Path


def teaching_records():
    # shortcut: scalar sigma_xx only; a real elastic workflow must check relevant tensor components.
    values = [(20, 4, -10.0, 2.0), (30, 4, -10.1, 0.6),
              (40, 4, -10.12, 0.16), (50, 4, -10.123, 0.10),
              (60, 4, -10.1234, 0.09), (70, 4, -10.1235, 0.088),
              (70, 6, -10.1265, 0.12), (70, 8, -10.1275, 0.13),
              (70, 10, -10.1277, 0.133)]
    return [dict(stage="cutoff" if i < 6 else "kpoints", ecut_Ry=c, kmesh=k,
                 energy_eV_atom=e, sigma_xx_GPa=s, scf_ok=True,
                 context="FIXED_PW_TEACHING_CONTEXT")
            for i, (c, k, e, s) in enumerate(values)]


def finite(x):
    return type(x) in (int, float) and math.isfinite(x)


def within(value, limit):
    return value <= limit or math.isclose(value, limit, rel_tol=1e-10, abs_tol=1e-10)


def replay(budget=8, records=None, energy_tol=2.0, stress_tol=0.05):
    if type(budget) is not int or budget < 0:
        raise ValueError("budget must be a non-negative integer")
    if any(not finite(t) or t <= 0 for t in (energy_tol, stress_tol)):
        raise ValueError("Tolerances must be positive finite numbers")
    records = teaching_records() if records is None else records
    result = dict(source="SYNTHETIC_CONVERGENCE", ABACUS_run=False,
                  physical_verified=False, final_property_verified=False,
                  budget=budget, used=0, energy_tol_meV_atom=energy_tol,
                  stress_tol_GPa=stress_tol, cutoff_confirmed=False,
                  kpoints_confirmed=False, audit=[])
    streak = dict(cutoff=0, kpoints=0)
    previous = None

    def finish(status, reason):
        result.update(status=status, reason=reason)
        return result

    for record in records:
        if result["used"] >= budget:
            return finish("NOT_CONVERGED_WITHIN_BUDGET", "No budget for the next confirmation record")
        if record.get("stage") == "kpoints" and not result["cutoff_confirmed"]:
            return finish("INSUFFICIENT_CONFIRMATION_DATA", "Confirm cutoff before k-point refinement")
        result["used"] += 1
        stage = record.get("stage")
        row = dict(job=result["used"], stage=stage, ecut_Ry=record.get("ecut_Ry"),
                   kmesh=record.get("kmesh"), state="PENDING")
        result["audit"].append(row)
        if type(record.get("scf_ok")) is not bool:
            row["state"] = "INVALID_SCF_FLAG"
            return finish("STOP_INVALID_SCF_FLAG", "SCF status must be an explicit boolean")
        if not record["scf_ok"]:
            row["state"] = "SCF_FAILED"
            return finish("STOP_SCF_FAILED", "Do not use unconverged energy in refinement comparisons")
        metrics = (record.get("energy_eV_atom"), record.get("sigma_xx_GPa"))
        if any(x is None for x in metrics):
            row["state"] = "MISSING_METRIC"
            return finish("STOP_MISSING_METRIC", "Missing data is not zero")
        if not all(finite(x) for x in metrics):
            row["state"] = "INVALID_METRIC"
            return finish("STOP_INVALID_METRIC", "Metrics must be finite numbers")
        valid = (stage in streak and record.get("context") == "FIXED_PW_TEACHING_CONTEXT"
                 and finite(record.get("ecut_Ry")) and record["ecut_Ry"] > 0
                 and type(record.get("kmesh")) is int and record["kmesh"] > 0)
        if previous is None:
            valid = valid and stage == "cutoff"
        elif stage == "cutoff":
            valid = (valid and previous["stage"] == "cutoff"
                     and record["kmesh"] == previous["kmesh"]
                     and record["ecut_Ry"] > previous["ecut_Ry"])
        else:
            valid = (valid and record["ecut_Ry"] == previous["ecut_Ry"]
                     and record["kmesh"] > previous["kmesh"])
        if not valid:
            row["state"] = "PROTOCOL_MISMATCH"
            return finish("STOP_PROTOCOL_MISMATCH", "Only the active refinement variable may change")
        row.update(energy_eV_atom=metrics[0], sigma_xx_GPa=metrics[1])
        if previous is None:
            row["state"] = "BASELINE"
        else:
            de = abs(metrics[0] - previous["energy_eV_atom"]) * 1000
            ds = abs(metrics[1] - previous["sigma_xx_GPa"])
            passed = within(de, energy_tol) and within(ds, stress_tol)
            streak[stage] = streak[stage] + 1 if passed else 0
            row.update(dE_meV_atom=de, dSigma_GPa=ds, passed=passed,
                       streak=streak[stage], state="PASS" if passed else "FAIL")
            result["cutoff_confirmed" if stage == "cutoff" else "kpoints_confirmed"] = streak[stage] >= 2
        previous = record
        if result["cutoff_confirmed"] and result["kpoints_confirmed"]:
            return finish("TEACHING_RULES_PASS", "Both sequential refinement checks passed twice; not a physics certificate")
    status = "NOT_CONVERGED_WITHIN_BUDGET" if result["used"] >= budget else "INSUFFICIENT_CONFIRMATION_DATA"
    return finish(status, "Further refinement evidence is still needed")


def self_test():
    assert replay(8)["status"] == "NOT_CONVERGED_WITHIN_BUDGET"
    assert replay(8)["cutoff_confirmed"] and not replay(8)["kpoints_confirmed"]
    assert replay(9)["status"] == "TEACHING_RULES_PASS"
    assert replay(5)["used"] == 5 and not replay(5)["cutoff_confirmed"]
    assert replay(0)["used"] == 0
    cases = [("scf_ok", False, "STOP_SCF_FAILED"),
             ("sigma_xx_GPa", None, "STOP_MISSING_METRIC"),
             ("energy_eV_atom", float("nan"), "STOP_INVALID_METRIC"),
             ("scf_ok", "true", "STOP_INVALID_SCF_FLAG"),
             ("kmesh", 6, "STOP_PROTOCOL_MISMATCH")]
    for key, value, status in cases:
        records = teaching_records()
        records[1][key] = value
        before = copy.deepcopy(records)
        outcome = replay(9, records)
        assert outcome["status"] == status and outcome["used"] == 2
        assert repr(records) == repr(before)
    assert within(2.0, 2.0) and not within(2.001, 2.0)
    assert all(not replay(b)["physical_verified"] for b in (0, 5, 8, 9))
    for options in (dict(budget=True), dict(budget=-1), dict(energy_tol=0),
                    dict(stress_tol=float("inf"))):
        try:
            replay(**options)
        except ValueError:
            pass
        else:
            raise AssertionError("Invalid argument accepted")
    print("SELF_TEST=PASS (budgets, confirmation, 5 failure cases, input guards)")


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--budget", type=int, default=8)
    parser.add_argument("--out", type=Path, default=Path("lesson61_run"))
    parser.add_argument("--self-test", action="store_true")
    args = parser.parse_args()
    if args.self_test:
        self_test()
        return
    if args.out.exists():
        parser.error("Output path exists; choose a new --out directory")
    try:
        result = replay(args.budget)
    except ValueError as exc:
        parser.error(str(exc))
    for row in result["audit"]:
        prefix = f"#{row['job']} {row['stage']} ecut={row['ecut_Ry']} Ry k={row['kmesh']}^3"
        if "passed" in row:
            print(f"{prefix}: dE={row['dE_meV_atom']:.3f} meV/atom; "
                  f"dSigma={row['dSigma_GPa']:.3f} GPa; {row['state']} streak={row['streak']}/2")
        else:
            print(f"{prefix}: {row['state']}")
    print(f"cutoff_confirmed={result['cutoff_confirmed']}; kpoints_confirmed={result['kpoints_confirmed']}")
    print(f"STATUS={result['status']}; used={result['used']}/{result['budget']}")
    print("MODE=SYNTHETIC_CONVERGENCE; ABACUS_run=False; final_property_verified=False")
    args.out.mkdir(parents=True, exist_ok=False)
    (args.out / "report.json").write_text(json.dumps(result, indent=2, allow_nan=False), encoding="utf-8")
    print(f"SAVED={args.out / 'report.json'}")


if __name__ == "__main__":
    main()

将lesson61_convergence.py保存到自己的课程文件夹,在该文件夹打开终端即可。

它是独立脚本,不需要插入之前的代码。核心只使用Python标准库,完整代码也已收录在下载讲义附录中。

程序回放内置教学记录,不会:

  • 运行ABACUS;
  • 自动解析真实SCF日志;
  • 提交HPC作业;
  • 测量实际计算时间或费用。

其中的SCF状态也是预设的教学布尔值,不是真实求解器证据。

7.2 先运行自测

复制代码
python lesson61_convergence.py --self-test

实际输出:

复制代码
SELF_TEST=PASS (budgets, confirmation, 5 failure cases, input guards)

测试包括预算控制、确认逻辑、自洽失败、指标缺失、非有限数和比较条件变化等。

7.3 使用8条记录预算

复制代码
python lesson61_convergence.py --budget 8 --out lesson61_run_8

实际输出:

复制代码
#1 cutoff ecut=20 Ry k=4^3: BASELINE
#2 cutoff ecut=30 Ry k=4^3: dE=100.000 meV/atom; dSigma=1.400 GPa; FAIL streak=0/2
#3 cutoff ecut=40 Ry k=4^3: dE=20.000 meV/atom; dSigma=0.440 GPa; FAIL streak=0/2
#4 cutoff ecut=50 Ry k=4^3: dE=3.000 meV/atom; dSigma=0.060 GPa; FAIL streak=0/2
#5 cutoff ecut=60 Ry k=4^3: dE=0.400 meV/atom; dSigma=0.010 GPa; PASS streak=1/2
#6 cutoff ecut=70 Ry k=4^3: dE=0.100 meV/atom; dSigma=0.002 GPa; PASS streak=2/2
#7 kpoints ecut=70 Ry k=6^3: dE=3.000 meV/atom; dSigma=0.032 GPa; FAIL streak=0/2
#8 kpoints ecut=70 Ry k=8^3: dE=1.000 meV/atom; dSigma=0.010 GPa; PASS streak=1/2
cutoff_confirmed=True; kpoints_confirmed=False
STATUS=NOT_CONVERGED_WITHIN_BUDGET; used=8/8
MODE=SYNTHETIC_CONVERGENCE; ABACUS_run=False; final_property_verified=False
SAVED=lesson61_run_8\report.json

解释几个字段:

  • BASELINE:第一条记录,没有前一个设置可以比较;
  • streak:当前连续通过次数,失败会归零;
  • cutoff_confirmed=True:满足本节截断能确认规则;
  • kpoints_confirmed=False:k点确认尚未完成;
  • final_property_verified=False:没有验证最终物性。

k=4^3只是输出中的网格简写,不是一个波矢的数值。

另外,脚本正常退出只表示回放和保存完成,不能据此宣布数值检查通过。后续自动化应读取JSON中的状态字段。

7.4 独立比较9条预算情形

复制代码
python lesson61_convergence.py --budget 9 --out lesson61_run_9

前8条相同,新增和改变的结果为:

复制代码
#9 kpoints ecut=70 Ry k=10^3: dE=0.200 meV/atom; dSigma=0.003 GPa; PASS streak=2/2
cutoff_confirmed=True; kpoints_confirmed=True
STATUS=TEACHING_RULES_PASS; used=9/9
MODE=SYNTHETIC_CONVERGENCE; ABACUS_run=False; final_property_verified=False
SAVED=lesson61_run_9\report.json

TEACHING_RULES_PASS仅表示构造记录通过了本节规则。

它不是实际材料的数值收敛证明,也不是最终弹性常数通过。

插图三:8条与9条预算的对照

格子表示记录计数,不表示每个任务的运行时间相同。

真实增加计算预算需要获得授权,不能由自动化系统自行扩额。重复练习时也应更换输出目录,程序不会覆盖已有结果。

八、误差预算:为什么应力只差一点,弹性常数可能差很多?

下一节将从应变---应力关系提取弹性常数。先看一个误差放大的例子。

采用正负应变计算斜率:

\ C\\approx \\frac{\\sigma(+\\varepsilon)-\\sigma(-\\varepsilon)} {2\\varepsilon}. \\

如果两端应力的绝对误差都不超过 \(\eta\),最坏情况下:

\ \|\\delta C\| \\leq \\frac{\\eta+\\eta}{2\\varepsilon} = \\frac{\\eta}{\\varepsilon}. \\

取:

\ \\eta=0.01\\ \\mathrm{GPa}, \\qquad \\varepsilon=0.001, \\

则:

\ \|\\delta C\|\\leq10\\ \\mathrm{GPa}. \\

如果希望在同一简化误差模型下将它控制到1 GPa,需要:

\ \\eta\\leq0.001\\ \\mathrm{GPa}. \\

这里有两个重要限制:

第一,\(\eta\)被假设为实际应力误差的上界;相邻设置差不是自动成立的误差上界。

第二,本节0.05 GPa教学阈值没有按上述1 GPa弹性目标设计,不能直接拿它承诺实际精度。

所以,真正的验收应直接检查:

  • 最终弹性常数在更严格设置下是否稳定;
  • 代表性正负应变状态是否足够收敛;
  • 不同体积或剪切状态是否需要额外检查。

只在平衡结构一个点上检查能量,不足以覆盖全部材料计算。

数值收敛也不能消除交换关联近似、赝势适用性或选错磁态等模型问题。

九、给自动化系统一张有限、清楚的计划

一份真实计划至少应包含:

项目 需要说明的内容
目标物性 总能量差、体积模量、\(C_{44}\)或其他量
固定条件 结构、赝势、泛函、磁态、单位与能量定义
加密顺序 初筛、进一步确认、k点检查、组合回查
验收要求 指标、阈值及最终物性检查
资源边界 最大尝试数、单作业时间、资源数量和总预算
停止与交接 失败、缺失或超预算时保留哪些记录

举一个资源算术示例:

若最多8个顺序作业,每个最多15分钟,固定使用8个CPU核,则运行时间合计上限为2小时,对应16核时。

这不包含排队时间,也不是真实成本预测。集群计费还要核对实际规则。

本节程序只实施记录数预算,不实施真实超时、资源配额或费用限制。

遇到异常,应该怎样报告?

情况 本节状态 原则
SCF未通过 STOP_SCF_FAILED 不使用未自洽能量进行有效比较
缺少应力 STOP_MISSING_METRIC 缺失不等于零
出现NaN或无穷大 STOP_INVALID_METRIC 检查数据来源
比较条件不一致 STOP_PROTOCOL_MISMATCH 不把多变量变化归因于一个参数
预算达到且缺少确认 NOT_CONVERGED_WITHIN_BUDGET 停止并说明未完成项

失败尝试也消耗资源,不能从统计中删除。

同样,不能为了得到"通过"而放宽阈值、重置计数或隐藏失败记录。

十、本节练习与参考答案

练习一:原始20---60 Ry五点数据中,将能量阈值收紧到0.2 meV/atom,有通过者吗?

没有。

60 Ry的相邻能量变化仍为0.4 meV/atom,不能在缺少进一步证据时直接宣布通过。

练习二:9条回放通过后,可以发布最终 \(C_{44}\) 吗?

不能。

尚未运行真实电子结构计算,也没有检查最终组合设置、剪切应变状态和 \(C_{44}\) 本身。

练习三:8条预算一定不够吗?

不是,取决于预先制定的计划。

如果已有合理依据,可以预先省去20 Ry点,从30 Ry开始,用5条截断能记录和3条新增k点记录完成本节规则。

但是,已经实际消耗的20 Ry尝试不能事后从成本中抹掉。

练习四:失败点能否直接跳过,继续比较?

不能默认这样做。

应先诊断原因,确认比较条件。失败作业不能当成有效物性点,也不能从资源统计中消失。

练习五:本节应该交付什么?

建议交付:

  • 一份固定条件记录;
  • 一张收敛检查图;
  • 一份预算与停止计划;
  • 一份明确写出未完成项的状态报告。

这些内容,比给出一个所谓"万能截断能"更能说明精度依据。

十一、小结与下一节安排

本节的核心可以归纳为五句话:

  1. SCF完成、基组收敛与k点收敛不是同一件事。
  2. 先确定目标物性,再制定相应的数值要求。
  3. 首次通过得到候选,加密检查提供进一步证据。
  4. 相邻差不是严格误差界,顺序筛查也需要组合回查。
  5. 预算不足时可以诚实停下,不能把未完成包装成可靠。
相关推荐
Shadow(⊙o⊙)1 小时前
LangChain 自定义工具全解析:从 @tool 到 bind_tools 的完整调用链路
java·服务器·前端·1024程序员节
Pointer Pursuit1 小时前
Linux环境变量
linux·服务器·c语言·链表·1024程序员节
weixin_539541771 小时前
Vue 中组件生命周期及uniapp页面生命周期的详细介绍
1024程序员节
AI技术新视界1 小时前
RSI的如何改进智能体的策略
1024程序员节
王大师王文峰1 小时前
Java+AI 面试题(二):业务场景设计 10 例【客服机器人、合同审查、Text2SQL、告警降噪、成本优化】场景题答法与追问链路
java·开发语言·人工智能
破壁者-燕1 小时前
MLE-VLM
人工智能
IT研究室1 小时前
最新计算机毕业设计选题推荐-基于深度学习的面部关键特征识别与检测-运行部署-文档指导-深度学习-YOLO
人工智能·深度学习·yolo·课程设计
紧跟先前的步伐1 小时前
Go AI Agent 实战 13|大模型流式输出 Streaming 的实现
人工智能·ai·golang·1024程序员节
初阳7851 小时前
【基于Qt5仿音乐播放器(三)】——音乐管理
1024程序员节