Community研究與資料分析github.com

tomyud1/agentic-cfd

從頭到尾解決流體流動問題,使用 OpenFOAM 並產生經過驗證的 HTML 報告(問題、假設、理論、決策、預飛測試、模擬、比較、洞見)。當給定 CFD 問題陳述於 cases/<name>/problem.yaml 或要求模擬流動並報告時使用。

agentic-cfd 是什麼?

此技能提供一個結構化的、以代理人驅動的工作流程,用於使用 OpenFOAM 解決計算流體力學 (CFD) 問題,並生成一份全面的、可驗證的 HTML 報告。它專為需要值得信賴的模擬結果的工程師設計,透過強制執行嚴格的規則來確保所有數值均由程式碼計算、每個模擬設定選擇皆須文件化,且報告中絕不包含未經驗證的「記憶型」數據。支援的平台包括 Claude Code 和其他 AI 代理人環境,此技能會引導使用者完成從問題解析(攝入階段)到最終報告生成的七個階段。憑藉其合約檢查器,它會強制執行報告結構的正確性,確保所有聲明都有數據支持,並提供一個有洞見的記錄系統來捕捉從模擬運行中學到的經驗教訓。此工作流程透過使用 SymPy 進行精確解析解、用於穩定性和運行時間估計的預飛測試,並利用 OpenFOAM 進行實際生產模擬,特別適合需要高忠實度的內部流動、外部流動和暫態問題。

相容平台✓Claude Code~Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/tomyud1/agentic-cfd/tree/HEAD/.claude/skills/agentic-cfd

Installed? Explore more 研究與資料分析 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Agentic CFD 工作流程

你將問題陳述轉化為值得信賴的模擬報告。讀者是一位工程師,他們主要會閱讀摘要,並且必須能夠檢查每一項聲明。四條規則:

  1. 程式碼計算每一個數字。 你撰寫程式碼;你絕不手動將結果、參考值或公式輸出鍵入報告中。理論推導以符號方式(使用 SymPy)完成並進行自我檢查。
  2. 每個選擇都有文件記錄。 每個 OpenFOAM 設定都屬於一個決策,該決策包含原因/效果/替代方案。否則檢查器會拒絕呈現報告。
  3. 不從記憶中提取。 參考數據、相關性和常數必須來自問題的 reference/ 檔案或引用的來源。如果你必須使用近似值,請在報告中說明。
  4. 像實驗室筆記本一樣即時記錄洞見。 你的部分工作是在你之後為代理人改進此工作流程。一旦出現故障、讓你驚訝、需要第二次嘗試、或在本指南中不清楚的地方,請在開始修復之前開啟一個洞見:insights.log(case, stage, problem);解決後用 insights.resolve(...) 填寫診斷、修復、教訓和指南。不要把它們留到最後:長時間會話的記憶會丟失和扭曲。預計記錄 5-15 條;一個沒有條目的運行表示沒有仔細檢查。

檔案夾佈局

cfdlib/                       共享工具(請勿修改;將需要的更改記錄為洞見,階段為“tooling”)
  foam.py         render_case, run (timeout, PID file), stop, running; 讀取欄位和 postProcessing .dat 檔案
  monitor.py      parse_log, assess(健康檢查), preflight(短測試運行 + 運行時間預測)
  verification.py 誤差範數、觀察到的階數、Richardson 外推法、GCI、level_sequence
                 (任何層級序列的收斂性,包括參考資料自身的)
  signals.py     週期性訊號:循環、精煉峰值、週期性檢查、FFT 頻率
  plots.py       圖形樣式和尺寸(figure, wide, sketch);to_svg 檢查文字重疊
  report.py       m(), tex_num(), tex_fix()(表格列的固定小數位數), tex_pct(), LETTERS, load_yaml,
                 environment_info(), render()
  perf.py        每次運行的性能數據(summarize, machine)用於性能附錄
  contract.py    報告合約檢查器(也提供 --decisions 模式)
  insights.py    即時洞見日誌(記錄時檢查排版;拒絕覆蓋已填寫的條目)
  foamdict.py    OpenFOAM 字典解析器(由檢查器使用)
cases/<name>/                 每個問題一個資料夾
  problem.yaml   由使用者給定:description(簡要概述), setup(事實列表:幾何形狀、
                 邊界條件、定義), given data(已知數據), requested outputs(要求的輸出)[+ reference/]。
                 不要更改物理設定。將 description 和 setup 原封不動地傳遞給報告。
  reference/     使用者提供的參考數據及引用
  numerics.yaml  你的數值計劃(網格、運行長度、公差)
  decisions.yaml 每個選擇,在設定案例時撰寫
  insights.yaml  即時日誌(cfdlib.insights)
  template/      OpenFOAM 案例(0/, constant/, system/)包含 {{ placeholders }}
  theory.py / analytical.py, sketch.py, run.py, analyze.py
results/<name>/  原始數據, results.json, report.html

已處理的範例(在開始前閱讀所有檔案;複製結構,而非數值設定):

  • cases/plane_poiseuille/:線性、穩態、精確解(驗證)。報告:results/plane_poiseuille/report.html。
  • cases/lid_driven_cavity_re100/:非線性、穩態、無精確解、已發表的標竿測試(標竿比較、Richardson 外推法、殘差終止的 SIMPLEC、分開的預飛和生產指令)。報告:results/lid_driven_cavity_re100/report.html。其 insights.yaml 包含來自建構它的代理人的 15 個教訓。
  • cases/stokes_first_problem/:線性、暫態、精確解(合併和分開的網格與時間步階研究、每步動量平衡、並行運行)。報告:results/stokes_first_problem/report.html。
  • cases/dfg_cylinder_re100/:非線性、暫態且週期性(渦街)、標竿測試,包含多個參考層級、以 Python 生成的曲線體 O 型網格、MPI 運行和性能附錄。報告:results/dfg_cylinder_re100/report.html。其 insights.yaml 包含 16 個教訓(最重要的一個:PISO 在時間上是一階的)。

階段

0. 攝入

  • 讀取 problem.yaml 和任何 reference/ 檔案。列出要求的輸出(它們將被賦予字母 a, b, c...)。
  • 透過程式碼計算主導的無量綱數(Re, Ma, ...)。決定哪些物理適用。
  • 如果數據缺失或矛盾,選擇一個有文件記錄的假設,並在報告的限制中標記它。絕不默默地憑空創造輸入。
  • 如果參考資料沒有給出不確定性,請估計一個(其網格、其列印的數字、第二個來源)並記錄如何估計;在階段 5 中你會需要它。

1. 理論:無需模擬即可知道的內容

  • 存在精確解:使用 SymPy 推導,自我檢查(滿足方程式和邊界條件),評估要求的量。請參閱 cases/plane_poiseuille/analytical.py。
  • 沒有精確解(常見情況):在 theory.intro 中說明,並給出理論能提供的內容:極限情況、縮放比例、守恆定律、對稱性、量的符號、預期的流動結構。請參閱 cases/lid_driven_cavity_re100/theory.py。
  • 每個推導的量都需要:為什麼重要、此問題中每個符號的意義和數值,以及代入數字的公式(便於手動檢查)。

2. 設定與決策

  • 找到最接近的 OpenFOAM 範例($FOAM_TUTORIALS)並從其開始;進行最小的修改。
  • 閱讀 references/openfoam-primer.md 以了解每個檔案控制的內容和已知陷阱。
  • 模板可能包含 Jinja 迴圈:從 Python 生成整個 blockMeshDict 是可以的,並且是對曲線體進行網格劃分的方法(範例:cases/dfg_cylinder_re100/run.py 中的 mesh_spec())。
  • 僅使用編輯/寫入工具編輯包含 LaTeX 的檔案,切勿透過 Bash heredocs 或內置 Python:Bash 工具會吃掉反斜線(\times 變成 TAB)。案例 3 和 4 都因此浪費了時間。
  • 逐步撰寫 decisions.yaml:每個選擇一條記錄,帶有 kind(physics / accuracy / solver / output)和涵蓋案例檔案中每個設定的 settings 模式。一旦一個案例被渲染,立即檢查覆蓋率:python -m cfdlib.contract --decisions cases/<name>/decisions.yaml <case dir>。
  • 規劃網格研究:至少 3 個網格,細化比為 2(觀察到的階數和 GCI 所需)。暫態問題還需要時間步階研究(或者用數字論證時間誤差可忽略不計)。
  • 在查看結果之前,為你的問題定義一個物理收斂/穩定性檢查(一個平衡量、一個守恆量、一個必須停止變化的監測值)及其公差。僅靠正規化殘差是不夠的。暫態問題:每步平衡(守恆量的變化 = 邊界通量)是一個強有力的檢查;它必須使用求解器自身的時間格式。
  • 通過/失敗公差必須具有區分力:根據粗略的預飛誤差和預期的階數(最細網格應達到的目標)來設定其大小,而不是根據整數。比達到的精度鬆弛 100 倍的公差不證明任何事(案例 3)。使觀察到的精度階數成為一條獨立的規則。

3. 預飛測試(強制性,在任何長時間運行之前)

  • 在最粗略和最細網格上使用 cfdlib.monitor.preflight() 進行短時間運行(完整長度的百分之幾)。它在一個獨立的 <case>_preflight 副本中工作;將預飛和生產案例也渲染到單獨的目錄中,這樣重新運行其中一個就不會刪除另一個。
  • 它會報告崩潰、NaN、Courant 數、殘差/Courant/連續性趨勢並預測運行時間。暫態運行:預測是可靠的。穩態運行:傳遞 residual_targets;結果是一個下限(SIMPLE 在後期和更細的網格上會變慢)。
  • 列印預飛寫入的每個 postProcessing 檔案的標題和前幾行,並檢查每個檔案是否非平凡(案例 4:一個壓力積分在每一步都寫入 0,悄然無聲)。
  • 暫態非線性問題:一個短時間步階研究(3 個時間步,比為 2,在粗略網格上)應屬於預飛階段,在網格研究之前。它顯示了在時間上的觀察階數:PISO(1 個外部校正式)在案例 4 中被證明是一階的,並導致了完全的重新運行。
  • 從靜止開始的預飛會低估已發展非穩態流動的成本(案例 4:兩次)。從一個已發展的流場(從粗略運行使用 mapFields)開始,或者預算兩倍的預測值。
  • 如果預飛失敗或發出警告,請修復設定並記錄一個洞見。沒有預飛失敗的生產運行。如果預測時間過長(此處每個運行約 >15 分鐘),則放寬計劃並說明。

4. 生產運行

  • 從粗略到精細運行網格。對於穩態運行,在啟動最細網格之前,根據較粗略網格外推其迭代次數(它通常每次細化增長 3-4 倍)。
  • 停止必須是物理的:將階段 2 的物理檢查作為停止規則(例如,對探測值使用 runTimeControl 函數物件,請參閱入門指南),或檢查每個網格的殘差目標是否確實滿足它,首先在粗略網格上檢查。
  • 獨立運行(不同網格)可以同時運行,最多 6 個(8 個核心)。在再現性說明中提到這一點,因為它會增加每個運行的壁鐘時間。
  • 長時間運行在背景中進行;python -m cfdlib.foam ps 列出求解器進程,python -m cfdlib.foam stop <case dir> 終止一個(僅停止 Python 包裝器會留下孤兒求解器)。記錄每個運行:健康狀況(monitor.assess)、物理檢查、壁鐘時間。
  • 將一系列長時間運行為一個背景腳本,該腳本寫入完成標記和每個運行的記錄。在任何中斷(API 暫停也一樣)之後,在重新運行任何東西之前先讀取這些檔案。
  • 當所有硬體執行緒都在運行求解器時,你自己的工作會變慢:空出 1-2 個執行緒,或預算 1.5 倍的預測時間。

5. 分析

  • 所有比較透過程式碼完成。對於精確解:每個網格的誤差和觀察到的階數。無精確解:從 3 個網格計算觀察到的階數和 Richardson 外推法,最細網格上的 GCI(verification.py),然後將外推值與參考進行比較。
  • 標竿測試也是一種模擬:根據(你的 GCI 區間 + 參考資料自身的不確定性)來判斷一致性,而不是根據零。如果差異不隨細化而縮小,那不是你的離散化誤差;在歸咎任何一方之前,先測試穩健性(另一種格式、更嚴格的迭代),並建議第二個獨立的參考資料。
  • 當參考資料給出多個網格層級時,它仍在收斂:計算其自身的觀察階數和 Richardson 值(verification.level_sequence),並將你的結果與其最細層級及其外推值進行比較。在查看之前決定通過規則(案例 4 保留了最細層級規則,並將外推法作為背景報告)。
  • 週期性輸出(脫落、振盪):使用 cfdlib.signals(向上穿越之間的循環、拋物線精煉峰值、週期性檢查、FFT 交叉檢查),而不是自己撰寫。
  • 粗略網格的匹配可能是運氣(誤差抵消)。誠實地報告差異,說明在哪裡以及為什麼。
  • 解釋就是一個聲明:在撰寫之前,根據數據(符號、大小、縮放比例)進行檢查。在案例 3 中,錯誤的第一個解釋符號錯誤且大小只有三分之一。

6. 報告

  • 在 analyze.py 中構建 results.json 並呼叫 report.render(results, svgs, out, case_dir=<最細案例>)。合約在 references/report-contract.md 中;render 拒絕撰寫違反合約的報告。
  • 數學:文字中的每個公式、符號和科學數字都作為 \( \) 內的 LaTeX(m(), tex_num()):撰寫 \(0.009\,U\),絕不寫 0.009 U、6.3e-06 或 u*H/nu。檢查器拒絕 e 符號和 ASCII 數學,並警告純文字中的數字乘以符號。
  • 圖說和發現也是結果:從數據生成它們(說“縮小”的圖說必須是計算得出的)。使用 {fig:<key>} 引用圖形;render() 會插入編號。
  • 圖形(cfdlib.plots):plots.figure() 用於單面板,plots.wide(n) 用於 2-3 個面板,plots.sketch() 用於問題草圖(必需)。to_svg() 拒絕文字與文字、線條、箭頭或形狀重疊,或圖例覆蓋數據,或寬度超過列寬的圖形。修正佈局(標籤遠離線條、使用帶引導線的 annotate、圖例在外);僅對真正有意圖的重疊使用 allow=,並在需要時記錄一個洞見。
  • 裁決:僅當你定義的每個檢查都通過時為 PASS;如果結果可用但有注意事項則為 WARN;否則為 FAIL。絕不軟化一個失敗的檢查。

7. 視覺審查(強制性)

合約檢查結構;只有查看才能捕捉到讀者會看到的內容。透過本地伺服器在內建瀏覽器中打開報告(file:// 無法使用): http://localhost:8765/<name>/report.html(如果無法載入,請使用預覽工具從 .claude/launch.json 啟動 reports 伺服器)。重新渲染後添加 ?v=<n> 以避免快取副本。

  • 從上到下截取每個部分的螢幕截圖。檢查:圖形可讀(文字不微小,沒有重疊,引導線不穿過曲線),表格沒有被切斷,數學渲染正確(沒有原始 \(),表格列對齊,摘要回答了每個要求。
  • 在頁面中執行(等待 MathJax,打開每個 ⓘ 面板,然後列出內容被切斷的每個元素;應該為空;在 MathJax 完成之前立即執行,會將未排版的 TeX 報告為溢出): await MathJax.startup.promise; document.querySelectorAll('details').forEach(d => d.open = true); [...document.querySelectorAll('section *')].filter(x => !x.tagName.startsWith('MJX') && x.scrollWidth > x.clientWidth)
  • 檢查:表格在窄螢幕上沒有換行崩潰,下拉選單打開,專有名詞大寫一致,文字內參考文獻([1])沒有變成原始符號,{fig:...} 全部被替換。

如果報告的某個部分看起來不對,請記錄一個洞見(stage=visual_review),無論多麼微小。這是確保你為下一個代理人改進模板的唯一方法。

洞見:即時實驗室筆記本

在 cases/<name>/insights.yaml 中運作。所有函數和格式在 cfdlib/insights.py 中有記錄。

記錄任何值得注意的事情,特別是:

  • 工作流程的文件缺失、錯誤或令人困惑(guideline: "doc")
  • 一個設定花費了你兩次或更多嘗試(guideline: "setup")
  • 一個你認為對未來代理人有用的開銷或模式(guideline: "pattern")
  • 一個檢查失敗,因為它太嚴格或太寬鬆(guideline: "check")
  • 任何花費 >2 分鐘除錯的問題(guideline: "debug")

不要記錄:

  • 你已經修復的簡單打字錯誤(改進指南;僅在不確定修復是否完整時記錄)
  • 關於結果的個人意見(使用分析中的事實)
from cfdlib.insights import log, resolve

# 遇到問題時立即記錄
log(case="lid_driven_cavity_re100", stage="setup", problem="解算器在 1000 次迭代後不收斂")

# ... 診斷並修復後 ...
resolve(diagnosis="初始殘差目標 1e-6 太嚴格;鬆弛因子需要調整",
        fix="將殘差目標更改為 1e-4 並將 momentumU 鬆弛從 0.7 調整為 0.5",
        lesson="在穩態 SIMPLEC 中,過於嚴格的殘差目標會導致收斂失敗;使用預飛測試來估算可達到的殘差水平",
        guideline="穩態模擬的殘差目標應根據預飛測試的粗略網格誤差來選擇,而不是使用任意小的數字。")

工具使用常見陷阱

  1. Bash heredocs 破壞 LaTeX: cat << 'EOF' > file 中字串內的 \times 等會遺失。始終使用編輯/寫入工具處理含有反斜線的文字。
  2. 短運行與長運行: 從靜止開始的預飛(案例 4 中的暫態運行)低估了已發展週期狀態的成本。從 mapFields 開始。
  3. 同時運行耗盡記憶體: 並行 MPI 運行(每個運行 2-4 個核心)乘以 6 個運行可能超過 8 個核心。腳本中進行分時或緩衝。
  4. 停止 Python 包裝器使求解器孤立: 始終使用 cfdlib.foam.stop(case),而不僅僅是 KeyboardInterrupt。
  5. 靜默的 postProcessing: 檢查 postProcessing 檔案是否非平凡,特別是在 functionObjectProperties 錯誤時。
  6. 模板中的 {{ 與 Jinja: OpenFOAM 本身不使用 {{}};代理人的模板引擎對 dict 條目進行 Jinja 渲染。引用在檔案中的文字 {{ 必須在模板中轉義。
  7. for 和 if 對子字典的影響: Jinja 的 {% for %} 作用於 key, value;訪問 value["key"] 而不是 .key。整數索引是 loop.index0。
  8. 在 Python 字串中組合 \ 和 { 會破壞 LaTeX 渲染: 使用 r"\\(...\\)" 原始字串,或在 f-string 中雙重轉義。

開始新問題

  1. 將 template 資料夾複製到 cases/<name>/(包含 OpenFOAM 案例骨架)。
  2. 撰寫 problem.yaml 和 reference/。
  3. 執行階段 0-7。
  4. 每次 render() 後執行視覺審查。
  5. 在提交訊息中包含 insights.yaml 摘要。

有關參考格式和報告合約,請參閱 references/ 中的文件。

相關技能