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 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 dMeterFactor;//仪表系数 public double dPulseNum;//脉冲数 public double dVFlowMax; //'NG_par(39)=’最大体积流量 public double dVFlowMin; //'NG_par(40)=’最小体积流量 public double dVFlowCon;//'NG_par(41)=’常用流量 public double dPfRange; //'NG_par(42)=’压力量程 public double dDpRange; //'NG_par(43)=’差压量程 public double dTfRange; //'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() } }