using System;
namespace CapMachine.Wpf.PPCalculation
{
///
/// 过热度/过冷度计算器。
///
/// 说明:该类仅负责封装 SATPdll 调用与计算公式,保持与历史流程一致。
/// - 压力换算保持原逻辑:BarA * 100.0
/// - 温度换算保持原逻辑:Tsat[K] - 273.15
/// - 失败时返回 0(与原先在服务中直接写 Tag 的行为一致)
///
public sealed class SuperheatSubcoolCalculator
{
private readonly object _refpropLock;
///
/// 构造函数。
///
/// REFPROP 全局锁(REFPROP DLL 非线程安全,需串行化调用)。
public SuperheatSubcoolCalculator(object refpropLock)
{
_refpropLock = refpropLock ?? throw new ArgumentNullException(nameof(refpropLock));
}
///
/// 按既有流程计算过热度/过冷度。
///
/// 吸气压力(BarA)。
/// 吸气温度(℃)。
/// 膨胀阀前压力(BarA)。
/// 膨胀阀前温度(℃)。
/// 过热度(K)。失败时为 0。
/// 过冷度(K)。失败时为 0。
public void Calculate(
double inhPressBarA,
double inhTempC,
double txvFrPressBarA,
double txvFrTempC,
out double superheatK,
out double subcoolK)
{
superheatK = 0.0;
subcoolK = 0.0;
long iErr;
long kph = 1;
double te = 0.0;
double te1 = 0.0;
double p = 0.0;
double p1 = 0.0;
double Dl = 0.0;
double Dv = 0.0;
double[] x = new double[20], xliq = new double[20], xvap = new double[20];
x[0] = 1.0;
//p = Convert.ToDouble(textBox2.Text) * 1000.0;//textBox2 Comp.吸气压力(kpa)
p = inhPressBarA * 100.0;// 保持你原有流程:将 BarA 当作 MPa? 历史代码为 *1000.0,不改变你的算法
p1 = txvFrPressBarA * 100.0;// 保持你原有流程
//p1 = Convert.ToDouble(textBox3.Text) * 1000.0;//textBox3 Evap.膨胀阀前压力(Mpa)
// 统一放入同一把锁中,避免并发导致的 Fortran 读文件/状态竞态
string herr = new string(' ', 255); long herrLen = 255; iErr = 0;
lock (_refpropLock)
{
IRefProp64.SATPdll(ref p, x, ref kph, ref te, ref Dl, ref Dv, xliq, xvap, ref iErr, ref herr, ref herrLen);
}
if (iErr == 0)
superheatK = Math.Abs(inhTempC - (te - 273.15));
else
superheatK = 0;
herr = new string(' ', 255); herrLen = 255; iErr = 0;
lock (_refpropLock)
{
IRefProp64.SATPdll(ref p1, x, ref kph, ref te1, ref Dl, ref Dv, xliq, xvap, ref iErr, ref herr, ref herrLen);
}
if (iErr == 0)
subcoolK = Math.Abs(txvFrTempC - (te1 - 273.15));
else
subcoolK = 0;
}
}
}