简介:Refprop 是美国国家标准与技术研究所开发的流体热力学与输运性质数据库。这份资料将 Refprop 程序、Matlab 调用包与配套使用说明打包成套,面向需要快速查询物性参数、并在 Matlab 中开展仿真计算的科研与工程人员,解决跨软件调用不便、人工查表效率低的问题。压缩包共 10 个文件,体积仅 9.14MB,核心以 exe/dll 程序、pdf/txt 说明文档为主,并包含 md/rst 说明文件及 h/m 形式的 Matlab 接口文件,结构一目了然。通过附带的调用包,用户可在 Matlab 中灵活获取 Refprop 的流体数据,省去重复建模与手工查表;安装替换步骤、接口函数说明和示例均写入文档,便于初学者上手,也可直接嵌入已有计算流程。目前已有 416 人学习浏览,适合热力学计算、制冷空调、能源动力等领域需要物性数据支撑的读者。
1. 为什么制冷仿真里离不开REFPROP,却总在Matlab这步卡住
"NISTRefprop+Matlab调用包"这个组合,做制冷循环、热泵设计、透平膨胀机仿真的人基本都绕不过去:REFPROP算工质物性的精度是行业基准,但它本质是个独立软件,要在Matlab里批量调用它,不是装个工具箱就能用。真正的难点在于调用包要自己配路径、自己传单位、自己解析返回结构,新手第一周最容易卡在"库加载失败"和"返回一堆负数错误码"上。这篇文章按我实际跑通的经验,讲清楚调用包的组成、最小可用命令、混合制冷剂调用方法,以及高频踩坑点的排查顺序,适合正在做热力学仿真或设备选型计算、需要批量拿密度焓熵粘度数据的工程师。
2. 别把调用包当工具箱:先搞清REFPROP的内核、流体文件和两条调用通道
2.1 REFPROP的"内核+流体文件"结构决定了调用方式
REFPROP本质上是一个计算内核加一堆数据文件。常见安装目录里,除了主程序和帮助文档,还会有两个关键的子目录:fluids 子目录放纯工质文件,文件名一般是 R134A.FLD、CO2.FLD、R32.FLD 这种"工质名+FLD"的形式;mixtures 子目录放混合物定义文件,常见的是 R410A.MIX、R404A.MIX 这类。真正干活的是编译好的共享库,Windows 下常见是 refprop.dll,Linux 和 macOS 下对应的是 librefprop.so 和 librefprop.dylib。
Matlab 本身不会计算物性,它只是把工质名、状态参数、请求的物性字段打包成一次底层调用,交给这个共享库算完再把结果拿回来。所以"Matlab调用包"并不是一个官方工具箱,而是一层翻译壳。这层壳做三件事:把工质名映射到对应的流体文件、把输入单位换算成 REFPROP 内部的 SI 制、把返回的浮点数数组转成可读的结构体。理解了这一点,后面遇到的所有坑基本都能归因到这三件事上——要么路径没指对,要么单位传错,要么返回结构解析错了。
2.2 官方调用包里常见文件与各自职责
拿到调用包后,我一般会先看你手里的版本里有哪些 .m 文件,不同小版本的命名会有出入,但核心文件职责基本一致。最常见的几个文件是这么分工的:
| 文件名 | 职责 | 什么时候用 |
|---|---|---|
| refprop.m | 主入口,处理单流体与混合物的字符串参数、单位换算和结果组装 | 绝大多数调用场景 |
| REFPROPf.m | 单点快速物性计算,参数列表更短,适合低级调用 | 你只想算一个密度或一个焓值 |
| REFPROPmixture.m | 旧版混合物接口,组分单独作为参数传入 | 旧版本或特殊组分传递方式 |
| SETUPdll.m | 加载共享库并检查路径 | 首次配置时手动跑一次 |
这里有个关键动作:不要只把主程序所在目录加进 Matlab 路径,fluids 和 mixtures 这两个数据目录也要加进去。REFPROP 运行时是按字符串去磁盘找流体文件的,如果用 addpath 只加了对的地方,漏了流体文件目录,调用时它会提示找不到工质,肉眼看起来像参数名写错,实际是数据路径没配上。
2.3 两条调用通道怎么选:官方wrapper与直接loadlibrary
除了官方 wrapper,老手还会选择直接用 Matlab 的 loadlibrary 命令加载共享库,绕开 wrapper 那层壳直接调底层函数。这两条通道各有好坏,我在不同项目里都用过。
| 调用方式 | 优点 | 缺点 | 适合谁 |
|---|---|---|---|
| 官方 wrapper(refprop.m) | 单位自动换算、字符串映射、返回结构清晰 | 每次调用有额外解析开销 | 绝大多数工程计算、批量循环 |
| 直接 loadlibrary + calllib | 少一层翻译,适合几十万点的大批量计算 | 要自己处理指针、内存和单位转换 | 长期跑仿真、做优化迭代的熟手 |
我的建议很简单:新手或者正常做设计计算,用官方 wrapper 就够了,跑批量点的时候只要注意别在循环里反复加载就行。真到了要做一个制冷循环的全年逐时仿真、单次要算几十万个状态点,那时候再考虑绕过 wrapper 直接调底层。这个决策不着急做,先把 wrapper 用顺。
3. 跑通第一个物性点:调用包的路径配置、最小示例与参数表
3.1 把调用包加进Matlab:路径不是只加根目录
拿到调用包并安装好 REFPROP 之后,第一步是写一个配置文件,把要用到的目录一次性加进 Matlab 路径。常见做法是新建一个 setup_refprop.m,内容如下:
% setup_refprop.m % 把 REFPROP 相关的三个目录加进 Matlab 路径 % refprop_root:REFPROP 的安装位置,按自己机器实际情况改 refprop_root = 'C:\Program Files (x86)\REFPROP'; % 常见安装位置,64位库在第2步看的实际情况为准 % 主程序目录,放 wrapper 的 m 文件 addpath(fullfile(refprop_root)); % 纯工质数据目录 addpath(fullfile(refprop_root, 'fluids')); % 混合物数据目录 addpath(fullfile(refprop_root, 'mixtures')); % 验证关键文件是否存在,不存在就停下来检查路径 assert(exist('refprop.m', 'file') == 2, '没有找到 refprop.m,请检查主目录路径'); assert(isfolder(fullfile(refprop_root, 'fluids')), '没有找到 fluids 数据目录'); assert(isfolder(fullfile(refprop_root, 'mixtures')), '没有找到 mixtures 数据目录'); disp('REFPROP 路径配置完成');这段代码的逻辑是先把主程序目录加进去,这样 Matlab 能找到 refprop.m 这个入口文件;然后把 fluids 和 mixtures 两个数据目录也加进去,因为 REFPROP 算纯工质和混合物时都是按文件名去目录里找数据文件的,少了任何一层都会在调用时报"找不到流体"或者直接返回错误码。
参数方面要注意两个点。第一,refprop_root 这个变量不要写死成上面这行,REFPROP 的安装位置在不同机器上差别很大,有的人装在 D 盘,有的人装在自定义目录,先打开安装目录看一眼再填。第二,assert 语句是我特意留的校验逻辑,防止路径配错后跑到调用环节才发现问题,用 exist 检查函数文件、用 isfolder 检查数据目录,这两个函数在 Matlab 上都是稳定的,不会出现兼容性问题。
3.2 最小示例:算R134a单点密度和焓
路径配好后,第一次调用建议先算一个已知状态点的物性,用来验证全链路。我常用 R134a 在 30℃、1 MPa 下的密度作为基准点,因为这类数据在制冷剂手册上都能查到,方便对比结果是否正常。
% 计算 R134a 在 30℃、1 MPa 下的密度和焓 % 先转成绝对单位:温度用 K,压力用 Pa T_K = 30 + 273.15; % 303.15 K P_Pa = 1e6; % 1 MPa = 1e6 Pa % 调用主入口 % refprop(输出物性, 输入条件1类型, 输入条件1值, 输入条件2类型, 输入条件2值, 流体名) % 这里请求输出密度 D 和焓 H,输入条件是温度 T 和压力 P out = refprop('DH', 'T', T_K, 'P', P_Pa, 'R134A'); disp(out); % 如果返回失败,打印错误信息辅助定位 if isfield(out, 'err') warning('REFPROP 调用返回错误: %s', out.err); end这段代码里最关键的是 refprop 函数的参数顺序:第一个参数是你要的物性字段字符串,'DH' 表示同时要密度 D 和焓 H;第二个参数是第一个输入条件的类型,这里 'T' 表示温度;第三个参数是温度值;第四个参数是第二个输入条件的类型 'P';第五个是压力值;第六个是流体名字符串,'R134A' 是制冷剂文件的实际名称。
不同小版本的调用包返回格式会有差异,有的版本直接返回一个结构体,有的版本返回两个输出值(结果值和错误码),还有的老版本返回的是 cell 数组。我自己的习惯是第一次调用时先不解析,直接 disp(out) 看下结构,再根据实际字段名去写后面的代码。这一步能省很多后面改代码的时间,因为网上教程写的字段名和实际包的字段名偶尔会对不上。
3.3 读懂输入参数:状态点标识符、单位制和输出字段速查
REFPROP 调的输入条件不是随便传一个函数值就行,它用两个字母的标识符告诉计算内核"你给的是什么状态"。这个标识符系统是调用包里最容易看晕的地方,但掌握了它,几乎所有调用都能拆解成"输入两个条件求一个或多个物性"。
| 输入标识 | 含义 | 常用于 |
|---|---|---|
| T | 温度 | 配合 P、H、S 使用 |
| P | 压力 | 配合 T、H、S 使用 |
| H | 比焓 | 节流过程、两相区计算 |
| S | 比熵 | 等熵压缩过程 |
| Q | 干度 | 两相区指定干度 |
| D | 密度 | 超临界区或特殊工况 |
输出字段则是你要的物性结果,常见的有 D(密度)、H(比焓)、S(比熵)、V(声速)、ETA(粘度)、TCX(导热系数)、CP(定压比热)、CV(定容比热)。一个常见的困惑是"为什么我传了 P 和 T,输出里还要再传一次 P?"其实不是,输出字段和输入条件类型是两套字符串体系,输入是告诉内核已知什么,输出是告诉内核想要什么,两者可以重复也可以完全不同。
单位制是另一个坑。REFPROP 内核的标准单位是 K、Pa、mol/mol,但不少调用包版本在 wrapper 层做了单位转换,允许你直接传 ℃ 和 kPa。我的建议是不要赌这个,第一次调用用一个已知状态点试出它的单位约定,比如传一个 300 进去看输出是密度约 28 kg/m³ 还是 28000 kg/m³,立刻就能判断出单位制。
4. 从纯工质到混合制冷剂:闪蒸模式、组分传递与批量循环
4.1 TP、PH、PS三种模式:不同状态点计算怎么选
REFPROP 的计算本质上是"给定两个独立状态参数,求平衡态的所有物性",业内叫闪蒸计算。三个用得最多的闪蒸模式是 TP、PH、PS,它们的适用场景非常明确,选错了计算结果会偏离物理意义。
| 闪蒸模式 | 给定参数 | 典型场景 |
|---|---|---|
| T+P | 温度、压力 | 系统某点的普通状态查询,最常用 |
| P+H | 压力、焓 | 节流阀前后、两相区干度计算 |
| P+S | 压力、熵 | 压缩机等熵压缩终点、膨胀机理想过程 |
PH 模式是我觉得最容易出价值但也最容易用错的一个。举个例子,计算节流阀后制冷剂在 0.2 MPa 下的状态,节流前后焓值不变,已知节流前焓值 h = 420 kJ/kg,这时候就适合用 P 和 H 来闪蒸:
% 已知 P=0.2 MPa, h=420 kJ/kg,求 R134a 的状态 P_Pa = 0.2e6; h_kJkg = 420; % 注意:焓的单位要按调用包约定来,常见是 kJ/kg out = refprop('TQ', 'P', P_Pa, 'H', h_kJkg, 'R134A'); disp(out);这段调用请求输出温度 T 和干度 Q,因为在两相区,P 和 H 的组合能直接确定温度和干度。如果你只想要干度判断节流后是不是两相,这个调用就是完整的答案。
用 PH 模式时有一个必须留心的点:如果压力对应的饱和温度下,给定焓值落在液相线以下或者气相线以上,REFPROP 会进入过冷或过热区域计算,这时候干度 Q 要么是 0 要么是 1,不会有中间值。很多人在两相区边缘看到 Q=0 或 Q=1 当成错误,其实不是,那是真实的物理状态,需要结合具体循环工况判断。
4.2 混合制冷剂:组分传错是头号翻车点
纯工质跑通之后,混合理工质是调用包最常翻车的地方。常见的错误不是调用格式不会写,而是组成传错——质量分数没有归一化、多传了或者少传了一个组分、组分数组类型不对,都会导致返回错误码。
% 计算 R32/R125 二元混合物在 30℃、1 MPa 下的密度和焓 % 质量分数各 0.5,注意分量和必须为 1 T_K = 30 + 273.15; P_Pa = 1e6; w = [0.5, 0.5]; % 质量分数数组,分量和为 1 % 调用混合物入口:流体名一个接一个传,最后传组分数组 out = refprop('DH', 'T', T_K, 'P', P_Pa, 'R32', 'R125', w); disp(out);这段代码背后做的事情是:REFPROP 先加载 R32 和 R125 两个纯工质的流体文件,再按 w 数组里的比例把它们组合成一个新的"虚拟流体",最后对这个虚拟流体做闪蒸计算。所以 w 数组的长度必须和流体名数量一致,R32、R125 两个名字就要配两个质量分数。
我建议传组分之前先做一次归一化校验,特别是组分来自界面输入或者数据表读取时,浮点累计误差很容易让质量分数变成 0.99999 或 1.00001。虽然 REFPROP 内部对微小偏差有一定容忍度,但在临界点附近计算时这些小偏差会被放大,输出结果看起来就像"跳变"了。一个简单的做法是在调用前加一行 w = w / sum(w),成本几乎为零,能省掉很多临界区域的诡异问题。
4.3 批量循环性能:一次初始化,多点复用
工程仿真里几乎没有只算一个点的情况,常见的是要给一整条工况曲线算物性,比如从 -20℃ 到 60℃ 每隔 5℃ 算一组密度和比热。最容易掉进去的性能陷阱是每次循环都重新加载一次库或重新找一次流体文件,导致大部分时间花在初始化而不是计算上。
% 批量计算 R410A 在 1 MPa 下从 0℃ 到 50℃ 的密度 P_Pa = 1e6; T_list = 0:10:50; % 0,10,20,30,40,50 n = length(T_list); % 预分配输出结构,避免循环里动态增长 rho = zeros(n, 1); h_list = zeros(n, 1); % 关键:流体名和组分在循环外只定义一次 fluid = 'R410A'; for i = 1:n T_K = T_list(i) + 273.15; out = refprop('DH', 'T', T_K, 'P', P_Pa, fluid); rho(i) = out.D; h_list(i) = out.H; end % 结果可视化 figure; plot(T_list, rho, 'o-'); xlabel('温度 / ℃'); ylabel('密度 / kg/m^3'); title('R410A 在 1 MPa 下的密度-温度曲线');这段循环里唯一的波动变量是温度,流体名字符串在循环外定义一次,循环体内不重复做字符串拼接、不重复加载路径。预分配 rho 和 h_list 两个数组也是有意为之,Matlab 里动态增长的数组在循环规模大时性能断崖式下降,先 zeros 再赋值是基本操作。
当循环量到了几万点级别,比如做全年逐时仿真,建议把温度压力组合先组织成两个列向量,一次性传给 REFPROP 的多点接口。多数新版调用包支持传数组而非标量,一次调用返回一整列结果,速度能提升一个数量级。判断你的调用包支持不支持的方法很简单:把 refprop 的第二个参数传一个向量进去试试,不报错就能用,报错就老老实实写循环。
5. 调用包高频踩坑:六个让人想放弃的现象、原因与解法
5.1 现象:loadlibrary 报错"未找到共享库",Matlab 直接崩或返回空结构
我第一次配置时遇到过这个问题,现象是调用包里的初始化脚本跑到 loadlibrary 那一步就卡住,报错信息五花八门,有的说找不到指定模块,有的说内存访问错误,还有的直接让 Matlab 崩溃。
原因基本是三个:一是 Matlab 位数和共享库位数不匹配,32 位 Matlab 调 64 位 dll,或者反过来,这是最常见的原因;二是杀毒软件把 dll 隔离或拦截了,REFPROP 的库文件经常被误报;三是共享库文件路径没加入系统 PATH,loadlibrary 按系统路径找文件,找不到就报错。
解决方法是先查位数:在 Matlab 里跑 computer 命令看返回是 PCWIN64 还是 PCWIN,然后去安装目录的文件属性里看 dll 的位数,确保两者一致。如果位数对但还报错,把杀毒软件的实时防护临时关掉再试一次。路径问题则直接用 loadlibrary 的完整路径形式,不要依赖 PATH 变量。
写脚本时我习惯加一个显式的库加载检查:
% 手动加载核心库文件,lib 参数在 Windows 上通常是 refprop % 注意写绝对路径,避免系统 PATH 找不到 [notfound, warnings_s] = loadlibrary('refprop.dll', 'refprop.h'); if ~isempty(notfound) error('共享库加载失败: %s', notfound); end disp('共享库加载成功');调用结束如果想释放库,用 unloadlibrary('refprop') 即可,但注意如果后面还要继续用就不要释放,重复加载释放会导致多次初始化,反而拖慢整体性能。
5.2 现象:调用返回一个很大的负数,常见是 -2 或 -101,但输入明明"看起来"没问题
这是高频问题,现象是 refprop 返回的错误码是一个负数,常见到看到 -2 就以为参数类型错了,到处查语法。
实际上负数错误码的机制要分两层看。第一层是输入参数没被识别,比如状态点标识符拼成了 'Temperature' 而不是 'T',或者流体名字符串和 .fld 文件名不完全一致,大小写错了也会找不到。第二层是数值本身越界,比如温度超过了该流体的有效范围上限,或者压力给成负压,计算内核在物理上没法求解就返回错误码。
一个稳妥的排查流程:先用 REFPROP 自带的图形界面输入同样的状态点,如果图形界面能算出结果而调用包报错,问题一定出在调用包的参数传递上;如果图形界面也算不出,那是状态点超出有效范围,换个工况即可。这个对比法能快速把问题分成"参数错"和"工况错"两类,比盯着错误码猜要快得多。
5.3 现象:两相区算出的焓和手册差很多,特别是干度靠近 0 或 1 的时候
我在某个制冷仿真 Demo 里比对过压缩机吸排气状态,发现接近饱和线的点计算结果经常和手册数据有几 kJ/kg 的偏差,起初以为是调用包坏了,后来才发现是输入条件的组合方式不对。
原因是 P 和 H 的组合在接近两相区边界时数值敏感度高,焓值一点点偏差会导致干度计算出现较大偏移。手册上给出的焓值通常保留一位小数,直接用这个值反算干度,误差很容易被放大。
解决方法是优先用 T 和 Q、P 和 Q 这种带干度的组合来计算两相区状态,干度比焓值稳定得多。如果确实只有焓值可用,那就要接受计算结果的误差范围,同时在输入焓时多保留几位有效数字。
另一个相关坑是:P 和 H 组合落在亚稳区,比如过热蒸汽状态但压力和焓对应起来却在饱和线以内,REFPROP 会给出一个在热力学上"不真实"的结果。遇到这种情况要回到物理上检查输入焓的来源,是不是上游状态算错了。
5.4 现象:混合物调用报组分超范围,或者结果对组分变化特别敏感
跑 R32/R125/R134a 三元混合物时,如果 w 数组的分量和不是 1,调用包会直接报错或者返回一个奇怪的结果。更隐蔽的情况是 w 在临界点附近哪怕差 0.001,输出物性也会有明显跳变。
原因一句话:混合物闪蒸对组成敏感是物理特性,不是代码 bug。尤其在三元混合物近临界区,组分的微小变化会导致相平衡计算大幅偏移。
解决方法是先把 w 归一化,再用 REFPROP 图形界面做一个组分扫描曲线,肉眼确认目标工况附近不是敏感区。如果是做循环仿真且系统在临界点附近运行,建议把组分作为优化变量做敏感性分析,而不是固定一组组分算全部工况。
5.5 现象:新开 Matlab 后又要重新配置路径,忘了就报"未定义函数或变量 refprop"
这是纯使用习惯问题。addpath 只对当前 Matlab 会话有效,关掉软件再打开就清空了。
原因是没把配置脚本写进 startup.m。Matlab 启动时自动执行用户目录下的 startup.m,把 addpath 语句放进去,以后每次打开都能直接用。
解决方法是简单到不值一提:
% 编辑或新建 startup.m,放在用户目录下 % 内容就是 setup_refprop.m 里面的 addpath 部分,或者直接调用它 run('D:\work\refprop_tools\setup_refprop.m');我一般会把所有和自己常用的第三方调用包相关的配置都集中到一个 startup.m 里,路径写绝对路径,不用相对路径。曾经因为路径里带中文导致配置不生效,折腾了一下午才发现,现在习惯所有工具目录一律英文命名。
5.6 现象:调用包能算但结果和工程手册对不上,密度差了 10% 以上
能出结果但数值不对,这类问题比报错更让人抓狂。现象是想校核一个 R134a 的密度,手册上是 35 kg/m³,调用包算出来 32 kg/m³,差得不多但没法接受。
原因大概率是单位制没对上。REFPROP 内核的基准单位是 K、Pa、mol/mol,如果你传了 30 当成 30℃ 但内核按 30K 理解,密度自然会差很多倍。另一种常见情况是压力单位传错,把 1 MPa 传成 1 kPa,整个状态点就偏离了。
解决方法是固定用绝对单位传参,K 和 Pa 作为标准,在自己封装函数层做单位转换。这样即使换一台机器、换一个调用包版本,核心调用代码不用改。养成这个习惯后,跨版本迁移调用包时会非常省心。
6. 把调用包封装成自己的物性函数:一个能少写大量重复代码的小习惯
前面几章都在讲怎么把 REFPROP 调用包用起来,但真正让它变成一个工程工具,我建议做最后一步:写一个自己的物性封装函数。原因很简单,调用包本身的参数格式太"底层",每次调用都要记字符串标识符、记单位制、记返回字段名,工程代码里到处都是裸的 refprop 调用,后期维护会很痛苦。
我的做法是做一个统一的入口,函数名用自己的项目缩写,输入输出全部用工程习惯的单位制。核心代码如下:
function r = fuel_rho_h(fluid, T_C, P_MPa) % 统一的物性查询函数,返回密度和焓 % 输入: % fluid - 工质名,如 'R134A'、'R410A' % T_C - 温度,摄氏度 % P_MPa - 压力,MPa % 输出: % r.rho - 密度,kg/m^3 % r.h - 比焓,kJ/kg % 内部转换成 REFPROP 内核单位 T_K = T_C + 273.15; P_Pa = P_MPa * 1e6; r = struct(); try out = refprop('DH', 'T', T_K, 'P', P_Pa, fluid); if isfield(out, 'D') r.rho = out.D; r.h = out.H; else r.rho = NaN; r.h = NaN; warning('REFPROP 无返回 D/H 字段,请检查流体名'); end catch ME r.rho = NaN; r.h = NaN; warning('物性计算失败: %s', ME.message); end end这个封装的三个价值很直接:第一,单位换算集中在一处,所有调用点都不用再操心 K 和 Pa;第二,错误处理统一收敛,调用失败时返回 NaN 而不是让整个脚本抛异常中断,批量仿真里单点失败不至于整体崩溃;第三,将来如果想换物性库,比如换成其他开源物性包,只需要改这一个函数内部实现,所有上层代码不用动。
我自己的项目里就是靠这个函数把 REFPROP 从"偶尔手动查状态"变成了"可以嵌进优化循环"的工具。曾经有个多工况寻优计算,上层循环调用它几万次,因为单位换算都在函数内部,外层代码干净,调试起来非常快。反观一个早期项目,所有调用裸写在主脚本里,每次改单位制都要全局搜索替换,那个痛至今记得。
如果要用到混合物,就在这个封装上再加一个分支,传入组分向量,内部调用混合理工质的 refprop 格式。再进一步,可以把返回的物性字段也做成年份式的选择,比如第三个参数传 'rho' 就只返回密度,传 'h' 只返回焓,这样调用点代码更短。
希望这次的经验能帮你把 REFPROP 调用包真正变成顺手工具。
本文还有配套的精品资源,点击获取