计算公式

This commit is contained in:
2026-03-08 21:07:48 +08:00
parent 4f45e2b5b6
commit 219b7e5829
5 changed files with 850 additions and 8 deletions

View File

@@ -58,9 +58,22 @@ namespace CapMachine.Wpf.Services
_drynessCalculator = drynessCalculator;
TagManager = MachineRtDataService.TagManger;
//SpeedTag = TagManager.DicTags.GetValueOrDefault("转速[rpm]");
//ExPressTag = TagManager.DicTags.GetValueOrDefault("排气压力[BarA]");
//ExTempTag = TagManager.DicTags.GetValueOrDefault("排气温度[℃]");
if (TagManager.TryGetShortTagByName("转速[rpm]", out ShortValueTag? speedShortTag))
{
SpeedTag = speedShortTag!;
}
if (TagManager.TryGetShortTagByName("排气压力[BarA]", out ShortValueTag? exPressShortTag))
{
ExPressTag = exPressShortTag!;
}
if (TagManager.TryGetShortTagByName("排气温度[℃]", out ShortValueTag? exTempShortTag))
{
ExTempTag = exTempShortTag!;
}
if (TagManager.TryGetShortTagByName("HV[W]", out ShortValueTag? hvPwShortTag))
{
HVPwTag = hvPwShortTag!;
}
if (TagManager.TryGetShortTagByName("吸气压力[BarA]", out ShortValueTag? InhPressShortControlTag))
{
InhPressTag = InhPressShortControlTag!;
@@ -162,6 +175,26 @@ namespace CapMachine.Wpf.Services
/// </summary>
public ShortValueTag InhPressTag { get; set; }
/// <summary>
/// 转速标签
/// </summary>
public ShortValueTag? SpeedTag { get; set; }
/// <summary>
/// 排气压力
/// </summary>
public ShortValueTag? ExPressTag { get; set; }
/// <summary>
/// 排气温度
/// </summary>
public ShortValueTag? ExTempTag { get; set; }
/// <summary>
/// 压缩机功率HV 电源)
/// </summary>
public ShortValueTag? HVPwTag { get; set; }
/// <summary>
/// 吸气温度
/// </summary>
@@ -415,6 +448,21 @@ namespace CapMachine.Wpf.Services
// 处理 err2
}
if (TryUpdateThermodynamicSixResults(out var thermoErr))
{
if (!string.IsNullOrWhiteSpace(thermoErr))
{
Logger?.Error($"六个物性结果计算警告: {thermoErr}");
}
}
else
{
if (!string.IsNullOrWhiteSpace(thermoErr))
{
Logger?.Error($"六个物性结果计算失败: {thermoErr}");
}
}
}
catch (Exception ex)
{
@@ -576,10 +624,10 @@ namespace CapMachine.Wpf.Services
/// <summary>
/// 计算气路阀前气相焓h_vap(单相气相)
///
/// THERMdll 封装:按 T(℃) 与上一步得到的 D[mol/L] 计算气相熵 s [kJ/(kg·K)]
/// LabVIEW 对应THERM(T, D) -> s[J/(mol·K)],再 /M[kg/mol] 并 *0.001
/// 计算气相熵(单相气相)。
///
/// THERMdll 封装:按 T(℃) 与上一步得到的 D[mol/L] 计算气相熵 s [kJ/(kg·K)]
/// LabVIEW 对应THERM(T, D) -> s[J/(mol·K)],再 /M[kg/mol] 并 *0.001
/// </summary>
/// <param name="temperatureC">气体阀前温度 C</param>
/// <param name="densityMolPerL">气相密度D_vap mol/l</param>
@@ -621,7 +669,7 @@ namespace CapMachine.Wpf.Services
}
// J/(mol·K) -> kJ/(kg·K):先除以 kg/mol再乘 0.001
entropy_kJ_per_kgK = (hJmol / molarMassKgPerMol) * 0.001;
entropy_kJ_per_kgK = (sJmolK / molarMassKgPerMol) * 0.001;
return true;
}
@@ -1028,5 +1076,771 @@ namespace CapMachine.Wpf.Services
return true;
}
///制热量、压缩机性能系数COP制热、等熵效率、制冷量、压缩机性能系数COP(制冷)、容积效率 计算
#region
private double _HeatingCapacityQh_kW;
/// <summary>
/// 制热量 Qh [kW]
/// </summary>
public double HeatingCapacityQh_kW
{
get { return _HeatingCapacityQh_kW; }
set { _HeatingCapacityQh_kW = value; RaisePropertyChanged(); }
}
private double _COPHeating;
/// <summary>
/// 压缩机性能系数 COP制热[-]
/// </summary>
public double COPHeating
{
get { return _COPHeating; }
set { _COPHeating = value; RaisePropertyChanged(); }
}
private double _IsentropicEfficiencyPct;
/// <summary>
/// 等熵效率 ηs [%]
/// </summary>
public double IsentropicEfficiencyPct
{
get { return _IsentropicEfficiencyPct; }
set { _IsentropicEfficiencyPct = value; RaisePropertyChanged(); }
}
private double _CoolingCapacityQc_kW;
/// <summary>
/// 制冷量 Qc [kW]
/// </summary>
public double CoolingCapacityQc_kW
{
get { return _CoolingCapacityQc_kW; }
set { _CoolingCapacityQc_kW = value; RaisePropertyChanged(); }
}
private double _COPCooling;
/// <summary>
/// 压缩机性能系数 COP制冷[-]
/// </summary>
public double COPCooling
{
get { return _COPCooling; }
set { _COPCooling = value; RaisePropertyChanged(); }
}
private double _VolumetricEfficiencyPct;
/// <summary>
/// 容积效率 ηv [%]
/// </summary>
public double VolumetricEfficiencyPct
{
get { return _VolumetricEfficiencyPct; }
set { _VolumetricEfficiencyPct = value; RaisePropertyChanged(); }
}
/// <summary>
/// 按流程图更新制热量、COP(制热)、等熵效率、制冷量、COP(制冷)、容积效率。
/// </summary>
/// <param name="error">
/// 错误/警告信息输出。
/// - 当方法返回 <see langword="false"/> 时,<paramref name="error"/> 为失败原因,调用方应视为本周期计算无效。
/// - 当方法返回 <see langword="true"/> 但 <paramref name="error"/> 非空时,表示仅部分结果无法计算(例如缺少排量导致容积效率为 NaN
/// </param>
/// <returns>
/// 是否成功完成本周期的结果更新。
/// - <see langword="true"/>:至少已成功更新 Qh/Qc/COP/ηs 等主要结果;容积效率可能因缺失排量而为 NaN。
/// - <see langword="false"/>:关键输入或 REFPROP 计算失败,本周期结果不更新。
/// </returns>
private bool TryUpdateThermodynamicSixResults(out string error)
{
error = string.Empty;
if (!TryGetCompressorPower_kW(out var w_kW, out var wErr))
{
error = wErr;
return false;
}
if (!TryGetRefrigerantMassFlow_kg_s(out var mRef_kg_s, out var mRefErr))
{
error = mRefErr;
return false;
}
if (!TryGetVaporPointState_ByTP_BarA_C(InhPressTag.PVModel.EngValue, InhTempTag.PVModel.EngValue, out var h1_kJkg, out var s1_kJkgK, out var v1_m3kg, out var p1Err))
{
error = $"h1/s1/吸气比容计算失败: {p1Err}";
return false;
}
if (ExPressTag == null || ExTempTag == null)
{
error = "缺少排气压力/排气温度标签";
return false;
}
if (!TryGetVaporPointEnthalpy_ByTP_BarA_C(ExPressTag.PVModel.EngValue, ExTempTag.PVModel.EngValue, out var h2_kJkg, out var p2Err))
{
error = $"h2 计算失败: {p2Err}";
return false;
}
if (!TryGetLiquidPointEnthalpy_ByTP_BarA_C(TxvFrPressTag.PVModel.EngValue, TxvFrTempTag.PVModel.EngValue, out var h3_kJkg, out var p3Err))
{
error = $"h3 计算失败: {p3Err}";
return false;
}
if (!TryGetIsentropicOutletEnthalpy_h2s_ByP2AndS1_BarA(ExPressTag.PVModel.EngValue, s1_kJkgK, out var h2s_kJkg, out var h2sErr))
{
error = $"h2s 计算失败: {h2sErr}";
return false;
}
if (!TryComputeCapacitiesAndCOP(mRef_kg_s, h1_kJkg, h2_kJkg, h3_kJkg, w_kW, out var qh_kW, out var qc_kW, out var copH, out var copC, out var capErr))
{
error = capErr;
return false;
}
if (!TryComputeIsentropicEfficiencyPct(h1_kJkg, h2_kJkg, h2s_kJkg, out var etaS_pct, out var etaSErr))
{
error = etaSErr;
return false;
}
HeatingCapacityQh_kW = qh_kW;
CoolingCapacityQc_kW = qc_kW;
COPHeating = copH;
COPCooling = copC;
IsentropicEfficiencyPct = etaS_pct;
if (!TryComputeVolumetricEfficiencyPct(mRef_kg_s, v1_m3kg, out var etaV_pct, out var etaVErr))
{
VolumetricEfficiencyPct = double.NaN;
error = etaVErr;
return true;
}
VolumetricEfficiencyPct = etaV_pct;
return true;
}
/// <summary>
/// 获取压缩机输入功率 <c>W</c>。
/// </summary>
/// <param name="w_kW">压缩机功率输出,单位 kW由 HV[W] / 1000 换算)。</param>
/// <param name="error">失败原因(如缺少标签或功率为 0/NaN。</param>
/// <returns>是否获取成功。</returns>
private bool TryGetCompressorPower_kW(out double w_kW, out string error)
{
w_kW = double.NaN;
error = string.Empty;
if (HVPwTag == null)
{
error = "缺少 HV[W] 功率标签";
return false;
}
double w_W = HVPwTag.PVModel.EngValue;
if (double.IsNaN(w_W) || double.IsInfinity(w_W) || w_W <= 0)
{
error = $"无效压缩机功率 HV[W]={w_W}";
return false;
}
w_kW = w_W / 1000.0;
return true;
}
/// <summary>
/// 获取冷媒质量流量(按流程图:总流量 - 油流量)。
/// </summary>
/// <param name="mRef_kg_s">
/// 冷媒质量流量输出,单位 kg/s。
/// 计算:<c>mRef = (VRV[kg/h] - Oil[kg/h]) / 3600</c>。
/// </param>
/// <param name="error">失败原因(如流量为 NaN/Inf 或计算后小于等于 0。</param>
/// <returns>是否获取成功。</returns>
private bool TryGetRefrigerantMassFlow_kg_s(out double mRef_kg_s, out string error)
{
mRef_kg_s = double.NaN;
error = string.Empty;
double mTotal_kg_h = VRVTag.PVModel.EngValue;
double mOil_kg_h = LubeFlowTag.PVModel.EngValue;
if (double.IsNaN(mTotal_kg_h) || double.IsInfinity(mTotal_kg_h))
{
error = "总流量(冷媒流量)为 NaN/Inf";
return false;
}
if (double.IsNaN(mOil_kg_h) || double.IsInfinity(mOil_kg_h))
{
error = "油流量为 NaN/Inf";
return false;
}
double mRef_kg_h = mTotal_kg_h - mOil_kg_h;
if (mRef_kg_h <= 0)
{
error = $"冷媒质量流量<=0总流量={mTotal_kg_h}kg/h油流量={mOil_kg_h}kg/h";
return false;
}
mRef_kg_s = mRef_kg_h / 3600.0;
return true;
}
/// <summary>
/// 按流程图TPRHO + THERM计算气相点的质量比焓 <c>h</c>。
/// </summary>
/// <param name="pressureBarA">压力,单位 BarA绝压。内部换算为 MPa<c>P_MPa = BarA * 0.1</c>。</param>
/// <param name="temperatureC">温度,单位 ℃。</param>
/// <param name="h_kJkg">质量比焓输出,单位 kJ/kg。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryGetVaporPointEnthalpy_ByTP_BarA_C(double pressureBarA, double temperatureC, out double h_kJkg, out string error)
{
h_kJkg = double.NaN;
error = string.Empty;
double pMPa = pressureBarA * 0.1;
if (!TryTPRHO_VaporDensity_ByTP_MPa_C(pMPa, temperatureC, out var d_molL, out var dErr))
{
error = dErr;
return false;
}
double tK = temperatureC + 273.15;
if (!TryTHERM_Enthalpy_kJkg_ByT_K_D(tK, d_molL, out h_kJkg, out var hErr))
{
error = hErr;
return false;
}
return true;
}
/// <summary>
/// 按流程图TPRHO + THERM计算液相点的质量比焓 <c>h</c>。
/// </summary>
/// <param name="pressureBarA">压力,单位 BarA绝压。内部换算为 MPa<c>P_MPa = BarA * 0.1</c>。</param>
/// <param name="temperatureC">温度,单位 ℃。</param>
/// <param name="h_kJkg">质量比焓输出,单位 kJ/kg。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryGetLiquidPointEnthalpy_ByTP_BarA_C(double pressureBarA, double temperatureC, out double h_kJkg, out string error)
{
h_kJkg = double.NaN;
error = string.Empty;
double pMPa = pressureBarA * 0.1;
if (!TryTPRHO_LiquidDensity_ByTP_MPa_C(pMPa, temperatureC, out var d_molL, out var dErr))
{
error = dErr;
return false;
}
if (!TryTHERM_LiquidEnthalpy_ByTD(temperatureC, d_molL, out h_kJkg, out var hErr))
{
error = hErr;
return false;
}
return true;
}
/// <summary>
/// 按流程图TPRHO + THERM计算气相点状态量质量比焓 <c>h</c>、质量比熵 <c>s</c>、比容 <c>v</c>。
/// </summary>
/// <param name="pressureBarA">压力,单位 BarA绝压。内部换算为 MPa。</param>
/// <param name="temperatureC">温度,单位 ℃。</param>
/// <param name="h_kJkg">质量比焓输出,单位 kJ/kg。</param>
/// <param name="s_kJkgK">质量比熵输出,单位 kJ/(kg·K)。</param>
/// <param name="v_m3kg">比容输出,单位 m³/kg。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryGetVaporPointState_ByTP_BarA_C(
double pressureBarA,
double temperatureC,
out double h_kJkg,
out double s_kJkgK,
out double v_m3kg,
out string error)
{
h_kJkg = double.NaN;
s_kJkgK = double.NaN;
v_m3kg = double.NaN;
error = string.Empty;
double pMPa = pressureBarA * 0.1;
if (!TryTPRHO_VaporDensity_ByTP_MPa_C(pMPa, temperatureC, out var d_molL, out var dErr))
{
error = dErr;
return false;
}
double tK = temperatureC + 273.15;
if (!TryTHERM_Enthalpy_kJkg_ByT_K_D(tK, d_molL, out h_kJkg, out var hErr))
{
error = hErr;
return false;
}
if (!TryTHERM_VaporEntropy_ByTD(temperatureC, d_molL, out s_kJkgK, out var sErr))
{
error = sErr;
return false;
}
if (!TryConvertMolarDensityToSpecificVolume(d_molL, out v_m3kg, out var vErr))
{
error = vErr;
return false;
}
return true;
}
/// <summary>
/// P-S 闪蒸(等熵压缩理想出口):由排气压力 <c>P2</c> 与吸气熵 <c>s1</c> 计算等熵出口焓 <c>h2s</c>。
/// </summary>
/// <param name="dischargePressureBarA">排气压力 P2单位 BarA绝压。内部换算为 kPa。</param>
/// <param name="suctionEntropy_kJkgK">吸气熵 s1单位 kJ/(kg·K)。内部换算为 J/(mol·K) 作为 PSFLSH 输入。</param>
/// <param name="h2s_kJkg">等熵出口焓 h2s 输出,单位 kJ/kg。</param>
/// <param name="error">失败原因(初始化 REFPROP 失败、PSFLSH 失败、换算失败等)。</param>
/// <returns>是否计算成功。</returns>
private bool TryGetIsentropicOutletEnthalpy_h2s_ByP2AndS1_BarA(double dischargePressureBarA, double suctionEntropy_kJkgK, out double h2s_kJkg, out string error)
{
h2s_kJkg = double.NaN;
error = string.Empty;
if (!EnsureRefpropInitialized(out var initErr))
{
error = initErr;
return false;
}
double pKPa = dischargePressureBarA * 100.0;
if (pKPa <= 0)
{
error = $"无效排气压力: {dischargePressureBarA} BarA";
return false;
}
if (double.IsNaN(suctionEntropy_kJkgK) || double.IsInfinity(suctionEntropy_kJkgK))
{
error = "无效吸气熵 s1";
return false;
}
if (!TryConvertS_kJkgK_To_JmolK(suctionEntropy_kJkgK, out var s_JmolK, out var convErr))
{
error = convErr;
return false;
}
double[] z = new double[20];
z[0] = 1.0;
double t = 0.0;
double d = 0.0;
double Dl = 0.0;
double Dv = 0.0;
double[] xliq = new double[20];
double[] xvap = new double[20];
double q = 0.0;
double ee = 0.0;
double h = 0.0;
double Cv = 0.0;
double Cp = 0.0;
double w = 0.0;
long ierr = 0;
long herrLen = 255;
string herr = new string(' ', 255);
lock (_refpropLock)
{
IRefProp64.PSFLSHdll(ref pKPa, ref s_JmolK, z, ref t, ref d, ref Dl, ref Dv, xliq, xvap, ref q, ref ee, ref h, ref Cv, ref Cp, ref w, ref ierr, ref herr, ref herrLen);
}
if (ierr != 0)
{
error = $"PSFLSH 错误: {herr.Trim()} (ierr={ierr})";
return false;
}
if (!TryConvertH_Jmol_To_kJkg(h, out h2s_kJkg, out var hConvErr))
{
error = hConvErr;
return false;
}
return true;
}
/// <summary>
/// 按流程图计算:制热量/制冷量与 COP。
/// </summary>
/// <param name="mRef_kg_s">冷媒质量流量,单位 kg/s。</param>
/// <param name="h1_kJkg">点1吸气质量比焓单位 kJ/kg。</param>
/// <param name="h2_kJkg">点2排气质量比焓单位 kJ/kg。</param>
/// <param name="h3_kJkg">点3阀前质量比焓单位 kJ/kg。</param>
/// <param name="w_kW">压缩机功率,单位 kW。</param>
/// <param name="qh_kW">制热量输出,单位 kW计算<c>mRef*(h2-h3)</c>。</param>
/// <param name="qc_kW">制冷量输出,单位 kW计算<c>mRef*(h1-h3)</c>。</param>
/// <param name="copHeating">COP(制热)输出,计算:<c>Qh/W</c>。</param>
/// <param name="copCooling">COP(制冷)输出,计算:<c>Qc/W</c>。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeCapacitiesAndCOP(
double mRef_kg_s,
double h1_kJkg,
double h2_kJkg,
double h3_kJkg,
double w_kW,
out double qh_kW,
out double qc_kW,
out double copHeating,
out double copCooling,
out string error)
{
qh_kW = double.NaN;
qc_kW = double.NaN;
copHeating = double.NaN;
copCooling = double.NaN;
error = string.Empty;
if (mRef_kg_s <= 0 || double.IsNaN(mRef_kg_s) || double.IsInfinity(mRef_kg_s))
{
error = "无效冷媒质量流量";
return false;
}
if (w_kW <= 0 || double.IsNaN(w_kW) || double.IsInfinity(w_kW))
{
error = "无效压缩机功率";
return false;
}
qh_kW = mRef_kg_s * (h2_kJkg - h3_kJkg);
qc_kW = mRef_kg_s * (h1_kJkg - h3_kJkg);
copHeating = qh_kW / w_kW;
copCooling = qc_kW / w_kW;
return true;
}
/// <summary>
/// 按流程图计算等熵效率:
/// <c>ηs[%] = (h2s - h1) / (h2 - h1) * 100</c>。
/// </summary>
/// <param name="h1_kJkg">点1吸气质量比焓单位 kJ/kg。</param>
/// <param name="h2_kJkg">点2排气质量比焓单位 kJ/kg。</param>
/// <param name="h2s_kJkg">等熵出口质量比焓,单位 kJ/kg。</param>
/// <param name="etaS_pct">等熵效率输出,单位 %。</param>
/// <param name="error">失败原因(如分母 h2-h1 过小等)。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeIsentropicEfficiencyPct(double h1_kJkg, double h2_kJkg, double h2s_kJkg, out double etaS_pct, out string error)
{
etaS_pct = double.NaN;
error = string.Empty;
double denom = h2_kJkg - h1_kJkg;
const double eps = 1e-9;
if (Math.Abs(denom) < eps)
{
error = "等熵效率分母(h2-h1)过小";
return false;
}
double eta = (h2s_kJkg - h1_kJkg) / denom;
if (double.IsNaN(eta) || double.IsInfinity(eta))
{
error = "等熵效率结果异常";
return false;
}
etaS_pct = eta * 100.0;
return true;
}
/// <summary>
/// 按流程图计算容积效率:
/// <c>ηv[%] = V_suc / V_theo * 100</c>。
/// </summary>
/// <param name="mRef_kg_s">冷媒质量流量,单位 kg/s。</param>
/// <param name="v1_m3kg">吸气比容,单位 m³/kg。</param>
/// <param name="etaV_pct">容积效率输出,单位 %。</param>
/// <param name="error">失败原因(缺少转速/排量、输入异常、理论体积流量为 0 等)。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeVolumetricEfficiencyPct(double mRef_kg_s, double v1_m3kg, out double etaV_pct, out string error)
{
etaV_pct = double.NaN;
error = string.Empty;
if (SpeedTag == null)
{
error = "缺少转速标签";
return false;
}
double speed_rpm = SpeedTag.PVModel.EngValue;
if (double.IsNaN(speed_rpm) || double.IsInfinity(speed_rpm) || speed_rpm <= 0)
{
error = $"无效转速: {speed_rpm} rpm";
return false;
}
if (!TryGetCompressorDisplacement_cc(out var disp_cc, out var dispErr))
{
error = dispErr;
return false;
}
if (double.IsNaN(v1_m3kg) || double.IsInfinity(v1_m3kg) || v1_m3kg <= 0)
{
error = "无效吸气比容";
return false;
}
if (double.IsNaN(mRef_kg_s) || double.IsInfinity(mRef_kg_s) || mRef_kg_s <= 0)
{
error = "无效冷媒质量流量";
return false;
}
double suctionVolFlow_m3_h = (mRef_kg_s * 3600.0) * v1_m3kg;
double theoVolFlow_m3_h = (speed_rpm / 60.0) * disp_cc * 0.0036;
if (theoVolFlow_m3_h <= 0)
{
error = "理论吸气体积流量<=0";
return false;
}
etaV_pct = (suctionVolFlow_m3_h / theoVolFlow_m3_h) * 100.0;
return true;
}
/// <summary>
/// 获取压缩机排量。
/// </summary>
/// <param name="displacement_cc">排量输出,单位 cccm³/rev。</param>
/// <param name="error">失败原因(未配置、解析失败、数值不合法)。</param>
/// <returns>是否获取成功。</returns>
private bool TryGetCompressorDisplacement_cc(out double displacement_cc, out string error)
{
displacement_cc = double.NaN;
error = string.Empty;
const string key = "CompressorDisplacementCc";
if (!ConfigHelper.IsExist(key))
{
error = $"未配置压缩机排量,请在 App.config/appSettings 增加 {key}(单位 cc";
return false;
}
string v = ConfigHelper.GetValue(key);
if (!double.TryParse(v, out displacement_cc))
{
error = $"压缩机排量配置无法解析: {v}";
return false;
}
if (displacement_cc <= 0)
{
error = $"压缩机排量<=0: {displacement_cc}";
return false;
}
return true;
}
/// <summary>
/// REFPROP TPFLSH 封装T-P 闪蒸):
/// 输入压力/温度,输出摩尔密度、摩尔焓、摩尔熵等,用于后续换算质量基准的 h/s 以及比容 v。
/// </summary>
/// <param name="pressureBarA">压力输入,单位 BarA绝压。内部换算为 kPa<c>P_kPa = BarA * 100</c>。</param>
/// <param name="temperatureC">温度输入,单位 ℃。内部换算为 K<c>T_K = ℃ + 273.15</c>。</param>
/// <param name="d_molL">整体摩尔密度输出,单位 mol/L。</param>
/// <param name="h_Jmol">摩尔焓输出,单位 J/mol。</param>
/// <param name="s_JmolK">摩尔熵输出,单位 J/(mol·K)。</param>
/// <param name="t_K">温度输出,单位 KREFPROP 可能返回收敛后的温度)。</param>
/// <param name="error">失败原因(初始化 REFPROP 失败、TPFLSH 错误等)。</param>
/// <returns>是否计算成功。</returns>
private bool TryTPFLSH_ByTP_BarA_C(
double pressureBarA,
double temperatureC,
out double d_molL,
out double h_Jmol,
out double s_JmolK,
out double t_K,
out string error)
{
d_molL = double.NaN;
h_Jmol = double.NaN;
s_JmolK = double.NaN;
t_K = double.NaN;
error = string.Empty;
if (!EnsureRefpropInitialized(out var initErr))
{
error = initErr;
return false;
}
double t = temperatureC + 273.15;
double pKPa = pressureBarA * 100.0;
if (pKPa <= 0)
{
error = $"无效压力: {pressureBarA} BarA";
return false;
}
double[] x = new double[20];
x[0] = 1.0;
double d = 0.0;
double Dl = 0.0;
double Dv = 0.0;
double[] xliq = new double[20];
double[] xvap = new double[20];
double q = 0.0;
double ee = 0.0;
double h = 0.0;
double ss = 0.0;
double Cv = 0.0;
double Cp = 0.0;
double w = 0.0;
long ierr = 0;
long herrLen = 255;
string herr = new string(' ', 255);
lock (_refpropLock)
{
IRefProp64.TPFLSHdll(ref t, ref pKPa, x, ref d, ref Dl, ref Dv, xliq, xvap, ref q, ref ee, ref h, ref ss, ref Cv, ref Cp, ref w, ref ierr, ref herr, ref herrLen);
}
if (ierr != 0)
{
error = $"TPFLSH 错误: {herr.Trim()} (ierr={ierr})";
return false;
}
d_molL = d;
h_Jmol = h;
s_JmolK = ss;
t_K = t;
return true;
}
/// <summary>
/// 单位换算J/mol -> kJ/kg。
/// </summary>
/// <param name="h_Jmol">摩尔焓,单位 J/mol。</param>
/// <param name="h_kJkg">质量比焓输出,单位 kJ/kg。</param>
/// <param name="error">失败原因(摩尔质量无效等)。</param>
/// <returns>是否换算成功。</returns>
private bool TryConvertH_Jmol_To_kJkg(double h_Jmol, out double h_kJkg, out string error)
{
h_kJkg = double.NaN;
error = string.Empty;
double molarMassKgPerMol = GetMolarMass();
if (molarMassKgPerMol <= 0)
{
error = "无效的摩尔质量";
return false;
}
h_kJkg = (h_Jmol / molarMassKgPerMol) * 0.001;
return true;
}
/// <summary>
/// 单位换算J/(mol·K) -> kJ/(kg·K)。
/// </summary>
/// <param name="s_JmolK">摩尔熵,单位 J/(mol·K)。</param>
/// <param name="s_kJkgK">质量比熵输出,单位 kJ/(kg·K)。</param>
/// <param name="error">失败原因(摩尔质量无效等)。</param>
/// <returns>是否换算成功。</returns>
private bool TryConvertS_JmolK_To_kJkgK(double s_JmolK, out double s_kJkgK, out string error)
{
s_kJkgK = double.NaN;
error = string.Empty;
double molarMassKgPerMol = GetMolarMass();
if (molarMassKgPerMol <= 0)
{
error = "无效的摩尔质量";
return false;
}
s_kJkgK = (s_JmolK / molarMassKgPerMol) * 0.001;
return true;
}
/// <summary>
/// 单位换算kJ/(kg·K) -> J/(mol·K)。
/// </summary>
/// <param name="s_kJkgK">质量比熵,单位 kJ/(kg·K)。</param>
/// <param name="s_JmolK">摩尔熵输出,单位 J/(mol·K)。</param>
/// <param name="error">失败原因(摩尔质量无效等)。</param>
/// <returns>是否换算成功。</returns>
private bool TryConvertS_kJkgK_To_JmolK(double s_kJkgK, out double s_JmolK, out string error)
{
s_JmolK = double.NaN;
error = string.Empty;
double molarMassKgPerMol = GetMolarMass();
if (molarMassKgPerMol <= 0)
{
error = "无效的摩尔质量";
return false;
}
s_JmolK = s_kJkgK * 1000.0 * molarMassKgPerMol;
return true;
}
/// <summary>
/// 单位换算:摩尔密度 mol/L -> 比容 m³/kg。
/// </summary>
/// <param name="d_molL">摩尔密度输入,单位 mol/L。</param>
/// <param name="v_m3kg">比容输出,单位 m³/kg。</param>
/// <param name="error">失败原因(摩尔密度/摩尔质量无效等)。</param>
/// <returns>是否换算成功。</returns>
private bool TryConvertMolarDensityToSpecificVolume(double d_molL, out double v_m3kg, out string error)
{
v_m3kg = double.NaN;
error = string.Empty;
if (double.IsNaN(d_molL) || double.IsInfinity(d_molL) || d_molL <= 0)
{
error = $"无效摩尔密度: {d_molL} mol/L";
return false;
}
double molarMassKgPerMol = GetMolarMass();
if (molarMassKgPerMol <= 0)
{
error = "无效的摩尔质量";
return false;
}
double rho_kg_m3 = d_molL * molarMassKgPerMol * 1000.0;
if (rho_kg_m3 <= 0)
{
error = $"无效密度: {rho_kg_m3} kg/m3";
return false;
}
v_m3kg = 1.0 / rho_kg_m3;
return true;
}
#endregion
}
}