ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OpenFOAM二次开发教程(02):环境与工具链——环境变量、wmake 与把 Doxygen 当地图

OpenFOAM二次开发教程(02):环境与工具链——环境变量、wmake 与把 Doxygen 当地图 OpenFOAM二次开发教程02环境与工具链——环境变量、wmake 与把 Doxygen 当地图版本与事实声明代码与命令同时适用于 OpenFOAM Foundation 版v14 为当前版本与 OpenCFD/ESI 版v2606 为当前版本差异处已双写。环境变量名WM_PROJECT_DIR、FOAM_SRC、FOAM_USER_APPBIN等与wmake用法来自官方文档站与官方课程讲义未在官方渠道确证的变量名本文不作使用。官方 Doxygen 入口Foundation 版https://cpp.openfoam.org/版本/ESI 版https://api.openfoam.com/版本/官方综合文档站为https://doc.openfoam.com/版本/。本文所有命令均可在任意已正确source的 OpenFOAM 环境中复现版本号不写死的场合以官方发布说明为准。一句话结论OpenFOAM 二次开发的一切找东西动作都可以归到三步——用环境变量定位路径WM_PROJECT_DIR、FOAM_SRC、FOAM_USER_APPBIN、用官方 Doxygen 定位类与成员、用foamToC定位运行期可选模型与表把自定义产物一律输出到FOAM_USER_APPBIN/FOAM_USER_LIBBIN是保证升级不毁工作的铁律。〇、本篇要解决的认知问题Q1OpenFOAM 的环境变量体系是怎么分层的为什么环境没 source 对是新手 90% 报错的根因Q2wmake到底做了什么Make/files与Make/options各自负责什么Q3拿到一个陌生的类名例如fvMatrix如何在 30 秒内定位它的源码与继承关系Q4foamToC这个工具能帮我查到什么为什么它比翻博客可靠Q5二次开发的自定义编译产物应该放在哪里放错位置会有什么后果一、机制解析1.1 环境变量OpenFOAM 的坐标系OpenFOAM 不把路径写死在代码里而是靠一层环境变量把安装位置与使用位置解耦。这样同一套源码可以装在任意路径、供多个用户使用。理解这层坐标系是排查一切找不到文件/找不到命令的前提。按用途分四类类别代表变量作用为什么对你重要项目级WM_PROJECT、WM_PROJECT_VERSION、WM_PROJECT_DIR项目名、版本号、安装根目录判定版本线、定位根目录的唯一权威来源路径级FOAM_SRC、FOAM_APP、FOAM_TUTORIALS、FOAM_ETC、FOAM_LIBBIN、FOAM_APPBIN库源码、应用、算例、配置、系统库/可执行读源码与找算例的地图坐标用户级FOAM_USER_APPBIN、FOAM_USER_LIBBIN、FOAM_USER_DIR用户自己的可执行与库铁律 4自定义产物只落这里平台级WM_ARCH、WM_COMPILER、WM_PRECISION_OPTION、WM_OPTIONS、WM_LABEL_SIZE架构、编译器、精度、优化、标签宽度编译产物目录名由它们拼成混用会导致库不兼容关键机制platforms/WM_OPTIONS目录。OpenFOAM 把编译产物放在以WM_OPTIONS形如linux64GccDPInt32Opt命名的平台目录里。这意味着当你从单精度 32 位标签切到双精度 64 位标签时必须重新编译——已编译的自定义库与新平台不兼容是链接时报 undefined reference的常见真凶。最佳实践一个项目固定一套WM_*配置并在 README 里写死。团队里有人用DPInt32Opt、有人用SPInt32Opt是最隐蔽的结果不一致来源。1.2 wmake官方构建系统wmake是 OpenFOAM 自带的构建工具它读两个文件Make/files声明编译什么、产物放哪。核心是两类语句——源文件名逐个列出要编译的.C与产物声明可执行用EXE ...库用LIB ...。Make/options声明怎么编译。核心是头文件搜索路径-I...与要链接的库-l...。约定编译可执行文件用EXE_INC/EXE_LIBS编译库用LIB_INC/LIB_LIBS——求解器属前者。对于用户自建求解器官方约定见课程讲义与官方文档是把产物指向用户目录Make/files ---------- mySolver.C EXE $(FOAM_USER_APPBIN)/mySolverMake/options ------------ EXE_INC \ -I$(LIB_SRC)/finiteVolume/lnInclude EXE_LIBS \ -lfiniteVolume注意Make/options里可执行文件与库用的是两组不同变量——EXE_INC/EXE_LIBS与LIB_INC/LIB_LIBS。写错变量名不会报错但链接会因缺库而失败是新手高频坑之一第 03、10 篇反复用到。三条wmake 心智模型wmake是增量编译。只改一个.C就只重编一个.C第一次编译慢是正常的第二次会快很多。lnInclude是头文件入口。OpenFOAM 把库的头文件软链到lnInclude目录这样Make/options里只需写一行-I.../lnInclude就能包含整库头文件。产物落平台目录。wmake会根据WM_OPTIONS把.o与最终产物放到对应platforms/子目录EXE $(FOAM_USER_APPBIN)/...则把可执行文件放到用户 bin。1.3 把 Doxygen 当地图源码定位三步法OpenFOAM 的类层次很深硬读源码容易迷路。官方维护的 DoxygenClass Reference提供了三件利器类索引按字母/命名空间列出所有类。想找fvMatrix直接搜类名。继承图Inheritance diagram一眼看出某个类继承自谁、被谁继承。例如查kOmegaSST能看到它属于Foam::RASModels命名空间并继承自kOmegaSSTBase——这正是第 09、10 篇要用的关键信息。“Go to the source code of this file”Doxygen 每个类页都有跳到.H/.C源码的链接看到的就是你本机安装的那一版的原始代码。源码定位三步法在 Doxygen 搜类名 → 拿到命名空间 继承链在类页点source code → 拿到.H头文件看清成员与虚函数契约用find $FOAM_SRC -name 类名.H在本机定位实际路径 → 打开同名.C看实现。三步走完你对这个类到底长什么样的认知是网上任何博客都给不了的铁律 1。1.4 foamToC运行期模型的自省工具foamToC是 OpenFOAM 的内容清单工具用来列出运行时可选的各种模型与表。官方用户指南明确给出了它的用法示例在讲派生边界条件时文档写道可以用foamToC -table scalarFunction1列出所有可用的标量Function1函数选项——这意味着你不用背函数名问工具即可。常见用法以官方文档与 Doxygen 记载为准foamToC-tablescalarFunction1# 列出标量 Function1 函数常数、多项式、表格、正弦等foamToC-tablemomentumTransport# 列出可选动量输运/湍流模型foamToC-solver求解器名-fvModels# 列出该求解器可用的 fvModels为什么它比翻博客可靠foamToC直接读你本机安装版本的注册表输出的名字必然与你环境匹配。博文可能来自另一个版本甚至另一条发行线按它写的类型名很可能触发 “Unknown … type”。1.5 一机多版本共存与环境隔离OpenFOAM 的两条发行线第 01 篇意味着一个很现实的场景同一台机器上可能同时装着多个版本例如 Foundation 的 v13 与 v14、ESI 的 v2512 与 v2606。如果环境变量没隔离干净你会遇到最令人困惑的一类报错——“明明装了却提示找不到或版本号对不上”。三条实践建议一个终端一个版本。每开一个新终端就 source 一次目标版本的环境脚本不要指望上次 source 的那套环境还在——环境变量只属于当时那个 shell这也是新开终端就报 command not found的根因。用WM_PROJECT_VERSION自证身份。在任何命令之前先echo $WM_PROJECT_VERSION这是判定我现在在哪个版本下工作的唯一可靠方法第 01 篇的版本线判定纪律。多版本并行工作时给终端标题或提示符加上版本标记。这是一个廉价但极其有效的习惯避免在 v13 的环境里编译 v14 的库这种代价高昂的错误。反直觉点多版本环境下最常见的严重问题不是命令找不到而是**“编译产物平台不匹配导致链接失败”**。因为它发生在编译期而非启动期报错信息undefined reference不会提示你版本搞错了——你必须自己养成先打印版本号再动手的肌肉记忆。1.6 自定义产物落位铁律 4 的工程含义OpenFOAM 系统目录$FOAM_APPBIN、$FOAM_LIBBIN属于安装的一部分。把自定义求解器/库写进去后果有三升级/重装即丢失。安装程序覆盖目录你的工作清零。平台不匹配。系统目录里混进你自己编译的库别人在另一WM_OPTIONS下运行就崩。污染不可追溯。出问题时无法判断是官方行为还是你的改动。正确做法统一到一条显式落到--prefix为user的位置。ESI 的插件仓库示例明确给出了这一约定./Allwmake -prefixuser会把产物安装到$FOAM_USER_APPBIN与$FOAM_USER_LIBBIN对应的Make/options中会sinclude $(GENERAL_RULES)/module-path-user来对齐用户路径。二、完整代码与逐行剖析代码 2-1环境体检脚本foam_doctor.sh#!/bin/sh# foam_doctor.sh —— OpenFOAM 二次开发环境体检# 用法先 source 好 OpenFOAM 的 etc/bashrc再执行 sh foam_doctor.sh# 说明只读检查 写一处用户目录探测不修改任何系统配置。set-ufail0echo 1. 版本线判定 if[-z${WM_PROJECT_VERSION:-}];thenecho[FAIL] WM_PROJECT_VERSION 未设置 —— 请先 source OpenFOAM 的 etc/bashrcexit1fiechoWM_PROJECT_VERSION $WM_PROJECT_VERSION# 依据形态判定版本线整数如 13/14→ Foundation以 v 开头如 v2606→ ESIcase$WM_PROJECT_VERSIONinv[0-9]*)lineOpenCFD/ESI 版年月编号;;[0-9]*)lineOpenFOAM Foundation 版整数编号;;*)line无法判定以官方发布说明为准;;esacecho判定版本线 $lineecho 2. 关键路径存在性 check_dir(){# $1变量名 $2用途说明evalp\${$1:-}if[-n$p][-d$p];thenecho[OK]$1$p($2)elseecho[FAIL]$1未设置或不存在 ($2);fail1fi}check_dir FOAM_SRC核心库源码第 05~13 篇改基类的地方check_dir FOAM_APP应用源码求解器与工具的参考实现check_dir FOAM_TUTORIALS官方算例铁律 7 回归验证的基准check_dir FOAM_ETC配置模板与环境脚本echo 3. 用户产物目录铁律 4check_dir FOAM_USER_APPBIN自定义求解器/工具输出目录check_dir FOAM_USER_LIBBIN自定义库输出目录echo 4. 平台一致性 # 编译产物目录名由 WM_OPTIONS 决定若它为空说明环境不完整。echoWM_OPTIONS ${WM_OPTIONS:-未设置}echoWM_COMPILER${WM_COMPILER:-未设置}echo 5. 工具可用性 fortinwmake foamToC foamDictionary blockMesh checkMesh;doifcommand-v$t/dev/null21;thenecho[OK]$t可用elseecho[WARN]$t不在 PATH部分工具随版本不同可能改名以官方文档为准fidoneecho[$fail-eq0]echo体检通过环境可用于二次开发。||echo体检未通过请按 FAIL 项修复。exit$fail逐行剖析set -u让脚本在引用未定义变量时立即报错——体检脚本最怕静默通过宁可早失败。版本线判定用case匹配变量形态整数开头13/14判为 Foundationv开头v2606判为 ESI。这是两条线编号规则铁律 2、3的机械化落地避免人脑记错。check_dir用eval做变量名→值的间接取值POSIXsh没有 bash 的${!var}eval是通用替代。这是环境体检脚本的经典写法。四个路径检查的注释直接标注它们服务于哪些篇目让脚本本身成为一张地图索引。平台一致性只打印不判定WM_OPTIONS的组合合法值取决于编译器/精度/标签写死判定会误伤交给读者用官方etc/bashrc里的注释核对更稳这也是不臆造纪律的体现。工具可用性只对wmake/foamToC/foamDictionary/blockMesh/checkMesh做command -v探测并对可能的改名给出 WARN 而非 FAIL——跨发行线工具集有差异宁松勿错。最后用退出码$fail返回状态使脚本可直接用于 CI 门禁第 20 篇回归层复用。代码 2-2用 Doxygen 源码定位一个类三步法演示脚本#!/bin/sh# locate_class.sh —— 源码定位三步法以 fvMatrix 为例# 用法sh locate_class.sh fvMatrix# 说明仅在本机源码树中查找不联网输出结果可直接用于核验文档。cls${1:-fvMatrix}# 目标类名默认演示用 fvMatrixecho 第 1 步官方 Doxygen # Foundation 版 API 站echo Foundation: https://cpp.openfoam.org/版本/ 搜索类名:${cls}# ESI 版 API 站echo ESI : https://api.openfoam.com/版本/ 搜索类名:${cls}echo 在该类页点 Go to the source code of this file 可看头文件与继承图。echoecho 第 2 步本机定位头文件.H# -path */lnInclude 优先排除软链副本避免同一头文件出现多次found_h$(find$FOAM_SRC-name${cls}.H-not-path*/lnInclude/*2/dev/null)if[-z$found_h];thenecho [WARN] 未在 \$FOAM_SRC找到${cls}.H可能是模板类或位于 applications/elseecho$found_h|seds/^/ H: /fiechoecho 第 3 步定位实现.Cfound_c$(find$FOAM_SRC-name${cls}.C-not-path*/lnInclude/*2/dev/null)[-n$found_c]echo$found_c|seds/^/ C: /||echo 该文件可能为纯头文件实现或使用 .C 之外的后缀echoecho 辅助列出该类所在目录的兄弟文件看同族实现first_h$(echo$found_h|head-n1)if[-n$first_h];thenecho 目录:$(dirname$first_h)ls-1$(dirname$first_h)|head-n12|seds/^/ /fi逐行剖析第 1 步给出两条发行线各自的 Doxygen 入口模板版本由读者替换并明确提示点 source code 链接这一关键动作——很多人不知道 Doxygen 能直接跳源码白白在 GitHub 上翻半天。find ... -not -path */lnInclude/*lnInclude里都是软链副本不排除就会得到一堆重复结果干扰判断。找不到.H时只给 WARN模板类如fvPatchFieldType类模板或实现位于applications/的情况都属正常硬报错会误导。第 3 步给出.C的实际路径改代码前先看实现是避免按头文件猜行为的关键。“列出兄弟文件这一步实测非常有用OpenFOAM 的模型族通常同目录并列如各类 RAS 模型一眼就能看到同族还有谁”这正是第 09、10 篇扩展模型的入口。三、常见报错与排查报错 3-1wmake报Make/files not found或Make/options not found。现象在求解器目录执行wmake直接失败。根因当前目录不是含Make/的源码目录或Make下文件名不被识别必须精确为files与options。解法ls Make确认两个文件名cd到正确目录再编译。铁律 1 延伸文件名的拼写也要以官方源码为准不要凭直觉写成Makefile。报错 3-2链接期undefined reference to ...。现象编译通过链接失败提示某符号未定义。根因有三其一Make/options的LIB_LIBS少写了-l库名其二你的自定义库是在另一个WM_OPTIONS平台下编译的与实际使用的不一致其三缺少lnInclude路径。解法先补齐LIB_LIBS再用echo $WM_OPTIONS确认平台标识若不一致则整库重编。报错 3-3运行期Unknown 类型 type 名字如 Unknown boundary condition type xxx。现象求解器启动即报类型找不到。根因该类型名拼错或该功能在另一条发行线/另一版本中才存在。解法用foamToC列出当前环境下可用类型如foamToC -table momentumTransport以工具输出为准再核对官方 Doxygen 对应版本。这是用工具对账替代用记忆对账的标准动作。报错 3-4command not found: foamToC。现象环境体检里foamToC报 WARN或直接找不到。根因不同发行线/版本的可用工具集不同部分工具在旧版本中不存在或名称不同。解法先echo $WM_PROJECT_VERSION判定版本线再到该线官方文档站doc.openfoam.com或 CFD Direct 用户指南确认该工具是否提供没有就用等价手段如直接查看src中的注册表实现。不要因为工具名字对不上就断定环境坏了。报错 3-5source后仍然一切报错。现象wmake: command not found且环境变量全空。根因source的脚本路径写错例如 source 了etc/config.sh/setup而非顶层etc/bashrc或用了不支持的 shell。解法以官方安装说明为准选择对应的环境脚本确认echo $WM_PROJECT_VERSION有输出。注意环境变量只在当前 shell 有效新终端需重新 source。四、动手练习练习 1环境体检运行代码 2-1。判定脚本退出码为 0输出中WM_PROJECT_VERSION非空且版本线判定正确FOAM_SRC、FOAM_TUTORIALS、FOAM_USER_APPBIN、FOAM_USER_LIBBIN四项均为[OK]。练习 2源码定位运行sh locate_class.sh fvMatrix与sh locate_class.sh fvMesh。判定两个类都能在本机$FOAM_SRC下找到.H实际路径能在官方 Doxygen 对应版本页找到同名类并读出其继承关系。练习 3工具对账运行foamToC -table scalarFunction1若该工具在您的版本中可用。判定能列出至少 5 个函数类型名任选一个类型名到官方 Doxygen 中搜索并确认存在。练习 4平台一致性打印WM_OPTIONS、WM_COMPILER、WM_PRECISION_OPTION、WM_LABEL_SIZE四个变量。判定能用自己的话解释WM_OPTIONS字符串的构成编译器 精度 标签宽度 优化并能说出换精度后为什么要重编自定义库。练习 5思考题无标准答案假设你要为一个自建求解器增加一个自定义库依赖写出Make/options中应包含的两类条目。验证要点(a) 是否写了EXE_INC指向lnInclude(b) 是否写了LIB_LIBS指定库名©Make/files中EXE是否指向$(FOAM_USER_APPBIN)铁律 4。五、小结与下一篇预告本篇把 OpenFOAM 的坐标系讲透了环境变量分四类项目级/路径级/用户级/平台级platforms/WM_OPTIONS决定了编译产物的兼容性wmake读Make/files编译什么、放哪与Make/options怎么编、链什么库两个文件查一个陌生类走Doxygen → 头文件 → 本机源码三步法foamToC是运行期模型名的权威对账工具。最重要的纪律依然是两条先读源码再写代码、自定义产物只落用户目录。第 03 篇《第一个求解器》将把这些工具用起来从最小骨架setRootCase.H/createTime.H/createMesh.H/createFields.H出发写一个能通过wmake编译、能在官方 cavity 算例上跑通的myFirstFoam——那是你第一次真正改 OpenFOAM 本身。本篇认知问题回显FAQQ1OpenFOAM 的环境变量体系是怎么分层的A分四类项目级WM_PROJECT、WM_PROJECT_VERSION、WM_PROJECT_DIR用于判定版本线与定位安装根目录、路径级FOAM_SRC 核心库源码、FOAM_APP 应用、FOAM_TUTORIALS 官方算例、FOAM_ETC 配置、FOAM_LIBBIN/FOAM_APPBIN 系统库与可执行、用户级FOAM_USER_APPBIN、FOAM_USER_LIBBIN自定义产物必须落这里、平台级WM_ARCH、WM_COMPILER、WM_PRECISION_OPTION、WM_LABEL_SIZE 等决定 platforms/WM_OPTIONS 目录名。没 source OpenFOAM 的 etc/bashrc 时这些变量为空是所有命令找不到报错的共同根因。Q2wmake 做了什么Make/files 与 Make/options 各负责什么Awmake 是 OpenFOAM 官方构建系统按 WM_OPTIONS 决定平台目录做增量编译。Make/files 声明编译什么与产物放哪逐个列出源文件 .C可执行用EXE $(FOAM_USER_APPBIN)/名字库用LIB ...。Make/options 声明怎么编译EXE_INC 给出头文件搜索路径一般是库的 lnIncludeLIB_LIBS 给出要链接的库-l库名。自定义求解器的 EXE 必须指向 FOAM_USER_APPBIN不污染系统目录。Q3如何快速定位一个陌生类如 fvMatrix的源码与继承关系A走源码定位三步法。第一步在官方 Doxygen 搜类名Foundation 版 cpp.openfoam.org/版本/ESI 版 api.openfoam.com/版本/拿到命名空间与继承图第二步在该类页点击 “Go to the source code of this file” 看头文件中的成员与虚函数契约第三步在本机用find $FOAM_SRC -name fvMatrix.H -not -path */lnInclude/*定位实际路径再打开同名 .C 看实现。排除 lnInclude 是为了避免软链副本造成重复结果。Q4foamToC 能查什么为什么比翻博客可靠AfoamToC 是内容清单/自省工具可列出当前环境可选的各种模型与表。官方用户指南示例给出foamToC -table scalarFunction1用于列出标量 Function1 函数常数、多项式、表格、正弦等类似地可列出动量输运湍流模型、以及某求解器可用的 fvModels。它可靠的原因是直接读取你本机安装版本的注册表输出必然与环境匹配博文可能来自其他版本或另一条发行线按其类型名编写会触发 “Unknown … type” 类报错。Q5自定义编译产物应放哪里放错会怎样A必须落到 FOAM_USER_APPBIN可执行与 FOAM_USER_LIBBIN库这是铁律 4。ESI 插件仓库的做法是./Allwmake -prefixuser并在 Make/options 中sinclude $(GENERAL_RULES)/module-path-user对齐用户路径。放进系统目录FOAM_APPBIN、FOAM_LIBBIN有三重后果升级或重装时被覆盖导致工作丢失、与他人不同 WM_OPTIONS 平台混用导致链接失败、出问题时无法区分官方行为与自有改动。此外切换精度或标签宽度后必须重新编译自定义库否则会因平台标识不一致而链接报错。
返回列表