GasFlowMeter/User/NG 带注释/NGCal.c

203 lines
5.2 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.

/*************************************************************************
* 文件: aga10.c
* 描述: 管理计算声速或C*的整体流程
* 创建并使用基于Detail和Therm类的对象
* 包含以下函数:
* AGA10_Init(), AGA10_UnInit(), SOS(), Crit(), Cperf(), CRi()
* 版本: ver 1.7 2002.11.17
* 作者: W.B. Peterson
* 修订:
* 版权 (c) 2002 美国天然气协会
**************************************************************************/
#include "NGCal.h"
#include "Therm.h"
#include "Detail.h"
// 创建文件作用域的对象指针一个Therm类对象和一个Detail类对象
static Therm *ptTherm;
static Detail *ptDetail;
/**************************************************************************
* 函数 : AGA10_Init()
* 参数 : void
* 返回值 : int
* 功能 : 初始化库;创建所需对象
* 修订 :
**************************************************************************/
int NGCal_Init(void)
{
ptDetail = (Detail *)malloc(sizeof(Detail));
// 创建用于计算密度的对象
if (NULL == ptDetail )
{
return MEMORY_ALLOCATION_ERROR;
}
// 创建用于计算热力学性质的对象
ptTherm = (Therm *)malloc(sizeof(Therm));
if (NULL == ptTherm )
{
return MEMORY_ALLOCATION_ERROR;
}
return AGA10_INITIALIZED;
}
/**************************************************************************
* 函数 : AGA10_UnInit()
* 参数 : void
* 返回值 : int
* 功能 : 反初始化库;删除对象
* 修订 :
**************************************************************************/
int NGCal_UnInit(void)
{
// 删除对象(如果存在)
if (ptDetail) free( ptDetail);
if (ptTherm) free (ptTherm);
return 0;
}
/**************************************************************************
* 函数 : SOS()
* 参数 : 指向外部AGA10数据结构的指针
* 返回值 : double
* 功能 : 计算声速和其他参数
* 修订 :
**************************************************************************/
double SOS(AGA10STRUCT *ptAGA10)
{
// 检查库是否就绪;必要时初始化
if (NULL == ptDetail || NULL == ptTherm)
{
NGCal_UnInit();
NGCal_Init();
}
// 调用函数计算密度和热力学性质
ptTherm->Run(ptTherm,ptAGA10, ptDetail);
// 基本声速计算不计算C*;初始化为零
ptAGA10->dCstar = 0.0;
// 返回声速给调用者
return ptAGA10->dSOS;
}
/**************************************************************************
* 函数 : Crit()
* 参数 : 指向外部AGA10数据结构的指针、Detail和Therm对象以及一个双精度浮点数管道中的气体速度
* 返回值 : double
* 功能 : 计算C*
* 修订 :
**************************************************************************/
double Crit(AGA10STRUCT *ptAGA10, double dPlenumVelocity)
{
// 函数局部变量
double DH, DDH, S, H;
double tolerance = 1.0;
double R, P, T, Z;
int i;
// 检查对象是否就绪;如果未就绪则尝试初始化
if (NULL == ptDetail || NULL == ptTherm)
{
NGCal_UnInit();
if (AGA10_INITIALIZED != NGCal_Init())
{
ptAGA10->lStatus = MEMORY_ALLOCATION_ERROR;
return 0.0;
}
}
// 首先计算密度和热力学性质
ptTherm->Run(ptTherm,ptAGA10, ptDetail);
// DH是从管道到喉部的焓变这是我们的初始猜测值
DH = (ptAGA10->dSOS * ptAGA10->dSOS - dPlenumVelocity * dPlenumVelocity) / 2.0;
// 在我们改变数据结构内容之前捕获管道条件
S = ptAGA10->dS;
H = ptAGA10->dH;
R = ptAGA10->dRhof;
P = ptAGA10->dPf;
Z = ptAGA10->dZf;
T = ptAGA10->dTf;
// 将DH的增量初始化为超出收敛容差的任意值
DDH = 10.0;
// 通过简单重复,搜索喷嘴喉部的压力、温度和声速,
// 在给定管道熵的情况下提供恒定焓。
// 如果循环执行超过100次仍未收敛则中止。
for (i = 1; i < MAX_NUM_OF_ITERATIONS; i++)
{
// 计算满足H和S的P和T
ptTherm->HS_Mode(ptTherm,ptAGA10, ptDetail, H - DH, S, true);
// 计算新的热力学性质包括SOS
ptTherm->Run(ptTherm,ptAGA10, ptDetail);
// 保存DH用于容差检查
DDH = DH;
// 重新计算DH
DH = (ptAGA10->dSOS * ptAGA10->dSOS - dPlenumVelocity * dPlenumVelocity) / 2.0;
// 如果达到容差则结束循环
if (fabs(DDH - DH) < tolerance) break;
}
// C*是真实气体临界流常数不要与Cperf或CRi混淆
ptAGA10->dCstar = (ptAGA10->dRhof * ptAGA10->dSOS) / sqrt(R * P * Z);
// 恢复原始管道压力和温度
ptAGA10->dPf = P;
ptAGA10->dTf = T;
// 将流体属性恢复为管道条件
ptTherm->Run(ptTherm,ptAGA10, ptDetail);
// 返回临界流函数给调用者
return ptAGA10->dCstar;
}
/**************************************************************************
* 函数 : Cperf()
* 参数 : 指向外部AGA10数据结构的指针
* 返回值 : double
* 功能 : 计算等熵完美气体临界流函数
* 修订 :
**************************************************************************/
double Cperf(AGA10STRUCT *ptAGA10)
{
double k, root, exponent;
k = ptAGA10->dKappa;
root = 2.0 / (k + 1.0);
exponent = (k + 1.0) / (k - 1.0);
// 等熵完美气体临界流函数C*i
return(sqrt(k * pow(root, exponent)));
}
/**************************************************************************
* 函数 : CRi()
* 参数 : 指向外部AGA10数据结构的指针
* 返回值 : double
* 功能 : 计算等熵真实气体临界流函数CRi
* 修订 :
**************************************************************************/
double CRi(AGA10STRUCT *ptAGA10)
{
return (Cperf(ptAGA10) / sqrt(ptAGA10->dZf));
}