Files
CapMachine/temp_hasco_thermo.cs
Tyrone CT 47834ea4dc 物性更改2
一些已知的更改
2026-05-07 22:11:27 +08:00

985 lines
35 KiB
C#
Raw Permalink 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 System;
using System.Diagnostics;
using System.Text;
namespace CapMachine.Wpf.PPCalculation
{
/// <summary>
/// 鍏釜鐗╂€х粨鏋滐紙鍒剁儹閲?COP(鍒剁儹)/绛夌喌鏁堢巼/鍒跺喎閲?COP(鍒跺喎)/瀹圭Н鏁堢巼锛夎绠楀皝瑁呯被銆? ///
/// 璇存槑锛? /// - 鏈被鐢ㄤ簬灏嗗師鍏堜綅浜?PPCService 鐨勮绠楄繃绋嬪畬鏁存惉杩佷负鐙珛绫伙紝鏂逛究鍚庣画缁存姢涓庡姣旈獙璇併€? /// - 璁畻鍏紡銆佸崟浣嶆崲绠椼€丷EFPROP 璋冪敤閾捐矾搴斾笌鐜版湁瀹炵幇淇濇寔涓€鑷达紝浠呭仛缁撴瀯鎬у皝瑁呫€? /// </summary>
public sealed class ThermodynamicSixResultsCalculator
{
private readonly object _refpropLock;
private static volatile bool _rpInitialized;
private static string _rpFluidFile = string.Empty;
private double _h3TempOffset_C = -10.0;
public void SetH3TempOffset_C(double offsetC)
{
if (double.IsNaN(offsetC) || double.IsInfinity(offsetC))
{
return;
}
_h3TempOffset_C = offsetC;
}
/// <summary>
/// 鏋勯€犲嚱鏁般€? /// </summary>
/// <param name="refpropLock">REFPROP 鍏ㄥ眬浜掓枼閿佸璞★紙寤鸿浼犲叆涓?PPCService 鐩稿悓鐨勯攣瀵硅薄锛岄伩鍏嶅苟鍙戠珵鎬侊級銆?/param>
public ThermodynamicSixResultsCalculator(object refpropLock)
{
_refpropLock = refpropLock ?? throw new ArgumentNullException(nameof(refpropLock));
}
/// <summary>
/// 杈撳叆妯″瀷锛堜粠 Tag 鎴栧閮ㄦ潵婧愯鍙栧悗浼犲叆锛夈€? /// </summary>
public readonly struct Input
{
public Input(
double suctionPress_BarA,
double suctionTemp_C,
double dischargePress_BarA,
double dischargeTemp_C,
double txvFrPress_BarA,
double txvFrTemp_C,
double hvPower_W,
double totalFlow_kg_h,
double speed_rpm,
double displacement_cc)
{
SuctionPress_BarA = suctionPress_BarA;
SuctionTemp_C = suctionTemp_C;
DischargePress_BarA = dischargePress_BarA;
DischargeTemp_C = dischargeTemp_C;
TxvFrPress_BarA = txvFrPress_BarA;
TxvFrTemp_C = txvFrTemp_C;
HvPower_W = hvPower_W;
TotalFlow_kg_h = totalFlow_kg_h;
Speed_rpm = speed_rpm;
Displacement_cc = displacement_cc;
}
public double SuctionPress_BarA { get; }
public double SuctionTemp_C { get; }
public double DischargePress_BarA { get; }
public double DischargeTemp_C { get; }
public double TxvFrPress_BarA { get; }
public double TxvFrTemp_C { get; }
public double HvPower_W { get; }
public double TotalFlow_kg_h { get; }
public double Speed_rpm { get; }
public double Displacement_cc { get; }
}
/// <summary>
/// 璁$畻杈撳嚭妯″瀷銆? /// </summary>
public readonly struct Result
{
public Result(
double heatingCapacityQh_kW,
double coolingCapacityQc_kW,
double copHeating,
double copCooling,
double isentropicEfficiencyPct,
double volumetricEfficiencyPct,
double mRef_kg_s,
double w_kW,
double h1_kJkg,
double s1_JmolK,
double v1_m3kg,
double h2_kJkg,
double h3_kJkg,
double h2s_kJkg)
{
HeatingCapacityQh_kW = heatingCapacityQh_kW;
CoolingCapacityQc_kW = coolingCapacityQc_kW;
COPHeating = copHeating;
COPCooling = copCooling;
IsentropicEfficiencyPct = isentropicEfficiencyPct;
VolumetricEfficiencyPct = volumetricEfficiencyPct;
MRef_kg_s = mRef_kg_s;
W_kW = w_kW;
H1_kJkg = h1_kJkg;
S1_JmolK = s1_JmolK;
V1_m3kg = v1_m3kg;
H2_kJkg = h2_kJkg;
H3_kJkg = h3_kJkg;
H2s_kJkg = h2s_kJkg;
}
public double HeatingCapacityQh_kW { get; }
public double CoolingCapacityQc_kW { get; }
public double COPHeating { get; }
public double COPCooling { get; }
public double IsentropicEfficiencyPct { get; }
public double VolumetricEfficiencyPct { get; }
public double MRef_kg_s { get; }
public double W_kW { get; }
public double H1_kJkg { get; }
public double S1_JmolK { get; }
public double V1_m3kg { get; }
public double H2_kJkg { get; }
public double H3_kJkg { get; }
public double H2s_kJkg { get; }
}
/// <summary>
/// 璁$畻鍏釜鐗╂€х粨鏋溿€? ///
/// 杩斿洖鍊硷細
/// - true锛氳嚦灏戝凡鎴愬姛璁畻 Qh/Qc/COP/畏s锛涘绉晥鐜囪嫢澶辫触灏嗚繑鍥?NaN锛屼絾鏈柟娉曚粛杩斿洖 true锛屽苟閫氳繃 error 杈撳嚭璀﹀憡淇℃伅銆? /// - false锛氬叧閿緭鍏?REFPROP 璁$畻澶辫触銆? /// </summary>
/// <param name="input">杈撳叆鍙傛暟銆?/param>
/// <param name="result">杈撳嚭缁撴灉銆?/param>
/// <param name="error">閿欒/璀﹀憡淇℃伅銆?/param>
/// <returns>鏄惁鎴愬姛銆?/returns>
public bool TryCalculate(Input input, out Result result, out string error)
{
result = default;
error = string.Empty;
if (!EnsureRefpropInitialized(out var initErr))
{
error = initErr;
return false;
}
var w_W = input.HvPower_W;
if (!double.IsNaN(w_W) && !double.IsInfinity(w_W) && w_W == 0)
{
result = new Result(
heatingCapacityQh_kW: 0,
coolingCapacityQc_kW: 0,
copHeating: 0,
copCooling: 0,
isentropicEfficiencyPct: 0,
volumetricEfficiencyPct: 0,
mRef_kg_s: 0,
w_kW: 0,
h1_kJkg: 0,
s1_JmolK: 0,
v1_m3kg: 0,
h2_kJkg: 0,
h3_kJkg: 0,
h2s_kJkg: 0);
return true;
}
if (!TryGetCompressorPower_kW(input, out var w_kW, out var wErr))
{
error = wErr;
return false;
}
if (!TryGetRefrigerantMassFlow_kg_s(input, out var mRef_kg_s, out var mRefErr))
{
error = mRefErr;
return false;
}
if (!TryGetVaporPointState_ByTP_BarA_C(input.SuctionPress_BarA, input.SuctionTemp_C, out var h1_kJkg, out var s1_JmolK, out var v1_m3kg, out var p1Err))
{
error = $"h1/s1/鍚告皵姣斿璁$畻澶辫触: {p1Err}";
return false;
}
if (!TryGetVaporPointEnthalpy_ByTP_BarA_C(input.DischargePress_BarA, input.DischargeTemp_C, out var h2_kJkg, out var p2Err))
{
error = $"h2 璁$畻澶辫触: {p2Err}";
return false;
}
double txvFrTempForH3_C = input.TxvFrTemp_C;
if (TryGetTxvFrTempForH3_ByDischargePress_BarA(input.DischargePress_BarA, out var derivedTxvFrTempForH3_C, out var satWarn))
{
txvFrTempForH3_C = derivedTxvFrTempForH3_C;
}
else if (!string.IsNullOrWhiteSpace(satWarn))
{
error = string.IsNullOrWhiteSpace(error)
? $"h3娓╁害鏀圭敤SATP(鎺掓皵鍘嬪姏)璁畻Tsat澶辫触锛屽凡鍥為€€浣跨敤TxvFrTemp_C銆傚師鍥? {satWarn}"
: $"{error}; h3娓╁害鏀圭敤SATP(鎺掓皵鍘嬪姏)璁畻Tsat澶辫触锛屽凡鍥為€€浣跨敤TxvFrTemp_C銆傚師鍥? {satWarn}";
}
if (!TryGetLiquidPointEnthalpy_ByTP_BarA_C(input.TxvFrPress_BarA, txvFrTempForH3_C, out var h3_kJkg, out var p3Err))
{
error = $"h3 璁$畻澶辫触: {p3Err}";
return false;
}
if (!TryGetIsentropicOutletEnthalpy_h2s_ByP2AndS1_BarA(input.DischargePress_BarA, s1_JmolK, 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(mRef_kg_s, h1_kJkg, h2s_kJkg, w_kW, out var etaS_pct, out var etaSErr))
{
error = etaSErr;
return false;
}
if (!TryComputeVolumetricEfficiencyPct(mRef_kg_s, v1_m3kg, input.Speed_rpm, input.Displacement_cc, out var etaV_pct, out var etaVErr))
{
result = new Result(
heatingCapacityQh_kW: qh_kW,
coolingCapacityQc_kW: qc_kW,
copHeating: copH,
copCooling: copC,
isentropicEfficiencyPct: etaS_pct,
volumetricEfficiencyPct: double.NaN,
mRef_kg_s: mRef_kg_s,
w_kW: w_kW,
h1_kJkg: h1_kJkg,
s1_JmolK: s1_JmolK,
v1_m3kg: v1_m3kg,
h2_kJkg: h2_kJkg,
h3_kJkg: h3_kJkg,
h2s_kJkg: h2s_kJkg);
error = etaVErr;
return true;
}
result = new Result(
heatingCapacityQh_kW: qh_kW,
coolingCapacityQc_kW: qc_kW,
copHeating: copH,
copCooling: copC,
isentropicEfficiencyPct: etaS_pct,
volumetricEfficiencyPct: etaV_pct,
mRef_kg_s: mRef_kg_s,
w_kW: w_kW,
h1_kJkg: h1_kJkg,
s1_JmolK: s1_JmolK,
v1_m3kg: v1_m3kg,
h2_kJkg: h2_kJkg,
h3_kJkg: h3_kJkg,
h2s_kJkg: h2s_kJkg);
return true;
}
/// <summary>
/// 杈撳嚭璋冭瘯蹇収鍒?Console/Debug锛堢敤浜庝汉宸ュ姣旈獙璇侊級銆? /// </summary>
/// <param name="title">鏍囬/闃舵鏍囪瘑銆?/param>
/// <param name="input">杈撳叆銆?/param>
/// <param name="result">杈撳嚭缁撴灉锛堝彲涓?null锛岃〃绀鸿绠楀け璐ユ椂浠呰緭鍑鸿緭鍏ワ級銆?/param>
/// <param name="error">閿欒/璀﹀憡銆?/param>
public static void PrintDebugSnapshotToConsole(string title, Input input, Result? result, string error)
{
void Print(string line)
{
try { Debug.WriteLine(line); } catch { }
try { Console.WriteLine(line); } catch { }
}
Print($"================ {title} ================");
Print("--- Inputs ---");
Print($"Suction : T1={input.SuctionTemp_C} 掳C, P1={input.SuctionPress_BarA} BarA");
Print($"Discharge : T2={input.DischargeTemp_C} 掳C, P2={input.DischargePress_BarA} BarA");
Print($"TXV-before : T3={input.TxvFrTemp_C} 掳C, P3={input.TxvFrPress_BarA} BarA");
Print($"Flow : mTotal={input.TotalFlow_kg_h} kg/h");
Print($"Power(HV) : W={input.HvPower_W} W");
Print($"Speed : n={input.Speed_rpm} rpm");
Print($"Disp : disp={input.Displacement_cc} cc");
if (result.HasValue)
{
var r = result.Value;
Print("--- Intermediate (computed) ---");
Print($"mRef={r.MRef_kg_s:F8} kg/s, W={r.W_kW:F6} kW");
Print($"h1={r.H1_kJkg:F6} kJ/kg");
Print($"s1={r.S1_JmolK:F6} J/(mol路K)");
Print($"v1={r.V1_m3kg:F8} m3/kg");
Print($"h2={r.H2_kJkg:F6} kJ/kg");
Print($"h3={r.H3_kJkg:F6} kJ/kg");
Print($"h2s={r.H2s_kJkg:F6} kJ/kg");
Print("--- Final (computed) ---");
Print($"Qc={r.CoolingCapacityQc_kW:F5} kW");
Print($"COP(cool)={r.COPCooling:F5}");
Print($"Qh={r.HeatingCapacityQh_kW:F5} kW");
Print($"COP(heat)={r.COPHeating:F5}");
Print($"etaS={r.IsentropicEfficiencyPct:F4} %");
Print($"etaV={r.VolumetricEfficiencyPct:F3} %");
}
if (!string.IsNullOrWhiteSpace(error))
{
Print($"--- Error/Warning ---\r\n{error}");
}
Print("====================================================");
}
private 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, hfmixLen = hfmix.Length, hrfLen = hrf.Length, 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;
_rpFluidFile = hfldCore;
return true;
}
}
catch (Exception ex)
{
error = $"REFPROP 鍒濆鍖栧紓甯? {ex.Message}";
_rpInitialized = false;
return false;
}
}
private static double GetMolarMass()
{
double wmm = 0, Trp = 0, Tnbpt = 0, Tc = 0, Pc = 0, Dc = 0, Zc = 0, acf = 0, dip = 0, 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 bool TryGetCompressorPower_kW(Input input, out double w_kW, out string error)
{
w_kW = double.NaN;
error = string.Empty;
double w_W = input.HvPower_W;
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;
}
private bool TryGetRefrigerantMassFlow_kg_s(Input input, out double mRef_kg_s, out string error)
{
mRef_kg_s = double.NaN;
error = string.Empty;
double mTotal_kg_h = input.TotalFlow_kg_h;
if (double.IsNaN(mTotal_kg_h) || double.IsInfinity(mTotal_kg_h))
{
error = "鎬绘祦閲?鍐峰獟娴侀噺)涓?NaN/Inf";
return false;
}
double mRef_kg_h = mTotal_kg_h;
if (mRef_kg_h <= 0)
{
error = $"鍐峰獟璐ㄩ噺娴侀噺<=0锛屾€绘祦閲?{mTotal_kg_h}kg/h";
return false;
}
mRef_kg_s = mRef_kg_h / 3600.0;
return true;
}
private bool TryGetVaporPointEnthalpy_ByTP_BarA_C(double pressureBarA, double temperatureC, out double h_kJkg, out string error)
{
h_kJkg = double.NaN;
error = string.Empty;
if (!TryTPFLSH_ByTP_BarA_C(pressureBarA, temperatureC, out _, out var h_Jmol, out _, out _, out var flashErr))
{
error = flashErr;
return false;
}
if (!TryConvertH_Jmol_To_kJkg(h_Jmol, out h_kJkg, out var hErr))
{
error = hErr;
return false;
}
return true;
}
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;
}
private bool TryGetVaporPointState_ByTP_BarA_C(
double pressureBarA,
double temperatureC,
out double h_kJkg,
out double s_JmolK,
out double v_m3kg,
out string error)
{
h_kJkg = double.NaN;
s_JmolK = double.NaN;
v_m3kg = double.NaN;
error = string.Empty;
if (!TryTPFLSH_ByTP_BarA_C(pressureBarA, temperatureC, out var d_molL, out var h_Jmol, out var sOut_JmolK, out _, out var flashErr))
{
error = flashErr;
return false;
}
if (!TryConvertH_Jmol_To_kJkg(h_Jmol, out h_kJkg, out var hErr))
{
error = hErr;
return false;
}
s_JmolK = sOut_JmolK;
if (double.IsNaN(s_JmolK) || double.IsInfinity(s_JmolK))
{
error = "鏃犳晥鍚告皵鐔?;
return false;
}
if (!TryConvertMolarDensityToSpecificVolume(d_molL, out v_m3kg, out var vErr))
{
error = vErr;
return false;
}
return true;
}
private bool TryGetIsentropicOutletEnthalpy_h2s_ByP2AndS1_BarA(double dischargePressureBarA, double suctionEntropy_JmolK, 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_JmolK) || double.IsInfinity(suctionEntropy_JmolK))
{
error = "鏃犳晥鍚告皵鐔?s1";
return false;
}
double s_JmolK = suctionEntropy_JmolK;
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;
}
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;
}
private bool TryComputeIsentropicEfficiencyPct(double mRef_kg_s, double h1_kJkg, double h2s_kJkg, double w_kW, out double etaS_pct, out string error)
{
etaS_pct = 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(w_kW) || double.IsInfinity(w_kW) || w_kW <= 0)
{
error = "鏃犳晥鍘嬬缉鏈哄姛鐜?;
return false;
}
double dh_isentropic = h2s_kJkg - h1_kJkg;
double eta = (mRef_kg_s * dh_isentropic) / w_kW;
if (double.IsNaN(eta) || double.IsInfinity(eta))
{
error = "绛夌喌鏁堢巼缁撴灉寮傚父";
return false;
}
etaS_pct = eta * 100.0;
return true;
}
private bool TryComputeVolumetricEfficiencyPct(
double mRef_kg_s,
double v1_m3kg,
double speed_rpm,
double displacement_cc,
out double etaV_pct,
out string error)
{
etaV_pct = 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(displacement_cc) || double.IsInfinity(displacement_cc) || displacement_cc <= 0)
{
error = $"鏃犳晥鎺掗噺: {displacement_cc} cc";
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) * displacement_cc * 0.0036;
if (theoVolFlow_m3_h <= 0)
{
error = "鐞嗚鍚告皵浣撶Н娴侀噺<=0";
return false;
}
etaV_pct = (suctionVolFlow_m3_h / theoVolFlow_m3_h) * 100.0;
return true;
}
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;
}
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;
}
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;
}
private 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;
}
private 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, e = 0, hJmol = 0, sJmolK = 0, cv = 0, cp = 0, w = 0, 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;
}
private bool TrySATP_SaturationTemperatureK_ByP_BarA(double pressureBarA, out double tSatK, out string error)
{
tSatK = double.NaN;
error = string.Empty;
if (!EnsureRefpropInitialized(out var initErr))
{
error = initErr;
return false;
}
double pKPa = pressureBarA * 100.0;
if (pKPa <= 0)
{
error = $"鏃犳晥鍘嬪姏: {pressureBarA} BarA";
return false;
}
double[] x = new double[20];
x[0] = 1.0;
long kph = 1;
double t = 0.0;
double Dl = 0.0;
double Dv = 0.0;
double[] xliq = new double[20];
double[] xvap = new double[20];
long ierr = 0;
long herrLen = 255;
string herr = new string(' ', 255);
lock (_refpropLock)
{
IRefProp64.SATPdll(ref pKPa, x, ref kph, ref t, ref Dl, ref Dv, xliq, xvap, ref ierr, ref herr, ref herrLen);
}
if (ierr != 0)
{
error = $"SATP 閿欒: {herr.Trim()} (ierr={ierr})";
return false;
}
tSatK = t;
return true;
}
private bool TryGetTxvFrTempForH3_ByDischargePress_BarA(double dischargePressBarA, out double txvFrTempForH3_C, out string warning)
{
txvFrTempForH3_C = double.NaN;
warning = string.Empty;
if (!TrySATP_SaturationTemperatureK_ByP_BarA(dischargePressBarA, out var tSatK, out var satErr))
{
warning = satErr;
return false;
}
double tSatC = tSatK - 273.15;
double offsetC = _h3TempOffset_C;
txvFrTempForH3_C = tSatC + offsetC;
return true;
}
/// <summary>
/// 鐢熸垚涓€娈典究浜庝繚瀛?瀵规瘮鐨勬枃鏈姤鍛娿€? /// </summary>
/// <param name="title">鏍囬銆?/param>
/// <param name="input">杈撳叆銆?/param>
/// <param name="result">杈撳嚭銆?/param>
/// <param name="error">閿欒/璀﹀憡銆?/param>
/// <returns>鎶ュ憡鏂囨湰銆?/returns>
public static string BuildDebugReport(string title, Input input, Result? result, string error)
{
var sb = new StringBuilder(512);
sb.AppendLine($"================ {title} ================");
sb.AppendLine("--- Inputs ---");
sb.AppendLine($"Suction : T1={input.SuctionTemp_C} 掳C, P1={input.SuctionPress_BarA} BarA");
sb.AppendLine($"Discharge : T2={input.DischargeTemp_C} 掳C, P2={input.DischargePress_BarA} BarA");
sb.AppendLine($"TXV-before : T3={input.TxvFrTemp_C} 掳C, P3={input.TxvFrPress_BarA} BarA");
sb.AppendLine($"Flow : mTotal={input.TotalFlow_kg_h} kg/h");
sb.AppendLine($"Power(HV) : W={input.HvPower_W} W");
sb.AppendLine($"Speed : n={input.Speed_rpm} rpm");
sb.AppendLine($"Disp : disp={input.Displacement_cc} cc");
if (result.HasValue)
{
var r = result.Value;
sb.AppendLine("--- Intermediate (computed) ---");
sb.AppendLine($"mRef={r.MRef_kg_s:F8} kg/s, W={r.W_kW:F6} kW");
sb.AppendLine($"h1={r.H1_kJkg:F6} kJ/kg");
sb.AppendLine($"s1={r.S1_JmolK:F6} J/(mol路K)");
sb.AppendLine($"v1={r.V1_m3kg:F8} m3/kg");
sb.AppendLine($"h2={r.H2_kJkg:F6} kJ/kg");
sb.AppendLine($"h3={r.H3_kJkg:F6} kJ/kg");
sb.AppendLine($"h2s={r.H2s_kJkg:F6} kJ/kg");
sb.AppendLine("--- Final (computed) ---");
sb.AppendLine($"Qc={r.CoolingCapacityQc_kW:F5} kW");
sb.AppendLine($"COP(cool)={r.COPCooling:F5}");
sb.AppendLine($"Qh={r.HeatingCapacityQh_kW:F5} kW");
sb.AppendLine($"COP(heat)={r.COPHeating:F5}");
sb.AppendLine($"etaS={r.IsentropicEfficiencyPct:F4} %");
sb.AppendLine($"etaV={r.VolumetricEfficiencyPct:F3} %");
}
if (!string.IsNullOrWhiteSpace(error))
{
sb.AppendLine("--- Error/Warning ---");
sb.AppendLine(error);
}
sb.AppendLine("====================================================");
return sb.ToString();
}
}
}