(iapws95/contrib/libSBTL/SBTL.h)
///////////////////////////////////////////////////////////////////////////
// LibSBTL_vu_95 - SBTL library based on IAPWS-95.
//
// Copyright (C) Zittau/Goerlitz University of Applied Sciences (2015).
// All rights reserved.
//
// License:
//
// This software (source code) is provided and licensed to the Idaho National Laboratory (INL) under the following conditions:
// 1) INL is allowed to use the LibSBTL_vu_95 source code in RELAP-7 or BISON software, including internal research codes that are not distributed outside INL, and to modify it to meet INL requirements.
// 2) INL is allowed to redistribute the source code of the property library LibSBTL_vu_95 along with the RELAP-7 or BISON source code to RELAP 7 or BISON licensees.
// 3) The licensees of RELAP-7 or BISON are allowed to use the library LibSBTL_vu_95 in RELAP-7 or BISON only. A redistribution of the source code of LibSBTL_vu_95 or parts of it to third parties is not allowed.
// For more information please refer to the license information of RELAP-7 or BISON.
//
// Disclaimer:
// The Zittau/Goerlitz University of Applied Sciences (HSZG) uses its best efforts to deliver a high-quality software and to verify that the computed information is correct. However, HSZG makes no warranties to that effect, and HSZG shall not be liable for any damage that may result from errors or omissions in the software.
//
// Citation:
// M. Kunick, H.-J. Kretzschmar,
// Property Library LibSBTL_vu_95 for Water and Steam according to the IAPWS Guideline on the Fast Calculation of Steam and Water Properties with the Spline-Based Table Look-Up Method (SBTL) based on the Scientific Formulation IAPWS-95 and Current IAPWS Formulations for Transport Properties,
// Zittau/Goerlitz University of Applied Sciences, Department of Technical Thermodynamics, Zittau, Germany (2015).
//
// Version: 0.9.5
//
// SBTL
//
#include "math.h"
//
#pragma once
//
//-----------------------------------------------------------------------------
// return values (error flags)
//-----------------------------------------------------------------------------
//
#ifndef NAN
#define NAN (1.0/0.0)
#endif
#define ERR_VAL NAN
#define I_OK 0
#define I_ERR 1
//
//-----------------------------------------------------------------------------
// region flags
//-----------------------------------------------------------------------------
//
#define IREG_ERR 0
#define IREG_L 1
#define IREG_G 2
#define IREG_TP 3
//
//-----------------------------------------------------------------------------
// struct states
//-----------------------------------------------------------------------------
//
//known properties:
#define STR_ERR 0 // - none (needs to be initialized with ireg-call)
#define STR_PDP 1 // - region
// - auxiliary variables for property calculations (single-phase region & two-phase region)
// - auxiliary variables for derivatives in the single-phase region
#define STR_DTP 2 // - all above
// - auxiliary variables for derivatives in the two-phase region (calculated if required, preserved for multiple use)
//
//-----------------------------------------------------------------------------
// structs to handle preliminary results and auxiliary variables:
//-----------------------------------------------------------------------------
//
///////////////////////////////////////////////////////////////////////////////
// - auxiliary variables of first derivatives (liquid)
///////////////////////////////////////////////////////////////////////////////
//
typedef struct _DERIV_1 {
double x1tmin; //v(u)_min - 100 MPa isobar (with a small offset which is 0.995 for p(v,u), t(v,u) and 0.993 for all other variables)
double x1tmax; //v(u)_max - liquid spinodal
double dvdu_vt; //(dv/du)_vt
double K; //slope of scaling function: (x1zmax-x1zmin)/(x1tmax-x1tmin)
// constructor
_DERIV_1() { reset();}
// reset
void reset() {
x1tmin =ERR_VAL;
x1tmax =ERR_VAL;
dvdu_vt =ERR_VAL;
K =ERR_VAL;
}
} DERIV_1;
//
///////////////////////////////////////////////////////////////////////////////
// - auxiliary variables of first and second derivatives (liquid)
///////////////////////////////////////////////////////////////////////////////
//
typedef struct _DERIV_2 {
double x1tmin; //v(u)_min
double dvdu_min; //(dv/du)_min
double d2vdu2_min; //(d2v/du2)_min
double x1tmax; //v(u)_max
double dvdu_max; //(dv/du)_max
double d2vdu2_max; //(d2v/du2)_max
double dvtdu_v; //(dvt/du)_v
double dvdu_vt; //(dv/du)_vt
double K; //(x1zmax-x1zmin)/(x1tmax-x1tmin)
double d2vtdu2_v; //(d2vt/du2)_v
double d2vtdvdu; //(d2vt/dvdu)
// constructor
_DERIV_2() { reset();}
// reset
void reset() {
x1tmin =ERR_VAL;
dvdu_min =ERR_VAL;
d2vdu2_min =ERR_VAL;
x1tmax =ERR_VAL;
dvdu_max =ERR_VAL;
d2vdu2_max =ERR_VAL;
dvtdu_v =ERR_VAL;
dvdu_vt =ERR_VAL;
K =ERR_VAL;
d2vtdu2_v =ERR_VAL;
d2vtdvdu =ERR_VAL;
}
} DERIV_2;
//
///////////////////////////////////////////////////////////////////////////////
// - derivatives in the two-phase region
///////////////////////////////////////////////////////////////////////////////
//
typedef struct _DERIV_TP {
double ps_; //values below computed for this
double x_; //state point
double dtsdp; //dts/dp
double dvldp; //dv'/dp
double dvvdp; //dv"/dp
double duldp; //du'/dp
double duvdp; //du"/dp
double dxdp_v; //(dx/dp)_v
double dxdp_u; //(dx/dp)_u
double dpdv_u; //(dp/dv)_u
double dpdu_v; //(dp/du)_v
double dtdv_u; //(dt/dv)_u
double dtdu_v; //(dt/du)_v
double dudv_pt; //(du/dv)_p = (du/dv)_t
// constructor
_DERIV_TP() { reset();}
// reset
void reset() {
ps_ =ERR_VAL;
x_ =ERR_VAL;
dtsdp =ERR_VAL;
dvldp =ERR_VAL;
dvvdp =ERR_VAL;
duldp =ERR_VAL;
duvdp =ERR_VAL;
dxdp_v =ERR_VAL;
dxdp_u =ERR_VAL;
dpdv_u =ERR_VAL;
dpdu_v =ERR_VAL;
dtdv_u =ERR_VAL;
dtdu_v =ERR_VAL;
dudv_pt=ERR_VAL;
}
//
bool IsCalculated(double ps, double x) {
//if(ps_>0. && x_>0. && ps_==ps && x_==x) {
if(ps_==ps && x_==x) {
return true;
} else {
reset();
return false;
}
}
} DERIV_TP;
//
///////////////////////////////////////////////////////////////////////////////
// - struct to be used by ireg_vu_SBTL95 (DERIV_TP d_tp is used by DIFF_SAT_VU_SPL95 directly)
// - this is also used by ireg_pv_SBTL95 and ireg_ps_SBTL95
///////////////////////////////////////////////////////////////////////////////
//
typedef struct _STR_vu_SBTL95 {
//
double v_; //values below computed for this
double u_; //state point
double p_; //check p_,v_ for given (p,v), p_,s_ for given (p,s), and p_,h_ for given (p,h)
double h_; //check p_,h_ for given (p,h) and h_,s_ for given (h,s)
double s_; //check p_,s_ for given (p,s) and h_,s_ for given (h,s)
//
int ireg; //region flag (see above)
double vls_pt; //scaled volume (liquid phase only: for p,t)
double vls_z; //scaled volume (liquid phase only: for remaining properties)
#ifndef SBTL_USE_C_AUX
DERIV_2 dpt_l; //1st and 2nd derivatives of p and t are required to calculate cp, cv, and their derivatives (liquid phase only)
#else
DERIV_1 dpt_l; //derivatives of p and t are required to calculate cp, cv (liquid phase only)
#endif
DERIV_1 dz_l; //derivatives of z (liquid phase only)
double vt; //transformed volume (gas phase only)
double ps; //saturation pressure (two-phase region only)
double ts; //saturation temperature (two-phase region only)
double x; //vapor fraction (two-phase region only)
double v1; //sat. liquid volume (two-phase region only)
double v1s_pt; //scaled sat. liquid volume (two-phase region only: for p,t)
double v1s_z; //scaled sat. liquid volume (two-phase region only: remaining properties)
#ifndef SBTL_USE_C_AUX
DERIV_2 dpt_1; //1st and 2nd derivatives of p and t are required to calculate cp1, cv1, and their derivatives (two-phase region only)
#else
DERIV_1 dpt_1; //sat. liquid: derivatives of p and t are required to calculate cp1, cv1 (two-phase region only)
#endif
DERIV_1 dz_1; //sat. liquid: derivatives of z (two-phase region only)
double v2; //sat. vapor volume (two-phase region only)
double v2t; //transf. sat. vapor volume (two-phase region only)
double u1; //sat. liquid int. energy (two-phase region only)
double u2; //sat. vapor int. energy (two-phase region only)
DERIV_TP d_tp; //derivatives in two-phase region
// constructor
_STR_vu_SBTL95() { reset();}
// reset
void reset() {
v_ =ERR_VAL;
u_ =ERR_VAL;
p_ =ERR_VAL;
h_ =ERR_VAL;
s_ =ERR_VAL;
//
ireg =IREG_ERR;
vls_pt =ERR_VAL;
vls_z =ERR_VAL;
vt =ERR_VAL;
ps =ERR_VAL;
ts =ERR_VAL;
x =ERR_VAL;
v1 =ERR_VAL;
v1s_pt =ERR_VAL;
v1s_z =ERR_VAL;
v2 =ERR_VAL;
v2t =ERR_VAL;
u1 =ERR_VAL;
u2 =ERR_VAL;
}
//
int GetState(double v, double u) {
if(v_==v && u_==u) {
if(ireg==IREG_TP) {
if(d_tp.IsCalculated(ps,x)) return STR_DTP;
else return STR_PDP;
} else {
return STR_PDP;
}
} else {
reset();
return STR_ERR;
}
}
//
int GetStatePV(double p, double v) {
if(p_==p && v_==v) {
if(ireg==IREG_TP) {
if(d_tp.IsCalculated(ps,x)) return STR_DTP;
else return STR_PDP;
} else {
return STR_PDP;
}
} else {
reset();
return STR_ERR;
}
}
//
int GetStatePS(double p, double s) {
if(p_==p && s_==s) {
if(ireg==IREG_TP) {
if(d_tp.IsCalculated(ps,x)) return STR_DTP;
else return STR_PDP;
} else {
return STR_PDP;
}
} else {
reset();
return STR_ERR;
}
}
//
int GetStatePH(double p, double h) {
if(p_==p && h_==h) {
if(ireg==IREG_TP) {
if(d_tp.IsCalculated(ps,x)) return STR_DTP;
else return STR_PDP;
} else {
return STR_PDP;
}
} else {
reset();
return STR_ERR;
}
}
//
int GetStateHS(double h, double s) {
if(h_==h && s_==s) {
if(ireg==IREG_TP) {
if(d_tp.IsCalculated(ps,x)) return STR_DTP;
else return STR_PDP;
} else {
return STR_PDP;
}
} else {
reset();
return STR_ERR;
}
}
//
int GetStateVH(double v, double h) {
if(v_==v && h_==h) {
if(ireg==IREG_TP) {
if(d_tp.IsCalculated(ps,x)) return STR_DTP;
else return STR_PDP;
} else {
return STR_PDP;
}
} else {
reset();
return STR_ERR;
}
}
} STR_vu_SBTL95;
//
///////////////////////////////////////////////////////////////////////////////
// - struct to be used by ireg_vu_SBTL95M
// - this is also used by ireg_pv_SBTL95M and ireg_ps_SBTL95M
///////////////////////////////////////////////////////////////////////////////
//
typedef struct _STR_vu_SBTL95M {
//
double v_; //values below computed for this
double u_; //state point
double p_; //check p_,v_ for given (p,v), p_,s_ for given (p,s), and p_,h_ for given (p,h)
double h_; //check p_,h_ for given (p,h) and h_,s_ for given (h,s)
double s_; //check p_,s_ for given (p,s) and h_,s_ for given (h,s)
//
int ireg; //region flag (see above)
double vls_pt; //scaled volume (liquid phase only: for p,t)
double vls_z; //scaled volume (liquid phase only: for remaining properties)
#ifndef SBTL_USE_C_AUX
DERIV_2 dpt_l; //1st and 2nd derivatives of p and t are required to calculate cp, cv, and their derivatives (liquid phase only)
#else
DERIV_1 dpt_l; //derivatives of p and t are required to calculate cp, cv (liquid phase only)
#endif
DERIV_1 dz_l; //derivatives of z (liquid phase only)
double vt; //transformed volume (gas phase only)
// constructor
_STR_vu_SBTL95M() { reset();}
// reset
void reset() {
v_ =ERR_VAL;
u_ =ERR_VAL;
p_ =ERR_VAL;
h_ =ERR_VAL;
s_ =ERR_VAL;
//
ireg =IREG_ERR;
vls_pt =ERR_VAL;
vls_z =ERR_VAL;
vt =ERR_VAL;
}
//
int GetState(double v, double u) {
if(v_==v && u_==u) {
return STR_PDP;
} else {
return STR_ERR;
}
}
//
int GetStatePV(double p, double v) {
if(p_==p && v_==v) {
return STR_PDP;
} else {
reset();
return STR_ERR;
}
}
//
int GetStatePS(double p, double s) {
if(p_==p && s_==s) {
return STR_PDP;
} else {
reset();
return STR_ERR;
}
}
//
int GetStatePH(double p, double h) {
if(p_==p && h_==h) {
return STR_PDP;
} else {
reset();
return STR_ERR;
}
}
//
int GetStateHS(double h, double s) {
if(h_==h && s_==s) {
return STR_PDP;
} else {
reset();
return STR_ERR;
}
}
//
int GetStateVH(double v, double h) {
if(v_==v && h_==h) {
return STR_PDP;
} else {
reset();
return STR_ERR;
}
}
} STR_vu_SBTL95M;
//