我在 FreeCAD 裡畫了一台頂吸式排油煙機:900 × 500 mm 的煙罩、兩片槽孔油網、雙吸離心風機蝸殼、方轉圓,接到 Ø150 煙管。外觀和零件都對得起來,但它到底抽不抽得順,光看 CAD 是看不出來的。
所以我把這台機器丟進 OpenFOAM 跑機內氣流,看兩片油網分得均不均、哪裡有死區、哪一段最耗壓。跑完之後再依結果回頭改 CAD,改了兩個地方重算一次驗證。結果很老實:一個改善有效,另一個白做了。這篇把整個過程、踩到的坑和那個失敗的改法都寫下來。
測試環境
- FreeCAD 1.0.2(headless
freecadcmd跑 Python 腳本建模)- OpenFOAM v2312(macOS app 版):snappyHexMesh 切網格、simpleFoam 求解
- ParaView 6.1.1(
pvbatch出圖與統計)- Apple Silicon 8 核,MPI 平行計算
- 前置知識:知道什麼是網格、邊界條件就夠了,公式盡量不放
先講結論
- 油網端是平衡的:兩片油網分流 49.7 % : 50.3 %,38 條槽孔的平均風速都在 1.8~2.5 m/s,不用改。
- 方轉圓太短:原本 60 mm 長,擴張角太大,氣流在壁面分離。加長到 120 mm 後,方轉圓加煙管的全壓損失從 76.9 Pa 降到 58.5 Pa(−24 %)。
- 前斜面導流板沒用:本來想封住前下角的低速區,結果集煙腔其他地方的低速區反而變大,還多了一個會積油的封閉角落。
從 CAD 到流體域:直接拿零件做布林運算
CFD 要的不是機器本身,而是「空氣能流過的空間」。我沒有另外畫一份流體模型,而是寫了一支 build_fluid.py,直接從 RangeHood.FCStd 取出實際零件做布林運算:
# 流體域 = 進氣空間 ∪ 煙罩外形 ∪ 方轉圓內芯 ∪ Ø148 煙管
envelope = room
for part in (S("Pad_Hood"), neck, S("Loft_Core"), duct): # 逐個融合
envelope = envelope.fuse(part)
envelope = envelope.removeSplitter()
# 再扣掉煙罩殼、底板、兩片油網、蝸殼、馬達、控制盒、方轉圓殼、油杯……
cut = envelope
for n, sh in solids.items():
cut = cut.cut(sh)
fluid = next(s for s in cut.Solids if s.isInside(V(0, 0, 100), 1e-6, True))
這裡第一個坑:fuse() 一次傳一整個 list 進去,回來的是空的 shape,也不報錯。改成逐個融合才正常。
煙罩下方我另外加了一塊 1300 × 800 × 400 mm 的「廚房空間」當進氣區,讓油網的進風自然形成,不用在油網表面硬塞一個速度。流體域的每個面再依位置分成 inlet、outlet、filter、blower、wall 五組,匯出成一個分組 STL 給 snappyHexMesh 用。
深灰是油網,藍灰是風機蝸殼與馬達,淺灰是煙罩、方轉圓和煙管。網格煙罩內 5 mm、油網槽孔和蝸殼 2.5 mm,總共 182 萬個 cells,8 核跑 2000 步大約 81 分鐘。
最大的簡化:沒有葉輪的排油煙機
這次我沒有放葉輪。要模擬旋轉葉輪,得解析 40 片 1.2 mm 厚的葉片,再加 MRF 旋轉區,網格量會多 3~5 倍。第一版先不做,改成在煙管出口直接指定風量 15 m³/min(強檔),讓空氣「被抽出去」;廚房那幾面設成大氣壓力,兩片油網要分多少流量,交給流道阻力自己決定。
這個簡化的代價要先講清楚:沒有葉輪,兩側喇叭口吸進來的氣流會在蝸殼中間直接對撞,蝸殼段的損失和流場都不是實機狀態。所以後面的分析只看蝸殼以外的段落:油網、集煙腔、方轉圓、煙管。
| 邊界 | 設定 |
|---|---|
| 煙管出口 | 固定風量 0.25 m³/s(flowRateOutletVelocity) |
| 廚房空間底面與三個側面 | 總壓 0 Pa(totalPressure) |
| 牆面、油網、蝸殼、煙罩、管壁 | 無滑移壁面+壁面函數 |
| 紊流模型 | k-ω SST |
3 kW 爐火的熱也沒有算進來。15 m³/min 的風量下,3 kW 對流熱只會讓出風升溫約 10 K,對機內流場影響不大,所以用等溫計算。
殘差卡住、壓力一直晃:改用時間平均
simpleFoam 是穩態求解器,正常情況下殘差會一路往下掉。這次跑到 200 步左右就卡住不動了,系統全壓在 ±60 Pa 之間來回擺盪。
原因就是前面講的蝸殼對撞:沒有葉輪的蝸殼裡,兩股進風本來就不會穩定下來。硬要它收斂沒有意義,我的做法是用 fieldAverage 從第 1200 步開始做平均,報告的數字一律取第 1200~2000 步的平均值。好消息是我真正關心的油網分流很穩,只在 50 % ± 1.4 % 之間小幅擺動。
差點寫錯的數字:全壓多乘了一次密度
這個坑值得單獨講。OpenFOAM 的 simpleFoam 是不可壓縮求解器,壓力場 p 存的是「運動壓力」(除以密度後的值),要乘上 ρ = 1.2 才是 Pa。我用 pressure function object 算全壓時加了 rho rhoInf; rhoInf 1.2;,然後在後處理腳本裡又乘了一次 1.2。
第一版算出來的系統全壓損失是 422 Pa,看起來也沒什麼不對。抓到它是因為我做了一個檢查:全壓減靜壓應該等於動壓,至少要大於 ½ρU²,結果對不起來。回頭查才發現 total(p) 在設了 rhoInf 之後已經是 Pa,不用再乘。修正後是 352 Pa。
教訓:單位轉換最好在寫入的地方就確定好,後處理再用一個獨立的物理關係(像這裡的動壓)交叉檢查。
v1 結果:油網很平衡,方轉圓太短
油網:分流和槽孔風速都很均勻
兩片油網的流量分別是 49.7 % 和 50.3 %。把槽孔中間(z = 2 mm)切一刀俯視,38 條槽孔的顏色幾乎一樣:
逐條算平均風速,最高的是風機進風口正下方(x ≈ ±150 mm)約 2.5 m/s,最低的是最外側和最靠中間的槽孔約 1.8 m/s,差距不到 30 %。油脂負荷不會特別集中在某一區。
集煙腔:持續翻攪的滾動渦
從油網下方放流線,可以看到氣流穿過油網後,在集煙腔裡形成沿左右方向的大型滾動渦,再從兩側進入風機。風速低於 0.3 m/s 的「死區」只佔集煙腔體積的 1.9 %,主要在前斜面下緣、兩片油網中間和左右兩端。
全壓損失:真正該改的是方轉圓
在每一段的進出口放取樣平面,算面積平均全壓,相減就是這段流道吃掉的能量:
| 段落 | 全壓損失 | 備註 |
|---|---|---|
| 油網(進+出) | 4.2 Pa | 幾乎不耗壓 |
| 集煙腔 → 蝸殼出口 | 271 Pa | 無葉輪,不代表實機 |
| 方轉圓 | 57 Pa | 壁面分離 |
| 煙管 158 mm | 20 Pa | 偏流在管內重新整流;直管摩擦本身只有約 3 Pa |
扣掉不能信的蝸殼段,方轉圓加煙管的 77 Pa 是最大宗,相當於出口動壓 127 Pa 的六成。原因很直接:方轉圓只有 60 mm 長,在前後方向要從 88.8 mm 擴張到 148 mm,擴張半角約 26°。一般擴散段要不分離,半角大概要壓在 7~15° 以內,26° 明顯太陡,氣流貼不住壁面,主流偏到一側直接衝進煙管。
另外我也用粗網格重算了一次確認敏感度:分流比和死區比例幾乎不變,但方轉圓損失粗網格只有 30 Pa、細網格 57 Pa,還沒收斂。所以方轉圓的「絕對值」要保守看,但「它是最該改的地方」這個結論兩組網格都一致。
回頭改 CAD:兩個修改
這是我覺得這套流程最有價值的地方:CAD 是參數化腳本建的,改設計只要動幾行,重建、重切網格、重算,全部是同一條管線。這次改了兩處:
- 方轉圓從 60 mm 加長到 120 mm:擴張半角從約 26° 降到約 14°。機身頂部多 60 mm,煙囪罩裡空間夠。
- 前斜面加一片導流板:1 mm 鈑金、60° 斜置,從油網前緣接到前斜面,把前下角的低速區封起來,想把氣流導向油網前緣。
# build_appliances.py
ZT = P["HoodH"] + 1.2; LT = 120 # v2:60 → 120,擴張半角 26° → 14°
fb = body(doc, "Body_FrontBaffle", (176, 180, 184), "metal")
sk = sketch(fb, "Sketch_FrontBaffle", YZ)
poly(sk, [...]) # 斜板截面,兩端算到和油網、前斜面的交點
pad(fb, "Pad_FrontBaffle", sk, P["W"] - 2 * P["T"], mid=True)
重建後跑一次干涉檢查,導流板和煙罩、油網、控制盒都沒有重疊。v2 的網格設定、邊界條件、平均區間和 v1 完全相同,兩版的數字可以直接相減。
v2 結果:一個有效、一個白做
| 指標 | v1 | v2 | 變化 |
|---|---|---|---|
| 方轉圓 | 56.8 Pa | 47.5 Pa | −16 % |
| 煙管 | 20.0 Pa | 10.9 Pa | −45 % |
| 方轉圓+煙管 | 76.9 Pa | 58.5 Pa | −24 % |
| 出口全壓擺盪 | 119 Pa | 82 Pa | −31 % |
| 集煙腔低速區(< 0.3 m/s) | 0.83 L | 1.30 L | +57 % |
| 油網分流 | 49.7 % | 50.0 % | 不變 |
方轉圓加長:有效,但沒有我預估的多
側剖面上下對照很明顯:v1 的方轉圓前側斜壁有一條綠色的分離低速帶,v2 擴張變緩之後明顯縮小,進入煙管的高速區比較集中在中央。煙管段的損失直接少了 45 %,因為偏流變輕,管子裡不用再花力氣重新整流。
不過我原本估計可以「減少一半」,實際只有 −24 %。剩下的損失主要來自方轉圓入口:蝸殼出口送出來的射流本身就嚴重偏斜,而這又是無葉輪模型的產物。實機有葉輪時蝸殼出口的速度分布不同,實際改善幅度要等 MRF 模型才知道。
導流板:封錯地方了
這個就尷尬了。導流板確實把前下角封住了(下圖 v2 左下的深色三角形),但集煙腔其他地方的低速區從 0.83 L 增加到 1.30 L。導流板頂端和前斜面接合處形成一個轉折,背風側長出新的低速區:
回頭用 v1 的時間平均場細看才發現,我封掉的那個角落平均風速其實有 0.69 m/s,只佔 v1 低速區的三分之一左右。真正的低速區分散在兩片油網中間的中央帶、左右兩端和集煙腔頂部。加了導流板之後,中央帶的低速體積反而從 0.30 L 翻倍到 0.60 L。
更糟的是,封起來的角落只靠 1 mm 的組裝間隙和集煙腔相通,裡面的空氣是靜止的。油氣滲進去,就會在一個拆不到、看不到的地方積油。
要公平地說,0.5 L 的差異大約是集煙腔體積的 0.8 %,和 v1 粗細網格之間的差異同一個量級,我不會斷定導流板「讓集煙腔變差 57 %」。但能確定的是,它沒有帶來預期的改善,還多了清潔問題,所以這片導流板不採用。
反省一下:v1 跑完時我看剖面圖,前斜面下緣那塊深藍色很顯眼,就直覺認定它是主要死區。應該先把低速區的體積按位置拆開算清楚,再決定要改哪裡。圖上最顯眼的地方,不一定是量最多的地方。
這次模擬不能回答的問題
- 風機工作點:沒有葉輪、沒有 P-Q 曲線,352 Pa 的系統損失不能拿來當風機需要的靜壓,也不能估噪音。
- 真實油網:CAD 裡是單層 4 mm 槽孔板。實機常見的多層鋁網或擋板式油網,壓損通常高一個數量級,而且會隨積油上升。
- 捕集效率:廚房側風、安裝高度、熱羽流這些決定「油煙有沒有被吸進去」的因素都沒算。
- 沒有實測:這是自己設計的模型,沒有實機數據可以比對。絕對數字抓 ±20 %,兩個版本之間的相對比較比較可靠。
Troubleshooting 速查
症狀 → 解法
- FreeCAD
fuse()回傳空 shape:不要一次傳 list,逐個融合。#includeEtc "caseDicts/meshQualityDict"找不到:直接把 meshQualityControls 的數值寫進snappyHexMeshDict。- snappyHexMesh 切完 patch 名稱變成
fluid_inlet:多 region 的 STL 會加上檔名前綴,邊界條件要跟著改;另外會多一個沒有面的backgroundpatch,也要給它一個邊界條件。- surfaceFieldValue 報
Entry 'writeFields' not found:v2312 要明確寫writeFields false;。- 取樣平面報
Region has no faces:平面剛好落在網格面上,或 bounds 太窄(bounds 是用 cell 中心判斷的)。平面稍微偏移、bounds 放寬。- 全壓數字看起來太大:
pressurefunction object 設了rhoInf之後輸出已經是 Pa,別再乘密度;靜壓p才要乘。- 穩態殘差卡住、數值擺盪:先確認是不是流場本身不穩定(像這次的無葉輪蝸殼),是的話用
fieldAverage取時間平均,不要硬調鬆弛因子。- pvbatch 出圖第二張以後是空白的:第一次 Render 會重設相機,每張圖開一個新的 view,相機在第一次 Render 之後再設。
- MPI 平行計算突然慢了 5~10 倍:8 核全吃滿時,背景只要有一個吃 CPU 的程式就會拖慢所有 process,跑之前先看一下活動監視器。
寫在最後
這次最有感的是「CAD → CFD → 改 CAD → 再驗證」這個迴圈真的跑得起來。流體域直接從零件布林運算出來,網格和求解都是腳本,改一個參數重跑一輪,就能拿到同條件的對照數字。方轉圓加長的效果,用這種方式驗證比憑經驗估更可靠。
另一個收穫是那片失敗的導流板。如果只跑一次 v1 就交差,「前斜面加導流片」會一直留在建議清單上看起來很合理。實際做下去才知道它封錯了地方。改設計之前,先把問題量清楚,比看圖猜重要得多。
下一步是把葉輪放進去,用 MRF 算出風機的 P-Q 工作點,順便確認方轉圓加長在有葉輪的情況下到底改善多少。有在做家電或風機流道 CFD 的朋友,特別是無葉輪簡化怎麼處理比較好,歡迎留言交流。
沒有留言:
張貼留言