尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

OpenFOAM二次开发教程(08):物性与热物性模型扩展——thermophysicalProperties 解剖

OpenFOAM二次开发教程(08):物性与热物性模型扩展——thermophysicalProperties 解剖 OpenFOAM二次开发教程08物性与热物性模型扩展——thermophysicalProperties 解剖版本与事实声明hConst的字典项Cp、Hf、Tref、Href等与janaf的字典项Tlow、Thigh、Tcommon、lowCpCoeffs、highCpCoeffs来自 OpenCFD/ESI 官方文档站doc.openfoam.com/2606的热物性模型参考页hPolynomial的字典项Hf、Sf、CpCoeffs8同源。热力学模型族eConst、hConst、hPolynomial、janaf等的对照来自官方文档与官方课程讲义中对该库的分类说明。具体模型类型名会随版本增删落笔前请用foamToC与官方文档核对本机可用清单本文不对未在官方文档中确证的模型作断言。文中一切物性数值均为示例性占位须替换为工质真实数据来自权威物性数据库或文献不代表任何标准规定。一句话结论OpenFOAM 的热物性不是写死在代码里的常数而是由constant/thermophysicalProperties字典选定的模型类型在运行期通过工厂机制实例化——hConst用常数比热加生成焓、hPolynomial用多项式系数、janaf用分段 JANAF 系数要扩展物性只需新增一个派生类并注册进类型表而不是修改任何已有模型。〇、本篇要解决的认知问题Q1为什么物性要做成字典选类型 工厂创建对象而不是直接写常数Q2hConst、hPolynomial、janaf三类热力学模型的字典格式分别是什么各自适合什么场景Q3热力学模型与输运模型有什么区别它们在字典里怎么分块Q4工厂机制是怎么工作的——为什么我在字典里写一个类型名代码就能找到对应实现Q5自定义物性的规范做法是什么四步法改错物性会发生什么一、机制解析1.1 为什么物性必须可配置把物性写死在 C 代码里的三个后果每换一种工质就要重编译——工程上不可接受无法做敏感性分析——你没法在脚本里改物性再批量跑第 19 篇 DOE 的前提被砍掉无法审计——一年后没人知道模型里用的是哪个物性数据。OpenFOAM 的解法是代码只定义物性模型的接口与算法具体数值全部来自字典。于是换工质 改字典做敏感性分析 脚本改字典审计 看字典文件。为什么这对你重要这决定了二次开发的姿势。你要加一种物性模型时加的是算法实现你要用另一种物性时改的是字典。不要为了换物性去改代码——那是典型的用错工具。1.2 热力学模型三件套hConst / hPolynomial / janaf官方文档给出的字典格式如下三者的差别在比热如何处理①hConst——常数比热最简字典项来自官方文档项含义单位Cp定压比热J/(kg·K)Hf生成焓J/kgTref参考温度K默认取标准温度TstdHref参考焓J/kg适合温度范围窄、比热近似恒定的场合如常温液体、部分气体工程估算。②hPolynomial——多项式比热字典项来自官方文档thermodynamics { Hf scalar; Sf scalar; CpCoeffs8 (c1 c2 c3 c4 c5 c6 c7 c8); }比热由多项式系数给出CpCoeffs是比热多项式的系数数组再由其积分得到焓与熵。适合比热随温度平滑变化的工质且你有拟合系数。③janaf——分段 JANAF 系数工程最常用字典项来自官方文档项含义Tlow低温限Thigh高温限Tcommon分段共同温度低温段与高温段的分界lowCpCoeffs低温段系数highCpCoeffs高温段系数JANAF热力学数据表系数在低温段与高温段分别拟合因此在大温度范围内精度好。适合燃烧、高温气体、宽温域问题。经验法则工程上先用janaf如果工质有 JANAF 数据没有就退到hPolynomial只有温度范围很窄、比热几乎不变时才用hConst。用hConst做宽温域问题是最常见的物理错误伪装成数值错误的案例。1.3 热力学模型 vs 输运模型字典里的两块thermophysicalProperties通常分成若干子字典最重要的两块是thermodynamics管能量相关——比热、焓、熵上面三类模型都在这里选。transport管黏性/导热/扩散——黏度、热导率等如何随温度变化输运模型。为什么必须分开它们回答不同的物理问题。热力学模型决定能量状态输运模型决定动量与能量如何传递。用错输运模型例如高温气体用了常数黏度不会立刻报错但会让流动结构偏离真实——又是无声错误。最佳实践把选哪个模型写进项目文档并在foamToC输出里核对类型名确实存在不同版本的注册类型会变。1.4 工厂机制字典类型名如何变成对象这是 OpenFOAM 最优雅的设计之一值得单独理解字典里写 thermodynamics { type hConst; ... } │ ① 运行期读取类型名 hConst ▼ ② 在“已注册类型表”里查找该名字表由各模型源文件的注册宏在库加载时构建 ▼ ③ 找到 → 调用该类的构造函数用字典中的子项初始化 ④ 找不到 → 报 Unknown thermodynamics type hConst关键推论这解释了本系列反复出现的几条铁律“类型名存在依赖对应库被加载”。这就是铁律 5自定义库必须在controlDict的libs里加载的根本原因——库没加载类型表里就没有你的类型名。类型名拼错 运行期报错而且报错发生在构造对象时可能在你看来代码明明是对的。扩展物性的正确方式是新增类 注册不是改原有类——这样多个模型可以共存、可互相切换。1.5 自定义物性的四步法按通用做法具体文件名与宏名以本机源码为准复制最接近的官方模型目录如hConst到用户目录重命名如MyConstThermo改类名与TypeName让类名与注册的类型名一致差异要严格跟随官方写法改写Make/files与Make/options产物用LIB $(FOAM_USER_LIBBIN)/libMyThermoMake/options用LIB_INC/LIB_LIBS第 02 篇的库变量组并sinclude用户模块路径规则wmake libso编译在controlDict的libs中加载字典里把type换成你的新类型名跑官方回归算例验证。反直觉点第 4 步最关键却最容易被忘。编译成功但运行时报 Unknown type99% 是忘了libs加载而不是编译失败。二、完整代码与逐行剖析代码 2-1一个完整的constant/thermophysicalPropertiesJanaf 版/*--------------------------------*- C -*----------------------------------*\ | | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | | | \\ / A nd | | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; location constant; object thermophysicalProperties; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // 顶层指定“热物性包”的组合方式具体可用名以官方文档与本机 foamToC 为准 type heRhoThermo; // 示例以焓为变量的可压缩热物性组合 // ---------- 热力学管比热、焓、熵 ---------- thermodynamics { type janaf; // 分段 JANAF 系数 // 分段温度低温限 / 分段点 / 高温限 Tlow 200; // 示例值单位 K —— 必须替换为工质真实数据 Thigh 6000; Tcommon 1000; // 低/高温段系数顺序与个数必须严格符合官方格式 lowCpCoeffs ( 3.0 1.0e-3 0 0 0 0 0 ); // 占位示例非任何真实工质 highCpCoeffs ( 2.5 1.5e-3 0 0 0 0 0 ); // 占位示例 Hf 0; // 生成焓示例 Sf 0; // 标准熵示例 } // ---------- 输运管黏度、导热等 ---------- transport { // 输运模型类型名以官方文档与本机 foamToC 输出为准不同版本可用名可能不同 // type 与 系数 示例 // type const; // mu value; // Pr value; } // ---------- 其它视组合而定---------- // energy / equationOfState / mixture 等子字典是否存在 // 取决于顶层 type 的选择以官方同类算例为模板最稳。 // ************************************************************************* //逐行剖析FoamFile段里location constant与object thermophysicalPropertiesOpenFOAM 用object做字典自校验名字写错可能触发类型/位置检查。顶层type示例heRhoThermo决定热物性包的组合方式它决定了需要哪些子字典thermodynamics、transport可能还有equationOfState/energy/mixture。实践建议不要自己拼装直接复制官方同类算例并替换数值——这是最快也最不容易错的方式铁律 1 的延伸。thermodynamics用janaf三段温度 两段系数是 JANAF 的标准结构。系数个数与顺序必须与官方格式严格一致多写或少写一个数会让模型静默错位甚至算得出来但完全不对。lowCpCoeffs/highCpCoeffs的数值我写成占位示例并明确声明这是不臆造数值纪律在现场的体现。真实工质系数请查权威热力学数据表或官方算例自带的物性数据。transport块保留为注释并注明类型名以官方文档与foamToC为准不同版本输运模型可用名会变本文不对未在本轮官方文档中逐项核实的具体类型名作断言。最后一段注释提醒子字典是否存在取决于顶层type这是配置此类字典最容易踩的坑——照抄一个不同顶层的算例会缺一堆子字典。代码 2-2物性核对与自省脚本POSIX Shell#!/bin/sh# check_thermo.sh —— 物性配置核对语法、类型索引、量纲一致性线索# 用法sh check_thermo.sh 算例路径set-eucase${1:?用法:sh check_thermo.sh 算例路径}dict$case/constant/thermophysicalPropertiesecho 1. 字典是否存在 [-f$dict]echo[OK] 找到$dict||{echo[FAIL] 不存在不可压缩算例可能用 transportProperties;exit1;}echo 2. 用 foamDictionary 结构化读取关键项 # -entry 支持点号路径访问嵌套子字典foreintypethermodynamics.type thermodynamics.Tlow thermodynamics.Thigh thermodynamics.Tcommon;doprintf %-26s $efoamDictionary-entry$e-value$dict2/dev/null||echo(该版本/该组合下不存在此键)doneecho 3. 列出本环境可用的热力学模型类型名 # 以工具输出为权威清单避免凭记忆写类型名铁律 1foamToC-tablethermodynamics2/dev/null\||echo (本版本可能不支持该 -table 名请查官方文档确认正确的表名)echo 4. 量纲线索核对人工必看echo 注意检查Tlow/Tcommon/Thigh 是否为递增且覆盖你的工况温度范围echo Cp/Hf/Sf 的量纲是否与所用热物性‘包’的自洽要求一致逐行剖析用foamDictionary -entry ... -value读嵌套项如thermodynamics.type这是结构化核对比grep可靠第 04 篇的工具延续。foamToC -table thermodynamics用来列可用类型名把能写什么类型名从记忆问题变成工具问题。若该表名在本版本不支持脚本明确提示查官方文档确认表名而不是硬编码一个可能错的表名。第 4 步是人工核对清单而非自动断言温度分段是否递增、是否覆盖工况这些属于工程判断脚本不该越权给结论——这也是不臆造判据的体现。代码 2-3自定义物性类的骨架C示意/*---------------------------------------------------------------------------*\ MyConstThermo.H —— 自定义常数热力学模型骨架仿 hConst 的写法 注意类名、TypeName、注册宏、构造签名必须与所继承的基类契约一致 请务必以本机 $FOAM_SRC 中同名官方模型的源码为模板不要凭记忆补全。 \*---------------------------------------------------------------------------*/#ifndefMyConstThermo_H#defineMyConstThermo_H#includethermodynamicConstants.H// 以本机实际 include 路径为准Tstd 等常量#includethermo.H// 热力学基类头本机路径以源码为准namespaceFoam{namespacethermophysicalModels{classMyConstThermo:publicthermoMyConstThermo// 继承官方热力学基类模板写法以本机为准{// ---- 私有数据全部来自字典 ----scalar Cp_;// 定压比热scalar Hf_;// 生成焓scalar Tref_;// 参考温度scalar Href_;// 参考焓public:// 类型名注册用的规范名字字符串必须与字典中 type 的值完全一致TypeName(MyConstThermo);// ---- 构造函数从字典读取物性读法与官方 hConst 保持一致----MyConstThermo(constdictionarydict);// ---- 必须实现的接口比热、焓、熵等----scalarCp(constscalar p,constscalar T)const{returnCp_;}scalarHs(constscalar p,constscalar T)const{/* 按基类契约实现 */}scalarS(constscalar p,constscalar T)const{/* 按基类契约实现 */}// ---- 写回字典保证配置可复现----voidwrite(Ostreamos)const;};}// End namespace thermophysicalModels}// End namespace Foam#endif逐行剖析类名与TypeName(MyConstThermo)的字符串必须与字典里的type完全一致——这是工厂机制的接口契约。私有数据全部来自字典构造这是物性可配置的实现方式不要在这里写任何硬编码数值。接口函数Cp、Hs、S等必须按基类契约实现名字、参数、返回类型都不能改。这就是本系列反复说的继承契约——改错了编译失败漏实现了运行期崩溃。write(Ostream)把配置写回字典这是可复现性的细节官方模型的标配。我用注释明确标注请以本机源码为模板不要凭记忆补全因为不同版本基类头文件路径与模板写法有差异这类细节正是最容易编造出错的地方。这一段是骨架示意不是可复制即编译的成品。三、常见报错与排查报错 3-1-- FOAM FATAL ERROR: Unknown thermodynamics type MyConstThermo。现象字典里写了自定义类型名运行时报找不到。根因顺序上最常见的是库未加载controlDict的libs里没写你的库其次才是类型名拼写不一致或未注册铁律 5。解法先在controlDict的libs中加入libMyThermo.so再核对TypeName字符串与字典type是否逐字符一致最后确认wmake产物确实在$FOAM_USER_LIBBIN。报错 3-2物性系数个数不匹配——算得出来但数值完全不对。现象不报错结果明显异常。根因lowCpCoeffs/highCpCoeffs的系数个数与官方格式不一致导致模型按错位读取或温度分段Tlow/Tcommon/Thigh写反/不递增导致选错分段。解法以官方算例的物性文件为模板逐项对齐用代码 2-2 打印各项并人工核对分段递增性与覆盖范围。报错 3-3-- FOAM FATAL IO ERROR: keyword ... is undefined in dictionary ...thermophysicalProperties。现象缺子字典或子项。根因顶层type变了但子字典没跟着变例如从常数比热组合换成含状态方程的组合就会多要求equationOfState等。解法按顶层type选择对应官方算例模板补齐所需子字典不要在半套配置上打补丁。报错 3-4换物性后结果剧变但代码没改。现象仅改字典结果差异巨大。根因物性单位或量纲与预期不符例如比热填成了每摩尔而非每千克值或误用了常数比热去覆盖宽温域工况。解法先用代码 2-2 核对关键项把比热/焓的单位写进项目文档宽温域问题改用janaf或hPolynomial并核对系数来源。报错 3-5编译自定义物性库报undefined reference或no such file基类头找不到。现象wmake libso失败。根因Make/options里缺LIB_INC路径缺-I.../lnInclude或热物性库的 include 路径或LIB_LIBS缺对应库。解法直接复制官方同模型的Make/options再改库名这是最快且最不易错的路径确认用的是库变量组LIB_INC/LIB_LIBS而不是EXE_*第 02 篇的坑。四、动手练习练习 1字典核对用代码 2-2 检查一个官方可压缩算例的thermophysicalProperties。判定能读出顶层type、thermodynamics.type、温度分段三项foamToC或官方文档能确认该热力学类型名在本环境存在。练习 2三方对比把同一个算例的热力学模型分别设为hConst、hPolynomial、janaf用同一工质的合理数据各跑一次并记录某个监测量的变化。判定能观察到宽温域工况下三者的差异能说出为什么hConst在宽温域下误差最大。练习 3配置完整性把顶层type换成另一个官方支持的组合例如从含状态方程的组合换成不含的组合或反之观察报错与所需子字典的变化。判定能列出换顶层 type 后新增/删除了哪些子字典并能解释工厂机制如何决定所需配置。练习 4工厂机制验证在controlDict的libs中故意移除自定义或额外的库若你已有自定义库或故意把字典type拼错一个字母。判定能复现Unknown ... type报错并能分别说明库未加载与类型名拼错两种根因的区别。练习 5思考题无标准答案设计一个自定义热力学模型的接口清单不写实现。验证要点(a) 是否明确列出需要从字典读取的所有数据(b) 是否列出必须实现的接口函数比热、焓、熵等并为每个标注参数与返回类型需与基类契约一致© 是否包含write以支持配置可复现(d) 是否明确编译产物落$FOAM_USER_LIBBIN并在controlDict的libs加载。五、小结与下一篇预告本篇解决了第 07 篇留下的工程隐患物性不该写死在代码里。三条核心认知——物性由thermophysicalProperties字典选型、运行期由工厂机制实例化热力学模型分hConst常数比热、hPolynomial多项式、janaf分段 JANAF三条路线宽温域首选janafthermodynamics与transport分块管理能量与黏性/导热不可混淆。加上一条纪律扩展物性 新增类 注册 加载库铁律 5。第 09 篇《湍流模型架构》把同样的工厂 派生类思路搬到湍流领域BasicMomentumTransportModel→RASModel→eddyViscosity的继承链、kOmegaSST与kOmegaSSTBase的分工、correct()的契约——那是你扩展湍流模型之前必须画清的那张图。本篇认知问题回显FAQQ1为什么物性要做成字典选类型而不是写常数A写死在代码里有三重问题换工质必须重新编译、无法用脚本批量改物性做敏感性分析、无法审计当初用的是哪份物性数据。OpenFOAM 让代码只定义物性模型的接口与算法具体类型与数值由 constant/thermophysicalProperties 字典给出于是换工质只需改字典批量扫描只需脚本改字典审计只需查看字典文件。二次开发时应牢记加物性算法才改代码用另一种物性只改字典。Q2hConst、hPolynomial、janaf 的字典格式与适用场景AhConst 用常数比热字典项有 Cp定压比热J/kg/K、Hf生成焓、Tref参考温度默认取标准温度 Tstd、Href参考焓适合温度范围窄、比热近似恒定的场合。hPolynomial 用多项式比热字典项有 Hf、Sf 和 CpCoeffs8比热多项式系数数组适合比热随温度平滑变化且已有拟合系数的工质。janaf 用分段 JANAF 系数字典项有 Tlow、Thigh、Tcommon分段共同温度、lowCpCoeffs、highCpCoeffs适合燃烧、高温气体、宽温域问题。工程上优先 janaf。Q3热力学模型与输运模型有什么区别Athermodynamics 子字典管能量相关物性即比热、焓、熵hConst、hPolynomial、janaf 都在这里选transport 子字典管黏性与导热等传递相关物性例如黏度、热导率随温度的关系。二者回答不同物理问题热力学模型决定能量状态输运模型决定动量与能量如何传递。用错输运模型如高温气体用常数黏度不会立刻报错但会静默偏离真实流动结构因此要把模型选择写入项目文档并用官方工具核对类型名。Q4工厂机制怎么让字典类型名变成对象A运行期读取字典中的类型名后在已注册类型表中查找该名字这张表由各模型源文件的注册宏在库加载时构建找到则调用该类构造函数并用字典子项初始化找不到则报 Unknown … type。两条推论很重要类型名存在性依赖对应库被加载所以自定义库必须在 controlDict 的 libs 中加载铁律 5类型名拼错会在构造对象时报错。扩展物性的正确方式是新增类并注册而不是修改原有类这样多个模型可共存互切。Q5自定义物性的规范做法是什么A四步法。第一步复制最接近的官方模型目录到用户目录并重命名如仿 hConst 得到 MyConstThermo。第二步改类名与 TypeName使注册的类型名与字典中 type 的值严格一致并按基类契约实现所需接口比热、焓、熵等与 write 以支持配置可复现。第三步改 Make/files 与 Make/options产物用LIB $(FOAM_USER_LIBBIN)/libMyThermo使用库变量组 LIB_INC/LIB_LIBS 并 sinclude 用户模块路径规则。第四步用 wmake libso 编译在 controlDict 的 libs 中加载库把字典 type 换成新类型名跑官方回归算例验证。运行期报 Unknown type 时优先检查库是否已加载。
返回列表