简介:面向在64位Windows环境下从事热力学与流体物性计算的MATLAB用户,这份资源提供REFPROP库的调用配套文件,重点解决64位MATLAB与NIST REFPROP动态库对接、流体定义加载及基础接口调用问题,适合制冷、热交换器设计、化学工程计算等场景的中级使用者。压缩包共117个文件,约1.64MB,主体为105个fld流体定义文件,并包含dll动态链接库、m脚本接口及BNC、ppf等配置与数据文件,目录构成覆盖物性计算所需的基础资源,便于按类型快速定位。已有6075人学习,说明其在MATLAB物性调用需求中具有一定参考度。随包附带的函数说明与提示文件可帮助读者理解接口封装、参数传递和错误处理思路,并可用于密度、焓、熵等物性查询与后续工程模拟,价值在于减少自行配置和摸索接口的时间。
1. 64 位 MATLAB 调 REFPROP:为什么"下载即可用"到了自己机器上就打不开
装完 MATLAB,把 REFPROP 文件夹解压到硬盘,兴冲冲跑示例,第一个报错往往是「错误使用 loadlibrary,无法打开共享库」。matlab refprop 64 这套组合的坑几乎从来不在物性算法上,而是卡在库能不能挂进去这一步:MATLAB 是 32 位还是 64 位、DLL 实际叫什么名字、calllib 用的别名对不对、FLUIDS 目录在不在相对路径上,四件事错一件,后面所有算焓值、算密度的代码一行都跑不起来。这份资源把 64 位 DLL、头文件、封装好的 refpropm.m 和流体文件目录摆成了一套能直接加载的结构,省掉的正是这段最枯燥的对齐工作。往下按加载、调用、批量、排查的顺序走一遍。
2. 目录、DLL 与头文件:把 REFPROP 库挂进 MATLAB 的三步加载
很多人拿到资源的第一反应是把REFPRP64.dll单独拷到工作目录,然后 loadlibrary 报错,接着开始怀疑文件损坏。问题在于 REFPROP 不是一个孤立的 DLL,它运行时还要按相对路径去读FLUIDS\下的流体文件、去MIXTURES\下读混合物配比。DLL 和这两个目录一旦分家,loadlibrary这一步照样能过,因为加载只校验导出表和头文件声明;真正炸的是第一次调用,回来的是一长串被空格填满的herr字符串,看不出所以然。
所以先把目录摆对,再谈代码。这一步花五分钟,能省掉后面两小时的瞎猜。
2.1 目录布局:DLL、头文件与 FLUIDS 必须同根
一套标准的 64 位目录长这样:
REFPROP\ ├─ REFPRP64.dll ← 64 位动态库,位数必须和 MATLAB 对上 ├─ refprop.h ← 函数原型声明,loadlibrary 靠它解析参数类型 ├─ refpropm.m ← 封装层,日常调用只碰这个文件 ├─ FLUIDS\ ← 纯流体文件 │ ├─ WATER.FLD │ ├─ R32.FLD │ └─ ... └─ MIXTURES\ ← 混合物文件 └─ *.MIXREFPRP64.dll和refprop.h必须同级,因为 loadlibrary 的第二个参数可以是相对文件名,MATLAB 会去 DLL 所在目录找头文件;FLUIDS 和 MIXTURES 也必须和 DLL 同级,因为库内部拼接的是.\FLUIDS\xxx.FLD这种相对路径。我一般会在每次开工的头几行把路径固定住,不依赖 MATLAB 启动时的当前目录:
% 每次开工先跑这段:路径固定 + 前置校验 root = 'D:\REFPROP'; % 换成你自己的安装根目录 assert(exist(fullfile(root,'REFPRP64.dll'),'file')==2, 'DLL 不在这个目录'); assert(exist(fullfile(root,'refprop.h'),'file')==2, '头文件缺失'); assert(exist(fullfile(root,'FLUIDS','WATER.FLD'),'file')==2, 'FLUIDS 目录不完整'); cd(root); % 让库里的相对路径解析有一个确定的起点 addpath(root); % 让 refpropm.m 能被直接调用三个assert是提前拦截:等 calllib 报错时,错误信息是一整串英文加空格填充,远不如"FLUIDS 目录不完整"这句直白。cd(root)这一步看着土,但确实必要——部分版本的封装层在拼流体文件路径时用的是硬编码的相对前缀,当前目录不对,它就找不到文件。如果你不想改变当前目录,那就得改refpropm.m里的路径拼接逻辑,把前缀换成fullfile(root,'FLUIDS')。
addpath(root)只加根目录不加子目录,因为refpropm.m在根目录下,FLUIDS 不需要进搜索路径——它由库自己去读,不是 MATLAB 去读。
2.2 别名(alias):改一行,后面几十处 calllib 都不用动
打开refpropm.m,搜索loadlibrary,第一次出现的位置大概长这样:
% 原文件里通常是(32 位版本的写法): % loadlibrary('refprop.dll','refprop.h','alias','refprop'); % % 64 位要换成实际的 DLL 文件名,但 alias 保持 'refprop' 不变 if ~libisloaded('refprop') [notfound, warn] = loadlibrary('REFPRP64.dll','refprop.h','alias','refprop'); end这里有一个容易被忽略的机制:calllib 的第一个参数是别名,不是文件名。refpropm.m全文有几十处calllib('refprop', 'REFPROPdll', ...)、calllib('refprop', 'SETUPdll', ...),它们引用的都是别名。你把 alias 设成'refprop',这几十处一行都不用改;如果不写 alias,MATLAB 默认拿文件名去掉扩展名当别名,也就是'REFPRP64',那你就得全文替换,漏一处就在运行时炸一处。
[notfound, warn]这两个返回值别丢。notfound会列出头文件里声明了、但 DLL 里没有导出的函数名;warn是参数类型推断的告警。两个都接住,出问题时屏幕上至少有线索;不接的话 MATLAB 照样往下跑,错在第一次 calllib 上,排查成本高一个量级。
还有一点:if ~libisloaded('refprop')这个判断不要删。DLL 加载后常驻内存,重复 loadlibrary 会告警甚至报错;而在 parfor 或者多次调用脚本的场景里,这个判断就是那层保险。
2.3 加载自检:libisloaded、libfunctions 与一次饱和水验收
加载完不要急着跑业务代码,三步验收,每步都有明确的期望值:
% 第一步:库是否在内存里 libisloaded('refprop') % 期望返回 1(logical) % 第二步:导出表是否解析成功 fns = libfunctions('refprop'); % 元胞数组 any(strcmp(fns,'REFPROPdll')) % 期望 1 any(strcmp(fns,'SETUPdll')) % 期望 1 any(strcmp(fns,'INFOdll')) % 期望 1 % 第三步:真算一个点,和常识对拍 Tb = refpropm('T','P',101.325,'Q',0,'WATER') % 期望 373.1243 附近,也就是常压饱和水 99.97 ℃第一步返回 0 说明库压根没进内存,回去看 2.2。第二步里libfunctions列出的是 DLL 的导出表,如果REFPROPdll不在里面,说明你加载的是个残缺文件或者名字对不上。第三步才是真正的端到端验收——它同时验证了库、FLUIDS 目录、封装层三者的连通性,因为这一次调用内部会先SETUPdll装载WATER.FLD,再调REFPROPdll算泡点温度。
如果第三步报错,把返回的herr打印出来看首尾,中间那些空格是固定长度的填充,有效信息都在开头几个词里。这一步过了,说明整套东西通了,可以开始写业务代码。
3. refpropm 的入参结构:两个状态量如何决定剩下的全部物性
REFPROP 的核心逻辑是"状态方程 + 两个独立状态量"。你给它任意两个独立强度量,它把整个状态钉死,剩下的所有物性都能算出来。refpropm 就是把这套逻辑包装成一行函数调用,理解了这个前提,参数该怎么填就不会乱。
3.1 通用形式与输出符号
% 通用形式: % [p1, p2] = refpropm('输出符号', '状态量1', 值1, '状态量2', 值2, '流体名') % 输出符号最多两个字符,字符顺序对应返回值的顺序 % 单点:300 K、101.325 kPa 下的水和密度、焓 [D, H] = refpropm('DH', 'T', 300, 'P', 101.325, 'WATER'); % 输出符号顺序可以调换,返回值的顺序跟着变 [H, D] = refpropm('HD', 'T', 300, 'P', 101.325, 'WATER'); % 只要一个输出,就只写一个字符 rho_mol = refpropm('D', 'T', 300, 'P', 101.325, 'WATER');几个参数说明。'DH'这种双字符输出是封装层支持的写法,省一次 DLL 调用;如果你的工况点很多,能用双输出就别拆成两次单输出,累计下来差得不少。'T'、'P'这两个状态量的先后顺序不影响结果,('T',T,'P',p)和('P',p,'T',T)等价,因为库内部是按符号识别而不是按位置。流体名可以带扩展名'WATER.FLD',也可以不带,封装层会自动补;带.MIX后缀的走混合物分支,那是另一条路径。
真正需要注意的是:两个状态量必须独立。给T和P在单相区没问题,在两相区就出事,因为两相区里温度和压力是一一对应的,不构成独立方程组。这个坑在 5.2 里细讲。
3.2 单位账:mol 基、质量基与 kPa 的一次性换算
这是新手翻车最集中的地方。REFPROP 内核是摩尔基的,封装层返回的也是摩尔基,而工程上大家习惯用质量基。不换算直接拿去用,密度会差三个数量级,焓值差两个数量级,而且数值看起来"挺正常",特别容易蒙混过关。
| 符号 | 物理量 | 库内单位 | 转工程单位 |
|---|---|---|---|
T | 温度 | K | 减 273.15 得 ℃ |
P | 压力 | kPa | 除 1000 得 MPa |
D | 密度 | mol/L | × 摩尔质量 × 1000 得 kg/m³ |
H | 比焓 | J/mol | ÷ 摩尔质量 得 J/kg |
S | 比熵 | J/(mol·K) | ÷ 摩尔质量 得 J/(kg·K) |
U | 内能 | J/mol | ÷ 摩尔质量 |
C | 定压比热 | J/(mol·K) | ÷ 摩尔质量 |
V | 动力粘度 | µPa·s | ÷ 1e6 得 Pa·s |
L | 导热系数 | W/(m·K) | 无需换算 |
Q | 干度 | mol/mol | 质量干度需按组分折算 |
提示:不同版本封装层的符号有增补,表面张力、声速、压缩因子这些可能用别的字母。以你本机
refpropm.m开头那段 help 注释为准——那份注释和配套的 DLL 是同一个版本出来的,比任何网上抄来的对照表都可靠。
换算写成代码是这样:
M = 18.0153e-3; % 水的摩尔质量,kg/mol T = 300; p = 101.325; % K, kPa [D, H] = refpropm('DH','T',T,'P',p,'WATER'); rho = D * M * 1000; % mol/L -> kg/m^3 h = H / M; % J/mol -> J/kg fprintf('rho = %.2f kg/m3, h = %.1f kJ/kg\n', rho, h/1000); % 期望 rho ≈ 996.5, h ≈ 112.5M这一步对纯质可以手填,但混合物绝对不能手填。混合物的摩尔质量随配比变化,写死一个值,整套结果都是错的。混合物的M要向库要,或者按组分摩尔分数加权算——后者更稳妥,因为你能自己核对。
还有一个隐蔽的点:V的单位是微帕·秒,不是帕·秒。做雷诺数计算时忘了除 1e6,雷诺数会小六个数量级,然后你会以为是物性库算错了。
3.3 混合物与 .MIX 文件:配比写在哪
混合物不走函数参数,走文件。REFPROP 的惯例是在MIXTURES\下放一个.MIX文本文件,里面声明组分和摩尔分数,调用时把文件名当流体名传进去。
我一般不去背.MIX的格式,而是直接抄一份现成的改:
% 步骤一:在 MIXTURES 目录里挑一个组分数量对得上的现成 .MIX, % 复制一份改名,用文本编辑器打开 % 步骤二:前几行是组分文件名(比如 R32.FLD、R125.FLD 各占一行), % 后面跟一一对应的摩尔分数,顺序不能错位 % 步骤三:保存到 MIXTURES\ 下,文件名大写,扩展名 .MIX % 步骤四:调用时把文件名当流体名用 D = refpropm('D','T',300,'P',800,'MYMIX.MIX');为什么要抄而不是自己写:.MIX文件对行序、注释符、分数个数的容错很低,自己从零敲一个,十个里有八个会因为格式问题报"流体未找到"。抄一份现成的,格式肯定是对的,你只改数字,成功率接近百分之百。
配比之和要归一,写 0.5 和 0.5 没问题,写 50 和 50 就废了。改完.MIX文件后还有一个缓存问题——DLL 已经把旧的配比读进内存了,不重新装载读不到新值。这一点在 5.2 的坑五里有专门的处理办法。
3.4 饱和线与两相区:Q 的两端与临界点附近
带Q的调用是另一类工况:
p = 101.325; Tb = refpropm('T','P',p,'Q',0,'WATER'); % 泡点温度 Td = refpropm('T','P',p,'Q',1,'WATER'); % 露点温度 % 纯质:泡露点重合 fprintf('泡点 %.4f K,露点 %.4f K,差值 %.4f K\n', Tb, Td, Td-Tb);纯质的泡点和露点在给定压力下是同一个温度,差值应该是 0(浮点误差范围内)。混合物就不一样了,泡点和露点之间有一段温度滑移,这个差值本身就是一个有用的输出——做换热器分段计算时,滑移量
本文还有配套的精品资源,点击获取