222 lines
5.8 KiB
C++
222 lines
5.8 KiB
C++
|
|
/*************************************************************************
|
|
* File: aga10.cpp
|
|
* Description: Manages overall process of calculating speed of sound
|
|
* or C*; creates and uses objects based on Detail and Therm classes
|
|
* Contains the following functions:
|
|
* AGA10_Init(), AGA10_UnInit(), SOS(), Crit(), Cperf(), CRi()
|
|
* Version: ver 1.7 2002.11.17
|
|
* Author: W.B. Peterson
|
|
*Revisions:
|
|
*Copyright (c) 2002 American Gas Association
|
|
|
|
**************************************************************************/
|
|
|
|
#include "aga10.h" #include "therm.h" #include "detail.h" #include "math.h"
|
|
|
|
|
|
//Create file-scope pointers to objects we will need; one of Therm class
|
|
|
|
//and one of Detail class.
|
|
|
|
static Therm *ptTherm ; static Detail *ptDetail ;
|
|
|
|
/**************************************************************************
|
|
|
|
* Function : AGA10_Init()
|
|
* Arguments : void
|
|
* Returns : int
|
|
* Purpose : Initializes library; creates required objects
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
int AGA10_Init(void)
|
|
|
|
{
|
|
//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 AGA10_INITIALIZED ;
|
|
|
|
}// AGA10_Init
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
* Function : AGA10_UnInit()
|
|
* Arguments : void
|
|
* Returns : int
|
|
* Purpose : Un-initializes library; deletes objects
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
int AGA10_UnInit(void)
|
|
|
|
{
|
|
// delete the objects (if they exist) if (ptDetail) delete ptDetail ;
|
|
if (ptTherm) delete ptTherm ; return 0 ;
|
|
|
|
}// AGA10_UnInit
|
|
|
|
|
|
/**************************************************************************
|
|
* Function : SOS()
|
|
* Arguments : Pointers to external AGA10 data struct
|
|
* Returns : double
|
|
* Purpose : calculates speed of sound and other parameters
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
double SOS(AGA10STRUCT *ptAGA10)
|
|
|
|
{
|
|
// check if library is ready; initialize if necessary if (NULL == ptDetail || NULL == ptTherm)
|
|
|
|
{
|
|
AGA10_UnInit() ;
|
|
AGA10_Init() ;
|
|
|
|
}
|
|
|
|
//Call function to calculate densities and thermodynamic properties ptTherm->Run(ptAGA10, 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 :
|
|
**************************************************************************/
|
|
|
|
double Crit(AGA10STRUCT *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)
|
|
|
|
{
|
|
AGA10_UnInit() ;
|
|
|
|
if (AGA10_INITIALIZED != AGA10_Init())
|
|
{
|
|
|
|
ptAGA10->lStatus = MEMORY_ALLOCATION_ERROR ; return 0.0 ;
|
|
|
|
}
|
|
}
|
|
|
|
//begin by calculating densities and thermodynamic properties ptTherm->Run(ptAGA10, 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(ptAGA10, ptDetail, H - DH, S, true) ;
|
|
|
|
//calculate new thermo, including SOS ptTherm->Run(ptAGA10, 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 (fabs(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) / 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(ptAGA10, ptDetail) ;
|
|
|
|
//return the critical flow function to caller return ptAGA10->dCstar ;
|
|
|
|
}// Crit()
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
* Function : Cperf()
|
|
* Arguments : pointer to external AGA10 data struct
|
|
* Returns : double
|
|
* Purpose : calculates isentropic perfect gas critical flow function
|
|
* Revisions :
|
|
**************************************************************************/
|
|
|
|
double Cperf(AGA10STRUCT *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(sqrt(k * 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(AGA10STRUCT *ptAGA10)
|
|
|
|
{
|
|
|
|
return (Cperf(ptAGA10) / sqrt(ptAGA10->dZf)) ;
|
|
}// CRi()
|