Files
CapMachine/CapMachine.Wpf/Services/PPCThermodynamicSixResultsCalculationInput.cs
2026-03-26 17:47:56 +08:00

1456 lines
57 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using CapMachine.Core;
using CapMachine.Wpf.PPCalculation;
using System;
namespace CapMachine.Wpf.Services
{
/// <summary>
/// 六个热力结果值计算的输入数据。
/// </summary>
/// <remarks>
/// 该输入对象对应六个结果值计算过程中用到的全部外部测点/配置量。
/// 所有字段均采用当前系统中已经约定好的工程单位,不在本对象中做任何换算。
/// </remarks>
public sealed class PPCThermodynamicSixResultsCalculationInput
{
/// <summary>
/// 压缩机输入功率,单位 W。
/// 当前来源为 HV 功率标签。
/// </summary>
public double CompressorPowerW { get; set; }
/// <summary>
/// 总流量(冷媒流量标签当前语义),单位 kg/h。
/// 该值会与油流量做差,得到真正参与热力计算的冷媒质量流量。
/// </summary>
public double TotalMassFlowKgPerHour { get; set; }
/// <summary>
/// 润滑油流量,单位 kg/h。
/// </summary>
public double OilMassFlowKgPerHour { get; set; }
/// <summary>
/// 吸气压力,单位 BarA绝压
/// </summary>
public double SuctionPressureBarA { get; set; }
/// <summary>
/// 吸气温度,单位 ℃。
/// </summary>
public double SuctionTemperatureC { get; set; }
/// <summary>
/// 排气压力,单位 BarA绝压
/// </summary>
public double DischargePressureBarA { get; set; }
/// <summary>
/// 排气温度,单位 ℃。
/// </summary>
public double DischargeTemperatureC { get; set; }
/// <summary>
/// 膨胀阀前液路压力,单位 BarA绝压
/// </summary>
public double LiquidPressureBarA { get; set; }
/// <summary>
/// 膨胀阀前液路温度,单位 ℃。
/// </summary>
public double LiquidTemperatureC { get; set; }
/// <summary>
/// 压缩机转速,单位 rpm。
/// 用于容积效率计算。
/// </summary>
public double CompressorSpeedRpm { get; set; }
/// <summary>
/// 压缩机单转排量,单位 cc。
/// 用于理论体积流量计算。
/// </summary>
public double CompressorDisplacementCc { get; set; }
}
/// <summary>
/// 六个热力结果值计算结果。
/// </summary>
/// <remarks>
/// 默认均初始化为 <see cref="double.NaN"/>,用于明确区分“未成功得到结果”和“得到有效数值”。
/// </remarks>
public sealed class PPCThermodynamicSixResultsCalculationResult
{
/// <summary>
/// 制热量 Qh单位 kW。
/// 计算公式:<c>Qh = mRef * (h2 - h3)</c>。
/// </summary>
public double HeatingCapacityQh_kW { get; set; } = double.NaN;
/// <summary>
/// 制冷量 Qc单位 kW。
/// 计算公式:<c>Qc = mRef * (h1 - h3)</c>。
/// </summary>
public double CoolingCapacityQc_kW { get; set; } = double.NaN;
/// <summary>
/// 制热 COP。
/// 计算公式:<c>COPHeating = Qh / W</c>。
/// </summary>
public double COPHeating { get; set; } = double.NaN;
/// <summary>
/// 制冷 COP。
/// 计算公式:<c>COPCooling = Qc / W</c>。
/// </summary>
public double COPCooling { get; set; } = double.NaN;
/// <summary>
/// 等熵效率,单位 %。
/// 计算公式:<c>(h2s - h1) / (h2 - h1) * 100</c>。
/// </summary>
public double IsentropicEfficiencyPct { get; set; } = double.NaN;
/// <summary>
/// 容积效率,单位 %。
/// 计算公式:<c>实际吸气体积流量 / 理论吸气体积流量 * 100</c>。
/// </summary>
public double VolumetricEfficiencyPct { get; set; } = double.NaN;
}
/// <summary>
/// 六个热力结果值独立计算类。
/// </summary>
/// <remarks>
/// 本类负责以下六个结果的完整计算流程:
/// - 制热量
/// - COP(制热)
/// - 等熵效率
/// - 制冷量
/// - COP(制冷)
/// - 容积效率
///
/// 设计目标是把“结果计算逻辑”从 <c>PPCService</c> 中抽离出来,
/// 让服务层只负责取标签和写回,计算类只负责计算本身。
/// 为降低后续新增其他计算类时对已验算结果的影响范围,
/// 本类将自身所需的底层 REFPROP 支撑实现内聚在类内私有 support 中。
///
/// 当前实现严格保持既有流程不变:
/// 1. 由总流量和油流量得到冷媒质量流量
/// 2. 由吸气点得到 h1 / s1 / v1
/// 3. 由排气点得到 h2
/// 4. 由液路点得到 h3
/// 5. 由排气压力和吸气熵得到 h2s
/// 6. 计算 Qh / Qc / COP / 等熵效率 / 容积效率
/// </remarks>
public sealed class PPCThermodynamicSixResultsCalculator
{
/// <summary>
/// 底层物性计算支持对象。
/// 负责提供 REFPROP 初始化与 TPRHO / THERM / PSFLSH 等共用能力。
/// </summary>
private readonly LocalCalculationSupport _support;
/// <summary>
/// 初始化六个热力结果值计算类。
/// </summary>
public PPCThermodynamicSixResultsCalculator()
{
_support = new LocalCalculationSupport();
}
/// <summary>
/// 按既定流程一次性计算六个热力结果值。
/// </summary>
/// <param name="input">输入数据,包含功率、流量、吸排气状态点、液路状态点、转速与排量。</param>
/// <param name="result">输出结果对象。</param>
/// <param name="error">
/// 错误或警告信息。
/// 当前逻辑中,若“容积效率”计算失败但其他 5 个结果成功,会返回 <see langword="true"/>
/// 同时通过此参数把容积效率失败原因返回给上层,保持原有行为不变。
/// </param>
/// <returns>
/// - <see langword="true"/>:主要结果计算完成;容积效率可能成功也可能失败
/// - <see langword="false"/>:关键输入或关键热力步骤失败
/// </returns>
public bool TryCalculate(PPCThermodynamicSixResultsCalculationInput input, out PPCThermodynamicSixResultsCalculationResult result, out string error)
{
// 创建输出对象,并将错误文本清空。
result = new PPCThermodynamicSixResultsCalculationResult();
error = string.Empty;
// 所有物性函数调用之前,先确保 REFPROP 已完成初始化。
if (!_support.EnsureRefpropInitialized(out var initErr))
{
error = initErr;
return false;
}
// 第 1 步:将压缩机输入功率由 W 换算为 kW。
if (!TryGetCompressorPower_kW(input.CompressorPowerW, out var w_kW, out var wErr))
{
error = wErr;
return false;
}
// 第 2 步:根据“总流量 - 油流量”,得到真正参与循环的冷媒质量流量,
// 并从 kg/h 换算到后续公式使用的 kg/s。
if (!TryGetRefrigerantMassFlow_kg_s(input.TotalMassFlowKgPerHour, input.OilMassFlowKgPerHour, out var mRef_kg_s, out var mRefErr))
{
error = mRefErr;
return false;
}
// 第 3 步:由吸气压力/温度求出吸气点状态:
// - h1吸气比焓
// - s1吸气比熵
// - v1吸气比容
if (!TryGetVaporPointState_ByTP_BarA_C(input.SuctionPressureBarA, input.SuctionTemperatureC, out var h1_kJkg, out var s1_kJkgK, out var v1_m3kg, out var p1Err))
{
error = $"h1/s1/吸气比容计算失败: {p1Err}";
return false;
}
// 第 4 步:由排气压力/温度求排气比焓 h2。
if (!TryGetVaporPointEnthalpy_ByTP_BarA_C(input.DischargePressureBarA, input.DischargeTemperatureC, out var h2_kJkg, out var p2Err))
{
error = $"h2 计算失败: {p2Err}";
return false;
}
// 第 5 步:由液路压力/温度求液路比焓 h3。
if (!TryGetLiquidPointEnthalpy_ByTP_BarA_C(input.LiquidPressureBarA, input.LiquidTemperatureC, out var h3_kJkg, out var p3Err))
{
error = $"h3 计算失败: {p3Err}";
return false;
}
// 第 6 步:由排气压力 P2 和吸气熵 s1 求等熵出口焓 h2s。
if (!_support.TryGetIsentropicOutletEnthalpy_h2s_ByP2AndS1_BarA(input.DischargePressureBarA, s1_kJkgK, out var h2s_kJkg, out var h2sErr))
{
error = $"h2s 计算失败: {h2sErr}";
return false;
}
// 第 7 步:计算 Qh、Qc、COP(制热)、COP(制冷)。
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;
}
// 第 8 步:计算等熵效率。
if (!TryComputeIsentropicEfficiencyPct(h1_kJkg, h2_kJkg, h2s_kJkg, out var etaS_pct, out var etaSErr))
{
error = etaSErr;
return false;
}
// 先写入 5 个关键结果。
result.HeatingCapacityQh_kW = qh_kW;
result.CoolingCapacityQc_kW = qc_kW;
result.COPHeating = copH;
result.COPCooling = copC;
result.IsentropicEfficiencyPct = etaS_pct;
// 最后再算容积效率。
// 当前逻辑特意保持与旧实现一致:
// 即使容积效率失败,只要前面 5 个主结果已经成功,就仍然返回 true
// 同时把失败原因放到 error 中,供调用方决定是否记录为警告。
if (!TryComputeVolumetricEfficiencyPct(mRef_kg_s, v1_m3kg, input.CompressorSpeedRpm, input.CompressorDisplacementCc, out var etaV_pct, out var etaVErr))
{
error = etaVErr;
return true;
}
result.VolumetricEfficiencyPct = etaV_pct;
return true;
}
/// <summary>
/// 获取压缩机输入功率并换算为 kW。
/// </summary>
/// <param name="compressorPowerW">输入功率,单位 W。</param>
/// <param name="w_kW">输出功率,单位 kW。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否换算成功。</returns>
private bool TryGetCompressorPower_kW(double compressorPowerW, out double w_kW, out string error)
{
w_kW = double.NaN;
error = string.Empty;
// 读取输入功率,并做基础合法性校验。
double w_W = compressorPowerW;
if (double.IsNaN(w_W) || double.IsInfinity(w_W) || w_W <= 0)
{
error = $"无效压缩机功率 HV[W]={w_W}";
return false;
}
// 六个热力结果公式里统一使用 kW因此这里做 W -> kW 的标准换算。
w_kW = w_W / 1000.0;
return true;
}
/// <summary>
/// 获取冷媒质量流量,输出单位 kg/s。
/// </summary>
/// <param name="totalMassFlowKgPerHour">总流量,单位 kg/h。</param>
/// <param name="oilMassFlowKgPerHour">油流量,单位 kg/h。</param>
/// <param name="mRef_kg_s">冷媒质量流量输出,单位 kg/s。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
/// <remarks>
/// 当前流程保持与图片/旧代码一致:
/// 1. 读取总流量 kg/h
/// 2. 读取油流量 kg/h
/// 3. 冷媒流量 = 总流量 - 油流量
/// 4. 再由 kg/h 换算为 kg/s
/// </remarks>
private bool TryGetRefrigerantMassFlow_kg_s(double totalMassFlowKgPerHour, double oilMassFlowKgPerHour, out double mRef_kg_s, out string error)
{
mRef_kg_s = double.NaN;
error = string.Empty;
// 先读取总流量。
if (!TryGetTotalMassFlow_kg_h(totalMassFlowKgPerHour, out var mTotal_kg_h, out var totalErr))
{
error = totalErr;
return false;
}
// 再读取油流量。
if (!TryGetOilMassFlow_kg_h(oilMassFlowKgPerHour, out var mOil_kg_h, out var oilErr))
{
error = oilErr;
return false;
}
// 计算真正参与循环的冷媒质量流量mRef = mTotal - mOil。
if (!TryComputeRefrigerantMassFlow_kg_h(mTotal_kg_h, mOil_kg_h, out var mRef_kg_h, out var refErr))
{
error = refErr;
return false;
}
// 将 kg/h 换算成后续容量计算使用的 kg/s。
return TryConvertMassFlow_kg_h_To_kg_s(mRef_kg_h, out mRef_kg_s, out error);
}
/// <summary>
/// 获取总流量,单位 kg/h。
/// </summary>
/// <param name="totalMassFlowKgPerHour">输入总流量。</param>
/// <param name="mTotal_kg_h">输出总流量。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否读取成功。</returns>
private bool TryGetTotalMassFlow_kg_h(double totalMassFlowKgPerHour, out double mTotal_kg_h, out string error)
{
mTotal_kg_h = double.NaN;
error = string.Empty;
// 当前方法只做数值读取和合法性校验,不做其他换算。
mTotal_kg_h = totalMassFlowKgPerHour;
if (double.IsNaN(mTotal_kg_h) || double.IsInfinity(mTotal_kg_h))
{
error = "总流量(冷媒流量)为 NaN/Inf";
return false;
}
return true;
}
/// <summary>
/// 获取油流量,单位 kg/h。
/// </summary>
/// <param name="oilMassFlowKgPerHour">输入油流量。</param>
/// <param name="mOil_kg_h">输出油流量。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否读取成功。</returns>
private bool TryGetOilMassFlow_kg_h(double oilMassFlowKgPerHour, out double mOil_kg_h, out string error)
{
mOil_kg_h = double.NaN;
error = string.Empty;
// 当前方法只做数值读取和合法性校验,不做其他换算。
mOil_kg_h = oilMassFlowKgPerHour;
if (double.IsNaN(mOil_kg_h) || double.IsInfinity(mOil_kg_h))
{
error = "油流量为 NaN/Inf";
return false;
}
return true;
}
/// <summary>
/// 计算冷媒质量流量,单位 kg/h。
/// </summary>
/// <param name="mTotal_kg_h">总流量,单位 kg/h。</param>
/// <param name="mOil_kg_h">油流量,单位 kg/h。</param>
/// <param name="mRef_kg_h">冷媒质量流量输出,单位 kg/h。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeRefrigerantMassFlow_kg_h(double mTotal_kg_h, double mOil_kg_h, out double mRef_kg_h, out string error)
{
mRef_kg_h = double.NaN;
error = string.Empty;
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;
}
// 与既有实现一致:冷媒质量流量 = 总流量 - 油流量。
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;
}
return true;
}
/// <summary>
/// 将质量流量从 kg/h 换算到 kg/s。
/// </summary>
/// <param name="massFlow_kg_h">输入质量流量,单位 kg/h。</param>
/// <param name="massFlow_kg_s">输出质量流量,单位 kg/s。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否换算成功。</returns>
private bool TryConvertMassFlow_kg_h_To_kg_s(double massFlow_kg_h, out double massFlow_kg_s, out string error)
{
massFlow_kg_s = double.NaN;
error = string.Empty;
if (double.IsNaN(massFlow_kg_h) || double.IsInfinity(massFlow_kg_h) || massFlow_kg_h <= 0)
{
error = $"无效质量流量={massFlow_kg_h}kg/h";
return false;
}
// 1 小时 = 3600 秒,因此 kg/h -> kg/s 需要除以 3600。
massFlow_kg_s = massFlow_kg_h / 3600.0;
return true;
}
/// <summary>
/// 由某一气相状态点的压力 / 温度求质量比焓。
/// </summary>
/// <param name="pressureBarA">输入压力,单位 BarA绝压。</param>
/// <param name="temperatureC">输入温度,单位 ℃。</param>
/// <param name="h_kJkg">输出质量比焓,单位 kJ/kg。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
/// <remarks>
/// 当前流程:
/// 1. BarA -> MPa
/// 2. 用气相 TPRHO 求摩尔密度 D
/// 3. 用 THERM 求焓
/// </remarks>
private bool TryGetVaporPointEnthalpy_ByTP_BarA_C(double pressureBarA, double temperatureC, out double h_kJkg, out string error)
{
h_kJkg = double.NaN;
error = string.Empty;
// 物性 helper 的压力输入单位是 MPa因此先换算。
double pMPa = pressureBarA * 0.1;
// 先求气相摩尔密度 D。
if (!_support.TryTPRHO_VaporDensity_ByTP_MPa_C(pMPa, temperatureC, out var d_molL, out var dErr))
{
error = dErr;
return false;
}
// THERM helper 的温度输入为 K因此把 ℃ 转成 K 后再求焓。
double tK = temperatureC + 273.15;
if (!_support.TryTHERM_Enthalpy_kJkg_ByT_K_D(tK, d_molL, out h_kJkg, out var hErr))
{
error = hErr;
return false;
}
return true;
}
/// <summary>
/// 由某一液相状态点的压力 / 温度求质量比焓。
/// </summary>
/// <param name="pressureBarA">输入压力,单位 BarA绝压。</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;
// 物性 helper 的压力输入单位是 MPa因此先换算。
double pMPa = pressureBarA * 0.1;
// 先按液相路径求摩尔密度 D。
if (!_support.TryTPRHO_LiquidDensity_ByTP_MPa_C(pMPa, temperatureC, out var d_molL, out var dErr))
{
error = dErr;
return false;
}
// 再按液相路径求质量比焓 h。
if (!_support.TryTHERM_LiquidEnthalpy_ByTD(temperatureC, d_molL, out h_kJkg, out var hErr))
{
error = hErr;
return false;
}
return true;
}
/// <summary>
/// 由某一气相状态点的压力 / 温度联合求取 h、s、v。
/// </summary>
/// <param name="pressureBarA">输入压力,单位 BarA绝压。</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;
// 第一步BarA -> MPa。
double pMPa = pressureBarA * 0.1;
// 第二步:由气相 TPRHO 求摩尔密度 D。
if (!_support.TryTPRHO_VaporDensity_ByTP_MPa_C(pMPa, temperatureC, out var d_molL, out var dErr))
{
error = dErr;
return false;
}
// 第三步:用 THERM 求吸气点比焓 h1。
double tK = temperatureC + 273.15;
if (!_support.TryTHERM_Enthalpy_kJkg_ByT_K_D(tK, d_molL, out h_kJkg, out var hErr))
{
error = hErr;
return false;
}
// 第四步:用 THERM 求吸气点比熵 s1。
if (!_support.TryTHERM_VaporEntropy_ByTD(temperatureC, d_molL, out s_kJkgK, out var sErr))
{
error = sErr;
return false;
}
// 第五步:由摩尔密度换算为质量比容 v1。
if (!_support.TryConvertMolarDensityToSpecificVolume(d_molL, out v_m3kg, out var vErr))
{
error = vErr;
return false;
}
return true;
}
/// <summary>
/// 统一计算制热量、制冷量、制热 COP、制冷 COP。
/// </summary>
/// <param name="mRef_kg_s">冷媒质量流量,单位 kg/s。</param>
/// <param name="h1_kJkg">吸气比焓,单位 kJ/kg。</param>
/// <param name="h2_kJkg">排气比焓,单位 kJ/kg。</param>
/// <param name="h3_kJkg">液路比焓,单位 kJ/kg。</param>
/// <param name="w_kW">压缩机功率,单位 kW。</param>
/// <param name="qh_kW">制热量输出,单位 kW。</param>
/// <param name="qc_kW">制冷量输出,单位 kW。</param>
/// <param name="copHeating">制热 COP 输出。</param>
/// <param name="copCooling">制冷 COP 输出。</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;
// 先算制热量Qh = mRef * (h2 - h3)。
if (!TryComputeHeatingCapacityQh_kW(mRef_kg_s, h2_kJkg, h3_kJkg, out qh_kW, out var qhErr))
{
error = qhErr;
return false;
}
// 再算制冷量Qc = mRef * (h1 - h3)。
if (!TryComputeCoolingCapacityQc_kW(mRef_kg_s, h1_kJkg, h3_kJkg, out qc_kW, out var qcErr))
{
error = qcErr;
return false;
}
// 制热 COP = Qh / W。
if (!TryComputeHeatingCOP(qh_kW, w_kW, out copHeating, out var copHErr))
{
error = copHErr;
return false;
}
// 制冷 COP = Qc / W。
if (!TryComputeCoolingCOP(qc_kW, w_kW, out copCooling, out var copCErr))
{
error = copCErr;
return false;
}
return true;
}
/// <summary>
/// 计算焓差,单位 kJ/kg。
/// </summary>
/// <param name="minuend_kJkg">被减数,单位 kJ/kg。</param>
/// <param name="subtrahend_kJkg">减数,单位 kJ/kg。</param>
/// <param name="quantityName">当前计算量名称,用于拼接错误信息。</param>
/// <param name="deltaH_kJkg">焓差输出,单位 kJ/kg。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeEnthalpyDifference_kJkg(double minuend_kJkg, double subtrahend_kJkg, string quantityName, out double deltaH_kJkg, out string error)
{
deltaH_kJkg = double.NaN;
error = string.Empty;
// 先校验输入两端焓值是否有效。
if (double.IsNaN(minuend_kJkg) || double.IsInfinity(minuend_kJkg) || double.IsNaN(subtrahend_kJkg) || double.IsInfinity(subtrahend_kJkg))
{
error = $"{quantityName}输入存在 NaN/Inf";
return false;
}
// 焓差按“被减数 - 减数”计算。
deltaH_kJkg = minuend_kJkg - subtrahend_kJkg;
if (double.IsNaN(deltaH_kJkg) || double.IsInfinity(deltaH_kJkg))
{
error = $"{quantityName}结果异常";
return false;
}
return true;
}
/// <summary>
/// 根据质量流量与焓差计算容量,单位 kW。
/// </summary>
/// <param name="mRef_kg_s">冷媒质量流量,单位 kg/s。</param>
/// <param name="deltaH_kJkg">焓差,单位 kJ/kg。</param>
/// <param name="quantityName">容量名称,用于错误信息。</param>
/// <param name="capacity_kW">容量输出,单位 kW。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
/// <remarks>
/// 公式:<c>Capacity = mRef * Δh</c>。
/// 因为 <c>kg/s * kJ/kg = kJ/s = kW</c>,所以结果天然就是 kW。
/// </remarks>
private bool TryComputeCapacity_kW(double mRef_kg_s, double deltaH_kJkg, string quantityName, out double capacity_kW, out string error)
{
capacity_kW = double.NaN;
error = string.Empty;
// 校验冷媒质量流量是否有效。
if (double.IsNaN(mRef_kg_s) || double.IsInfinity(mRef_kg_s) || mRef_kg_s <= 0)
{
error = "无效冷媒质量流量";
return false;
}
// 校验焓差是否有效。
if (double.IsNaN(deltaH_kJkg) || double.IsInfinity(deltaH_kJkg))
{
error = $"{quantityName}焓差异常";
return false;
}
// 按容量公式直接计算。
capacity_kW = mRef_kg_s * deltaH_kJkg;
if (double.IsNaN(capacity_kW) || double.IsInfinity(capacity_kW))
{
error = $"{quantityName}结果异常";
return false;
}
return true;
}
/// <summary>
/// 计算制热量 Qh单位 kW。
/// </summary>
/// <param name="mRef_kg_s">冷媒质量流量,单位 kg/s。</param>
/// <param name="h2_kJkg">排气比焓 h2单位 kJ/kg。</param>
/// <param name="h3_kJkg">液路比焓 h3单位 kJ/kg。</param>
/// <param name="qh_kW">制热量输出,单位 kW。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeHeatingCapacityQh_kW(double mRef_kg_s, double h2_kJkg, double h3_kJkg, out double qh_kW, out string error)
{
qh_kW = double.NaN;
error = string.Empty;
// 先计算制热焓差:(h2 - h3)。
if (!TryComputeEnthalpyDifference_kJkg(h2_kJkg, h3_kJkg, "制热焓差(h2-h3)", out var deltaH_kJkg, out var deltaErr))
{
error = deltaErr;
return false;
}
// 再由质量流量与焓差得到制热量。
return TryComputeCapacity_kW(mRef_kg_s, deltaH_kJkg, "制热量Qh", out qh_kW, out error);
}
/// <summary>
/// 计算制冷量 Qc单位 kW。
/// </summary>
/// <param name="mRef_kg_s">冷媒质量流量,单位 kg/s。</param>
/// <param name="h1_kJkg">吸气比焓 h1单位 kJ/kg。</param>
/// <param name="h3_kJkg">液路比焓 h3单位 kJ/kg。</param>
/// <param name="qc_kW">制冷量输出,单位 kW。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeCoolingCapacityQc_kW(double mRef_kg_s, double h1_kJkg, double h3_kJkg, out double qc_kW, out string error)
{
qc_kW = double.NaN;
error = string.Empty;
// 先计算制冷焓差:(h1 - h3)。
if (!TryComputeEnthalpyDifference_kJkg(h1_kJkg, h3_kJkg, "制冷焓差(h1-h3)", out var deltaH_kJkg, out var deltaErr))
{
error = deltaErr;
return false;
}
// 再由质量流量与焓差得到制冷量。
return TryComputeCapacity_kW(mRef_kg_s, deltaH_kJkg, "制冷量Qc", out qc_kW, out error);
}
/// <summary>
/// 计算 COP。
/// </summary>
/// <param name="capacity_kW">容量,单位 kW。</param>
/// <param name="w_kW">压缩机输入功率,单位 kW。</param>
/// <param name="quantityName">当前 COP 名称,用于错误信息。</param>
/// <param name="cop">COP 输出。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeCOP(double capacity_kW, double w_kW, string quantityName, out double cop, out string error)
{
cop = double.NaN;
error = string.Empty;
// 容量必须是有效数值。
if (double.IsNaN(capacity_kW) || double.IsInfinity(capacity_kW))
{
error = $"{quantityName}输入异常";
return false;
}
// 功率必须有效且大于 0避免除零。
if (double.IsNaN(w_kW) || double.IsInfinity(w_kW) || w_kW <= 0)
{
error = "无效压缩机功率";
return false;
}
// COP = 容量 / 输入功率。
cop = capacity_kW / w_kW;
if (double.IsNaN(cop) || double.IsInfinity(cop))
{
error = $"{quantityName}结果异常";
return false;
}
return true;
}
/// <summary>
/// 计算制热 COP。
/// </summary>
/// <param name="qh_kW">制热量,单位 kW。</param>
/// <param name="w_kW">压缩机输入功率,单位 kW。</param>
/// <param name="copHeating">制热 COP 输出。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeHeatingCOP(double qh_kW, double w_kW, out double copHeating, out string error)
{
return TryComputeCOP(qh_kW, w_kW, "COP(制热)", out copHeating, out error);
}
/// <summary>
/// 计算制冷 COP。
/// </summary>
/// <param name="qc_kW">制冷量,单位 kW。</param>
/// <param name="w_kW">压缩机输入功率,单位 kW。</param>
/// <param name="copCooling">制冷 COP 输出。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeCoolingCOP(double qc_kW, double w_kW, out double copCooling, out string error)
{
return TryComputeCOP(qc_kW, w_kW, "COP(制冷)", out copCooling, out error);
}
/// <summary>
/// 计算等熵效率,单位 %。
/// </summary>
/// <param name="h1_kJkg">吸气比焓 h1单位 kJ/kg。</param>
/// <param name="h2_kJkg">实际排气比焓 h2单位 kJ/kg。</param>
/// <param name="h2s_kJkg">等熵出口比焓 h2s单位 kJ/kg。</param>
/// <param name="etaS_pct">等熵效率输出,单位 %。</param>
/// <param name="error">失败原因。</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;
// 实际压缩焓升:(h2 - h1)。
if (!TryComputeEnthalpyDifference_kJkg(h2_kJkg, h1_kJkg, "实际压缩焓升(h2-h1)", out var actualRise_kJkg, out var actualErr))
{
error = actualErr;
return false;
}
// 等熵压缩焓升:(h2s - h1)。
if (!TryComputeEnthalpyDifference_kJkg(h2s_kJkg, h1_kJkg, "等熵压缩焓升(h2s-h1)", out var isentropicRise_kJkg, out var isoErr))
{
error = isoErr;
return false;
}
// 等熵效率 = 等熵焓升 / 实际焓升 * 100%。
return TryComputeEfficiencyPct(isentropicRise_kJkg, actualRise_kJkg, "等熵效率", out etaS_pct, out error);
}
/// <summary>
/// 计算容积效率,单位 %。
/// </summary>
/// <param name="mRef_kg_s">冷媒质量流量,单位 kg/s。</param>
/// <param name="v1_m3kg">吸气比容 v1单位 m³/kg。</param>
/// <param name="speed_rpm">压缩机转速,单位 rpm。</param>
/// <param name="disp_cc">压缩机排量,单位 cc。</param>
/// <param name="etaV_pct">容积效率输出,单位 %。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeVolumetricEfficiencyPct(double mRef_kg_s, double v1_m3kg, double speed_rpm, double disp_cc, out double etaV_pct, out string error)
{
etaV_pct = double.NaN;
error = string.Empty;
// 先校验转速。
if (!TryGetCompressorSpeed_rpm(speed_rpm, out var validatedSpeed_rpm, out var speedErr))
{
error = speedErr;
return false;
}
// 再校验排量。
if (!TryGetCompressorDisplacement_cc(disp_cc, out var validatedDisp_cc, out var dispErr))
{
error = dispErr;
return false;
}
// 计算实际吸气体积流量。
if (!TryComputeSuctionVolumeFlow_m3_h(mRef_kg_s, v1_m3kg, out var suctionVolFlow_m3_h, out var suctionErr))
{
error = suctionErr;
return false;
}
// 计算理论吸气体积流量。
if (!TryComputeTheoreticalVolumeFlow_m3_h(validatedSpeed_rpm, validatedDisp_cc, out var theoVolFlow_m3_h, out var theoErr))
{
error = theoErr;
return false;
}
// 容积效率 = 实际吸气体积流量 / 理论吸气体积流量 * 100%。
return TryComputeEfficiencyPct(suctionVolFlow_m3_h, theoVolFlow_m3_h, "容积效率", out etaV_pct, out error);
}
/// <summary>
/// 计算百分比效率。
/// </summary>
/// <param name="numerator">分子。</param>
/// <param name="denominator">分母。</param>
/// <param name="quantityName">当前效率名称,用于错误信息。</param>
/// <param name="efficiencyPct">效率输出,单位 %。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeEfficiencyPct(double numerator, double denominator, string quantityName, out double efficiencyPct, out string error)
{
efficiencyPct = double.NaN;
error = string.Empty;
// 先校验分子。
if (double.IsNaN(numerator) || double.IsInfinity(numerator))
{
error = $"{quantityName}分子异常";
return false;
}
// 再校验分母,避免除零或极小数造成结果发散。
const double eps = 1e-9;
if (double.IsNaN(denominator) || double.IsInfinity(denominator) || Math.Abs(denominator) < eps)
{
error = $"{quantityName}分母过小或异常";
return false;
}
// 效率 = 分子 / 分母。
double efficiency = numerator / denominator;
if (double.IsNaN(efficiency) || double.IsInfinity(efficiency))
{
error = $"{quantityName}结果异常";
return false;
}
// 将无量纲效率换算为百分数。
efficiencyPct = efficiency * 100.0;
return true;
}
/// <summary>
/// 获取并校验压缩机转速,单位 rpm。
/// </summary>
/// <param name="compressorSpeedRpm">输入转速,单位 rpm。</param>
/// <param name="speed_rpm">输出转速,单位 rpm。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否获取成功。</returns>
private bool TryGetCompressorSpeed_rpm(double compressorSpeedRpm, out double speed_rpm, out string error)
{
speed_rpm = double.NaN;
error = string.Empty;
// 当前方法只做读取与合法性校验。
speed_rpm = compressorSpeedRpm;
if (double.IsNaN(speed_rpm) || double.IsInfinity(speed_rpm) || speed_rpm <= 0)
{
error = $"无效转速: {speed_rpm} rpm";
return false;
}
return true;
}
/// <summary>
/// 计算实际吸气体积流量,单位 m³/h。
/// </summary>
/// <param name="mRef_kg_s">冷媒质量流量,单位 kg/s。</param>
/// <param name="v1_m3kg">吸气比容,单位 m³/kg。</param>
/// <param name="suctionVolFlow_m3_h">实际吸气体积流量输出,单位 m³/h。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
private bool TryComputeSuctionVolumeFlow_m3_h(double mRef_kg_s, double v1_m3kg, out double suctionVolFlow_m3_h, out string error)
{
suctionVolFlow_m3_h = double.NaN;
error = string.Empty;
// 校验质量流量。
if (double.IsNaN(mRef_kg_s) || double.IsInfinity(mRef_kg_s) || mRef_kg_s <= 0)
{
error = "无效冷媒质量流量";
return false;
}
// 校验吸气比容。
if (double.IsNaN(v1_m3kg) || double.IsInfinity(v1_m3kg) || v1_m3kg <= 0)
{
error = "无效吸气比容";
return false;
}
// 实际吸气体积流量 = (kg/s * 3600) * m³/kg = m³/h。
suctionVolFlow_m3_h = (mRef_kg_s * 3600.0) * v1_m3kg;
if (double.IsNaN(suctionVolFlow_m3_h) || double.IsInfinity(suctionVolFlow_m3_h))
{
error = "实际吸气体积流量结果异常";
return false;
}
return true;
}
/// <summary>
/// 计算理论吸气体积流量,单位 m³/h。
/// </summary>
/// <param name="speed_rpm">压缩机转速,单位 rpm。</param>
/// <param name="disp_cc">压缩机排量,单位 cc。</param>
/// <param name="theoVolFlow_m3_h">理论吸气体积流量输出,单位 m³/h。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否计算成功。</returns>
/// <remarks>
/// 当前公式保持原实现不变:
/// <c>(speed_rpm / 60.0) * disp_cc * 0.0036</c>
/// </remarks>
private bool TryComputeTheoreticalVolumeFlow_m3_h(double speed_rpm, double disp_cc, out double theoVolFlow_m3_h, out string error)
{
theoVolFlow_m3_h = double.NaN;
error = string.Empty;
if (double.IsNaN(speed_rpm) || double.IsInfinity(speed_rpm) || speed_rpm <= 0)
{
error = $"无效转速: {speed_rpm} rpm";
return false;
}
if (double.IsNaN(disp_cc) || double.IsInfinity(disp_cc) || disp_cc <= 0)
{
error = $"无效压缩机排量: {disp_cc} cc";
return false;
}
// 理论体积流量公式保持原有写法不变。
theoVolFlow_m3_h = (speed_rpm / 60.0) * disp_cc * 0.0036;
if (double.IsNaN(theoVolFlow_m3_h) || double.IsInfinity(theoVolFlow_m3_h) || theoVolFlow_m3_h <= 0)
{
error = "理论吸气体积流量<=0";
return false;
}
return true;
}
/// <summary>
/// 获取并校验压缩机排量,单位 cc。
/// </summary>
/// <param name="compressorDisplacementCc">输入排量,单位 cc。</param>
/// <param name="displacement_cc">输出排量,单位 cc。</param>
/// <param name="error">失败原因。</param>
/// <returns>是否获取成功。</returns>
private bool TryGetCompressorDisplacement_cc(double compressorDisplacementCc, out double displacement_cc, out string error)
{
displacement_cc = double.NaN;
error = string.Empty;
// 当前方法只做读取与合法性校验。
displacement_cc = compressorDisplacementCc;
if (double.IsNaN(displacement_cc) || double.IsInfinity(displacement_cc) || displacement_cc <= 0)
{
error = $"压缩机排量<=0: {displacement_cc}";
return false;
}
return true;
}
/// <summary>
/// 六个热力结果计算类私有的底层物性支持实现。
/// </summary>
/// <remarks>
/// 该实现仅服务当前六结果计算类,不与其他结果类共享实现细节,
/// 这样即使后续为了新计算类调整别处的 support也不会影响本类已验算通过的流程。
/// </remarks>
private sealed class LocalCalculationSupport : IPPCCalculationSupport
{
private static readonly object _refpropLock = RefpropGlobalSync.SyncRoot;
private static volatile bool _rpInitialized;
public bool EnsureRefpropInitialized(out string error)
{
error = string.Empty;
if (_rpInitialized)
{
return true;
}
try
{
lock (_refpropLock)
{
if (_rpInitialized)
{
return true;
}
string hpath = ConfigHelper.GetValue("FluidsPath");
if (string.IsNullOrWhiteSpace(hpath))
{
hpath = @".\PPCalculation\REFPROP\FLUIDS";
}
string configuredCryogen = ConfigHelper.GetValue("Cryogen");
if (string.IsNullOrWhiteSpace(configuredCryogen))
{
configuredCryogen = "R134a";
}
string hfldCore = configuredCryogen.Equals("R134a", StringComparison.OrdinalIgnoreCase)
? "R134A.FLD"
: "R134A.FLD";
long size = hpath.Length;
string hpathPadded = hpath + new string(' ', Math.Max(0, 255 - (int)size));
IRefProp64.SETPATHdll(hpathPadded, ref size);
long numComps = 1;
string hfld = hfldCore;
size = hfld.Length;
string hfldPadded = hfld + new string(' ', Math.Max(0, 10000 - (int)size));
string hfmix = "hmx.bnc" + new string(' ', 255);
string hrf = "DEF";
string herr = new string(' ', 255);
long ierr = 0;
long hfldLen = hfldPadded.Length;
long hfmixLen = hfmix.Length;
long hrfLen = hrf.Length;
long herrLen = herr.Length;
IRefProp64.SETUPdll(ref numComps, ref hfldPadded, ref hfmix, ref hrf,
ref ierr, ref herr, ref hfldLen, ref hfmixLen, ref hrfLen, ref herrLen);
if (ierr != 0)
{
error = $"REFPROP 初始化失败: {herr.Trim()} (ierr={ierr})";
_rpInitialized = false;
return false;
}
_rpInitialized = true;
return true;
}
}
catch (Exception ex)
{
error = $"REFPROP 初始化异常: {ex.Message}";
_rpInitialized = false;
return false;
}
}
public bool TrySATP_SaturationByP_MPa(double pressureMPa, out double tSatK, out double Dl_molL, out double Dv_molL, out string error) => throw new NotSupportedException();
public bool TryTPRHO_VaporDensity_ByTP_MPa_C(double pressureMPa, double temperatureC, out double densityMolPerL, out string error)
{
densityMolPerL = double.NaN;
error = string.Empty;
double tK = temperatureC + 273.15;
double pKPa = pressureMPa * 1000.0;
double[] x = new double[20];
x[0] = 1.0;
long kph = 2;
long kguess = 0;
double D = 0.0;
long ierr = 0;
long herrLen = 255;
string herr = new string(' ', 255);
lock (_refpropLock)
{
IRefProp64.TPRHOdll(ref tK, ref pKPa, x, ref kph, ref kguess, ref D, ref ierr, ref herr, ref herrLen);
}
if (ierr != 0)
{
error = $"TPRHO 错误: {herr.Trim()} (ierr={ierr})";
return false;
}
densityMolPerL = D;
return true;
}
public bool TryTHERM_VaporEntropy_ByTD(double temperatureC, double densityMolPerL, out double entropy_kJ_per_kgK, out string error)
{
entropy_kJ_per_kgK = double.NaN;
error = string.Empty;
double tK = temperatureC + 273.15;
double D = densityMolPerL;
double[] x = new double[20];
x[0] = 1.0;
double pOut = 0;
double e = 0;
double hJmol = 0;
double sJmolK = 0;
double cv = 0;
double cp = 0;
double w = 0;
double hjt = 0;
double molarMassKgPerMol = GetMolarMass();
if (molarMassKgPerMol <= 0)
{
error = "无效的摩尔质量";
return false;
}
lock (_refpropLock)
{
IRefProp64.THERMdll(ref tK, ref D, x, ref pOut, ref e, ref hJmol, ref sJmolK, ref cv, ref cp, ref w, ref hjt);
}
entropy_kJ_per_kgK = (sJmolK / molarMassKgPerMol) * 0.001;
return true;
}
public bool TryTPRHO_LiquidDensity_ByTP_MPa_C(double pressureMPa, double temperatureC, out double densityMolPerL, out string error)
{
densityMolPerL = double.NaN;
error = string.Empty;
double tK = temperatureC + 273.15;
double pKPa = pressureMPa * 1000.0;
double[] x = new double[20];
x[0] = 1.0;
long kph = 1;
long kguess = 0;
double D = 0.0;
long ierr = 0;
long herrLen = 255;
string herr = new string(' ', 255);
lock (_refpropLock)
{
IRefProp64.TPRHOdll(ref tK, ref pKPa, x, ref kph, ref kguess, ref D, ref ierr, ref herr, ref herrLen);
}
if (ierr != 0)
{
error = $"TPRHO(液相) 错误: {herr.Trim()} (ierr={ierr})";
return false;
}
densityMolPerL = D;
return true;
}
public bool TryTHERM_LiquidEnthalpy_ByTD(double temperatureC, double densityMolPerL, out double h_liq_kJ_per_kg, out string error)
{
h_liq_kJ_per_kg = double.NaN;
error = string.Empty;
double tK = temperatureC + 273.15;
double D = densityMolPerL;
double[] x = new double[20];
x[0] = 1.0;
double pOut = 0;
double e = 0;
double hJmol = 0;
double sJmolK = 0;
double cv = 0;
double cp = 0;
double w = 0;
double hjt = 0;
double molarMassKgPerMol = GetMolarMass();
if (molarMassKgPerMol <= 0)
{
error = "无效的摩尔质量";
return false;
}
lock (_refpropLock)
{
IRefProp64.THERMdll(ref tK, ref D, x, ref pOut, ref e, ref hJmol, ref sJmolK, ref cv, ref cp, ref w, ref hjt);
}
h_liq_kJ_per_kg = (hJmol / molarMassKgPerMol) * 0.001;
return true;
}
public bool TryTHERM_Enthalpy_kJkg_ByT_K_D(double temperatureK, double densityMolPerL, out double h_kJ_per_kg, out string error)
{
h_kJ_per_kg = double.NaN;
error = string.Empty;
double tK = temperatureK;
double D = densityMolPerL;
double[] x = new double[20];
x[0] = 1.0;
double pOut = 0;
double e = 0;
double hJmol = 0;
double sJmolK = 0;
double cv = 0;
double cp = 0;
double w = 0;
double hjt = 0;
double molarMassKgPerMol = GetMolarMass();
if (molarMassKgPerMol <= 0)
{
error = "无效的摩尔质量";
return false;
}
lock (_refpropLock)
{
IRefProp64.THERMdll(ref tK, ref D, x, ref pOut, ref e, ref hJmol, ref sJmolK, ref cv, ref cp, ref w, ref hjt);
}
h_kJ_per_kg = (hJmol / molarMassKgPerMol) * 0.001;
return true;
}
public 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;
}
public bool TryGetIsentropicOutletEnthalpy_h2s_ByP2AndS1_BarA(double dischargePressureBarA, double suctionEntropy_kJkgK, out double h2s_kJkg, out string error)
{
h2s_kJkg = double.NaN;
error = string.Empty;
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;
}
return TryConvertH_Jmol_To_kJkg(h, out h2s_kJkg, out error);
}
private static double GetMolarMass()
{
double wmm = 0;
double Trp = 0;
double Tnbpt = 0;
double Tc = 0;
double Pc = 0;
double Dc = 0;
double Zc = 0;
double acf = 0;
double dip = 0;
double Rgas = 0;
long componentId = 1;
IRefProp64.INFOdll(ref componentId, ref wmm, ref Trp, ref Tnbpt, ref Tc, ref Pc, ref Dc, ref Zc, ref acf, ref dip, ref Rgas);
return wmm * 0.001;
}
private static 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;
}
private static 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;
}
}
}
}