530 lines
21 KiB
C#
530 lines
21 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
namespace NG_Tools
|
|
{
|
|
public class NG_Cal
|
|
{
|
|
public const int NORMAL = 9000;
|
|
public const int NG_Cal_INITIALIZED = 9001;
|
|
public const int MEMORY_ALLOCATION_ERROR = 9002;
|
|
public const int GENERAL_CALCULATION_FAILURE = 9003;
|
|
public const int MAX_NUM_OF_ITERATIONS_EXCEEDED = 9004;
|
|
public const int NEGATIVE_DENSITY_DERIVATIVE = 9005;
|
|
public const int MAX_DENSITY_IN_BRAKET_EXCEEDED = 9006;
|
|
/* number of components */
|
|
public const int NUMBEROFCOMPONENTS = 21;
|
|
/* maximum number of tries within search routines */
|
|
public const int MAX_NUM_OF_ITERATIONS = 100;
|
|
/* default tolerance limits */
|
|
public const double P_CHG_TOL = 0.001; /* 0.001 Pa */
|
|
public const double T_CHG_TOL = 0.001; /* 0.001 of a Kelvin */
|
|
/* maximum allowable P & T */
|
|
public const double P_MAX = 1.379e8; // maximum pressure (Pa) ~= 20,000 psi
|
|
public const double P_MIN = 0.0; // maximum pressure = 0
|
|
public const double T_MAX = 473.15; // maximum temperature (K) ~= 392 F
|
|
public const double T_MIN = 143.0; // maximum temperature (K) ~= -200 F
|
|
/* universal gas constant, in two configurations */
|
|
public const double RGASKJ = 8.314510e-3; /* in kJ mol^-1 K^-1 */
|
|
public const double RGAS = 8.314510; /* in J mol^-1 K^-1 */
|
|
/* the main data structure used by this library */
|
|
public struct GasPropsSTRUCT
|
|
{ /* corresponds to the control group in meter classes */
|
|
|
|
public int lStatus; /* calculation status 计算状态 */
|
|
public bool bForceUpdate; /*执行全部计算的标志 signal to perform full calculation */
|
|
public double[] adMixture; /*气体摩尔组成 Composition in mole fraction */
|
|
public double[] adMixtureV; /*气体体积组成 Composition in mole fraction */
|
|
public double[] adMixtureD; /*气体质量组成 Composition in mole fraction */
|
|
public int dCbtj; //参比条件 101325 0,15,20
|
|
public int dCbtj_E; //燃烧参比条件 101325 0,15,20
|
|
|
|
public double dPb; /*参比压力 Contract base Pressure (Pa) */
|
|
public double dTb; /* 参比温度Contract base temperature (K) */
|
|
public double dPf; /*绝对压力 Absolute Pressure (Pa) */
|
|
public double dTf; /*工况温度 Flowing temperature (K) */
|
|
|
|
|
|
// basic output from AGA 8 Detail method
|
|
public double dMrx; /*分子量 mixture molar mass */
|
|
public double dZb; /* 标况压缩因子compressibility at contract base condition */
|
|
public double dZf; /* 工况压缩因子compressibility at flowing condition */
|
|
public double dFpv; /*超压缩系数 supercompressibility */
|
|
public double dDb; /* 标况摩尔密度molar density at contract base conditions (moles/dm3) */
|
|
public double dDf; /*工况摩尔密度 molar density at flowing conditions (moles/dm3) */
|
|
public double dRhob; /* 标况质量密度mass density at contract base conditions (kg/m3) */
|
|
public double dRhof; /*工况质量密度 mass density at flowing conditions (kg/m3) */
|
|
public double dRD_Ideal; /* 理想气体的相对密度ideal gas relative density */
|
|
public double dRD_Real; /* 真实气体的相对密度real gas relative density */
|
|
// additional output
|
|
public double dHo; /*理想气体的比焓 ideal gas specific enthalpy */
|
|
public double dH; /*真实气体的焓 real gas specific enthalpy (J/kg) */
|
|
public double dS; /* 真实气体的熵real gas specific entropy (J/kg-mol.K)*/
|
|
public double dCpi; /*理想气体定压热容 ideal gas constant pressure heat capacity (J/kg-mol.K)*/
|
|
public double dCp; /* 定压热容real gas constant pressure heat capacity (J/kg-mol.K)*/
|
|
public double dCv; /*定容积热容 real gas constant volume heat capacity (J/kg-mol.K)*/
|
|
public double dk; /* 比热比ratio of specific heats */
|
|
public double dKappa; /*等熵指数 isentropic exponent, denoted with Greek letter kappa */
|
|
public double dSOS; /* 声速speed of sound (m/s) */
|
|
public double dCstar; /*临界流函数 critical flow factor C* */
|
|
|
|
// 11062 输出
|
|
|
|
public double dHhvMol; //摩尔高位发热量
|
|
public double dLhvMol; //摩尔低位发热量
|
|
public double dHhvv; //体积高位发热量
|
|
public double dLhvv; //体积低位发热量
|
|
public double dHhvm; //质量高位发热量
|
|
public double dLhvm; //质量地位发热量
|
|
|
|
public double dZb11062; //标况压缩因子
|
|
public double dRhob11062; /* 标况质量密度mass density at contract base conditions (kg/m3) */
|
|
public double dRhof11062; /*工况质量密度 mass density at flowing conditions (kg/m3) */
|
|
public double dRD_Ideal11062; /* 理想气体的相对密度ideal gas relative density */
|
|
public double dRD_Real11062; /* 真实气体的相对密度real gas relative density */
|
|
public double dWobbeIndex; /* 真实气体的沃泊指数 */
|
|
|
|
|
|
public double Pc; // '临界压力
|
|
public double TC; /// '临界温度
|
|
public double Bzsx; // '爆炸上限
|
|
public double Bzxx; // '爆炸下限
|
|
public double TotalC; // '总炭含量 (kg/m3)
|
|
public double C2; // 'C2组分含量 (kg/m3)
|
|
public double C2j; // 'C2以上组分含量 (kg/m3)
|
|
public double C3j; // 'C3以上组分含量 (kg/m3)
|
|
public double C4j; // 'C4以上组分含量 (kg/m3)
|
|
public double C5j; // 'C5以上组分含量 (kg/m3)
|
|
public double C6j; // 'C6以上组分含量 (kg/m3)
|
|
public double C3C4; // 'C3C4组分含量 (kg/m3)
|
|
|
|
}
|
|
public struct FlowParStruct //流量相关参数
|
|
{
|
|
//流量计算输入参数信息
|
|
public int dFlowCalbz; //流量计算标准
|
|
public int dZcalbz; //压缩因子计算标准
|
|
public int dCbtj; //计量参比条件压力
|
|
public double dPb_M; //计量参比条件压力
|
|
public double dTb_M; //计量参比条件温度
|
|
public double dPb_E; //燃烧参比条件压力
|
|
public double dTb_E; //燃烧参比条件温度
|
|
public double dPatm;//当地大气压
|
|
public int dPatmUnit;//当地大气压单位
|
|
public double[] dNG_Compents;//天然气组分
|
|
|
|
public int dMeterType;// 流量计类别
|
|
public int dCoreType;//节流装置类型
|
|
public int dPtmode; //取压方式
|
|
public int dPipeType; // 管道类型
|
|
public double dPipeD; //管道内径
|
|
public int dLenUnit; //长度单位
|
|
public double dPipeDtemp; //管道内径参考温度
|
|
public int dPileDtempUint; //温度单位
|
|
public int dPipeMaterial; //管道材料
|
|
|
|
public double dOrificeD; //孔板孔径
|
|
public int dOrificeUnit; //长度单位
|
|
public double dOrificeDtemp; //孔板内径参考温度
|
|
public int dOrificeDtempUnit; //温度单位
|
|
public int dOrificeMaterial; //孔板材料
|
|
public int dOrificeSharpness; //锐利度系数计算方法
|
|
public double dOrificeRk; //孔板入口圆弧半径
|
|
public int dOrificeRkLenUint;//长度单位
|
|
public double dPf;//输入压力
|
|
public int dPfUnit;//压力单位
|
|
public int dPfType; //压力类型
|
|
public double dTf; //输入温度
|
|
public int dTfUnit;//温度单位
|
|
public double dDp; //输入差压
|
|
public int dDpUnit; //压力单位
|
|
public int dVFlowUnit; //体积流量单位
|
|
public int dMFlowUnit; //'NG_Par(33) = ComboBox15.SelectedIndex '质量流量单位
|
|
public int dEFlowUnit; //'NG_Par(34) = ComboBox16.SelectedIndex '能量流量单位
|
|
public double dCd;//流出系数
|
|
public double dCdCalMethod;//流出系数计算方法 0 检定证书 0回归公式
|
|
public double dMeterFactor;//仪表系数
|
|
public double dPulseNum;//脉冲数
|
|
|
|
public double dVFlowMax; //'NG_par(39)=’最大体积流量
|
|
public double dVFlowMin; //'NG_par(40)=’最小体积流量
|
|
public double dVFlowCon;//'NG_par(41)=’常用流量
|
|
public double dPfRangeMin; //'NG_par(42)=’压力量程
|
|
public double dPfRangeMax; //'NG_par(42)=’压力量程
|
|
public double dDpRangeMin; //'NG_par(43)=’差压量程
|
|
public double dDpRangeMax; //'NG_par(43)=’差压量程
|
|
public double dTfRangeMin; //'NG_par(44)=’温度计量程
|
|
public double dTfRangeMax; //'NG_par(44)=’温度计量程
|
|
|
|
//流量计算输出参数
|
|
public double dE; //'求渐近速度系数 E
|
|
public double dFG; //'求相对密度系数 FG
|
|
public double dFT; //'求流动温度系数 'FT
|
|
public double dDViscosity; //'求动力粘度 dlnd
|
|
public double dDExpCoefficient; //'求可膨胀系数
|
|
public double dRnPipe; //'管道雷诺数
|
|
public double dBk; //'孔板锐利度系数Bk
|
|
public double dRoughNessPipe; //'管道粗糙度系数 Gme
|
|
public double dCdCorrect; //'修正后的流出系数
|
|
public double dCdNozell; //'喷嘴的流出系数
|
|
public double dVFlowb;//'标况体积流量 m³、s
|
|
public double dVFlowf; //'工况体积流量
|
|
public double dMFlowb;//'标况质量流量
|
|
public double dEFlowb;//'标况能量流量
|
|
public double dVelocityFlow;//'管道内天然气流速
|
|
public double dPressLost;//'压力损失
|
|
public double dBeta;//'直径比
|
|
public double dKappa;//'等熵指数
|
|
|
|
}
|
|
|
|
//public struct SqgyParStruct //输气工艺相关参数
|
|
//{
|
|
// public int dCalName; //计算项目
|
|
// public int dPipleD; //管道内径mm
|
|
// public int dPipleDw; //管道内径外径mm
|
|
// public int dPipleBh; //管道壁厚 mm
|
|
// public double dPipleTotalLength; //管道总长度 km
|
|
// public double dPiplePointLength; //管道任意点长度 km
|
|
// public double dPstart; //起点压力终点压力MPa
|
|
// public double dPend; //终点压力MPa
|
|
// public double dFlow; //输气能力
|
|
// public double dRd;//相对密度
|
|
// public double dZf;//压缩因子
|
|
// public double[] dNG_Compents;//天然气组分
|
|
|
|
// public double dPavg;//管道平均压力
|
|
// public double dPavgPoint;//管道任意点的平均压力
|
|
|
|
|
|
//}
|
|
|
|
/* enumerations for tracking gas components */
|
|
enum gascomp
|
|
{
|
|
XiC1 = 0, XiN2, XiCO2, XiC2, XiC3,
|
|
XiH2O, XiH2S, XiH2, XiCO, XiO2, XiIC4, XiNC4,
|
|
XiIC5, XiNC5, XiNC6, XiNC7, XiNC8, XiNC9, XiNC10, XiHe, XiAr
|
|
};
|
|
|
|
|
|
/* FUNCTION PROTOTYPES */
|
|
/* prototypes for initialization */
|
|
// int NG_Cal_Init(void) ; /* initialize library */
|
|
// int NG_Cal_UnInit(void) ; /* un-initialize library */
|
|
///* function prototype for basic VOS calculation */
|
|
// double SOS(ref AGA10.GasPropsSTRUCT ) ;
|
|
///* function prototype for a C* calculation */
|
|
// double Crit(ref AGA10.GasPropsSTRUCT , double) ;
|
|
|
|
|
|
|
|
public Therm ptTherm;
|
|
public Detail ptDetail;
|
|
|
|
/**************************************************************************
|
|
|
|
* Function : NG_Cal_Init()
|
|
* Arguments : void
|
|
* Returns : int
|
|
* Purpose : Initializes library; creates required objects
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
public int NG_Cal_Init()
|
|
{
|
|
//create object for calculating density
|
|
if (null == (ptDetail = new Detail()))
|
|
{
|
|
return MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
|
|
//create object for calculating thermodynamic properties
|
|
if (null == (ptTherm = new Therm()))
|
|
{
|
|
return MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
|
|
return NG_Cal_INITIALIZED;
|
|
|
|
}// NG_Cal_Init
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* Function : NG_Cal_UnInit()
|
|
* Arguments : void
|
|
* Returns : int
|
|
* Purpose : Un-initializes library; deletes objects
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
public int NG_Cal_UnInit()
|
|
{
|
|
// delete the objects (if they exist)
|
|
ptDetail = null;
|
|
ptTherm = null;
|
|
return 0;
|
|
|
|
}// NG_Cal_UnInit
|
|
|
|
|
|
/**************************************************************************
|
|
* Function : SOS()
|
|
* Arguments : Pointers to external AGA10 data struct
|
|
* Returns : double
|
|
* Purpose : calculates speed of sound and other parameters
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
public double SOS(ref GasPropsSTRUCT ptAGA10)
|
|
{
|
|
// check if library is ready; initialize if necessary
|
|
if (null == ptDetail || null == ptTherm)
|
|
{
|
|
NG_Cal_UnInit();
|
|
NG_Cal_Init();
|
|
|
|
}
|
|
|
|
switch (ptAGA10.dCbtj)
|
|
{
|
|
case 2:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 273.15;
|
|
break;
|
|
case 1:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 288.15;
|
|
break;
|
|
case 0:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 293.15;
|
|
break;
|
|
}
|
|
|
|
|
|
//Call function to calculate densities and thermodynamic properties
|
|
ptTherm.Run(ref ptAGA10, ref ptDetail);
|
|
|
|
//the basic sound speed calculation doesn't calculate C*; initialize to zero
|
|
ptAGA10.dCstar = 0.0;
|
|
|
|
//return the speed of sound to caller
|
|
|
|
return ptAGA10.dSOS;
|
|
|
|
}// VOS()
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* Function : Crit()
|
|
* Arguments : Pointers to external AGA10 data struct, Detail and Therm
|
|
* objects and a double precision float (gas velocity in plenum)
|
|
* Returns : double
|
|
* Purpose : calculates C*
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
public double Crit(ref NG_Cal.GasPropsSTRUCT ptAGA10, double dPlenumVelocity)
|
|
{
|
|
//variables local to function
|
|
double DH, DDH, S, H;
|
|
double tolerance = 1.0;
|
|
double R, P, T, Z;
|
|
|
|
int i;
|
|
|
|
//check objects for readiness; try to initialize if not
|
|
if (null == ptDetail || null == ptTherm)
|
|
{
|
|
NG_Cal_UnInit();
|
|
|
|
if (NG_Cal_INITIALIZED != NG_Cal_Init())
|
|
{
|
|
|
|
ptAGA10.lStatus = MEMORY_ALLOCATION_ERROR; return 0.0;
|
|
|
|
}
|
|
}
|
|
switch (ptAGA10.dCbtj)
|
|
{
|
|
case 2:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 273.15;
|
|
break;
|
|
case 1:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 288.15;
|
|
break;
|
|
case 0:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 293.15;
|
|
break;
|
|
|
|
|
|
}
|
|
//begin by calculating densities and thermodynamic properties
|
|
ptTherm.Run(ref ptAGA10, ref ptDetail);
|
|
|
|
//DH is enthalpy change from plenum to throat; this is our initial guess
|
|
|
|
DH = (ptAGA10.dSOS * ptAGA10.dSOS - dPlenumVelocity * dPlenumVelocity) / 2.0;
|
|
|
|
//trap plenum conditions before we alter the data stucture's contents
|
|
S = ptAGA10.dS;
|
|
|
|
H = ptAGA10.dH;
|
|
|
|
R = ptAGA10.dRhof;
|
|
P = ptAGA10.dPf;
|
|
Z = ptAGA10.dZf;
|
|
T = ptAGA10.dTf;
|
|
|
|
//initialize delta of DH to an arbitrary value outside of
|
|
|
|
//convergence tolerance
|
|
DDH = 10.0;
|
|
|
|
//Via simple repetition, search for a pressure, temperature and sound speed
|
|
|
|
//at a nozzle throat which provide constant enthalpy, given the entropy known
|
|
//at the plenum. Abort if loop executes more than 100 times without convergence.
|
|
for (i = 1; i < MAX_NUM_OF_ITERATIONS; i++)
|
|
{
|
|
|
|
// calculate P and T to satisfy H and S
|
|
ptTherm.HS_Mode(ref ptAGA10, ref ptDetail, H - DH, S, true);
|
|
|
|
//calculate new thermo, including SOS
|
|
ptTherm.Run(ref ptAGA10, ref ptDetail);
|
|
|
|
//hold DH for tolerance check
|
|
|
|
DDH = DH;
|
|
|
|
// recalculate DH
|
|
|
|
DH = (ptAGA10.dSOS * ptAGA10.dSOS - dPlenumVelocity * dPlenumVelocity) / 2.0;
|
|
|
|
// end loop if tolerance reached
|
|
|
|
if (Math.Abs(DDH - DH) < tolerance) break;
|
|
}
|
|
|
|
//C* is the real gas critical flow constant (not to be confused with Cperf or CRi)
|
|
ptAGA10.dCstar = (ptAGA10.dRhof * ptAGA10.dSOS) / Math.Sqrt(R * P * Z);
|
|
|
|
//put the original plenum pressure and temperature back
|
|
|
|
ptAGA10.dPf = P;
|
|
ptAGA10.dTf = T;
|
|
|
|
//restore fluid props to plenum conditions
|
|
ptTherm.Run(ref ptAGA10, ref ptDetail);
|
|
|
|
GB11062 ptGB11062 = new GB11062();
|
|
|
|
ptGB11062.Run(ref ptAGA10);
|
|
|
|
//return the critical flow function to caller
|
|
return ptAGA10.dCstar;
|
|
|
|
}// Crit()
|
|
|
|
/**************************************************************************
|
|
|
|
* Function : Crit()
|
|
* Arguments : Pointers to external AGA10 data struct, Detail and Therm
|
|
* objects and a double precision float (gas velocity in plenum)
|
|
* Returns : double
|
|
* Purpose : calculates C*
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
public double Zcal(ref NG_Cal.GasPropsSTRUCT ptAGA10, double dPlenumVelocity)
|
|
{
|
|
//variables local to function
|
|
|
|
|
|
|
|
//check objects for readiness; try to initialize if not
|
|
if (null == ptDetail || null == ptTherm)
|
|
{
|
|
NG_Cal_UnInit();
|
|
|
|
if (NG_Cal_INITIALIZED != NG_Cal_Init())
|
|
{
|
|
|
|
ptAGA10.lStatus = MEMORY_ALLOCATION_ERROR; return 0.0;
|
|
|
|
}
|
|
}
|
|
switch (ptAGA10.dCbtj)
|
|
{
|
|
case 2:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 273.15;
|
|
break;
|
|
case 1:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 288.15;
|
|
break;
|
|
case 0:
|
|
ptAGA10.dPb = 101325;
|
|
ptAGA10.dTb = 293.15;
|
|
break;
|
|
|
|
|
|
}
|
|
//begin by calculating densities and thermodynamic properties
|
|
ptTherm.Run(ref ptAGA10, ref ptDetail);
|
|
|
|
|
|
GB11062 ptGB11062 = new GB11062();
|
|
|
|
ptGB11062.Run(ref ptAGA10);
|
|
|
|
//return the critical flow function to caller
|
|
return ptAGA10.dZf;
|
|
|
|
}// Z()
|
|
|
|
/**************************************************************************
|
|
* Function : Cperf()
|
|
* Arguments : pointer to external AGA10 data struct
|
|
* Returns : double
|
|
* Purpose : calculates isentropic perfect gas critical flow function
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
double Cperf(ref NG_Cal.GasPropsSTRUCT ptAGA10)
|
|
{
|
|
|
|
double k, root, exponent;
|
|
|
|
k = ptAGA10.dKappa; root = 2.0 / (k + 1.0);
|
|
exponent = (k + 1.0) / (k - 1.0);
|
|
|
|
// isentropic perfect gas critical flow function C*i
|
|
return (Math.Sqrt(k * Math.Pow(root, exponent)));
|
|
|
|
}// Cperf
|
|
/**************************************************************************
|
|
* Function : CRi()
|
|
* Arguments : pointer to external AGA10 data struct
|
|
* Returns : double
|
|
* Purpose : calculates isentropic real gas critical flow function CRi
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
double CRi(ref NG_Cal.GasPropsSTRUCT ptAGA10)
|
|
{
|
|
return (Cperf(ref ptAGA10) / Math.Sqrt(ptAGA10.dZf));
|
|
}// CRi()
|
|
}
|
|
} |