├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── bin └── .gitignore ├── demo ├── ExcelVBA │ ├── README.md │ ├── app_template_seuif97.xlsm │ ├── img │ │ ├── demo_module.jpg │ │ └── import_module.jpg │ └── seuif97.bas ├── MATLAB64 │ ├── README.md │ ├── demo_seuif97.m │ └── seuif97 │ │ ├── libseuif97.dll │ │ ├── seuif97.h │ │ └── seuif97.m ├── README.md ├── demo-c │ ├── README.md │ ├── Turbine_H-S.cpp │ ├── demo.c │ └── include │ │ └── seuif97.h ├── demo-csharp │ ├── demo_seuif97.cs │ └── seuif97.cs ├── demo-fortran │ ├── demo.f08 │ └── seuif97.f08 ├── demo-go │ ├── demo.go │ └── seuif97.h ├── demo-java │ ├── demoseuif97.java │ ├── jna.jar │ └── seuif97.java ├── demo-modelica │ ├── demo_seuif97.mo │ └── demomodelica │ │ ├── demo.mo │ │ ├── package.mo │ │ ├── package.order │ │ └── seuif97.mo ├── demo-pascal │ ├── demo.pas │ └── seuif97.pas ├── demo-python │ ├── Diagram_H-S.py │ ├── Diagram_T-S.py │ ├── README.md │ ├── Turbine_H-S.py │ ├── demo_seuif97.py │ ├── img │ │ ├── T-S.jpg │ │ └── turbine_expansion_line.jpg │ └── seuif97.py └── demo-rust │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ ├── main.rs │ └── seuif97.rs ├── doc ├── 基于最短加法链状态空间树的IAPWS-IF97快速计算方法.pdf └── 水和水蒸汽热力性质IAPWS-IF97公式的通用计算模型.pdf ├── makefile ├── shared_lib ├── Linux │ └── x64 │ │ └── libseuif97.so └── Windows │ ├── x64 │ ├── libseuif97.def │ ├── libseuif97.dll │ └── libseuif97.lib │ └── x86 │ ├── libseuif97.def │ ├── libseuif97.dll │ └── libseuif97.lib ├── src ├── algo │ ├── algorithm.h │ ├── polynomial.c │ ├── polynomial_solo.c │ ├── root.c │ ├── rqm.c │ └── sac.c ├── common │ ├── boundaries.c │ ├── common.h │ ├── constand.h │ ├── propertry_id.h │ ├── propertry_pair.c │ ├── region.c │ ├── seuif97.c │ ├── seuif97.h │ ├── thermodynamic_process.c │ └── transport.c ├── r1 │ ├── region1.h │ ├── region1_T_phps.c │ ├── region1_coff.h │ ├── region1_gfe.c │ ├── region1_out.c │ ├── region1_pT.c │ ├── region1_pT_ext.c │ ├── region1_p_hs.c │ ├── region1_pair.ext.c │ ├── region1_solo_ij.h │ └── region1_solo_power.c ├── r2 │ ├── region2.h │ ├── region2_T_ph.c │ ├── region2_T_ps.c │ ├── region2_coff.h │ ├── region2_gfe.c │ ├── region2_out.c │ ├── region2_pT.c │ ├── region2_pT_ext.c │ ├── region2_p_hs.c │ ├── region2_pair.ext.c │ ├── region2_solo_ij.h │ └── region2_solo_power.c ├── r3 │ ├── region3.h │ ├── region3_Td.c │ ├── region3_Td_ext.c │ ├── region3_Tv_phps.c │ ├── region3_coff.h │ ├── region3_hfe.c │ ├── region3_out.c │ ├── region3_p_hs.c │ ├── region3_pair.ext.c │ ├── region3_solo_ij.h │ ├── region3_solo_power.c │ ├── region3_v_pT.c │ └── region3_v_pT_subregion_.c ├── r4 │ ├── region4.h │ ├── region4_T_hs.c │ ├── region4_hxsx.c │ ├── region4_out.c │ ├── region4_pair_ext.c │ └── region4_sat_pT.c └── r5 │ ├── region5.h │ ├── region5_coff.h │ ├── region5_gfe.c │ ├── region5_out.c │ ├── region5_pT.c │ ├── region5_pT_ext.c │ ├── region5_pair.ext.c │ └── region5_ph_ps_hs.c ├── test ├── if97_data.h ├── makefile ├── test_hs.c ├── test_hxsx.c ├── test_ph.c ├── test_process.c ├── test_ps.c ├── test_pt.c ├── test_pv.c ├── test_th.c ├── test_ts.c └── test_tv.c └── unity ├── unity.c ├── unity.h └── unity_internals.h /.gitignore: -------------------------------------------------------------------------------- 1 | /demo/demo-python/__pycache__ 2 | /build 3 | *.exe 4 | *.class 5 | *.o 6 | *.mod -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5.0) 2 | 3 | project(seuif97 VERSION 0.1.0) 4 | 5 | include_directories(./src/common ./src/algo ./src/r1 ./src/r2 ./src/r3 ./src/r4 ./src/r5 ) 6 | 7 | aux_source_directory(./src/common/ SRC_COM) 8 | aux_source_directory(./src/algo/ SRC_ALGO) 9 | aux_source_directory(./src/r1/ SRC_R1) 10 | aux_source_directory(./src/r2/ SRC_R2) 11 | aux_source_directory(./src/r3/ SRC_R3) 12 | aux_source_directory(./src/r4/ SRC_R4) 13 | aux_source_directory(./src/r5/ SRC_R5) 14 | if (MSVC) 15 | set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) 16 | endif() 17 | add_library(seuif97 SHARED ${SRC_COM} ${SRC_ALGO} ${SRC_R1} ${SRC_R2} ${SRC_R3} ${SRC_R4} ${SRC_R5}) 18 | 19 | set(EXE_SOURCES ./demo/demo-c/demo.c) 20 | add_executable(demo ${EXE_SOURCES}) 21 | target_include_directories(demo PRIVATE ${PROJECT_SOURCE_DIR}/demo/demo-c/include) 22 | target_link_libraries(demo PRIVATE seuif97) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2023 Cheng Maohua 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore -------------------------------------------------------------------------------- /demo/ExcelVBA/README.md: -------------------------------------------------------------------------------- 1 | # Using SEUIF97 in Excel 2 | 3 | **The Dynamic Library** 4 | 5 | copy `libseuif97.dll` in the [Windows/x86](../../shared_lib/Windows/x86) or [Windows/x64](../../shared_lib/Windows/x64) folder to a default path of Windows32/64's DLL : `C:\Windows\system` 6 | 7 | **Excel workbook** 8 | 9 | You can choose one of the following two methods to start your Excel workbook 10 | 11 | * use [app_template_seuif97.xlsm](./app_template_seuif97.xlsm) file with `seuif97.bas` inside to start your work directly

12 | 13 | 14 | * import `seuif97.bas` to the Excel workbook without macro

15 | 16 | Press `ALT+F11`, then `File` ->` Import File` [seuif97.bas](./seuif97.bas) into the workbook 17 | 18 | ![import_module](./img/import_module.jpg) 19 | 20 | after that, use `seuif97` in the cells 21 | 22 | ![demo_module](./img/demo_module.jpg) 23 | 24 | -------------------------------------------------------------------------------- /demo/ExcelVBA/app_template_seuif97.xlsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/demo/ExcelVBA/app_template_seuif97.xlsm -------------------------------------------------------------------------------- /demo/ExcelVBA/img/demo_module.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/demo/ExcelVBA/img/demo_module.jpg -------------------------------------------------------------------------------- /demo/ExcelVBA/img/import_module.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/demo/ExcelVBA/img/import_module.jpg -------------------------------------------------------------------------------- /demo/MATLAB64/README.md: -------------------------------------------------------------------------------- 1 | # The Interface for MATLAB(Windows64) 2 | 3 | * copy the folder `\seuif97` in `MATLAB64` to the path `\extern` of the installed MATLAB 4 | 5 | For example,if MATLAB 2018a is installed : `C:\Program Files\MATLAB\R2018a\extern\` 6 | 7 | * Add the path `C:\Program Files\MATLAB\R2018a\extern\seuif97` to the Search Path of MATLAB -------------------------------------------------------------------------------- /demo/MATLAB64/demo_seuif97.m: -------------------------------------------------------------------------------- 1 | % The demo using libseuif97 in MATLAB for Windows 64 2 | % 3 | % 1 Put the following files in the path `\extern\seuif97` of the installed MATLAB 4 | % 5 | % libseuif97.dll 6 | % seuif97.h 7 | % seuif97.m 8 | % 9 | % 2 Add the path to the Search Path of MATLAB 10 | % 11 | % License: this code is in the public domain 12 | % 13 | % Author: Cheng Maohua 14 | % Email: cmh@seu.edu.cn 15 | % 16 | % Last modified: 2019.01.08 17 | % 18 | 19 | myfuns = seuif97; 20 | p=18.0; 21 | t=535; 22 | h=myfuns.pt(p,t,4); 23 | s=myfuns.pt(p,t,5); 24 | v=myfuns.pt(p,t,3); 25 | fprintf('(p,t),h,s,v: %.2f,%.2f,%.2f,%.4f,%.4f\n',p,t,h,s,v); 26 | -------------------------------------------------------------------------------- /demo/MATLAB64/seuif97/libseuif97.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/demo/MATLAB64/seuif97/libseuif97.dll -------------------------------------------------------------------------------- /demo/MATLAB64/seuif97/seuif97.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is header file of SEUIF97 3 | 4 | Author: Cheng Maohua 5 | Email: cmh@seu.edu.cn 6 | 7 | */ 8 | 9 | #ifndef SEUIF97_H 10 | #define SEUIF97_H 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #ifdef WIN32 17 | 18 | #define IMPORT __declspec(dllimport) double __stdcall 19 | 20 | #else 21 | 22 | #define IMPORT double 23 | 24 | #endif 25 | 26 | IMPORT pt(double p, double t, int o_id); 27 | IMPORT ph(double p, double h, int o_id); 28 | IMPORT ps(double p, double s, int o_id); 29 | IMPORT pv(double p, double v, int o_id); 30 | 31 | IMPORT th(double t, double h, int o_id); 32 | IMPORT ts(double t, double s, int o_id); 33 | IMPORT tv(double t, double v, int o_id); 34 | 35 | IMPORT hs(double h, double s, int o_id); 36 | 37 | IMPORT px(double p, double x, int o_id); 38 | IMPORT tx(double t, double x, int o_id); 39 | 40 | IMPORT hx(double h, double x, int o_id); 41 | IMPORT sx(double s, double x, int o_id); 42 | 43 | // Thermodynamic Process of Steam Turbine 44 | IMPORT ishd(double pi, double ti, double pe); 45 | IMPORT ief(double pi, double ti, double pe, double te); 46 | 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /demo/MATLAB64/seuif97/seuif97.m: -------------------------------------------------------------------------------- 1 | 2 | % The interface of libseuif97 to MATLAB for Windows 64 3 | % 4 | % 1 Put the following files in the path `\extern\seuif97` of the installed MATLAB% 5 | % 6 | % libseuif97.dll 7 | % seuif97.h 8 | % seuif97.m 9 | % 10 | % 2 Add the path to the Search Path of MATLAB 11 | % 12 | % License: this code is in the public domain 13 | % 14 | % Author: Cheng Maohua 15 | % Email: cmh@seu.edu.cn 16 | % 17 | % Last modified: 2019.01.08 18 | % 19 | 20 | function funs = seuif97 21 | if ~libisloaded('libseuif97') 22 | loadlibrary('libseuif97.dll','if97.h') 23 | end 24 | funs.pt=@pt; 25 | funs.ph=@ph; 26 | funs.ps=@ps; 27 | funs.pv=@pv; 28 | 29 | funs.th=@th; 30 | funs.ts=@ts; 31 | funs.tv=@tv; 32 | 33 | funs.hs=@hs; 34 | 35 | funs.px=@px; 36 | funs.tx=@tx; 37 | 38 | funs.hx=@hx; 39 | funs.sx=@sx; 40 | 41 | funs.ishd=@ishd; 42 | funs.ief=@ief; 43 | 44 | end 45 | 46 | function f=pt(p,t,wid) 47 | f=calllib('libseuif97', 'pt', p,t,wid); 48 | end 49 | 50 | function f=ph(p,h,wid) 51 | f=calllib('libseuif97', 'ph', p,h,wid); 52 | end 53 | 54 | function f=ps(p,s,wid) 55 | f=calllib('libseuif97', 'ps', p,s,wid); 56 | end 57 | 58 | function f=pv(p,v,wid) 59 | f=calllib('libseuif97', 'ph', p,v,wid); 60 | end 61 | 62 | function f=th(t,h,wid) 63 | f=calllib('libseuif97', 'th', t,h,wid); 64 | end 65 | 66 | function f=ts(t,s,wid) 67 | f=calllib('libseuif97', 'ts', t,s,wid); 68 | end 69 | 70 | function f=tv(t,v,wid) 71 | f=calllib('libseuif97', 'th', t,v,wid); 72 | end 73 | 74 | function f=hs(h,s,wid) 75 | f=calllib('libseuif97', 'hs', h,s,wid); 76 | end 77 | 78 | function f=px(p,x,wid) 79 | f=calllib('libseuif97', 'px', p,x,wid); 80 | end 81 | 82 | function f=tx(t,x,wid) 83 | f=calllib('libseuif97', 'tx', t,x,wid); 84 | end 85 | 86 | function f=hx(h,x,wid) 87 | f=calllib('libseuif97', 'hx', t,x,wid); 88 | end 89 | 90 | function f=sx(s,x,wid) 91 | f=calllib('libseuif97', 'sx', t,x,wid); 92 | end 93 | 94 | function f=ishd(pi,ti,pe) 95 | f=calllib('libseuif97', 'ishd', pi,ti,pe); 96 | end 97 | 98 | function f=ief(pi,ti,pe,te) 99 | f=calllib('libseuif97', 'ief', pi,ti,pe,te); 100 | end 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # Interfaces and Examples 2 | 3 | | Language | Interface | 4 | |:----------------------------------:|:-------------------------------------------------| 5 | | [C/C++](./demo-c) | [seuif97.h](./demo-c/include/seuif97.h) | 6 | | [Python](./demo-python) | [seuif97.py](./demo-python/seuif97.py) | 7 | | [C#](./demo-csharp) | [seuif97.cs](./demo-csharp/seuif97.cs) | 8 | | [Excel VBA](./ExcelVBA) | [seuif97.bas](./ExcelVBA/seuif97.bas) | 9 | | [Java](./demo-java) | [seuif97.java](./demo-java/seuif97.java) | 10 | | [MATLAB64](./MATLAB64) | [seuif97.m](./MATLAB64/seuif97/seuif97.m) | 11 | | [Rust](./demo-rust) | [seuif97.rs](./demo-rust/src/seuif97.rs) | 12 | | [Fortran](./demo-Fortran) | [seuif97.f08](./demo-fortran/seuif97.f08) | 13 | | [Pascal](./demo-pascal) | [seuif97.pas](./demo-pascal/seuif97.pas) | 14 | | [Modelica](./demo-modelica) | [seuif97.mo](./demo-modelica/demomodelica/seuif97.mo) | 15 | | [Golang](./demo-go) | **Example** [demo.go](./demo-go/demo.go) | 16 | 17 | You can modify these interfaces provided in the repository to your own APIs. -------------------------------------------------------------------------------- /demo/demo-c/README.md: -------------------------------------------------------------------------------- 1 | # Using SEUIF97 with C/C++ 2 | 3 | ## SEUIF97 4 | 5 | 1. dynamic library: 6 | * Windows `C:/Windows/system/libseuif97.dll` 7 | * Linux `./usr/lib/libseuif97.so` 8 | 2. header file: `./include/seuif97.h` 9 | 10 | ## Examples 11 | 12 | * [demo.c](./demo.c) 13 | 14 | * [H-S(Mollier) Diagram of Steam Turbine Expansion](./Turbine_H-S.cpp) 15 | -------------------------------------------------------------------------------- /demo/demo-c/Turbine_H-S.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | H-S(Mollier) Diagram of Steam Turbine Expansion 3 | 4 | using Gnuplot 5 | 6 | seuif97's lib and header file 7 | 1 Windows: libseuif97.dll 8 | 2 Linux: libseuif97.so 9 | 3 seuif97.h 10 | 11 | 4 lines: 12 | 1 Isobar line:p inlet 13 | 2 Isobar line:p outlet 14 | 3 isentropic line: (p inlet ,t inlet h inlet,s inlet), (p outlet,s inlet) 15 | 4 Expansion line: inlet,outlet 16 | 17 | Build using GCC: 18 | 19 | Windows: 20 | g++ -o turbine Turbine_H-S.cpp -LC:/Windows/system/ -lseuif97 -I./include 21 | 22 | Linux: 23 | g++ -o turbine Turbine_H-S.cpp -L/usr/lib -lseuif97 -lm -I./include 24 | 25 | Run: 26 | ./turbine 27 | 28 | Author: Cheng Maohua 29 | Email: cmh@seu.edu.cn 30 | */ 31 | 32 | #include 33 | #include 34 | #include "seuif97.h" 35 | 36 | using namespace std; 37 | 38 | struct wmstatus 39 | { 40 | double p, t, h, s; 41 | }; 42 | 43 | class Turbine 44 | { 45 | private: 46 | double his; 47 | 48 | public: 49 | wmstatus win, wex; 50 | double ef; 51 | 52 | Turbine(double pin, double tin, double pex, double tex); 53 | void analysis(void); 54 | void output(void); 55 | void expansionline(void); 56 | }; 57 | 58 | Turbine::Turbine(double pin, double tin, double pex, double tex) 59 | { 60 | win.p = pin; 61 | win.t = tin; 62 | wex.p = pex; 63 | wex.t = tex; 64 | } 65 | 66 | void Turbine::analysis(void) 67 | { 68 | ef = ief(win.p, win.t, wex.p, wex.t); 69 | his = ishd(win.p, win.t, wex.p); 70 | 71 | win.h =pt(win.p, win.t, 4); 72 | win.s =pt(win.p, win.t, 5); 73 | 74 | wex.h =pt(wex.p, wex.t, 4); 75 | wex.s =pt(wex.p, wex.t, 5); 76 | }; 77 | 78 | void Turbine::output(void) 79 | { 80 | cout << "(Pin,Tin) = (" << win.p << "," << win.t << ")" << endl; 81 | cout << "(Pex,Tex) = (" << wex.p << "," << wex.t << ")" << endl; 82 | cout << "The isentropic efficiency = " << setiosflags(ios::fixed) << setprecision(2) << ef << "%" << endl; 83 | }; 84 | 85 | void Turbine::expansionline(void) 86 | { 87 | double sdelta = 0.01; 88 | 89 | // 1 Isobar pin 90 | double s_isopin[2] = {win.s - sdelta, win.s + sdelta}; 91 | double h_isopin[2] = {ps(win.p, s_isopin[0], 4), ps(win.p, s_isopin[1], 4)}; 92 | 93 | // 2 Isobar pex 94 | double s_isopex[2] = {s_isopin[0], wex.s + sdelta}; 95 | double h_isopex[2] = {ps(wex.p, s_isopex[0], 4), ps(wex.p, s_isopex[1], 4)}; 96 | 97 | // 3 isentropic lines 98 | double h_isos[2] = {win.h, win.h - his}; 99 | double s_isos[2] = {win.s, win.s}; 100 | 101 | // 4 expansion Line 102 | double h_expL[2] = {win.h, wex.h}; 103 | double s_expL[2] = {win.s, wex.s}; 104 | 105 | // plot lines with gnuplot 106 | 107 | FILE *pipe = popen("gnuplot -persist", "w"); // Open a pipe to gnuplot 108 | if (pipe) // If gnuplot is found 109 | { 110 | fprintf(pipe, "set term wx\n"); // set the terminal 111 | fprintf(pipe, "set termoption enhanced\n"); // set enhanced text mode 112 | fprintf(pipe, "set xlabel 's(kJ/(kg.K))'\n"); 113 | fprintf(pipe, "set ylabel 'h(kJ/kg)'\n"); 114 | fprintf(pipe, "set title 'H-S(Mollier) Diagram of Steam Turbine Expansion'\n"); 115 | fprintf(pipe, "set yrange [%lf:%lf]\n", h_isopex[0] - 20, h_isopin[1] + 20); 116 | fprintf(pipe, "set xrange [%lf:%lf]\n", s_isopex[0] - 0.01, s_isopex[1] + 0.01); 117 | 118 | fprintf(pipe, "set label 'The isentropic efficiency=(h_1-h_2)/(h_1-h_{2s})= %.2f%%' at %lf,%lf left\n", ef, s_isopin[1] + 0.01, h_isopin[1] - 50); 119 | 120 | fprintf(pipe, "plot '-' title '' with line lc rgb 'blue', \ 121 | '-' title '' with line lc rgb 'blue',\ 122 | '-' title '' with linespoints lc rgb 'orange',\ 123 | '-' title 'Expansion Line' with linespoints lc rgb 'red'\n"); 124 | 125 | // 1 Isobar line : pin 126 | for (int i = 0; i < 2; i++) 127 | { 128 | fprintf(pipe, "%lf %lf\n", s_isopin[i], h_isopin[i]); 129 | } 130 | fprintf(pipe, "e"); 131 | 132 | // 2 Isobar line : pex 133 | fprintf(pipe, "\n"); // draw a new item! 134 | for (int i = 0; i < 2; i++) 135 | { 136 | fprintf(pipe, "%lf %lf\n", s_isopex[i], h_isopex[i]); 137 | } 138 | fprintf(pipe, "e"); 139 | 140 | // 3 isentropic lines 141 | fprintf(pipe, "\n"); 142 | for (int i = 0; i < 2; i++) 143 | { 144 | fprintf(pipe, "%lf %lf\n", s_isos[i], h_isos[i]); 145 | } 146 | fprintf(pipe, "e"); 147 | 148 | // 4 Expansion Line 149 | fprintf(pipe, "\n"); 150 | for (int i = 0; i < 2; i++) 151 | { 152 | fprintf(pipe, "%lf %lf\n", s_expL[i], h_expL[i]); 153 | } 154 | fprintf(pipe, "e"); 155 | 156 | fflush(pipe); 157 | fprintf(pipe, "exit\n"); // exit gnuplot 158 | pclose(pipe); //close pipe 159 | }; // end of if 160 | }; 161 | 162 | int main(void) 163 | { 164 | double pin = 16.0; 165 | double tin = 535.0; 166 | double pex = 3.56; 167 | double tex = 315.0; 168 | Turbine tb1 = Turbine(pin, tin, pex, tex); 169 | tb1.analysis(); 170 | tb1.output(); 171 | tb1.expansionline(); 172 | return 0; 173 | } 174 | -------------------------------------------------------------------------------- /demo/demo-c/demo.c: -------------------------------------------------------------------------------- 1 | /* 2 | Add SEUIF97 the paths of lib and header file to the environment variables of GCC/MinGW-W64 : 3 | 1 Windows: C:/Windows/system/libseuif97.dll 4 | 2 Linux: ./usr/lib/libseuif97.so 5 | 3 ./include/seuif97.h 6 | 7 | Build: 8 | Windows with MinGW-W64: 9 | gcc -o demo.exe demo.c -I./include -LC:/Windows/system/ -lseuif97 10 | 11 | Linux: 12 | gcc -o demo demo.c -I./include -L/usr/lib/ -lseuif97 -lm 13 | 14 | Run: 15 | ./demo 16 | 17 | Windows MSVC: seuif97.dll 18 | cl /Fedemo.exe /Fo./obj/demo.obj demo.c -I./include/ ./lib/seuif97.lib 19 | 20 | Author: Cheng Maohua 21 | */ 22 | 23 | #include 24 | #include 25 | #include "seuif97.h" 26 | 27 | int main(void) 28 | { 29 | 30 | double p = 16.13; 31 | double t = 535; 32 | double h, s, v; 33 | 34 | h = pt(p, t, 4); 35 | s = pt(p, t, 5); 36 | v = pt(p, t, 3); 37 | printf("(p,t)(%.2f,%.2f) h= %.2f, s= %.4f, v= %.4f\n", p, t, h, s, v); 38 | return EXIT_SUCCESS; 39 | } 40 | -------------------------------------------------------------------------------- /demo/demo-c/include/seuif97.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is header file of SEUIF97 3 | 4 | Author: Cheng Maohua 5 | Email: cmh@seu.edu.cn 6 | */ 7 | 8 | #ifndef SEUIF97_H 9 | #define SEUIF97_H 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #ifdef WIN32 16 | 17 | #define IMPORT __declspec(dllimport) double __stdcall 18 | 19 | #else 20 | 21 | #define IMPORT double 22 | 23 | #endif 24 | 25 | IMPORT pt(double p, double t, int o_id); 26 | IMPORT ph(double p, double h, int o_id); 27 | IMPORT ps(double p, double s, int o_id); 28 | IMPORT pv(double p, double v, int o_id); 29 | 30 | IMPORT th(double t, double h, int o_id); 31 | IMPORT ts(double t, double s, int o_id); 32 | IMPORT tv(double t, double v, int o_id); 33 | 34 | IMPORT hs(double h, double s, int o_id); 35 | 36 | IMPORT px(double p, double x, int o_id); 37 | IMPORT tx(double t, double x, int o_id); 38 | 39 | IMPORT hx(double h, double x, int o_id); 40 | IMPORT sx(double s, double x, int o_id); 41 | 42 | // Thermodynamic Process of Steam Turbine 43 | IMPORT ishd(double pi, double ti, double pe); 44 | IMPORT ief(double pi, double ti, double pe, double te); 45 | 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /demo/demo-csharp/demo_seuif97.cs: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | -------------- Windows --------------- 4 | 5 | Dependencies: 6 | ------ 7 | 1 SEUIF97 for Windows: C:/Windows/system/libseuif97.dll 8 | 2 API for C#: seuif97.cs 9 | 10 | Building the C# Application Using SEUIF97: 11 | ------- 12 | 13 | you may use the C# compiler and set the Platform target of application to the same as the dynamic library to build the C# Application Using SEUIF97 14 | 15 | 1 C# compiler 16 | 17 | you may use the C# compiler in Windows or Install the latest C# compiler 18 | 19 | 1.1 Using the C# compiler in Windows 20 | 21 | Add the path of C# compiler,for example C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ to the system environment variables #Path# 22 | 23 | 1.2 Install and use the latest C# compiler 24 | 25 | 1.2.1 Using #nuget# to install the latest C# compiler (https://github.com/dotnet/roslyn) 26 | 27 | 1) mkdir C:\csharp\ for the latest C# compiler,then download #nuget# to the path 28 | 29 | 2)In the path C:\csharp\, install the latest release without Visual Studio, run one of the following `nuget` command lines: 30 | 31 | >nuget install Microsoft.Net.Compilers # Install C# and VB compilers 32 | >nuget install Microsoft.CodeAnalysis # Install Language APIs and Services 33 | 34 | then the compiler is installed in the path, for example C:\csharp\Microsoft.Net.Compilers.2.10.0\tools\ 35 | 36 | 1.2.2 add the path C:\csharp\Microsoft.Net.Compilers.2.10.0\tools\ to the system environment variables #Path# 37 | 38 | 2. Build on x64 libseuif97.dll: 39 | 40 | >csc -out:demo.exe demo_seuif97.cs seuif97.cs /platform:"x64" 41 | 42 | 3. Run: 43 | 44 | >./demo 45 | 46 | ------------- Ubuntu ------------------- 47 | 48 | Dependencies: 49 | ------ 50 | 1 SEUIF97 for Linux64: /usr/lib/libseuif97.so 51 | 2 API for C#: seuif97.cs 52 | 53 | Building the C# Application Using SEUIF97: 54 | ------- 55 | 56 | 1 Install and use the C# compiler under Ubuntu 57 | 58 | 1.1 Install Nuget 59 | 60 | $sudo apt install nuget 61 | 62 | 1.1 Install C# compiler 63 | 64 | $nuget install Microsoft.Net.Compilers # Install C# and VB compilers 65 | $nuget install Microsoft.CodeAnalysis # Install Language APIs and Services 66 | 67 | 2. Build on x64 libseuif97.so: 68 | 69 | $csc -out:demo demo_seuif97.cs seuif97.cs /platform:"x64" 70 | 71 | 3. Run: 72 | 73 | $./demo 74 | 75 | ----------------------------------------- 76 | 77 | License: this code is in the public domain 78 | 79 | Author: Cheng Maohua 80 | Email: cmh@seu.edu.cn 81 | 82 | Last modified: 2019.01.05 83 | 84 | */ 85 | using System; 86 | 87 | using seuif97; 88 | 89 | namespace demo_seuif97 90 | { 91 | class demo_seuif97 92 | { 93 | 94 | static void Main(string[] args) 95 | { 96 | double p = 16.13; 97 | double t = 535.0; 98 | double h, s, v; 99 | h = Seuif97.pt(p, t, 4); 100 | s = Seuif97.pt(p, t, 5); 101 | v = Seuif97.pt(p, t, 3); 102 | Console.WriteLine("(p,t) h,s,v {0 :.00} {1:.0} {2:.000} {3:.000} {4:.000}", p, t, h, s, v); 103 | 104 | t = Seuif97.ph(p, h, 1); 105 | s = Seuif97.ph(p, h, 5); 106 | v = Seuif97.ph(p, h, 3); 107 | Console.WriteLine("(p,h) t,s,v {0 :.00} {1:.0} {2:.000} {3:.000} {4:.000}", p, h, t, s, v); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /demo/demo-csharp/seuif97.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The C# API of libseuif97.dll 3 | 4 | License: this code is in the public domain 5 | 6 | Author: Cheng Maohua 7 | Email: cmh@seu.edu.cn 8 | 9 | Last modified: 2019.01.05 10 | */ 11 | 12 | using System; 13 | using System.Runtime.InteropServices; 14 | 15 | namespace seuif97 16 | { 17 | public class Seuif97 18 | { 19 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 20 | public static extern double pt(double p, double t, int wid); 21 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 22 | public static extern double ph(double p, double h, int wid); 23 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 24 | public static extern double ps(double p, double s, int wid); 25 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 26 | public static extern double pv(double p, double v, int wid); 27 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 28 | public static extern double th(double t, double h, int wid); 29 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 30 | public static extern double ts(double t, double s, int wid); 31 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 32 | public static extern double tv(double t, double v, int wid); 33 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 34 | public static extern double hs(double h, double s, int wid); 35 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 36 | public static extern double px(double p, double x, int wid); 37 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 38 | public static extern double tx(double t, double x, int wid); 39 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 40 | public static extern double hx(double h, double x, int wid); 41 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 42 | public static extern double sx(double s, double x, int wid); 43 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 44 | 45 | public static extern double ishd(double pi, double ti, double pe); 46 | [DllImport("libseuif97", CallingConvention = CallingConvention.StdCall)] 47 | public static extern double ief(double pi, double ti, double pe, double te); 48 | 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /demo/demo-fortran/demo.f08: -------------------------------------------------------------------------------- 1 | ! 2 | ! SEUIF97 Library: 3 | ! 4 | ! 1 Windows: C:/Windows/system/libseuif97.dll 5 | ! 2 Linux: /usr/lib/libseuif97.so 6 | ! 3 The Module: ./seuif97.f08 7 | 8 | ! Build: 9 | ! Windows with MinGW-W64 10 | ! >gfortran -fno-underscoring -c seuif97.f08 -LC:/Windows/system/ -lseuif97 11 | ! >gfortran -fno-underscoring -o demo demo.f08 -LC:/Windows/system/ -lseuif97 12 | ! 13 | ! Linux: 14 | ! $gfortran -fno-underscoring -c seuif97.f08 -L/usr/lib/ -lseuif97 -lm 15 | ! $gfortran -fno-underscoring -o demo demo.f08 seuif97.f08 -L/usr/lib/ -lseuif97 -lm 16 | ! 17 | ! Run: 18 | ! ./demo 19 | ! 20 | ! Author: Cheng Maohua 21 | ! Email: cmh@seu.edu.cn 22 | ! 23 | ! Last modified: 2019.01.05 24 | ! 25 | 26 | program demo 27 | use iso_c_binding 28 | use seuif97 29 | implicit none 30 | real(c_double) :: p,t,h,s,v 31 | p = 16.13; 32 | t = 535.0; 33 | 34 | h = pt(p, t, 4); 35 | s = pt(p, t, 5); 36 | v = pt(p, t, 3); 37 | write (*,'(A,F10.2,F10.2,F10.2,F10.4,F10.4)') "(p,t),h,s,v",p,t,h,s,v 38 | 39 | t = ph(p, h, 1); 40 | s = ph(p, h, 5); 41 | v = ph(p, h, 3); 42 | write (*,'(A,F10.2,F10.2,F10.2,F10.4,F10.4)') "(p,h),t,s,v",p,h,t,s,v 43 | 44 | t = ps(p, s, 1); 45 | h = ps(p, s, 4); 46 | v = ps(p, s, 3); 47 | write (*,'(A,F10.2,F10.2,F10.2,F10.4,F10.4)') "(p,s),t,h,v",p,s,t,h,v 48 | 49 | p = th(t, h, 0); 50 | s = th(t, h, 5); 51 | v = th(t, h, 3); 52 | write (*,'(A,F10.2,F10.2,F10.2,F10.4,F10.4)') "(t,h),p,s,v",t,h,p,s,v 53 | 54 | end program demo -------------------------------------------------------------------------------- /demo/demo-fortran/seuif97.f08: -------------------------------------------------------------------------------- 1 | ! 2 | ! The interface of libseuif97 3 | ! 4 | ! License: this code is in the public domain 5 | ! 6 | ! Author: Cheng Maohua 7 | ! Email: cmh@seu.edu.cn 8 | ! 9 | ! Last modified: 2019.01.05 10 | ! 11 | module seuif97 12 | implicit none 13 | Interface 14 | real(c_double) function pt(p,t,wid) bind (C,name="pt") 15 | use iso_c_binding 16 | real(c_double), value :: p,t 17 | integer(c_int), value ::wid 18 | end function pt 19 | 20 | real(c_double) function ph(p,h,wid) bind (C,name="ph") 21 | use iso_c_binding 22 | real(c_double), value :: p,h 23 | integer(c_int), value ::wid 24 | end function ph 25 | 26 | real(c_double) function ps(p,s,wid) bind (C,name="ps") 27 | use iso_c_binding 28 | real(c_double), value :: p,s 29 | integer(c_int), value ::wid 30 | end function ps 31 | 32 | real(c_double) function pv(p,v,wid) bind (C,name="pv") 33 | use iso_c_binding 34 | real(c_double), value :: p,v 35 | integer(c_int), value ::wid 36 | end function pv 37 | 38 | real(c_double) function th(t,h,wid) bind (C,name="th") 39 | use iso_c_binding 40 | real(c_double), value :: t,h 41 | integer(c_int), value ::wid 42 | end function th 43 | 44 | real(c_double) function ts(t,s,wid) bind (C,name="ts") 45 | use iso_c_binding 46 | real(c_double), value :: t,s 47 | integer(c_int), value ::wid 48 | end function ts 49 | 50 | real(c_double) function tv(t,v,wid) bind (C,name="tv") 51 | use iso_c_binding 52 | real(c_double), value :: t,v 53 | integer(c_int), value ::wid 54 | end function tv 55 | 56 | real(c_double) function hs(h,s,wid) bind (C,name="hs") 57 | use iso_c_binding 58 | real(c_double), value :: h,s 59 | integer(c_int), value ::wid 60 | end function hs 61 | 62 | real(c_double) function px(p,x,wid) bind (C,name="px") 63 | use iso_c_binding 64 | real(c_double), value :: p,x 65 | integer(c_int), value ::wid 66 | end function px 67 | 68 | real(c_double) function tx(t,x,wid) bind (C,name="tx") 69 | use iso_c_binding 70 | real(c_double), value :: t,x 71 | integer(c_int), value ::wid 72 | end function tx 73 | 74 | real(c_double) function hx(h,x,wid) bind (C,name="hx") 75 | use iso_c_binding 76 | real(c_double), value :: h,x 77 | integer(c_int), value ::wid 78 | end function hx 79 | 80 | real(c_double) function sx(s,x,wid) bind (C,name="sx") 81 | use iso_c_binding 82 | real(c_double), value :: s,x 83 | integer(c_int), value ::wid 84 | end function sx 85 | 86 | real(c_double) function ishd(pi,ti,pe) bind (C,name="ishd") 87 | use iso_c_binding 88 | real(c_double), value :: pi,ti,pe 89 | end function ishd 90 | 91 | real(c_double) function ief(pi,ti,pe,te) bind (C,name="ief") 92 | use iso_c_binding 93 | real(c_double), value :: pi,ti,pe,te 94 | end function ief 95 | 96 | End Interface 97 | 98 | 99 | end module 100 | -------------------------------------------------------------------------------- /demo/demo-go/demo.go: -------------------------------------------------------------------------------- 1 | // cgo LDFLAGS: 2 | // Linux: -L/usr/lib/ -lseuif97 -lm 3 | // Windows: -LC:/Windows/system -llibseuif97 4 | package main 5 | /* 6 | #cgo LDFLAGS: -LC:/Windows/system -llibseuif97 7 | #include "seuif97.h" 8 | */ 9 | import "C" 10 | import "fmt" 11 | 12 | func main() { 13 | p:=16.14 14 | t:=512.0 15 | oid:=4 16 | h := C.pt(C.double(p),C.double(t),C.int(oid)) 17 | fmt.Printf("(p,t)=(%.2f, %.2f), h=%.2f\n",p,t,float64(h)) 18 | } 19 | -------------------------------------------------------------------------------- /demo/demo-go/seuif97.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is header file of SEUIF97 3 | 4 | Author: Cheng Maohua 5 | Email: cmh@seu.edu.cn 6 | */ 7 | 8 | #ifndef SEUIF97_H 9 | #define SEUIF97_H 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #ifdef WIN32 16 | 17 | #define IMPORT __declspec(dllimport) double __stdcall 18 | 19 | #else 20 | 21 | #define IMPORT double 22 | 23 | #endif 24 | 25 | IMPORT pt(double p, double t, int o_id); 26 | IMPORT ph(double p, double h, int o_id); 27 | IMPORT ps(double p, double s, int o_id); 28 | IMPORT pv(double p, double v, int o_id); 29 | 30 | IMPORT th(double t, double h, int o_id); 31 | IMPORT ts(double t, double s, int o_id); 32 | IMPORT tv(double t, double v, int o_id); 33 | 34 | IMPORT hs(double h, double s, int o_id); 35 | 36 | IMPORT px(double p, double x, int o_id); 37 | IMPORT tx(double t, double x, int o_id); 38 | 39 | IMPORT hx(double h, double x, int o_id); 40 | IMPORT sx(double s, double x, int o_id); 41 | 42 | // Thermodynamic Process of Steam Turbine 43 | IMPORT ishd(double pi, double ti, double pe); 44 | IMPORT ief(double pi, double ti, double pe, double te); 45 | 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /demo/demo-java/demoseuif97.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SEUIF97 Library: 4 | 5 | 1 Windows: C:/Windows/system/libseuif97.dll 6 | 2 Linux: /usr/lib/libseuif97.so 7 | 3 The Module: ./seuif97.java 8 | 9 | Java Native Access (JNA) 10 | ./jna.jar 11 | 12 | Build: 13 | 14 | javac -cp jna.jar seuif97.java demoseuif97.java 15 | java -cp .;jna.jar demoseuif97 16 | 17 | License: this code is in the public domain 18 | 19 | Author: Cheng Maohua 20 | Email: cmh@seu.edu.cn 21 | 22 | Last modified: 2019.01.07 23 | 24 | */ 25 | public class demoseuif97 { 26 | 27 | public static void main(String[] args){ 28 | double p=16.0; 29 | double t=540.0; 30 | double h; 31 | h=seuif97.INSTANCE.pt(p,t,4); 32 | System.out.printf("(p,t)->h: (%.1f %.1f) h: %.2f\n",p,t,h); 33 | t=seuif97.INSTANCE.ph(p,h,1); 34 | System.out.printf("(p,h)->t: (%.1f %.2f) t: %.2f ",p,h,t); 35 | } 36 | } -------------------------------------------------------------------------------- /demo/demo-java/jna.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/demo/demo-java/jna.jar -------------------------------------------------------------------------------- /demo/demo-java/seuif97.java: -------------------------------------------------------------------------------- 1 | /* 2 | The interface of libseuif97 through JNA 3 | https://github.com/java-native-access/jna 4 | 5 | Java Native Access (JNA) 6 | ./jna.jar 7 | 8 | SEUIF97 Library: 9 | 10 | 1 Windows: C:/Windows/system/libseuif97.dll 11 | 2 Linux: /usr/lib/libseuif97.so 12 | 13 | License: this code is in the public domain 14 | 15 | Author: Cheng Maohua 16 | Email: cmh@seu.edu.cn 17 | 18 | Last modified: 2019.01.07 19 | 20 | */ 21 | import com.sun.jna.Native; 22 | import com.sun.jna.Library; 23 | 24 | public interface seuif97 extends Library { 25 | 26 | seuif97 INSTANCE = (seuif97)Native.load("libseuif97", seuif97.class); 27 | 28 | public double pt(double p, double t, int o_id); 29 | public double ph(double p, double h, int o_id); 30 | public double ps(double p, double s, int o_id); 31 | public double pv(double p, double v, int o_id); 32 | 33 | public double th(double t, double s, int o_id); 34 | public double ts(double t, double s, int o_id); 35 | public double tv(double t, double v, int o_id); 36 | 37 | public double hs(double h, double s, int o_id); 38 | 39 | public double px(double p, double x, int o_id); 40 | public double tx(double t, double x, int o_id); 41 | 42 | public double hx(double h, double x, int o_id); 43 | public double sx(double s, double x, int o_id); 44 | 45 | public double ishd(double pi, double ti, double pe); 46 | public double ief(double pi, double ti, double pe, double te); 47 | } -------------------------------------------------------------------------------- /demo/demo-modelica/demo_seuif97.mo: -------------------------------------------------------------------------------- 1 | model demo_seuif97 "Model of seuif97" 2 | 3 | function pt 4 | input Real p; 5 | input Real t; 6 | input Integer w; 7 | output Real result; 8 | external"C" result = pt( 9 | p, 10 | t, 11 | w); 12 | annotation (Library="libseuif97"); 13 | end pt; 14 | 15 | Real h; 16 | parameter Real p=16; 17 | parameter Real t=542; 18 | parameter Integer w=4; 19 | 20 | equation 21 | h = pt( 22 | p, 23 | t, 24 | w); 25 | end demo_seuif97; 26 | -------------------------------------------------------------------------------- /demo/demo-modelica/demomodelica/demo.mo: -------------------------------------------------------------------------------- 1 | within demomodelica; 2 | 3 | model demo "demo of seuif97" 4 | 5 | Real h; 6 | parameter Real p=16; 7 | parameter Real t=542; 8 | parameter Integer w=4; 9 | 10 | equation 11 | h = seuif97.pt( 12 | p, 13 | t, 14 | w); 15 | end demo; 16 | -------------------------------------------------------------------------------- /demo/demo-modelica/demomodelica/package.mo: -------------------------------------------------------------------------------- 1 | within ; 2 | package demomodelica "demo seuif97" 3 | extends Modelica.Icons.Package; 4 | end demomodelica; 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /demo/demo-modelica/demomodelica/package.order: -------------------------------------------------------------------------------- 1 | seuif97 2 | demo 3 | -------------------------------------------------------------------------------- /demo/demo-modelica/demomodelica/seuif97.mo: -------------------------------------------------------------------------------- 1 | within demomodelica; 2 | model seuif97 "Model of seuif97" 3 | 4 | function pt 5 | input Real p; 6 | input Real t; 7 | input Integer w; 8 | output Real result; 9 | external"C" result = pt( 10 | p, 11 | t, 12 | w); 13 | annotation (Library="libseuif97"); 14 | end pt; 15 | 16 | end seuif97; 17 | -------------------------------------------------------------------------------- /demo/demo-pascal/demo.pas: -------------------------------------------------------------------------------- 1 | program demo; 2 | uses seuif97; 3 | 4 | var p,t,h,s:double; 5 | 6 | begin 7 | p:=16.0; 8 | t:=535.0; 9 | h:=seupt(p,t,IF97H); 10 | s:=seupt(p,t,IF97S); 11 | writeln('(h,s)',h,s); 12 | end. -------------------------------------------------------------------------------- /demo/demo-pascal/seuif97.pas: -------------------------------------------------------------------------------- 1 | unit seuif97; 2 | 3 | Interface 4 | const IF97LIB= 'libseuif97'; 5 | const IF97P=0; const IF97T=1; const IF97D=2; const IF97V=3; const IF97H=4; 6 | const IF97S=5; const IF97E=6; const IF97U=7; const IF97CP=8; const IF97CV=9; 7 | 8 | const IF97W=10; const IF97KS=11; const IF97F=12; const IF97G=13; const IF97Z=14; 9 | const IF97X=15; const IF97R=16; const IF97EC=17; const IF97KT=18; const IF97DVDT=19; 10 | 11 | const IF97DVDP=20; const IF97DPDT=21; const IF97IJTC=22; const IF97JTC=23; 12 | const IF97DV=24; const IF97KV=25; const IF97TC=26; const IF97TD=27; 13 | const IF97PR=28; const IF97ST=29; 14 | 15 | function pt( p,t:double; param:integer):double;external IF97LIB;// Windows stdcall : stdcall;external IF97LIB; 16 | function ph( p,h:double; param:integer):double;external IF97LIB; 17 | function ps( p,s:double; param:integer):double;external IF97LIB; 18 | function pv( p,v:double; param:integer):double;external IF97LIB; 19 | 20 | function th( t,h:double; param:integer):double;external IF97LIB; 21 | function ts( t,s:double; param:integer):double;external IF97LIB; 22 | function tv( t,v:double; param:integer):double;external IF97LIB; 23 | 24 | function px( p,v:double; param:integer):double;external IF97LIB; 25 | function tx( t,x:double; param:integer):double;external IF97LIB; 26 | 27 | function hx( h,v:double; param:integer):double;external IF97LIB; 28 | function sx( s,x:double; param:integer):double;external IF97LIB; 29 | 30 | function hs( p,v:double; param:integer):double;external IF97LIB; 31 | 32 | function ishd( pi,ti,pe:double):double;external IF97LIB; 33 | function ief( pi,ti,pe,te:double):double;external IF97LIB; 34 | 35 | implementation 36 | 37 | end. 38 | -------------------------------------------------------------------------------- /demo/demo-python/Diagram_H-S.py: -------------------------------------------------------------------------------- 1 | """ 2 | H-S(Mollier) Diagram 3 | 4 | 1 Calculating Isotherm lines isot(0.0,800.0)°C 5 | 2 Calculating Isobar lines isop(611.657e-6, 100.0)Mpa 6 | 3 Calculating saturation lines x=0,x=1 7 | 4 Calculating isoquality lines x(0.1,0.9) 8 | 9 | Author: Cheng Maohua. 2017.02.10 10 | Email: cmh@seu.edu.cn 11 | 12 | """ 13 | from seuif97 import pt2h, pt2s, tx2h, tx2s 14 | 15 | import matplotlib.pyplot as plt 16 | import numpy as np 17 | 18 | xAxis = "s" 19 | yAxis = "h" 20 | title = {"h": "h, kJ/kg", "s": "s, kJ/kgK"} 21 | 22 | plt.title("%s-%s Diagram" % (yAxis, xAxis)) 23 | plt.xlabel(title[xAxis]) 24 | plt.ylabel(title[yAxis]) 25 | plt.xlim(0, 12.5) 26 | plt.ylim(0, 4300) 27 | plt.grid() 28 | 29 | Pt = 611.657e-6 30 | 31 | isot = np.array([0, 50, 100, 200, 300, 400, 500, 600, 700, 800]) 32 | isop = np.array([Pt, 0.001, 0.01, 0.1, 1, 10, 20, 50, 100]) 33 | # Isotherm lines to plot, values in ºC 34 | for t in isot: 35 | h = np.array([pt2h(p, t) for p in isop]) 36 | s = np.array([pt2s(p, t) for p in isop]) 37 | plt.plot(s, h, 'g', lw=0.5) 38 | 39 | # Isobar lines to plot 40 | for p in isop: 41 | h = np.array([pt2h(p, t) for t in isot]) 42 | s = np.array([pt2s(p, t) for t in isot]) 43 | plt.plot(s, h, 'b', lw=0.5) 44 | 45 | tc = 647.096-273.15 46 | T = np.linspace(0.1, tc, 100) 47 | # Calculate saturation line 48 | for x in np.array([0, 1.0]): 49 | h = np.array([tx2h(t, x) for t in T]) 50 | s = np.array([tx2s(t, x) for t in T]) 51 | plt.plot(s, h, 'r', lw=1.0) 52 | 53 | # Isoquality lines to plot 54 | isox = np.linspace(0.1, 0.9, 11) 55 | for x in isox: 56 | h = np.array([tx2h(t, x) for t in T]) 57 | s = np.array([tx2s(t, x) for t in T]) 58 | plt.plot(s, h, 'r--', lw=0.5) 59 | 60 | plt.show() 61 | -------------------------------------------------------------------------------- /demo/demo-python/Diagram_T-S.py: -------------------------------------------------------------------------------- 1 | """ 2 | T-s Diagram 3 | 4 | 1 Calculating isoenthalpic lines isoh(200, 3600)kJ/kg 5 | 2 Calculating isobar lines isop(611.657e-6,100)MPa 6 | 3 Calculating saturation lines x=0,x=1 7 | 4 Calculating isoquality lines x(0.1,0.9) 8 | 9 | Author: Cheng Maohua. 2017.02.10 10 | Email: cmh@seu.edu.cn 11 | 12 | """ 13 | from seuif97 import ph2s, ph2t, tx2s, px2t, px2s 14 | 15 | import matplotlib.pyplot as plt 16 | import numpy as np 17 | 18 | xAxis = "s" 19 | yAxis = "T" 20 | title = {"T": "T, °C", "s": "s, kJ/kgK"} 21 | 22 | plt.title("%s-%s Diagram" % (yAxis, xAxis)) 23 | plt.xlabel(title[xAxis]) 24 | plt.ylabel(title[yAxis]) 25 | plt.grid() 26 | 27 | Pt = 611.657e-6 28 | isoh = np.linspace(200, 3600, 20) 29 | isop = np.array([Pt, 0.0015, 0.004, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 30 | 1.0, 2.0, 5.0, 10.0, 20.0, 35.0, 60,100.0]) 31 | # Calculating isoenthalpic lines isoh(200, 3600)kJ/kg 32 | for h in isoh: 33 | T = np.array([ph2t(p, h) for p in isop]) 34 | S = np.array([ph2s(p, h) for p in isop]) 35 | plt.plot(S, T, 'g', lw=0.5) 36 | # Calculating isobar lines isop(611.657e-6,100)MPa 37 | for p in isop: 38 | T = np.array([ph2t(p, h) for h in isoh]) 39 | S = np.array([ph2s(p, h) for h in isoh]) 40 | plt.plot(S, T, 'b', lw=0.5) 41 | 42 | # saturate water to wet steam 43 | for p in [Pt, 0.0015, 0.004]: 44 | s = ph2s(p, 200) 45 | t = ph2t(p, 200) 46 | s_sat_water = px2s(p, 0.0) 47 | t_sat_water = px2t(p, 0.0) 48 | plt.plot([s_sat_water, s], [t_sat_water, t], 'b', lw=0.5) 49 | 50 | 51 | tc = 647.096 - 273.15 52 | T = np.linspace(0.11, tc, 100) 53 | for x in np.array([0, 1.0]): 54 | S = np.array([tx2s(t, x) for t in T]) 55 | plt.plot(S, T, 'r', lw=1.0) 56 | 57 | for x in np.linspace(0.1, 0.9, 11): 58 | S = np.array([tx2s(t, x) for t in T]) 59 | plt.plot(S, T, 'r--', lw=0.5) 60 | 61 | plt.show() 62 | -------------------------------------------------------------------------------- /demo/demo-python/README.md: -------------------------------------------------------------------------------- 1 | # Python 2 | 3 | ## Install SEUIF97 library manually 4 | 5 | Put the shared library in the default `Lib` path of OS or the programming language, 6 | 7 | then,copy **seuif97.py** in the [api](./api) folder to a default path of Python's lib. 8 | 9 | **Windows(x86/64)** 10 | 11 | If you have installed Python3.8 in the C:\Python38\, copy to 12 | 13 | C:\Python38\Lib 14 | 15 | **Linux(x64/aarch64)** 16 | 17 | If you have installed Python3.8 18 | 19 | ```bash 20 | $sudo cp seuif97.py /usr/lib/python3.8/ 21 | ``` 22 | 23 | ## Functions 24 | 25 | The two type functions are provided in the [seuif97.py](../../api/seuif97.py): 26 | 27 | * ??2?(in1,in2) , e.g: `h=pt2h(p,t)` 28 | 29 | * first,second input parameters: the input properties(double) 30 | * the return: the calculated property value(double) 31 | 32 | * ??(in1,in2,propertyID), , e.g:`h=pt(p,t,4)`, the propertyID h is 4 33 | * first,second input parameters: the input properties(double) 34 | * third input parameter: the propertyID of the calculated property(int, 0-29), see Properties in libseuif97 35 | * the return: the calculated property value(double) 36 | 37 | ```python 38 | import seuif97 39 | 40 | p,t=16.10,535.10 41 | 42 | # ??2?(in1,in2) 43 | h=seuif97.pt2h(p,t) 44 | s=seuif97.pt2s(p,t) 45 | v=seuif97.pt2v(p,t) 46 | print("(p,t),h,s,v:", 47 | "{:>.2f}\t {:>.2f}\t {:>.2f}\t {:>.3f}\t {:>.4f}".format(p, t, h, s, v)) 48 | 49 | # ??(in1,in2,propertyid) 50 | t = seuif97.ph(p, h, 1) 51 | s = seuif97.ph(p, h, 5) 52 | v = seuif97.ph(p, h, 3) 53 | print("(p,h),t,s,v:", 54 | "{:>.2f}\t {:>.2f}\t {:>.2f}\t {:>.3f}\t {:>.4f}".format(p, h, t, s, v)) 55 | ``` 56 | 57 | #### Diagram Examples 58 | 59 | * [Diagram T-S](./Diagram_T-S.py) 60 | 61 | ![Diagram T-S](./img/T-S.jpg) 62 | 63 | * [H-S(Mollier) Diagram of Steam Turbine Expansion](./Turbine_H-S.py) 64 | 65 | ![turbine_expansion_line](./img/turbine_expansion_line.jpg) -------------------------------------------------------------------------------- /demo/demo-python/demo_seuif97.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | The Simple example of seuif97.py 4 | 5 | The input pairs implemented in seuif97.py 6 | 7 | (p,t) (p,h) (p,s) (p,v) 8 | 9 | (t,h) (t,s) (t,v) 10 | 11 | (h,s) 12 | 13 | (p,x) (t,x) 14 | 15 | The types of functions: 16 | 17 | 1 ??2?(in1,in2) , e.g: h=pt2h(p,t) 18 | 2 ??(in1,in2,propertyID), , e.g: h=pt(p,t,4), the propertyID h is 4 19 | 20 | License: this code is in the public domain 21 | 22 | Author: Cheng Maohua(cmh@seu.edu.cn) 23 | 24 | Last modified: 2018.11.28 25 | 26 | """ 27 | import seuif97 28 | 29 | p, t = 16.10, 535.10 30 | 31 | # ??2?(in1,in2) 32 | h = seuif97.pt2h(p, t) 33 | s = seuif97.pt2s(p, t) 34 | v = seuif97.pt2v(p, t) 35 | 36 | print("(p,t),h,s,v:", 37 | "{:>.2f}\t {:>.2f}\t {:>.2f}\t {:>.3f}\t {:>.4f}".format(p, t, h, s, v)) 38 | 39 | # ??(in1,in2,propertyid) 40 | t = seuif97.ph(p, h, 1) 41 | s = seuif97.ph(p, h, 5) 42 | v = seuif97.ph(p, h, 3) 43 | 44 | print("(p,h),t,s,v:", 45 | "{:>.2f}\t {:>.2f}\t {:>.2f}\t {:>.3f}\t {:>.4f}".format(p, h, t, s, v)) 46 | -------------------------------------------------------------------------------- /demo/demo-python/img/T-S.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/demo/demo-python/img/T-S.jpg -------------------------------------------------------------------------------- /demo/demo-python/img/turbine_expansion_line.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/demo/demo-python/img/turbine_expansion_line.jpg -------------------------------------------------------------------------------- /demo/demo-rust/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /demo/demo-rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "cfg-if" 5 | version = "1.0.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 8 | 9 | [[package]] 10 | name = "demoseuif97" 11 | version = "0.1.0" 12 | dependencies = [ 13 | "libloading", 14 | ] 15 | 16 | [[package]] 17 | name = "libloading" 18 | version = "0.6.7" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" 21 | dependencies = [ 22 | "cfg-if", 23 | "winapi", 24 | ] 25 | 26 | [[package]] 27 | name = "winapi" 28 | version = "0.3.9" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 31 | dependencies = [ 32 | "winapi-i686-pc-windows-gnu", 33 | "winapi-x86_64-pc-windows-gnu", 34 | ] 35 | 36 | [[package]] 37 | name = "winapi-i686-pc-windows-gnu" 38 | version = "0.4.0" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 41 | 42 | [[package]] 43 | name = "winapi-x86_64-pc-windows-gnu" 44 | version = "0.4.0" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 47 | -------------------------------------------------------------------------------- /demo/demo-rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "demoseuif97" 3 | version = "0.1.0" 4 | authors = ["thermalogic "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | libloading = "0.6.7" -------------------------------------------------------------------------------- /demo/demo-rust/src/main.rs: -------------------------------------------------------------------------------- 1 | mod seuif97; 2 | use seuif97::pt; 3 | 4 | fn main() { 5 | let p: f64 = 16.0; 6 | let t: f64 = 535.9; 7 | let h: f64 = pt(p, t, 4); 8 | let s: f64 = pt(p, t, 5); 9 | println!("{p} {t} {h} {s}"); 10 | } 11 | -------------------------------------------------------------------------------- /demo/demo-rust/src/seuif97.rs: -------------------------------------------------------------------------------- 1 | extern crate libloading as lib; 2 | 3 | fn resultpt(in1: f64, in2: f64, w: u32) -> Result> { 4 | let lib = lib::Library::new("libseuif97")?; 5 | unsafe { 6 | let func: lib::Symbol f64> = lib.get(b"pt")?; 7 | Ok(func(in1, in2, w)) 8 | } 9 | } 10 | 11 | pub fn pt(in1: f64, in2: f64, w: u32) -> f64 { 12 | let prop: f64 = match resultpt(in1, in2, w) { 13 | Ok(v) => v, 14 | Err(_e) => 1000.0, 15 | }; 16 | prop 17 | } 18 | -------------------------------------------------------------------------------- /doc/基于最短加法链状态空间树的IAPWS-IF97快速计算方法.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/doc/基于最短加法链状态空间树的IAPWS-IF97快速计算方法.pdf -------------------------------------------------------------------------------- /doc/水和水蒸汽热力性质IAPWS-IF97公式的通用计算模型.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/doc/水和水蒸汽热力性质IAPWS-IF97公式的通用计算模型.pdf -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | LIBDIR=./bin/ 2 | ifeq ($(OS),Windows_NT) 3 | LIBNAME =$(LIBDIR)libseuif97.dll 4 | LIBFLAGES=-static-libstdc++ -static-libgcc -static -Wl,--add-stdcall-alias,--output-def=$(LIBDIR)libseuif97.def,-out-implib=$(LIBDIR)libseuif97.lib 5 | else 6 | UNAME_S := $(shell uname -s) 7 | ifeq ($(UNAME_S),Linux) 8 | LIBNAME =$(LIBDIR)libseuif97.so 9 | endif 10 | endif 11 | 12 | CFLAGS=-O3 13 | 14 | # __stdcall for Windows VBA X64 15 | #CFLAGS=-O3 -DBUILD_DLL 16 | # __stdcall for Windows VBA X86 17 | #CFLAGS=-O3 -DBUILD_DLL -m32 18 | 19 | CC=gcc 20 | 21 | INC =-I ./src/common \ 22 | -I ./src/algo \ 23 | -I ./src/r1 \ 24 | -I ./src/r2 \ 25 | -I ./src/r3 \ 26 | -I ./src/r4 \ 27 | -I ./src/r5 28 | 29 | SRCS= ./src/algo/*.c \ 30 | ./src/common/*.c \ 31 | ./src/r1/*.c \ 32 | ./src/r2/*.c \ 33 | ./src/r3/*.c \ 34 | ./src/r4/*.c \ 35 | ./src/r5/*.c 36 | 37 | all: $(LIBNAME) 38 | 39 | $(LIBNAME): $(SRCS) 40 | $(CC) -shared -o $@ -fPIC $(CFLAGS) $^ $(INC) $(LIBFLAGES) 41 | 42 | tests: 43 | $(MAKE) -C ./test/ FILE=test_hs.c 44 | $(MAKE) -C ./test/ FILE=test_hxsx.c 45 | $(MAKE) -C ./test/ FILE=test_ph.c 46 | $(MAKE) -C ./test/ FILE=test_ps.c 47 | $(MAKE) -C ./test/ FILE=test_pv.c 48 | $(MAKE) -C ./test/ FILE=test_pt.c 49 | $(MAKE) -C ./test/ FILE=test_th.c 50 | $(MAKE) -C ./test/ FILE=test_ts.c 51 | $(MAKE) -C ./test/ FILE=test_tv.c 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /shared_lib/Linux/x64/libseuif97.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/shared_lib/Linux/x64/libseuif97.so -------------------------------------------------------------------------------- /shared_lib/Windows/x64/libseuif97.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | hs @1 3 | hx @2 4 | ief @3 5 | ishd @4 6 | ph @5 7 | ps @6 8 | pt @7 9 | pv @8 10 | px @9 11 | sx @10 12 | th @11 13 | ts @12 14 | tv @13 15 | tx @14 16 | -------------------------------------------------------------------------------- /shared_lib/Windows/x64/libseuif97.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/shared_lib/Windows/x64/libseuif97.dll -------------------------------------------------------------------------------- /shared_lib/Windows/x64/libseuif97.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/shared_lib/Windows/x64/libseuif97.lib -------------------------------------------------------------------------------- /shared_lib/Windows/x86/libseuif97.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | hs = hs@20 @1 3 | hs@20 @2 4 | hx = hx@20 @3 5 | hx@20 @4 6 | ief = ief@32 @5 7 | ief@32 @6 8 | ishd = ishd@24 @7 9 | ishd@24 @8 10 | ph = ph@20 @9 11 | ph@20 @10 12 | ps = ps@20 @11 13 | ps@20 @12 14 | pt = pt@20 @13 15 | pt@20 @14 16 | pv = pv@20 @15 17 | pv@20 @16 18 | px = px@20 @17 19 | px@20 @18 20 | sx = sx@20 @19 21 | sx@20 @20 22 | th = th@20 @21 23 | th@20 @22 24 | ts = ts@20 @23 25 | ts@20 @24 26 | tv = tv@20 @25 27 | tv@20 @26 28 | tx = tx@20 @27 29 | tx@20 @28 30 | -------------------------------------------------------------------------------- /shared_lib/Windows/x86/libseuif97.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/shared_lib/Windows/x86/libseuif97.dll -------------------------------------------------------------------------------- /shared_lib/Windows/x86/libseuif97.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thermalogic/SEUIF97/ec2b05b04d4b6da01f057c1161d256c606f8378c/shared_lib/Windows/x86/libseuif97.lib -------------------------------------------------------------------------------- /src/algo/algorithm.h: -------------------------------------------------------------------------------- 1 | /* 2 | The algorithms 3 | */ 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "../common/common.h" 9 | 10 | #define IPOW ipowsac 11 | // #define IPOW ipowrqm 12 | // #define IPOW powf 13 | 14 | #define SIGN(a, b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) 15 | 16 | double ipowsac(double x, int n); 17 | double ipowrqm(double x, int n); 18 | 19 | double poly(double vi, double vj, int size, IJnData *IJn); 20 | double poly_i(double vi, double vj, int size, IJnData *IJn); 21 | double poly_ii(double vi, double vj, int size, IJnData *IJn); 22 | double poly_j(double vi, double vj, int size, IJnData *IJn); 23 | double poly_jj(double vi, double vj, int size, IJnData *IJn); 24 | double poly_ij(double vi, double vj, int size, IJnData *IJn); 25 | // multiple 26 | void polys_0_j(double vi, double vj, int size, IJnData *IJn, double *poly_0, double *poly_j); 27 | void polys_i_ii_ij_jj(double vi, double vj, int size, IJnData *IJn, 28 | double *poly_i, double *poly_ii, double *poly_ij, double *poly_jj); 29 | 30 | static double soI_pow[45] = {(double)(0.0)}; 31 | static double soJ_pow[45] = {(double)(0.0)}; 32 | 33 | typedef void (*solo_power_fn)(double, double, double *, double *); 34 | 35 | double poly_solo(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power); 36 | double poly_solo_i(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power); 37 | double poly_solo_ii(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power); 38 | 39 | double poly_solo_j(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power); 40 | double poly_solo_ij(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power); 41 | double poly_solo_jj(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power); 42 | 43 | // multiple 44 | void polys_solo_0_i(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power, double *poly_0, double *poly_i); 45 | void polys_solo_0_j(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power, double *poly_0, double *poly_j); 46 | void polys_solo_i_j(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power, double *poly_i, double *poly_j); 47 | 48 | void polys_solo_i_ij(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power, 49 | double *poly_i, double *poly_ij); 50 | 51 | void polys_solo_i_ii(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power, double *poly_i, double *poly_ii); 52 | 53 | void polys_solo_i_ii_ij(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power, 54 | double *poly_i, double *poly_ii, double *poly_ij); 55 | 56 | void polys_solo_i_ij_jj(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power, 57 | double *poly_i, double *poly_ij, double *poly_jj); 58 | 59 | void polys_solo_i_ii_ij_jj(double vi, double vj, int size, IJnData *IJn, int *i2soI, int *j2soJ, solo_power_fn solo_i_j_power, 60 | double *poly_i, double *poly_ii, double *poly_ij, double *poly_jj); 61 | 62 | static double xacc = 1.0E-08; 63 | static int iMAX = 100; 64 | typedef double (*callfunc)(double, double); 65 | 66 | double rtsec1(callfunc func, double cVar2, double fr, double x1, 67 | double x2, double ft, double f, double xacc, int iMAX); 68 | double rtsec2(callfunc func, double cVar1, double fr, double x1, 69 | double x2, double fl, double f, double xacc, int iMAX); 70 | -------------------------------------------------------------------------------- /src/algo/polynomial.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | #include 5 | #include "algorithm.h" 6 | 7 | double poly(double vi, double vj, int size, IJnData *IJn) 8 | { 9 | double v = 0.0; 10 | for (int k = 0; k < size; k++) 11 | v += IJn[k].n * IPOW(vi, IJn[k].I) * IPOW(vj, IJn[k].J); 12 | return v; 13 | } 14 | 15 | double poly_i(double vi, double vj, int size, IJnData *IJn) 16 | { 17 | double v = 0.0; 18 | for (int k = 0; k < size; k++) 19 | v += IJn[k].n * IJn[k].I * IPOW(vi, IJn[k].I - 1) * IPOW(vj, IJn[k].J); 20 | return v; 21 | } 22 | 23 | double poly_ii(double vi, double vj, int size, IJnData *IJn) 24 | { 25 | double v = 0.0; 26 | for (int k = 0; k < size; k++) 27 | v += IJn[k].n * IJn[k].I * (IJn[k].I - 1) * IPOW(vi, IJn[k].I - 2) * IPOW(vj, IJn[k].J); 28 | return v; 29 | } 30 | 31 | double poly_j(double vi, double vj, int size, IJnData *IJn) 32 | { 33 | double v = 0.0; 34 | for (int k = 0; k < size; k++) 35 | v += IJn[k].n * IPOW(vi, IJn[k].I) * IJn[k].J * IPOW(vj, IJn[k].J - 1); 36 | return v; 37 | } 38 | 39 | double poly_jj(double vi, double vj, int size, IJnData *IJn) 40 | { 41 | double v = 0.0; 42 | for (int k = 0; k < size; k++) 43 | v += IJn[k].n * IPOW(vi, IJn[k].I) * IJn[k].J * (IJn[k].J - 1) * IPOW(vj, IJn[k].J - 2); 44 | return v; 45 | } 46 | 47 | double poly_ij(double vi, double vj, int size, IJnData *IJn) 48 | { 49 | double v = 0.0; 50 | for (int k = 0; k < size; k++) 51 | v += IJn[k].n * IJn[k].I * IPOW(vi, IJn[k].I - 1) * IJn[k].J * IPOW(vj, IJn[k].J - 1); 52 | return v; 53 | } 54 | //--------------multiple values ------------------------------------------------------ 55 | 56 | // /df/dvj 57 | void polys_0_j(double vi, double vj, int size, IJnData *IJn, double *poly_0, double *poly_j) 58 | { 59 | double item = 0.0; 60 | for (int k = 0; k < size; k++) 61 | { 62 | item = IJn[k].n * IPOW(vi, IJn[k].I) * IPOW(vj, IJn[k].J); 63 | *poly_0 += item; 64 | *poly_j += item * IJn[k].J; 65 | } 66 | *poly_j /= vj; 67 | } 68 | 69 | void polys_i_ii_ij_jj(double vi, double vj, int size, IJnData *IJn, 70 | double *poly_i, double *poly_ii, double *poly_ij, double *poly_jj) 71 | { 72 | double item = 0.0; 73 | double di_item = 0.0; 74 | 75 | for (int k = 0; k < size; k++) 76 | { 77 | item = IJn[k].n * IPOW(vi, IJn[k].I) * IPOW(vj, IJn[k].J); 78 | di_item=IJn[k].I *item; 79 | *poly_i += di_item; 80 | *poly_ii += di_item*(IJn[k].I-1); 81 | *poly_ij += di_item * IJn[k].J; 82 | 83 | *poly_jj += item * IJn[k].J*(IJn[k].J-1); 84 | 85 | } 86 | *poly_i /= vi; 87 | *poly_ii /= (vi*vi); 88 | *poly_ij /= (vi*vj); 89 | *poly_jj /= (vj*vj); 90 | } 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/algo/root.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Root Finding Methods For IAPWS - IF97 3 | // Ref: Numerical Reciples - Chapter 9 :Pages:347 ~ 368 4 | // Last updated: 2004.01.03 By Maohua Cheng 5 | //----------------------------------------------------------------------------- 6 | 7 | #include 8 | #include 9 | #include "algorithm.h" 10 | 11 | #define EPS 3.0e-8 12 | //---------------------------------------------------------------------------- 13 | // SECANT METHOD : Ch.9.2: Pages 357, 14 | // Using the secant method, find the root of a func throught lie between x1 and 15 | // x2. The root returned as rtsec, is refined until its accuracy is ABS(xacc) 16 | //---------------------------------------------------------------------------- 17 | 18 | double rtsec2(callfunc func, double cVar1,double fr,double x1, 19 | double x2, double fl,double f, double xacc, int iMAX) 20 | // rtsec2 :(*func)(cVar1,x)所求解是方程的第二个参数:x,x={x1,x2} 21 | // 第一个参数cVar1,迭代求解中不变 22 | // fr: fr:是输入的(*func)(double,double)计算结果 23 | // fr: fr:是输入的(*func)(x,cVar2)计算结果 24 | // fl: fr-(*func)(cVar1,x1) 25 | // f: fr-(*func)(cVar1,x2) 26 | // rts:返回x的解 27 | { 28 | double xl,rts,swap,dx; 29 | // pick the bound with the smaller function value as the most recent guess 30 | if (fabs(fl) < fabs(f)) { 31 | rts=x1; 32 | xl=x2; 33 | swap=fl; 34 | fl=f; 35 | f=swap; 36 | } else { 37 | xl=x1; 38 | rts=x2; 39 | } 40 | //scant loop 41 | int i=0; 42 | if ((f-fl)!=0.0) 43 | { 44 | do 45 | { 46 | dx=(xl-rts)*f/(f-fl); // increment with respect to latest value 47 | xl=rts; 48 | fl=f; 49 | rts += dx; 50 | // TODO: 可将解的上下限作为参数带进来,保证迭代过程的解不超上下限 51 | //rts must bounded in region X 52 | f=fr-(*func)(cVar1,rts); 53 | i++; 54 | } 55 | // while ((fabs(dx) > xacc)&&(i xacc)&&(i xacc && i100) rts=100; 102 | 103 | f=fr-(*func)(rts,cVar2); 104 | i++; 105 | 106 | } 107 | // while ((fabs(dx) > xacc)&&(i xacc)&&(i>= 1; 26 | x *= x; 27 | } while (n); 28 | 29 | return value; 30 | } 31 | 32 | double ipowrqm(double x, int n) 33 | { 34 | unsigned int un; 35 | if (n < 0) 36 | { 37 | x = 1.0 / x; 38 | un = -n; 39 | } 40 | else 41 | { 42 | un = n; 43 | } 44 | 45 | return posipowrqm(x, un); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/common/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct 4 | { 5 | int I, J; 6 | double n; 7 | } IJnData; 8 | 9 | // methods 10 | typedef double (*properties_region)(double, double, int); 11 | // tansport properties 12 | double viscosity(double rho, double T); 13 | double kinematic_viscosity(double rho, double T); 14 | double thCond(double rho, double T); 15 | double thermal_diffusivity(double tc, double cp, double d); 16 | double tension(double T); 17 | double prandtl_number(double dv, double cp, double tc); 18 | double thermal_diffusivity(double tc, double cp, double d); 19 | 20 | // double dielectric(double rho, double T); 21 | // double refractive(double rho, double T); 22 | // double Kw(double rho, double T); 23 | 24 | double pT_transport(double p, double T, int o_id, properties_region fn); 25 | double pT_reg(double p, double T, int o_id, properties_region pT_thermal, properties_region pT_ext); 26 | 27 | 28 | typedef int (*region_fn)(double, double); 29 | typedef double (*prop_fn)(double, double, int o_id); 30 | 31 | double pair_prop(double v1, double v2, int o_id, region_fn regfn, 32 | prop_fn fn1, 33 | prop_fn fn2, 34 | prop_fn fn3, 35 | prop_fn fn4, 36 | prop_fn fn5); 37 | 38 | 39 | double pT(double p, double T, int o_id); 40 | 41 | // Boundary equations: 42 | 43 | // IF97-Rev, Region2-Region3 44 | double B23_T2p(double T); // IF97-Rev, Eq 5 45 | double B23_p2T(double p); // IF97-Rev, Eq 5 46 | 47 | // (p,h)-> subregion 3 48 | double h2pSat_reg3(double h); // Supp-Tv(ph,ps)-2014.pdf, Eq 10 49 | // (p,s)-> subregion 50 | double s2pSat_reg3(double s); // Supp-Tv(ph,ps)-2014.pdf, Eq 11 51 | 52 | // reg3 (h,s) ->p 53 | double _h1_s(double s); // Supp-phs3-2014.pdf. Eq 3 54 | double _h3a_s(double s); // Supp-phs3-2014.pdf. Eq 4 55 | double _h2ab_s(double s); // Supp-phs3-2014.pdf. Eq 5 56 | double _h2c3b_s(double s); // Supp-phs3-2014.pdf. Eq 6 57 | double _h13_s(double s); // Supp-phs3-2014.pdf. Eq 7 58 | double _t_hs(double h, double s); // Supp-phs3-2014.pdf. Eq 8 59 | 60 | // region 61 | int pT_region(double p, double T); 62 | int ph_region(double p, double h); 63 | int ps_region(double p, double s); 64 | int hs_region(double h, double s); 65 | // the extended pairs 66 | int pv_region(double p, double v); 67 | int Th_region(double T, double h); 68 | int Ts_region(double T, double s); 69 | int Tv_region(double T, double v); -------------------------------------------------------------------------------- /src/common/constand.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define INVALID_OUTID -1000 4 | 5 | #define INVALID_P -2100 6 | #define INVALID_T -2101 7 | #define INVALID_S -2102 8 | #define INVALID_H -2103 9 | #define INVALID_PT -2201 10 | #define INVALID_HS -2202 11 | #define INVALID_VALUE -9999 12 | 13 | #define K 273.15; 14 | 15 | static double rgas_water = 0.461526; // gas constant in KJ/(kg K) 16 | // critical point 17 | static double tc_water = 647.096; // critical temperature in K 18 | static double pc_water = 22.064; // critical p in Mpa 19 | static double dc_water = 322.0; // critical density in kg/m**3 20 | static double sc_water = 4.41202148223476; // Critic entropy 21 | static double hc_water = 2.087546845e+03; // Critic entropy h 22 | // triple point 23 | static double Pt = 611.657e-6; // the triple point 24 | static double Tt = 273.16; // the triple point 25 | static double st_water = 5.85; // the triple point 26 | static double ht_water = 0.611783; // the triple point 27 | 28 | // T=623.15 region (1,3) 29 | static double Ps_623 = 16.5291642526045; // PMIN3 Ps_623 = _PSat_T(623.15) P Saturation at 623.15 K, boundary region 1-3 30 | // T=273.15 Tmin 31 | static double Pmin = 0.000611212677444; // Pmin = _PSat_T(273.15) Minimum pressure 32 | 33 | #define P01 16.53 34 | #define T01 1386.0 35 | #define TMAX1 623.15 36 | #define TMIN1 273.15 37 | #define PMAX1 100.00 38 | #define PMIN1 0.000611212677444 39 | 40 | #define T02 540.0 41 | #define P02 1.0 42 | #define TMAX2 1073.15 43 | #define TMIN2 273.15 44 | #define PMAX2 100.00 45 | #define PMIN2 1.0E-8 46 | 47 | #define D03 322.0 48 | #define T03 647.096 49 | #define TMAX3 863.15 50 | #define TMIN3 623.15 51 | #define PMAX3 100.0 52 | #define PMIN3 16.5291643 53 | 54 | #define TMAX4 647.096 55 | #define TMIN4 273.15 56 | #define PMAX4 22.064 57 | #define PMIN4 0.000611212677444 58 | #define HMAX4 2803.2738880203456 59 | #define HMIN4 0.38039218566765925 60 | #define SMAX4 9.153081306725117 61 | #define SMIN4 0.33567511183921145 62 | 63 | #define T05 1000.0 64 | #define P05 1.0 65 | #define TMAX5 2273.15 66 | #define TMIN5 1073.15 67 | #define PMAX5 50.0 68 | #define PMIN5 1.0E-8 69 | 70 | #define VMAX 1.0E+10 71 | #define VMIN 0.00095 72 | #define HMAX 7376.99 73 | #define HMIN -0.1 74 | #define SMAX 18.992 // 1.0E-8, 2273.15 75 | #define SMIN -0.008583 // 100,273.15 -------------------------------------------------------------------------------- /src/common/propertry_id.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // output propertry ID 4 | #define OP 0 5 | #define OT 1 6 | #define OD 2 7 | #define OV 3 // specific volume 8 | #define OH 4 9 | #define OS 5 10 | #define OE 6 // e: Specific exergy kJ/kg 11 | #define OU 7 // specific internal energy 12 | #define OCP 8 13 | #define OCV 9 14 | #define OW 10 15 | #define OKISE 11 // k: Isentropic exponent - 16 | #define OF 12 // f: Specific Helmholtz free energy kJ/kg 17 | #define OG 13 // g: Specific Gibbs free energy kJ/kg 18 | #define OZ 14 // z: Compressibility factor 19 | #define OX 15 20 | #define OR 16 21 | #define OIPCEC 17 // αv ipcec :Isobari cubic expansion coefficient 1/K 22 | #define OKT 18 // kT: Isothermal compressibility 1/Mpa 23 | #define ODVDT 19 24 | #define ODVDP 20 25 | #define ODPDT 21 26 | #define OIJTC 22 // ijoule Isothermal Joule-Thomson coefficient kJ/(kg·MPa) 27 | #define OJTC 23 // μ joule : Joule-Thomson coefficient K/MPa 28 | // transport 29 | #define ODV 24 30 | #define OKV 25 31 | #define OTC 26 32 | #define OTD 27 33 | #define OPR 28 34 | #define OST 29 35 | -------------------------------------------------------------------------------- /src/common/propertry_pair.c: -------------------------------------------------------------------------------- 1 | // Transport 2 | // 1. pT_transport -> 1,2,5 3 | // 2 Td_transport_reg3 in region3_out.c 4 | #include "../common/common.h" 5 | #include "../common/propertry_id.h" 6 | #include "../common/constand.h" 7 | #include "../algo/algorithm.h" 8 | #include "../r1/region1.h" 9 | #include "../r2/region2.h" 10 | #include "../r3/region3.h" 11 | #include "../r4/region4.h" 12 | #include "../r5/region5.h" 13 | 14 | double pT_transport(double p, double T, int o_id, properties_region fn) 15 | { 16 | double value; 17 | double d; 18 | double cp; 19 | double tc; 20 | double dv; 21 | switch (o_id) 22 | { 23 | case ODV: 24 | { 25 | d = (*fn)(p, T, OD); 26 | value = viscosity(d, T); 27 | break; 28 | } 29 | case OKV: 30 | { 31 | d = (*fn)(p, T, OD); 32 | value = kinematic_viscosity(d, T); 33 | break; 34 | } 35 | case OTC: 36 | { 37 | d = (*fn)(p, T, OD); 38 | value = thCond(d, T); 39 | break; 40 | } 41 | case OTD: 42 | { 43 | d = (*fn)(p, T, OD); 44 | cp = (*fn)(p, T, OCP); 45 | tc = thCond(d, T); 46 | value = thermal_diffusivity(tc, cp, d); 47 | break; 48 | } 49 | case OPR: 50 | { 51 | d = (*fn)(p, T, OD); 52 | dv = viscosity(d, T); 53 | cp = (*fn)(p, T, OCP); 54 | tc = thCond(d, T); 55 | value = prandtl_number(dv, cp, tc); 56 | break; 57 | } 58 | case OST: 59 | { 60 | value = tension(T); 61 | break; 62 | } 63 | default: 64 | { 65 | value = INVALID_OUTID; 66 | break; 67 | } 68 | } 69 | return value; 70 | } 71 | 72 | double pair_prop(double v1, double v2, int o_id, region_fn regfn, 73 | prop_fn fn1, 74 | prop_fn fn2, 75 | prop_fn fn3, 76 | prop_fn fn4, 77 | prop_fn fn5) 78 | { 79 | 80 | int region = (*regfn)(v1, v2); 81 | double v; 82 | switch (region) 83 | { 84 | case 1: 85 | v = fn1(v1, v2, o_id); 86 | break; 87 | case 2: 88 | v = fn2(v1, v2, o_id); 89 | break; 90 | case 3: 91 | v = fn3(v1, v2, o_id); 92 | break; 93 | case 4: 94 | v = fn4(v1, v2, o_id); 95 | break; 96 | case 5: 97 | v = fn5(v1, v2, o_id); 98 | break; 99 | default: 100 | v = region; 101 | break; 102 | } 103 | return v; 104 | } 105 | 106 | double pT(double p, double T, int o_id) 107 | { 108 | return pair_prop(p, T, o_id, pT_region, pT_reg1, pT_reg2, pT_reg3, pT_reg4, pT_reg5); 109 | } 110 | 111 | double pT_reg(double p, double T, int o_id, properties_region pT_thermal, properties_region pT_ext) 112 | // o_id: output propertry 113 | { 114 | double value; 115 | switch (o_id) 116 | { 117 | case OT: 118 | value = T; 119 | break; 120 | case OP: 121 | value = p; 122 | break; 123 | case OV: 124 | case OD: 125 | case OH: 126 | case OS: 127 | case OU: 128 | case OCV: 129 | case OCP: 130 | case OW: 131 | value = pT_thermal(p, T, o_id); 132 | break; 133 | case ODV: 134 | case OKV: 135 | case OTC: 136 | case OTD: 137 | case OPR: 138 | case OST: 139 | value = pT_transport(p, T, o_id, pT_thermal); 140 | break; 141 | default: 142 | value = pT_ext(p, T, o_id); 143 | break; 144 | } 145 | return value; 146 | } 147 | -------------------------------------------------------------------------------- /src/common/seuif97.c: -------------------------------------------------------------------------------- 1 | /* 2 | The API 3 | 4 | */ 5 | #include 6 | #include "../r1/region1.h" 7 | #include "../r2/region2.h" 8 | #include "../r3/region3.h" 9 | #include "../r4/region4.h" 10 | #include "../r5/region5.h" 11 | #include "common.h" 12 | #include "constand.h" 13 | #include "../algo/algorithm.h" 14 | #include "seuif97.h" 15 | 16 | IF97_DLL double pt(double p, double t, int o_id) 17 | { 18 | if (o_id == OT) 19 | { 20 | return t; 21 | } 22 | else 23 | return pair_prop(p, t + 273.15, o_id, pT_region, pT_reg1, pT_reg2, pT_reg3, pT_reg4, pT_reg5); 24 | } 25 | 26 | IF97_DLL double ph(double p, double h, int o_id) 27 | { 28 | if (o_id == OT) 29 | { 30 | return pair_prop(p, h, o_id, ph_region, ph_reg1, ph_reg2, ph_reg3, ph_reg4, ph_reg5) - 273.15; 31 | } 32 | else 33 | return pair_prop(p, h, o_id, ph_region, ph_reg1, ph_reg2, ph_reg3, ph_reg4, ph_reg5); 34 | } 35 | 36 | IF97_DLL double ps(double p, double s, int o_id) 37 | { 38 | if (o_id == OT) 39 | { 40 | return pair_prop(p, s, o_id, ps_region, ps_reg1, ps_reg2, ps_reg3, ps_reg4, ps_reg5) - 273.15; 41 | } 42 | else 43 | return pair_prop(p, s, o_id, ps_region, ps_reg1, ps_reg2, ps_reg3, ps_reg4, ps_reg5); 44 | } 45 | 46 | IF97_DLL double hs(double h, double s, int o_id) 47 | { 48 | if (o_id == OT) 49 | { 50 | return pair_prop(h, s, o_id, hs_region, hs_reg1, hs_reg2, hs_reg3, hs_reg4, hs_reg5) - 273.15; 51 | } 52 | else 53 | return pair_prop(h, s, o_id, hs_region, hs_reg1, hs_reg2, hs_reg3, hs_reg4, hs_reg5); 54 | } 55 | 56 | IF97_DLL double px(double p, double x, int o_id) 57 | { 58 | if (o_id == OT) 59 | { 60 | return px_reg4(p, x, o_id) - 273.15; 61 | } 62 | else 63 | return px_reg4(p, x, o_id); 64 | } 65 | 66 | IF97_DLL double tx(double t, double x, int o_id) 67 | { 68 | double T = t + 273.15; 69 | return Tx_reg4(T, x, o_id); 70 | } 71 | 72 | IF97_DLL double pv(double p, double v, int o_id) 73 | { 74 | double value = pair_prop(p, v, o_id, pv_region, pv_reg1, pv_reg2, pv_reg3, pv_reg4, pv_reg5); 75 | 76 | if (o_id == OT) 77 | { 78 | return value - 273.15; 79 | } 80 | else 81 | { 82 | return value; 83 | } 84 | } 85 | 86 | IF97_DLL double th(double t, double h, int o_id) 87 | { 88 | if (o_id == OT) 89 | { 90 | return t; 91 | } 92 | else if (o_id == OH) 93 | { 94 | return h; 95 | } 96 | double T = t + 273.15; 97 | double value = pair_prop(T, h, o_id, Th_region, Th_reg1, Th_reg2, Th_reg3, Th_reg4, Th_reg5); 98 | return value; 99 | } 100 | 101 | IF97_DLL double ts(double t, double s, int o_id) 102 | { 103 | if (o_id == OT) 104 | { 105 | return t; 106 | } 107 | else if (o_id == OS) 108 | { 109 | return s; 110 | } 111 | double T = t + 273.15; 112 | double value = pair_prop(T, s, o_id, Ts_region, Ts_reg1, Ts_reg2, Ts_reg3, Ts_reg4, Ts_reg5); 113 | return value; 114 | } 115 | 116 | IF97_DLL double tv(double t, double v, int o_id) 117 | { 118 | if (o_id == OT) 119 | { 120 | return t; 121 | } 122 | else if (o_id == OV) 123 | { 124 | return v; 125 | } 126 | else if (o_id == OD) 127 | { 128 | return 1.0 / v; 129 | } 130 | double T = t + 273.15; 131 | double value = pair_prop(T, v, o_id, Tv_region, Tv_reg1, Tv_reg2, Tv_reg3, Tv_reg4, Tv_reg5); 132 | return value; 133 | } 134 | 135 | // sehx(h,x,o_id) - the propertry of `o_id`(thermodynamic) 136 | IF97_DLL double hx(double h, double x, int o_id) 137 | { 138 | if ((h > HMAX4) || (h < HMIN4) || (x > 1.0) || (x < 0.0)) 139 | { 140 | return INVALID_VALUE; 141 | } 142 | if (o_id == OH) 143 | return h; 144 | else if (o_id == OX) 145 | return x; 146 | double value = hx_reg4(h, x, o_id); 147 | if (o_id == OT) 148 | { 149 | return value - 273.15; 150 | } 151 | return value; 152 | } 153 | 154 | // seusx(s,x,o_id) - the propertry of `o_id`(thermodynamic) 155 | IF97_DLL double sx(double s, double x, int o_id) 156 | { 157 | if ((s > SMAX4) || (s < SMIN4) || (x > 1.0) || (x < 0.0)) 158 | { 159 | return INVALID_VALUE; 160 | }; 161 | if (o_id == OS) 162 | return s; 163 | else if (o_id == OX) 164 | return x; 165 | double value = sx_reg4(s, x, o_id); 166 | if (o_id == OT) 167 | { 168 | return value - 273.15; 169 | } 170 | return value; 171 | } 172 | -------------------------------------------------------------------------------- /src/common/seuif97.h: -------------------------------------------------------------------------------- 1 | /* 2 | The header file of SEUIF97 3 | 4 | Author: Cheng Maohua 5 | Email: cmh@seu.edu.cn 6 | */ 7 | 8 | #ifndef SEUIF97_H 9 | 10 | #define SEUIF97_H 11 | 12 | #ifdef __cplusplus 13 | extern "C" 14 | { 15 | #endif 16 | 17 | #ifndef IF97_DLL 18 | #ifdef WIN32 // || _WIN32 /* To Microsoft Visual Basic for Application */ 19 | #if defined(BUILD_DLL) 20 | #define IF97_DLL __stdcall __declspec(dllexport) 21 | #elif defined(USE_DLL) 22 | #define IF97_DLL __stdcall __declspec(dllimport) 23 | #else 24 | #define IF97_DLL 25 | #endif 26 | #else 27 | #define IF97_DLL 28 | #endif 29 | #endif 30 | 31 | IF97_DLL double pt(double p, double t, int o_id); 32 | IF97_DLL double ph(double p, double h, int o_id); 33 | IF97_DLL double ps(double p, double s, int o_id); 34 | IF97_DLL double pv(double p, double v, int o_id); 35 | IF97_DLL double th(double t, double h, int o_id); 36 | 37 | IF97_DLL double ts(double t, double s, int o_id); 38 | IF97_DLL double tv(double t, double v, int o_id); 39 | IF97_DLL double hs(double h, double s, int o_id); 40 | IF97_DLL double px(double p, double x, int o_id); 41 | IF97_DLL double tx(double t, double x, int o_id); 42 | // 43 | IF97_DLL double hx(double h, double x, int o_id); 44 | IF97_DLL double sx(double s, double x, int o_id); 45 | 46 | // Functions of Thermodynamic Process 47 | IF97_DLL double ishd(double pi, double ti, double pe); 48 | IF97_DLL double ief(double pi, double ti, double pe, double te); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/common/thermodynamic_process.c: -------------------------------------------------------------------------------- 1 | /* 2 | Thermodynamic process 3 | */ 4 | #include "common.h" 5 | #include "constand.h" 6 | #include "propertry_id.h" 7 | #include "seuif97.h" 8 | 9 | IF97_DLL double ishd(double pi, double ti, double pe) 10 | { 11 | double hi, si, he_isos; 12 | if (pi <= pe) 13 | return INVALID_VALUE; 14 | 15 | hi = pt(pi, ti, OH); 16 | if (hi <= 0) 17 | return INVALID_VALUE; 18 | 19 | si = pt(pi, ti, OS); 20 | if (si < -500) 21 | return INVALID_VALUE; 22 | 23 | he_isos = ps(pe, si, OH); 24 | if (he_isos < 0) 25 | return INVALID_VALUE; 26 | 27 | return (hi - he_isos); 28 | } 29 | 30 | // superheated steam zone , % 31 | IF97_DLL double ief(double pi, double ti, double pe, double te) 32 | { 33 | double hi, si, he_isos, he, se, ishd, ahd; 34 | if (pi <= pe) 35 | return INVALID_VALUE; 36 | if (ti <= te) 37 | return INVALID_VALUE; 38 | 39 | hi = pt(pi, ti, OH); 40 | if (hi < -500) 41 | return INVALID_VALUE; 42 | 43 | si = pt(pi, ti, OS); 44 | if (si < -500) 45 | return INVALID_VALUE; 46 | 47 | he_isos = ps(pe, si, OH); 48 | if (he_isos < -500) 49 | return INVALID_VALUE; 50 | ishd = (hi - he_isos); 51 | 52 | he = pt(pe, te, OH); 53 | if (he < -500) 54 | return INVALID_VALUE; 55 | se = pt(pe, te, OS); 56 | if (se < -1000) 57 | return INVALID_VALUE; 58 | 59 | if ((se - si) <= 0) 60 | return INVALID_VALUE; 61 | 62 | ahd = (hi - he); 63 | return (100.0 * ahd / ishd); 64 | } 65 | -------------------------------------------------------------------------------- /src/common/transport.c: -------------------------------------------------------------------------------- 1 | /* The transfort rroperties: 2 | Properties(): 3 | 4 | | Propertry | Unit | Symbol | o_id | 5 | | ------------------------------------- | :---------: |:-----: |:---------: | 6 | | Dynamic viscosity | kg/(m·s) | η | 24 | 7 | | Kinematic viscosity | m^2/s | ν | 25 | 8 | | Thermal conductivity | W/(m.K) | λ | 26 | 9 | | Thermal diffusivity | um^2/s | a | 27 | 10 | | Prandtl number | | Pr | 28 | 11 | | Surface tension | N/m | σ | 29 | 12 | 13 | */ 14 | #include 15 | #include "../common/constand.h" 16 | #include "../common/common.h" 17 | #include "../common/propertry_id.h" 18 | #include "../algo/algorithm.h" 19 | 20 | // Prandtl number=dv*cp/tc 21 | // * dv: Dynamic viscosity Pa.s 22 | // * cp: specific isobaric heat capacity 23 | // * tc: Thermal conductivity W/(m.K) 24 | double prandtl_number(double dv, double cp, double tc) 25 | { 26 | return 1.0E+3 * dv * cp / tc; 27 | } 28 | 29 | // Thermal diffusivity m²/s 30 | // * Thermal diffusivity = 1.0e-3*tc /(cp*d) 31 | // * cp: specific isobaric heat capacity 32 | // * tc: Thermal conductivity W/(m.K) 33 | // * d : Density kg/m³ 34 | double thermal_diffusivity(double tc, double cp, double d) 35 | { 36 | return 1.0e-3 * tc / (cp * d); 37 | } 38 | 39 | double kinematic_viscosity(double rho, double T) 40 | { 41 | double dv = viscosity(rho, T); 42 | return dv / rho; 43 | } 44 | 45 | double viscosity(double rho, double T) 46 | /* 47 | rho : float 48 | Density [kg/m³] 49 | T : float 50 | Temperature [K] 51 | mu : float 52 | Viscosity [Pa·s] 53 | IAPWS, Release on the IAPWS Formulation 2008 for the Viscosity of Ordinary 54 | Water Substance, http://www.iapws.org/relguide/viscosity.html 55 | */ 56 | { 57 | double Tr = T / tc_water; 58 | double Dr = rho / dc_water; 59 | 60 | double no[4] = {1.67752, 2.20462, 0.6366564, -0.241605}; 61 | double suma = 0.0; 62 | for (int i = 0; i < 4; i++) 63 | { 64 | suma += no[i] / IPOW(Tr, i); 65 | } 66 | double fi0 = 100.0 * sqrt(Tr) / suma; 67 | 68 | // Page 5 Table2 Coefficients Hij 69 | IJnData ijH[21] = { 70 | {0, 0, 5.20094e-1}, 71 | {1, 0, 8.50895e-2}, 72 | {2, 0, -1.08374}, 73 | {3, 0, -2.89555e-1}, 74 | {0, 1, 2.22531e-1}, 75 | {1, 1, 9.99115e-1}, 76 | {2, 1, 1.88797}, 77 | {3, 1, 1.26613}, 78 | {5, 1, 1.20573e-1}, 79 | {0, 2, -2.81378e-1}, 80 | {1, 2, -9.06851e-1}, 81 | {2, 2, -7.72479e-1}, 82 | {3, 2, -4.89837e-1}, 83 | {4, 2, -2.57040e-1}, 84 | {0, 3, 1.61913e-1}, 85 | {1, 3, 2.57399e-1}, 86 | {0, 4, -3.25372e-2}, 87 | {3, 4, 6.98452e-2}, 88 | {4, 5, 8.72102e-3}, 89 | {3, 6, -4.35673e-3}, 90 | {5, 6, -5.93264e-4}, 91 | }; 92 | 93 | suma = poly(1.0 / Tr - 1.0, Dr - 1.0, 21, ijH); 94 | double fi1 = exp(Dr * suma); 95 | double fi2 = 1.0; 96 | return fi0 * fi1 * fi2 * 1.0e-6; 97 | } 98 | 99 | double thCond(double rho, double T) 100 | /* quation for the thermal conductivity 101 | 102 | rho : float 103 | Density [kg/m³] 104 | T : float 105 | Temperature [K] 106 | k : float 107 | Thermal conductivity [W/mK] 108 | IAPWS, Release on the IAPWS Formulation 2011 for the Thermal Conductivity 109 | of Ordinary Water Substance, http://www.iapws.org/relguide/ThCond.html 110 | */ 111 | { 112 | double d = rho / dc_water; 113 | double Tr = T / tc_water; 114 | // Page 6 Table 1. Coefficients Lk in Eq.(16) 115 | double no[5] = { 116 | 2.443221e-3, 117 | 1.323095e-2, 118 | 6.770357e-3, 119 | -3.454586e-3, 120 | 4.096266e-4, 121 | }; 122 | double suma = 0.0; 123 | for (int i = 0; i < 5; i++) 124 | { 125 | suma += no[i] / IPOW(Tr, i); 126 | } 127 | double L0 = sqrt(Tr) / suma; 128 | // Page 6 Table 2. Coefficients Lij in Eq(17) 129 | double nij[5][6] = { 130 | {1.60397357, -0.646013523, 0.111443906, 0.102997357, -0.0504123634, 0.00609859258}, 131 | {2.33771842, -2.78843778, 1.53616167, -0.463045512, 0.0832827019, -0.00719201245}, 132 | {2.19650529, -4.54580785, 3.55777244, -1.40944978, 0.275418278, -0.0205938816}, 133 | {-1.21051378, 1.60812989, -0.621178141, 0.0716373224, 0.0, 0.0}, 134 | {-2.7203370, 4.57586331, -3.18369245, 1.1168348, -0.19268305, 0.012913842}, 135 | }; 136 | suma = 0.0; 137 | 138 | for (int i = 0; i < 5; i++) 139 | { 140 | double suma2 = 0.0; 141 | for (int j = 0; j < 6; j++) 142 | 143 | { 144 | suma2 += nij[i][j] * IPOW(d - 1.0, j); 145 | } 146 | suma += IPOW(1.0 / Tr - 1.0, i) * suma2; 147 | }; 148 | 149 | double L1 = exp(d * suma); 150 | 151 | double L2 = 0.0; 152 | return 1e-3 * (L0 * L1 + L2); 153 | } 154 | 155 | double tension(double T) 156 | /* T : float Temperature [K] 157 | 158 | Returns sigma : float Surface tension [N/m] 159 | 160 | Raises 161 | * 248.15 ≤ T ≤ 647 162 | * Estrapolate to -25ºC in supercooled liquid metastable state 163 | 164 | IAPWS, Revised Release on Surface Tension of Ordinary Water Substance 165 | June 2014, http://www.iapws.org/relguide/Surf-H2O.html 166 | */ 167 | { 168 | if (248.15 <= T && T <= tc_water) 169 | { 170 | double Tr = T / tc_water; 171 | return 1e-3 * (235.8 * pow(1.0 - Tr, 1.256) * (1.0 - 0.625 * (1.0 - Tr))); 172 | } 173 | else 174 | { 175 | return INVALID_VALUE; 176 | }; 177 | } 178 | -------------------------------------------------------------------------------- /src/r1/region1.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------- 2 | IAPWS-IF97 Region1: 3 | 1: IAPWS, R7-97(2012) 4 | IF97-Rev.pdf: P6-9 5 | 1)fundamental: (p,t)->v,u,s,h,cp,cv,w 6 | 2)backward: (p,h)->T, (p,s)->T 7 | 8 | 2: IAPWS, SR2-01(2014) 9 | Supp-PHS12-2014.pdf (h,s)->p 10 | 11 | Author: Cheng Maohua 12 | Email: cmh@seu.edu.cn 13 | */ 14 | #pragma once 15 | #include "../common/common.h" 16 | #include "../common/propertry_id.h" 17 | 18 | double gamma_reg1(double pi, double tau); 19 | double gamma_pi_reg1(double pi, double tau); 20 | double gamma_pipi_reg1(double pi, double tau); 21 | double gamma_pitau_reg1(double pi, double tau); 22 | double gamma_tau_reg1(double pi, double tau); 23 | double gamma_tautau_reg1(double pi, double tau); 24 | 25 | void polys_solo_0_i_reg1(double pi, double tau, double *poly, double *poly_pi); 26 | void polys_solo_0_j_reg1(double pi, double tau, double *poly, double *poly_tau); 27 | void polys_solo_i_j_reg1(double pi, double tau, double *poly_pi, double *poly_tau); 28 | void polys_solo_i_ii_reg1(double pi, double tau, double *poly_pi, double *poly_pipi); 29 | void polys_solo_i_ij_reg1(double pi, double tau, double *poly_pi, double *poly_pitau); 30 | void polys_solo_i_ii_ij_reg1(double pi, double tau, double *poly_pi, double *poly_pipi, double *poly_pitau); 31 | void polys_solo_i_ij_jj_reg1(double pi, double tau, double *poly_pi, double *poly_pitau, double *poly_tautau); 32 | void polys_solo_i_ii_ij_jj_reg1(double pi, double tau, double *poly_pi, double *poly_pipi, double *poly_pitau, double *poly_tautau); 33 | 34 | // IF97 fundamental: (p,t) 35 | double pT2v_reg1(double p, double T); 36 | double pT2u_reg1(double p, double T); 37 | double pT2s_reg1(double p, double T); 38 | double pT2h_reg1(double p, double T); 39 | double pT2cv_reg1(double p, double T); 40 | double pT2cp_reg1(double p, double T); 41 | double pT2w_reg1(double p, double T); 42 | 43 | // IF97 extended: (p,t) 44 | double pT2k_reg1(double p, double T); 45 | double pT2ipcec_reg1(double p, double T); 46 | double pT2kt_reg1(double p, double T); 47 | 48 | double pT2g_reg1(double p, double T); 49 | double pT2f_reg1(double p, double T); 50 | 51 | double pT2joule_reg1(double p, double T); 52 | double pT2ijoule_reg1(double p, double T); 53 | 54 | double pT2z_reg1(double p, double T); 55 | double pT2e_reg1(double p, double T); 56 | 57 | double pT2dpdtcv_reg1(double p, double T); 58 | double pT2dvdpct_reg1(double p, double T); 59 | double pT2dvdtcp_reg1(double p, double T); 60 | 61 | // IF97 backward: (p,h)->T, (p,s)->T,(h,s)->p 62 | double ph2T_reg1(double p, double h); 63 | double ps2T_reg1(double p, double s); 64 | double hs2p_reg1(double h, double s); 65 | 66 | // the extend input pairs 67 | // (p,v)->T (T,v)->p (T,s)->p 68 | double pv2T_reg1(double p, double v); 69 | double Tv2p_reg1(double T,double v); 70 | double Ts2p_reg1(double T, double s); 71 | double Th2p_reg1(double T, double h); 72 | 73 | // (p,T)-> properties 74 | double pT_ext_reg1(double p, double T, int o_id); 75 | double pT_thermal_reg1(double p, double T, int o_id); 76 | 77 | // pairs 78 | double pT_reg1(double p, double T, int o_id); 79 | double ph_reg1(double p, double h, int o_id); 80 | double ps_reg1(double p, double h, int o_id); 81 | double hs_reg1(double p, double h, int o_id); 82 | // the extend input pairs 83 | // (p,v) (T,v)p (T,s) 84 | double pv_reg1(double p, double v, int o_id); 85 | double Tv_reg1(double T, double v, int o_id); 86 | double Ts_reg1(double T, double s, int o_id); 87 | double Th_reg1(double T, double h, int o_id); 88 | -------------------------------------------------------------------------------- /src/r1/region1_T_phps.c: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------- 2 | // August 2007 IF97: IF97-Rev.pdf: P6-9 3 | // IAPWS -IF 97 Backware Equation for Region 1: 4 | // Backward (p,h)->T, (p,s)->T 5 | // (P,S)->T (P,H)->T 6 | // 7 | //--------------------------------------------------------------------------- 8 | #include 9 | #include "region1.h" 10 | #include "../algo/algorithm.h" 11 | #include "region1_coff.h" 12 | 13 | //------------------------------------------------------------- 14 | // Backward equation T(p,h) for region 1 15 | //-------------------------------------------------------------- 16 | double ph2T_reg1(double p, double h) 17 | { 18 | // Page 11, Table6 :Initialize coefficients and exponents (P,H)->T for region 1 19 | IJnData IJn[] = { 20 | {0, 0, -238.72489924521}, 21 | {0, 1, 404.21188637945}, 22 | {0, 2, 113.49746881718}, 23 | {0, 6, -5.8457616048039}, 24 | {0, 22, -1.528548241314E-04}, 25 | {0, 32, -1.0866707695377E-06}, 26 | {1, 0, -13.391744872602}, 27 | {1, 1, 43.211039183559}, 28 | {1, 2, -54.010067170506}, 29 | {1, 3, 30.535892203916}, 30 | {1, 4, -6.5964749423638}, 31 | {1, 10, 9.3965400878363E-03}, 32 | {1, 32, 1.157364750534E-07}, 33 | {2, 10, -2.5858641282073E-05}, 34 | {2, 32, -4.0644363084799E-09}, 35 | {3, 10, 6.6456186191635E-08}, 36 | {3, 32, 8.0670734103027E-11}, 37 | {4, 32, -9.3477771213947E-13}, 38 | {5, 32, 5.8265442020601E-15}, 39 | {6, 32, -1.5020185953503E-17}}; 40 | 41 | double pi, eta; 42 | double theta; 43 | pi = p / 1.0; 44 | eta = h / 2500.0 + 1.0; 45 | theta = poly(pi, eta, 20, IJn); 46 | return (1.0 *theta); 47 | 48 | /*double T1, T2, T, f1, f2; 49 | T1 = (1.0 * theta); 50 | f1 = h - pT2h_reg1(p, T1); 51 | if (fabs(f1) > xacc) 52 | { 53 | if (f1 > 0) 54 | T2 = (1.0 + f1 / h) * T1; // TODO: 1.05 用 1+f1/h 是不是更快,没有测试 55 | else 56 | T2 = (1.0 - f1 / h) * T1; 57 | 58 | f2 = h - pT2h_reg1(p, T2); 59 | 60 | T = rtsec2(pT2h_reg1, p, h, T1, T2, f1, f2, xacc, iMAX); 61 | } 62 | else 63 | T = T1; 64 | 65 | return T;*/ 66 | } 67 | 68 | //---------------------------------------------------------------- 69 | // Backward equation T(p,s) for region 1 70 | //---------------------------------------------------------------- 71 | double ps2T_reg1(double p, double s) 72 | // Page 12, Table 8 : Initialize coefficients and exponents (P,S)->T for region 1 73 | { 74 | IJnData IJn[] = { 75 | {0, 0, 0.17478268058307e3}, 76 | {0, 1, 0.34806930892873e2}, 77 | {0, 2, 0.65292584978455e1}, 78 | {0, 3, 0.33039981775489}, 79 | {0, 11, -0.19281382923196e-6}, 80 | 81 | {0, 31, -0.24909197244573e-22}, 82 | {1, 0, -0.26107636489332}, 83 | {1, 1, 0.22592965981586}, 84 | {1, 2, -0.64256463395226e-1}, 85 | {1, 3, 0.78876289270526e-2}, 86 | 87 | {1, 12, 0.35672110607366e-9}, 88 | {1, 31, 0.17332496994895e-23}, 89 | {2, 0, 0.56608900654837e-3}, 90 | {2, 1, -0.32635483139717e-3}, 91 | {2, 2, 0.44778286690632e-4}, 92 | 93 | {2, 9, -0.51322156908507e-9}, 94 | {2, 31, -0.42522657042207e-25}, 95 | {3, 10, 0.26400441360689e-12}, 96 | {3, 32, 0.78124600459723e-28}, 97 | {4, 32, -0.30732199903668e-30}}; 98 | 99 | double pi, sigma; 100 | double theta; 101 | pi = p / 1.0; 102 | sigma = s / 1.0 + 2.0; 103 | theta = poly(pi, sigma, 20, IJn); 104 | return (1.0*theta); 105 | 106 | /* 107 | // iteration: refine 108 | double T1, T2, T, f1, f2; 109 | T1 = (1.0 * theta); 110 | f1 = s - pT2s_reg1(p, T1); 111 | if (fabs(f1) > xacc) 112 | { 113 | if (f1 > 0) // pT2s_reg1(p,T1)< s ,the T1< expt T,so, T2=1.05*T1 T(T1,T2) 114 | T2 = (1.0 + f1 / s) * T1; 115 | else 116 | T2 = (1.0 - f1 / s) * T1; 117 | 118 | f2 = s - pT2s_reg1(p, T2); 119 | T = rtsec2(pT2s_reg1, p, s, T1, T2, f1, f2, xacc, iMAX); 120 | } 121 | else 122 | T = T1; 123 | 124 | return T;*/ 125 | } 126 | -------------------------------------------------------------------------------- /src/r1/region1_coff.h: -------------------------------------------------------------------------------- 1 | // Initialize coefficients and exponents for region 1 2 | 3 | #pragma once 4 | 5 | #include "../common/common.h" 6 | 7 | static const double r1pstar = 16.53; // MPa 8 | static const double r1Tstar = 1386.0; // K 9 | 10 | static IJnData IJn[] = { 11 | {0, -2, 0.14632971213167E+00}, 12 | {0, -1, -0.84548187169114E+00}, 13 | {0, 0, -0.37563603672040E+01}, 14 | {0, 1, 0.33855169168385E+01}, 15 | {0, 2, -0.95791963387872E+00}, 16 | 17 | {0, 3, 0.15772038513228E+00}, 18 | {0, 4, -0.16616417199501E-01}, 19 | {0, 5, 0.81214629983568E-03}, 20 | {1, -9, 0.28319080123804E-03}, 21 | {1, -7, -0.60706301565874E-03}, 22 | 23 | {1, -1, -0.18990068218419E-01}, 24 | {1, 0, -0.32529748770505E-01}, 25 | {1, 1, -0.21841717175414E-01}, 26 | {1, 3, -0.52838357969930E-04}, 27 | {2, -3, -0.47184321073267E-03}, 28 | 29 | {2, 0, -0.30001780793026E-03}, 30 | {2, 1, 0.47661393906987E-04}, 31 | {2, 3, -0.44141845330846E-05}, 32 | {2, 17, -0.72694996297594E-15}, 33 | {3, -4, -0.31679644845054E-04}, 34 | 35 | {3, 0, -0.28270797985312E-05}, 36 | {3, 6, -0.85205128120103E-09}, 37 | {4, -5, -0.22425281908000E-05}, 38 | {4, -2, -0.65171222895601E-06}, 39 | {4, 10, -0.14341729937924E-12}, 40 | 41 | {5, -8, -0.40516996860117E-06}, 42 | {8, -11, -0.12734301741641E-08}, 43 | {8, -6, -0.17424871230634E-09}, 44 | {21, -29, -0.68762131295531E-18}, 45 | {23, -31, 0.14478307828521E-19}, 46 | 47 | {29, -38, 0.26335781662795E-22}, 48 | {30, -39, -0.11947622640071E-22}, 49 | {31, -40, 0.18228094581404E-23}, 50 | {32, -41, -0.93537087292458E-25}}; 51 | -------------------------------------------------------------------------------- /src/r1/region1_gfe.c: -------------------------------------------------------------------------------- 1 | // Initialize coefficients and exponents for region 1 2 | #include 3 | #include "region1.h" 4 | #include "region1_coff.h" 5 | #include "../algo/algorithm.h" 6 | #include "region1_solo_ij.h" 7 | 8 | double gamma_reg1(double pi, double tau) 9 | { 10 | return poly_solo(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1); 11 | } 12 | 13 | double gamma_pi_reg1(double pi, double tau) 14 | { 15 | return -poly_solo_i(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1); 16 | } 17 | 18 | double gamma_tau_reg1(double pi, double tau) 19 | { 20 | return poly_solo_j(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1); 21 | } 22 | 23 | double gamma_tautau_reg1(double pi, double tau) 24 | { 25 | return poly_solo_jj(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1); 26 | } 27 | 28 | double gamma_pitau_reg1(double pi, double tau) 29 | { 30 | return -poly_solo_ij(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1); 31 | } 32 | 33 | double gamma_pipi_reg1(double pi, double tau) 34 | { 35 | return -poly_solo_ii(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1); 36 | } 37 | 38 | //------------------------------------------------------------------------------ 39 | // 40 | //---------------------------------------------------------------------------- 41 | 42 | void polys_solo_0_i_reg1(double pi, double tau, double *poly, double *poly_pi) 43 | { 44 | polys_solo_0_i(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1, poly, poly_pi); 45 | *poly_pi = -(*poly_pi); 46 | } 47 | 48 | void polys_solo_0_j_reg1(double pi, double tau, double *poly, double *poly_tau) 49 | { 50 | polys_solo_0_j(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1, poly, poly_tau); 51 | } 52 | 53 | void polys_solo_i_j_reg1(double pi, double tau, double *poly_pi, double *poly_tau) 54 | { 55 | polys_solo_i_j(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1, poly_pi, poly_tau); 56 | *poly_pi = -(*poly_pi); 57 | } 58 | 59 | void polys_solo_i_ii_reg1(double pi, double tau, double *poly_pi, double *poly_pipi) 60 | { 61 | polys_solo_i_ii(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1, poly_pi, poly_pipi); 62 | *poly_pi = -(*poly_pi); 63 | } 64 | 65 | void polys_solo_i_ij_reg1(double pi, double tau, double *poly_pi, double *poly_pitau) 66 | { 67 | polys_solo_i_ij(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1, poly_pi, poly_pitau); 68 | *poly_pi = -(*poly_pi); 69 | *poly_pitau = -(*poly_pitau); 70 | } 71 | 72 | void polys_solo_i_ii_ij_reg1(double pi, double tau, double *poly_pi, double *poly_pipi, double *poly_pitau) 73 | { 74 | polys_solo_i_ii_ij(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1, poly_pi,poly_pipi, poly_pitau); 75 | *poly_pi = -(*poly_pi); 76 | *poly_pitau = -(*poly_pitau); 77 | } 78 | 79 | void polys_solo_i_ij_jj_reg1(double pi, double tau, double *poly_pi, double *poly_pitau, double *poly_tautau) 80 | { 81 | polys_solo_i_ij_jj(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1, poly_pi,poly_pitau, poly_tautau); 82 | *poly_pi = -(*poly_pi); 83 | *poly_pitau = -(*poly_pitau); 84 | } 85 | 86 | void polys_solo_i_ii_ij_jj_reg1(double pi, double tau, double *poly_pi, double *poly_pipi, double *poly_pitau, double *poly_tautau) 87 | { 88 | polys_solo_i_ii_ij_jj(7.1 - pi, tau - 1.222, 34, IJn, i2soI, j2soJ, solo_ij_pow_reg1, poly_pi, poly_pipi, poly_pitau, poly_tautau); 89 | *poly_pi = -(*poly_pi); 90 | *poly_pitau = -(*poly_pitau); 91 | } -------------------------------------------------------------------------------- /src/r1/region1_out.c: -------------------------------------------------------------------------------- 1 | /* 2 | The API of region 1 3 | */ 4 | #include "region1.h" 5 | #include "../common/propertry_id.h" 6 | #include "../common/common.h" 7 | 8 | double pT_reg1(double p, double T, int o_id) 9 | // o_id: output propertry 10 | { 11 | double value = 0.0; 12 | switch (o_id) 13 | { 14 | case OX: 15 | value = 0.0; 16 | break; 17 | case OR: 18 | value = 1.0; 19 | break; 20 | default: 21 | value = pT_reg(p, T, o_id, pT_thermal_reg1, pT_ext_reg1); 22 | break; 23 | } 24 | return value; 25 | } 26 | 27 | double ph_reg1(double p, double h, int o_id) 28 | // o_id: output propertry 29 | { 30 | if (o_id == OP) 31 | return p; 32 | if (o_id == OH) 33 | return h; 34 | 35 | double T; 36 | T = ph2T_reg1(p, h); 37 | return pT_reg1(p, T, o_id); 38 | } 39 | 40 | double ps_reg1(double p, double s, int o_id) 41 | // o_id: output propertry 42 | { 43 | if (o_id == OP) 44 | return p; 45 | if (o_id == OS) 46 | return s; 47 | 48 | double T; 49 | T = ps2T_reg1(p, s); 50 | return pT_reg1(p, T, o_id); 51 | } 52 | 53 | double hs_reg1(double h, double s, int o_id) 54 | // o_id: output propertry 55 | { 56 | if (o_id == OH) 57 | return h; 58 | if (o_id == OS) 59 | return s; 60 | 61 | double p; 62 | p = hs2p_reg1(h, s); 63 | return ph_reg1(p, h, o_id); 64 | } 65 | 66 | //---------------------------------------- 67 | // the extend input pairs (p.v) 68 | //------------------------------------------------------------------ 69 | double pv_reg1(double p, double v, int o_id) 70 | // o_id: output propertry 71 | { 72 | if (o_id == OP) 73 | return p; 74 | if (o_id == OV) 75 | return v; 76 | 77 | double T; 78 | T = pv2T_reg1(p, v); 79 | return pT_reg1(p, T, o_id); 80 | } 81 | 82 | double Tv_reg1(double T, double v, int o_id) 83 | // o_id: output propertry 84 | { 85 | if (o_id == OT) 86 | return T; 87 | if (o_id == OV) 88 | return v; 89 | 90 | double p; 91 | p = Tv2p_reg1(T, v); 92 | return pT_reg1(p, T, o_id); 93 | } 94 | 95 | // (T,s) 96 | double Ts_reg1(double T, double s, int o_id) 97 | // o_id: output propertry 98 | { 99 | if (o_id == OT) 100 | return T; 101 | if (o_id == OS) 102 | return s; 103 | 104 | double p; 105 | p = Ts2p_reg1(T, s); 106 | return pT_reg1(p, T, o_id); 107 | } 108 | 109 | 110 | // (T,h) 111 | double Th_reg1(double T, double h, int o_id) 112 | // o_id: output propertry 113 | { 114 | if (o_id == OT) 115 | return T; 116 | if (o_id == OH) 117 | return h; 118 | 119 | double p = Th2p_reg1(T, h); 120 | if (o_id == OP) 121 | return p; 122 | return pT_reg1(p, T, o_id); 123 | } -------------------------------------------------------------------------------- /src/r1/region1_p_hs.c: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------- 2 | IAPWS -IF 97 Backware Equation (H,S)->P for Region 1: 3 | IAPWS-IF97-S01: Supp-PHS12-2014.pdf June 2014 4 | (h,s)->p 5 | -------------------------------------------------------------------- */ 6 | 7 | #include 8 | #include "region1.h" 9 | #include "../algo/algorithm.h" 10 | 11 | // helper for iter (h,s)->p 12 | double ph2s_reg1(double p, double h) 13 | { 14 | double T; 15 | T = ph2T_reg1(p, h); 16 | return pT2s_reg1(p, T); 17 | } 18 | 19 | //---------------------------------------------------------------- 20 | // Backward equation p(h,s) for region 1 21 | //---------------------------------------------------------------- 22 | double hs2p_reg1(double h, double s) 23 | { 24 | // Page 5, Table 2 : 25 | // Initialize coefficients and exponents (H,S)->P for region 1 26 | IJnData IJn[] = { 27 | {0, 0, -.691997014660582}, 28 | {0, 1, -.183612548787560e2}, 29 | {0, 2, -.928332409297335e1}, 30 | {0, 4, .659639569909906e2}, 31 | {0, 5, -.162060388912024e2}, 32 | 33 | {0, 6, .450620017338667e3}, 34 | {0, 8, .854680678224170e3}, 35 | {0, 14, .607523214001162e4}, 36 | {1, 0, .326487682621856e2}, 37 | {1, 1, -.269408844582931e2}, 38 | 39 | {1, 4, -.319947848334300e3}, 40 | {1, 6, -.928354307043320e3}, 41 | {2, 0, .303634537455249e2}, 42 | {2, 1, -.650540422444146e2}, 43 | {2, 10, -.430991316516130e4}, 44 | 45 | {3, 4, -.747512324096068e3}, 46 | {4, 1, .730000345529245e3}, 47 | {4, 4, .114284032569021e4}, 48 | {5, 0, -.436407041874559e3}}; 49 | double eta, sigma; 50 | double pi; 51 | eta = h / 3400.0 + 0.05; 52 | sigma = s / 7.6 + 0.05; 53 | pi= poly(eta,sigma , 19,IJn); 54 | return (100.0*pi); 55 | 56 | /*// iteration: refine 57 | double p1, p2, p, f1, f2; 58 | p1 = (100.0 * pi); 59 | f1 = s - ph2s_reg1(p1, h); 60 | if (fabs(f1) > xacc) 61 | { 62 | if (f1 > 0) // pT2s_reg1(p,h)< s ,the p1< expt p,so, p2=1.05*p1 p(p1,p2) 63 | p2 = (1.0 + f1 / s) * p1; 64 | else 65 | p2 = (1.0 - f1 / s) * p1; 66 | 67 | f2 = s - ph2s_reg1(p2, h); 68 | p = rtsec1(ph2s_reg1, h, s, p1, p2, f1, f2, xacc, iMAX); 69 | } 70 | else 71 | p = p1; 72 | 73 | return p;*/ 74 | } 75 | -------------------------------------------------------------------------------- /src/r1/region1_pair.ext.c: -------------------------------------------------------------------------------- 1 | /* 2 | The extended pairs 3 | (p,v)->T 4 | (T,v)->p (T,h)->p (T,s)->p 5 | */ 6 | #include 7 | #include 8 | #include "../common/constand.h" 9 | #include "../common/propertry_id.h" 10 | #include "../algo/algorithm.h" 11 | #include "region1.h" 12 | #include "region1_coff.h" 13 | #include "region1_solo_ij.h" 14 | #include "../r4/region4.h" 15 | 16 | // Region 1 (p,v)->T using the secant method and refine adjust 17 | // * p: pressure MPa 18 | // * v: specific volume m^3/kg 19 | // * T: temperature K 20 | double pv2T_reg1(double p, double v) 21 | { 22 | double T1, T2, f1, f, v1, v2, T; 23 | T1 = TMIN1; 24 | v1 = pT2v_reg1(p, T1); 25 | if ((p >= 16.5291643) && (p <= 100.0)) 26 | { 27 | T2 = TMAX1; 28 | } 29 | else 30 | { 31 | T2 = TSat(p); 32 | }; 33 | v2 = pT2v_reg1(p, T2); 34 | f = v - pT2v_reg1(p, T2); 35 | if ((v2 - v1) != 0.0) 36 | { 37 | T1 = T1 + (T2 - T1) * (v - v1) / (v2 - v1); 38 | } 39 | f1 = v - pT2v_reg1(p, T1); 40 | T = rtsec2(pT2v_reg1, p, v, T1, T2, f1, f, xacc, iMAX); 41 | if (T >= 300) 42 | if (fabs(f1) < xacc) 43 | return (T1); 44 | 45 | f = v - pT2v_reg1(p, T); 46 | if (fabs(f) > xacc) 47 | { 48 | int success = 0; 49 | int sum = 0; 50 | T1 = T; 51 | f1 = f; 52 | if (f < 0) // t大了 53 | { 54 | while (!success) 55 | { 56 | T1 -= 0.1; 57 | if (T1 < 273.15) 58 | { 59 | T = 273.15; 60 | break; 61 | }; 62 | f1 = v - pT2v_reg1(p, T1); 63 | if (fabs(f1) < fabs(f)) 64 | { 65 | f = f1; 66 | T = T1; 67 | } 68 | if (fabs(f1) < xacc) 69 | { 70 | T = T1; 71 | break; 72 | } 73 | sum += 1; 74 | if (sum > 10000) 75 | success = 1; 76 | }; 77 | } 78 | else 79 | { 80 | while (!success) 81 | { 82 | T1 += 0.1; 83 | if (T1 > 623.15) 84 | { 85 | T = 623.15; 86 | break; 87 | }; 88 | f1 = v - pT2v_reg1(p, T1); 89 | if (fabs(f1) < fabs(f)) 90 | { 91 | f = f1; 92 | T = T1; 93 | } 94 | if (100 * fabs(f1) < xacc) 95 | { 96 | T = T1; 97 | break; 98 | } 99 | sum += 1; 100 | if (sum > 10000) 101 | { 102 | success = 1; 103 | } 104 | } 105 | } 106 | }; 107 | // 1 在低温区,v变化很小, 108 | // 2 在低温,低压区,v变化很小,同时变化规律发生反方向变化, T加,v减 109 | if (T < 290) 110 | { 111 | }; 112 | if (T < TMIN1) 113 | { 114 | T = TMIN1; 115 | } 116 | else 117 | { 118 | if (T > TMAX1) 119 | { 120 | T = TMAX1; 121 | }; 122 | }; 123 | return (T); 124 | } 125 | 126 | // Region 1 (T,v)->p using the secant method 127 | // T: temperature K 128 | // v: specific volume m^3/kg 129 | // p: pressure MPa 130 | double Tv2p_reg1(double T, double v) 131 | { 132 | double p1 = 0.3 * (pSat(T) + PMAX1); 133 | double p2 = 1.05 * p1; 134 | double f1 = v - pT2v_reg1(p1, T); 135 | double f = v - pT2v_reg1(p2, T); 136 | double p = rtsec1(pT2v_reg1, T, v, p1, p2, f1, f, xacc, iMAX); 137 | return p; 138 | } 139 | 140 | //---------------------------------------------- 141 | // (T,s)->p 142 | //---------------------------------------------- 143 | double Ts2p_reg1(double T, double s) 144 | { 145 | double tau, p, p1, p2, pmin1, s1, s2, f1, f2; 146 | pmin1 = pSat(T); 147 | p1 = pmin1; 148 | s1 = pT2s_reg1(p1, T); 149 | f1 = s - s1; 150 | p2 = PMAX1; 151 | s2 = pT2s_reg1(p2, T); 152 | f2 = s - s2; 153 | p1 = p2 - (p2 - p1) * (s - s2) / (s1 - s2); 154 | if (p1 < pmin1) 155 | p1 = pmin1; 156 | s1 = pT2s_reg1(p1, T); 157 | f1 = s - s1; 158 | if (fabs(f1) < xacc) 159 | return (p1); 160 | p = rtsec1(pT2s_reg1, T, s, p1, p2, f1, f2, xacc, iMAX); 161 | if (p > PMAX1) 162 | p = PMAX1; 163 | if (p < pmin1) 164 | p = pmin1; 165 | return (p); 166 | } 167 | 168 | // Region 1 (T,h)->p using the secant method 169 | // * T: temperature K 170 | // * h: specific enthalpy kJ/kg 171 | // * p: pressure MPa 172 | double Th2p_reg1(double T, double h) 173 | { 174 | double pmin1 = pSat(T); 175 | double p1 = pmin1; 176 | double p2 = PMAX1; // p1 + stepa 177 | double h1 = pT2h_reg1(p1, T); 178 | if (fabs(h - h1) < xacc) 179 | { 180 | return p1; 181 | }; 182 | double h2 = pT2h_reg1(p2, T); 183 | if (fabs(h - h2) < xacc) 184 | { 185 | return p2; 186 | } 187 | 188 | double f1 = h - pT2h_reg1(p1, T); 189 | double f = h - pT2h_reg1(p2, T); 190 | double p = rtsec1(pT2h_reg1, T, h, p1, p2, f1, f, xacc, iMAX); 191 | 192 | if (p > PMAX1) 193 | { 194 | p = PMAX1; 195 | } 196 | if (p < pmin1) 197 | { 198 | p = pmin1; 199 | } 200 | return p; 201 | } 202 | -------------------------------------------------------------------------------- /src/r1/region1_solo_ij.h: -------------------------------------------------------------------------------- 1 | /* 2 | the solo I,j 3 | */ 4 | #pragma once 5 | 6 | #include "../algo/algorithm.h" 7 | 8 | static const int soI[13] = {0, 1, 2, 3, 4, 5, 8, 21, 23, 29, 30, 31, 32}; 9 | 10 | static int i2soI[34] = {0, 0, 0, 0, 0, 11 | 0, 0, 0, 1, 1, 12 | 1, 1, 1, 1, 2, 13 | 2, 2, 2, 2, 3, 14 | 3, 3, 4, 4, 4, 15 | 5, 6, 6, 7, 8, 16 | 9, 10, 11, 12}; 17 | 18 | static const int soJ[25] = {-2, -1, 0, 1, 2, 3, 4, 5, -9, -7, -3, 17, -4, 6, -5, 10, 19 | -8, -11, -6, -29, -31, -38, -39, -40, -41}; 20 | 21 | static int j2soJ[34] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 5, 10, 2, 3, 5, 11, 12, 2, 22 | 13, 14, 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}; 23 | 24 | void solo_ij_pow_reg1(double vi, double vj, double *soI_pow, double *soJ_pow); -------------------------------------------------------------------------------- /src/r1/region1_solo_power.c: -------------------------------------------------------------------------------- 1 | /* 2 | The solo powers in region1 3 | */ 4 | #include "../algo/algorithm.h" 5 | #include "region1.h" 6 | #include "region1_coff.h" 7 | #include "region1_solo_ij.h" 8 | 9 | void solo_ij_pow_reg1(double vi,double vj,double *soI_pow,double *soJ_pow) 10 | { 11 | // [0, 1, 2, 3, 4, 5, 8, 21, 23, 29, 30, 31, 32]; 12 | 13 | soI_pow[0] = 1.0; 14 | for(int k=1; k<=5;k++) { 15 | soI_pow[k] = soI_pow[k - 1] * vi; 16 | } 17 | double vi2 = vi * vi; 18 | soI_pow[6] = soI_pow[5] * vi2 * vi; //8 19 | soI_pow[7] = soI_pow[6] * soI_pow[6] * soI_pow[5]; //21 20 | soI_pow[8] = soI_pow[7] * vi2; //23 21 | soI_pow[9] = soI_pow[6] * soI_pow[7]; 22 | for(int k=10; k<=12;k++) { 23 | soI_pow[k] = soI_pow[k - 1] * vi; 24 | } 25 | 26 | // -2, -1, 0, 1, 2, 3, 4, 5, -9, -7, -3, 17, -4, 6, -5, 10, -8, -11, -6, -29, -31, -38, -39, -40, -41, 27 | double vj2 = vj * vj; 28 | soJ_pow[0] = 1.0 / vj2; //-2 29 | soJ_pow[1] = 1.0 / vj; //-1 30 | soJ_pow[2] = 1.0; // 0 31 | soJ_pow[3] = vj; // 1 32 | soJ_pow[4] = vj2; //2 33 | soJ_pow[5]=soJ_pow[4]*vj; //3 34 | soJ_pow[6]=soJ_pow[5]*vj; //4 35 | soJ_pow[7]=soJ_pow[6]*vj; //5 36 | 37 | double J_pow7 = vj2 * soJ_pow[7]; 38 | double J_pow9 = soJ_pow[6] * soJ_pow[7]; 39 | double J_pow10 = J_pow9 *vj; 40 | 41 | soJ_pow[8] = 1.0 / J_pow9; //-9 42 | soJ_pow[9] = 1.0 / J_pow7; // -7 43 | soJ_pow[10] = 1.0 / soJ_pow[5]; // -3 44 | 45 | soJ_pow[11] = J_pow7 * J_pow10; // 17 46 | soJ_pow[12] = 1.0 / soJ_pow[6]; // -4 47 | soJ_pow[13] = soJ_pow[7] * vj; //6 48 | soJ_pow[14] = 1.0 / soJ_pow[7]; //-5 49 | soJ_pow[15] = J_pow10; // 10 50 | 51 | soJ_pow[16] = 1.0 / J_pow7/ vj; //-8 52 | soJ_pow[17] = 1.0 / soJ_pow[15]/ vj; //-11 53 | soJ_pow[18] = 1.0 / soJ_pow[13]; //-6 54 | soJ_pow[19] = (1.0 / J_pow10) * soJ_pow[16] * soJ_pow[17]; // -29 55 | soJ_pow[20] = soJ_pow[19] * soJ_pow[0]; //-31 56 | 57 | soJ_pow[21] = soJ_pow[20] * soJ_pow[9]; //-38 58 | for(int k=22; k<=24; k++) { 59 | // -39, -40, -41 60 | soJ_pow[k] = soJ_pow[k - 1] / vj; 61 | } 62 | 63 | 64 | /*for(int k=0; k<13; k++) { 65 | soI_pow[k] = IPOW(vi, soI[k]); 66 | } 67 | for(int k=0; k<25; k++) { 68 | soJ_pow[k] = IPOW(vj, soJ[k]); 69 | }*/ 70 | } 71 | -------------------------------------------------------------------------------- /src/r2/region2.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------- 2 | If97 and supp release 3 | 4 | 1: IF97 IAPWS, R7-97(2012) 5 | IF97-Rev.pdf: P12-32 6 | 1)fundamental: (p,t)->v,u,s,h,cp,cv,w 7 | 2)backward: (p,h)->T, (p,s)->T 8 | 9 | 2: IAPWS, SR2-01(2014) 10 | Supp-PHS12-2014.pdf (h,s)->p 11 | --------------------------------------------------------------*/ 12 | #pragma once 13 | 14 | #include "../common/common.h" 15 | 16 | double gamma0_reg2(double tau, double pi); 17 | double gamma0_pi_reg2(double pi); 18 | double gamma0_pipi_reg2(double pi); 19 | double gamma0_tau_reg2(double tau); 20 | double gamma0_tautau_reg2(double tau, double pi); 21 | double gamma0_pitau_reg2(); 22 | 23 | double gammar_reg2(double pi, double tau); 24 | double gammar_pi_reg2(double pi, double tau); 25 | double gammar_pipi_reg2(double pi, double tau); 26 | double gammar_pitau_reg2(double pi, double tau); 27 | double gammar_tau_reg2(double pi, double tau); 28 | double gammar_tautau_reg2(double pi, double tau); 29 | void polys_solo_0_i_reg2(double pi, double tau, double *poly, double *poly_pi); 30 | void polys_solo_0_j_reg2(double pi, double tau, double *poly, double *poly_tau); 31 | void polys_solo_i_j_reg2(double pi, double tau, double *poly_pi, double *poly_tau); 32 | void polys_solo_i_ii_reg2(double pi, double tau, double *poly_pi, double *poly_pipi); 33 | void polys_solo_i_ij_reg2(double pi, double tau, double *poly_pi, double *poly_pitau); 34 | void polys_solo_i_ii_ij_reg2(double pi, double tau, double *poly_pi, double *poly_pipi, double *poly_pitau); 35 | void polys_solo_i_ij_jj_reg2(double pi, double tau, double *poly_pi, double *poly_pitau, double *poly_tautau); 36 | void polys_solo_i_ii_ij_jj_reg2(double pi, double tau, double *poly_pi, double *poly_pipi, double *poly_pitau, double *poly_tautau); 37 | 38 | // IF97 fundamental: (p,t) 39 | double pT2v_reg2(double p, double T); 40 | double pT2u_reg2(double p, double T); 41 | double pT2s_reg2(double p, double T); 42 | double pT2h_reg2(double p, double T); 43 | double pT2cv_reg2(double p, double T); 44 | double pT2cp_reg2(double p, double T); 45 | double pT2w_reg2(double p, double T); 46 | 47 | // IF97 extended: (p,t) 48 | double pT2k_reg2(double p, double T); 49 | double pT2ipcec_reg2(double p, double T); 50 | double pT2kt_reg2(double p, double T); 51 | 52 | double pT2g_reg2(double p, double T); 53 | double pT2f_reg2(double p, double T); 54 | 55 | double pT2joule_reg2(double p, double T); 56 | double pT2ijoule_reg2(double p, double T); 57 | 58 | double pT2z_reg2(double p, double T); 59 | double pT2e_reg2(double p, double T); 60 | 61 | double pT2dpdtcv_reg2(double p, double T); 62 | double pT2dvdpct_reg2(double p, double T); 63 | double pT2dvdtcp_reg2(double p, double T); 64 | 65 | double pT2v_reg2(double p, double T); 66 | double pT2u_reg2(double p, double T); 67 | double pT2s_reg2(double p, double T); 68 | double pT2h_reg2(double p, double T); 69 | double pT2cp_reg2(double p, double T); 70 | double pT2cv_reg2(double p, double T); 71 | double pT2w_reg2(double p, double T); 72 | 73 | double ph2T_reg2(double p, double h); 74 | double ps2T_reg2(double p, double s); 75 | double hs2p_reg2(double h, double s); 76 | 77 | double ph2T_reg2a(double p, double h); 78 | double ph2T_reg2b(double p, double h); 79 | double ph2T_reg2c(double p, double h); 80 | 81 | double ps2T_reg2a(double p, double s); 82 | double ps2T_reg2b(double p, double s); 83 | double ps2T_reg2c(double p, double s); 84 | 85 | double hs2p_reg2a(double h, double s); 86 | double hs2p_reg2b(double h, double s); 87 | double hs2p_reg2c(double h, double s); 88 | 89 | // (p,T) ->properties 90 | double pT_ext_reg2(double p, double T, int o_id); 91 | double pT_thermal_reg2(double p, double T, int o_id); 92 | 93 | // the extend input pairs 94 | // (p,v)->T (T,v)->p (T,s)->p 95 | double pv2T_reg2(double p, double v); 96 | double Tv2p_reg2(double T, double v); 97 | double Ts2p_reg2(double T, double s); 98 | double Th2p_reg2(double T, double h); 99 | 100 | // pairs s 101 | double pT_reg2(double p, double T, int o_id); 102 | double ph_reg2(double p, double h, int o_id); 103 | double ps_reg2(double p, double h, int o_id); 104 | double hs_reg2(double p, double h, int o_id); 105 | // the extend input pairs 106 | // (p,v) (T,v)p (T,s) (T,h) 107 | double pv_reg2(double p, double v, int o_id); 108 | double Tv_reg2(double T, double v, int o_id); 109 | double Ts_reg2(double T, double s, int o_id); 110 | double Th_reg2(double T, double h, int o_id); 111 | -------------------------------------------------------------------------------- /src/r2/region2_coff.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../common/common.h" 3 | static const double r2Tstar = 540.0; // K 4 | static const double r2pstar = 1.0; // Mpa 为减少计算,没有使用这个变量 5 | 6 | static int r2j0[9] = {0, 1, -5, -4, -3, 7 | -2, -1, 2, 3}; 8 | 9 | static double n0[9] = {-9.6927686500217, 10 | 10.086655968018, 11 | -0.005608791128302, 12 | 0.071452738081455, 13 | -0.40710498223928, 14 | 1.4240819171444, 15 | -4.383951131945, 16 | -0.28408632460772, 17 | 0.021268463753307}; 18 | 19 | // Table 11 Page 13 The residual part gamma'r for region 2, Eq. (17) 20 | // 43 items 21 | static IJnData IJn[] = { 22 | {1, 0, -0.17731742473213E-02}, 23 | {1, 1, -0.17834862292358E-01}, 24 | {1, 2, -0.45996013696365E-01}, 25 | {1, 3, -0.57581259083432E-01}, 26 | {1, 6, -0.5032527872793E-01}, 27 | {2, 1, -0.33032641670203E-04}, 28 | {2, 2, -0.18948987516315E-03}, 29 | {2, 4, -0.39392777243355E-02}, 30 | {2, 7, -0.43797295650573E-01}, 31 | {2, 36, -2.6674547914087E-05}, 32 | {3, 0, 0.20481737692309E-07}, 33 | {3, 1, 0.43870667284435E-06}, 34 | {3, 3, -0.3227767723857E-04}, 35 | {3, 6, -0.15033924542148E-02}, 36 | {3, 35, -0.040668253562649}, 37 | {4, 1, -7.8847309559367E-10}, 38 | {4, 2, 1.2790717852285E-08}, 39 | {4, 3, 4.8225372718507E-07}, 40 | {5, 7, 2.2922076337661E-06}, 41 | {6, 3, -1.6714766451061E-11}, 42 | {6, 16, -2.1171472321355E-03}, 43 | {6, 35, -23.895741934104}, 44 | {7, 0, -5.905956432427E-18}, 45 | {7, 11, -1.2621808899101E-06}, 46 | {7, 25, -0.038946842435739}, 47 | {8, 8, 1.1256211360459E-11}, 48 | {8, 36, -8.2311340897998}, 49 | {9, 13, 1.9809712802088E-08}, 50 | {10, 4, 1.0406965210174E-19}, 51 | {10, 10, -1.0234747095929E-13}, 52 | {10, 14, -1.0018179379511E-09}, 53 | {16, 29, -8.0882908646985E-11}, 54 | {16, 50, 0.10693031879409}, 55 | {18, 57, -0.33662250574171}, 56 | {20, 20, 8.9185845355421E-25}, 57 | {20, 35, 3.0629316876232E-13}, 58 | {20, 48, -4.2002467698208E-06}, 59 | {21, 21, -5.9056029685639E-26}, 60 | {22, 53, 3.7826947613457E-06}, 61 | {23, 39, -1.2768608934681E-15}, 62 | {24, 26, 7.3087610595061E-29}, 63 | {24, 40, 5.5414715350778E-17}, 64 | {24, 58, -9.436970724121E-07}, 65 | }; -------------------------------------------------------------------------------- /src/r2/region2_gfe.c: -------------------------------------------------------------------------------- 1 | 2 | //--------------------------------------------------------------------------- 3 | // IAPWS -IF 97 Basic Equation for Region 2: Release : IF97-rev August 2007 4 | // The dimensionless Gibbs free energy gamma and its derivatives 5 | // REGION 2 G(p,T) EQUATIONS : Eq. (15), P13 6 | // the ideal-gas part : Eq. (16) 7 | // Cheng Maohua 8 | //------------------------------- 9 | 10 | // Initialize coefficients and exponents for region 2 11 | #include 12 | #include "../algo/algorithm.h" 13 | #include "region2.h" 14 | #include "region2_coff.h" 15 | #include "region2_solo_ij.h" 16 | 17 | // Ideal-gas part of fundamental equation for region 2 18 | // Eq16 P13 19 | double gamma0_reg2(double pi, double tau) 20 | 21 | { 22 | double gamma0 = log(pi); 23 | for (int i = 0; i < 9; i++) 24 | gamma0 += n0[i] * IPOW(tau, r2j0[i]); 25 | return gamma0; 26 | } 27 | 28 | double gamma0_pi_reg2(double pi) 29 | // First derivative in pi of ideal-gas part of fundamental equation for region 2 30 | { 31 | return 1.0 / pi; 32 | } 33 | 34 | double gamma0_pipi_reg2(double pi) 35 | // Second derivative in pi of ideal-gas part of fundamental equation for region 2 36 | { 37 | return -1.0 / pi / pi; 38 | } 39 | 40 | double gamma0_tau_reg2(double tau) 41 | // First derivative in tau of ideal-gas part of fundamental equation for region 2 42 | { 43 | double gamma0tau = 0.0; 44 | for (int i = 0; i < 9; i++) 45 | gamma0tau += n0[i] * r2j0[i] * IPOW(tau, r2j0[i] - 1); 46 | return gamma0tau; 47 | } 48 | 49 | double gamma0_tautau_reg2(double pi, double tau) 50 | // Second derivative in tau of ideal-gas part of fundamental equation for region 2 51 | { 52 | double gamma0tautau = 0.0; 53 | for (int i = 0; i < 9; i++) 54 | gamma0tautau += n0[i] * r2j0[i] * (r2j0[i] - 1) * IPOW(tau, r2j0[i] - 2); 55 | return gamma0tautau; 56 | } 57 | 58 | double gamma0_pitau_reg2() 59 | // Second derivative in pi and tau of ideal-gas part of fundamental equation for region 2 60 | { 61 | return 0.0; 62 | } 63 | 64 | //----------------------------------------------------------------- 65 | // polynominal with solo i,j 66 | //-------------------------------------------------------------------------------- 67 | 68 | double gammar_reg2(double pi, double tau) 69 | { 70 | return poly_solo(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2); 71 | } 72 | 73 | double gammar_pi_reg2(double pi, double tau) 74 | { 75 | return poly_solo_i(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2); 76 | } 77 | 78 | double gammar_pipi_reg2(double pi, double tau) 79 | { 80 | return poly_solo_ii(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2); 81 | } 82 | 83 | double gammar_pitau_reg2(double pi, double tau) 84 | { 85 | return poly_solo_ij(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2); 86 | } 87 | 88 | double gammar_tau_reg2(double pi, double tau) 89 | { 90 | return poly_solo_j(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2); 91 | } 92 | 93 | double gammar_tautau_reg2(double pi, double tau) 94 | { 95 | return poly_solo_jj(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2); 96 | } 97 | 98 | //----------------------------------------------------------------- 99 | // multiple polynominal with solo i,j 100 | //-------------------------------------------------------------------------------- 101 | 102 | void polys_solo_0_i_reg2(double pi, double tau, double *poly, double *poly_pi) 103 | { 104 | polys_solo_0_i(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2, poly, poly_pi); 105 | } 106 | 107 | void polys_solo_i_j_reg2(double pi, double tau, double *poly_pi, double *poly_tau) 108 | { 109 | polys_solo_i_j(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2, poly_pi, poly_tau); 110 | } 111 | 112 | void polys_solo_0_j_reg2(double pi, double tau, double *poly, double *poly_tau) 113 | { 114 | polys_solo_0_j(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2, poly, poly_tau); 115 | } 116 | 117 | void polys_solo_i_ij_reg2(double pi, double tau, double *poly_pi, double *poly_pitau) 118 | { 119 | polys_solo_i_ij(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2, poly_pi, poly_pitau); 120 | } 121 | 122 | void polys_solo_i_ii_reg2(double pi, double tau, double *poly_pi, double *poly_pipi) 123 | { 124 | polys_solo_i_ii(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2, poly_pi, poly_pipi); 125 | } 126 | 127 | void polys_solo_i_ij_jj_reg2(double pi, double tau, double *poly_pi, double *poly_pitau, double *poly_tautau) 128 | { 129 | polys_solo_i_ij_jj(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2, poly_pi, poly_pitau, poly_tautau); 130 | } 131 | 132 | void polys_solo_i_ii_ij_reg2(double pi, double tau, double *poly_pi, double *poly_pipi, double *poly_pitau) 133 | { 134 | polys_solo_i_ii_ij(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2, poly_pi, poly_pipi, poly_pitau); 135 | } 136 | 137 | void polys_solo_i_ii_ij_jj_reg2(double pi, double tau, double *poly_pi, double *poly_pipi, double *poly_pitau, double *poly_tautau) 138 | { 139 | polys_solo_i_ii_ij_jj(pi, tau - 0.5, 43, IJn, i2soI, j2soJ, solo_i_j_power_reg2, poly_pi, poly_pipi, poly_pitau, poly_tautau); 140 | } -------------------------------------------------------------------------------- /src/r2/region2_out.c: -------------------------------------------------------------------------------- 1 | /* 2 | The APT of region 2 3 | 4 | */ 5 | #include "region2.h" 6 | #include "../common/propertry_id.h" 7 | #include "../common/common.h" 8 | 9 | double pT_reg2(double p, double T, int o_id) 10 | // o_id: output propertry 11 | { 12 | double value = 0.0; 13 | switch (o_id) 14 | { 15 | case OX: 16 | value = 1.0; 17 | break; 18 | case OR: 19 | value = 2.0; 20 | break; 21 | default: 22 | value = pT_reg(p, T, o_id, pT_thermal_reg2, pT_ext_reg2); 23 | break; 24 | } 25 | return value; 26 | } 27 | 28 | double ph_reg2(double p, double h, int o_id) 29 | // o_id: output propertry 30 | { 31 | if (o_id == OP) 32 | return p; 33 | if (o_id == OH) 34 | return h; 35 | 36 | double T; 37 | T = ph2T_reg2(p, h); 38 | return pT_reg2(p, T, o_id); 39 | } 40 | 41 | double ps_reg2(double p, double s, int o_id) 42 | // o_id: output propertry 43 | { 44 | if (o_id == OP) 45 | return p; 46 | if (o_id == OS) 47 | return s; 48 | 49 | double T; 50 | T = ps2T_reg2(p, s); 51 | return pT_reg2(p, T, o_id); 52 | } 53 | 54 | double hs_reg2(double h, double s, int o_id) 55 | // o_id: output propertry 56 | { 57 | if (o_id == OH) 58 | return h; 59 | if (o_id == OS) 60 | return s; 61 | 62 | double p; 63 | p = hs2p_reg2(h, s); 64 | return ph_reg2(p, h, o_id); 65 | } 66 | 67 | //---------------------------------------- 68 | // the extend input pairs (p,v) T 69 | //------------------------------------------------------------------ 70 | double pv_reg2(double p, double v, int o_id) 71 | // o_id: output propertry 72 | { 73 | if (o_id == OP) 74 | return p; 75 | if (o_id == OV) 76 | return v; 77 | 78 | double T; 79 | T = pv2T_reg2(p, v); 80 | return pT_reg2(p, T, o_id); 81 | } 82 | 83 | double Tv_reg2(double T, double v, int o_id) 84 | // o_id: output propertry 85 | { 86 | if (o_id == OT) 87 | return T; 88 | if (o_id == OV) 89 | return v; 90 | 91 | double p; 92 | p = Tv2p_reg2(T, v); 93 | return pT_reg2(p, T, o_id); 94 | } 95 | 96 | // (T,s) 97 | double Ts_reg2(double T, double s, int o_id) 98 | // o_id: output propertry 99 | { 100 | if (o_id == OT) 101 | return T; 102 | if (o_id == OS) 103 | return s; 104 | 105 | double p; 106 | p = Ts2p_reg2(T, s); 107 | return pT_reg2(p, T, o_id); 108 | } 109 | 110 | // (T,h) 111 | double Th_reg2(double T, double h, int o_id) 112 | // o_id: output propertry 113 | { 114 | if (o_id == OT) 115 | return T; 116 | if (o_id == OH) 117 | return h; 118 | 119 | double p = Th2p_reg2(T, h); 120 | if (o_id == OP) 121 | return p; 122 | 123 | return pT_reg2(p, T, o_id); 124 | } -------------------------------------------------------------------------------- /src/r2/region2_solo_ij.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "../algo/algorithm.h" 4 | #include "../common/common.h" 5 | #include "region2_coff.h" 6 | 7 | static const int soI[17] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16, 18, 20, 21, 22, 23, 24}; 8 | 9 | static int i2soI[43] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 10 | 6, 6, 6, 7, 7, 8, 9, 9, 9, 10, 10, 11, 12, 12, 12, 11 | 13, 14, 15, 16, 16, 16}; 12 | 13 | static const int soJ[27] = {0, 1, 2, 3, 6, 4, 7, 14 | 36, 35, 16, 11, 25, 8, 13, 10, 15 | 14, 29, 50, 57, 20, 48, 21, 53, 39, 26, 40, 58}; 16 | 17 | static int j2soJ[43] = {0, 1, 2, 3, 4, 1, 2, 5, 6, 7, 0, 1, 3, 18 | 4, 8, 1, 2, 3, 6, 3, 9, 8, 0, 10, 11, 12, 7, 13, 5, 14, 15, 19 | 16, 17, 18, 19, 8, 20, 21, 22, 23, 24, 25, 26}; 20 | 21 | void solo_i_j_power_reg2(double vi, double vj, double soI_pow[], double soJ_pow[]); -------------------------------------------------------------------------------- /src/r2/region2_solo_power.c: -------------------------------------------------------------------------------- 1 | /* 2 | the solo powers in region2 3 | */ 4 | #include "../algo/algorithm.h" 5 | #include "region2.h" 6 | #include "region2_coff.h" 7 | #include "region2_solo_ij.h" 8 | 9 | void solo_i_j_power_reg2(double vi, double vj, double soI_pow[], double soJ_pow[]) 10 | { 11 | // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16, 18, 20, 21, 22, 23, 24]; 12 | soI_pow[0] = vi; 13 | for (int k = 1; k <= 9; k++) 14 | { 15 | soI_pow[k] = soI_pow[k - 1] * vi; 16 | } 17 | double vi2 = vi * vi; 18 | soI_pow[10] = soI_pow[9] * vi2 * vi2 * vi2; 19 | soI_pow[11] = soI_pow[10] * vi2; 20 | soI_pow[12] = soI_pow[11] * vi2; 21 | for (int k = 13; k <= 16; k++) 22 | { 23 | soI_pow[k] = soI_pow[k - 1] * vi; 24 | } 25 | 26 | // 0, 1, 2, 3, 6, 4, 7, 36, 35, 16, 11, 25, 8, 13, 10, 14, 29, 50, 57, 20, 48, 21, 53, 39, 26, 40, 58, 27 | 28 | soJ_pow[0] = 1.0; // 0 29 | soJ_pow[1] = vj; // 1 30 | soJ_pow[2] = vj * vj; // 2 31 | soJ_pow[3] = vj * soJ_pow[2]; // 3 32 | soJ_pow[4] = soJ_pow[3] * soJ_pow[3]; // 6 33 | 34 | soJ_pow[5] = soJ_pow[3] * vj; // 4 35 | soJ_pow[6] = soJ_pow[4] * vj; // 7 36 | 37 | double J_pow8 = soJ_pow[6] * vj; 38 | double J_pow10 = J_pow8 * soJ_pow[2]; 39 | double J_pow11 = J_pow8 * soJ_pow[3]; 40 | double J_pow16 = J_pow10 * soJ_pow[4]; 41 | double J_pow20 = J_pow10 * J_pow10; 42 | 43 | soJ_pow[7] = J_pow20 * J_pow16; // 36 44 | soJ_pow[8] = soJ_pow[7] / vj; // 35 45 | soJ_pow[9] = J_pow16; // 16 46 | soJ_pow[10] = J_pow11; // 11 47 | 48 | soJ_pow[11] = soJ_pow[8] / J_pow10; // 25 49 | soJ_pow[12] = J_pow8; // 8 50 | soJ_pow[13] = J_pow10 * soJ_pow[3]; // 13 51 | soJ_pow[14] = J_pow10; // 10 52 | soJ_pow[15] = J_pow10 * soJ_pow[5]; // 14 53 | 54 | soJ_pow[16] = J_pow16 * soJ_pow[13]; // 29 55 | soJ_pow[17] = soJ_pow[7] * soJ_pow[15]; // 50 56 | soJ_pow[18] = soJ_pow[17] * soJ_pow[6]; // 57 57 | soJ_pow[19] = J_pow20; // 20 58 | soJ_pow[20] = soJ_pow[8] * soJ_pow[13]; // 48 59 | 60 | soJ_pow[21] = J_pow20 * vj; // 21 61 | soJ_pow[22] = soJ_pow[17] * soJ_pow[3]; // 53 62 | soJ_pow[23] = soJ_pow[7] * soJ_pow[3]; // 39 63 | soJ_pow[24] = soJ_pow[11] * vj; // 26 64 | soJ_pow[25] = J_pow20 * J_pow20; // 40 65 | soJ_pow[26] = soJ_pow[18] * vj; // 58 66 | 67 | // for (int k = 0; k < 27; k++) 68 | //{ 69 | // soJ_pow[k] = IPOW(vj, soJ[k]); 70 | // } 71 | } -------------------------------------------------------------------------------- /src/r3/region3.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | 5 | double phi_reg3(double tau, double delta); 6 | double phi_delta_reg3(double tau, double delta); 7 | double phi_deltadelta_reg3(double tau, double delta); 8 | double phi_tau_reg3(double tau, double delta); 9 | double phi_tautau_reg3(double tau, double delta); 10 | double phi_deltatau_reg3(double tau, double delta); 11 | 12 | void polys_solo_0_j_reg3(double delta, double tau, double *poly, double *poly_tau); 13 | void polys_solo_i_j_reg3(double delta, double tau, double *poly_delta, double *poly_tau); 14 | void polys_solo_i_ii_ij_jj_reg3(double delta, double tau, 15 | double *poly_delta, 16 | double *poly_deltatau, 17 | double *poly_deltadelta, double *poly_tautau); 18 | 19 | 20 | 21 | double Td2p_reg3(double T, double d); 22 | double Td2u_reg3(double T, double d); 23 | double Td2s_reg3(double T, double d); 24 | double Td2h_reg3(double T, double d); 25 | double Td2cp_reg3(double T, double d); 26 | double Td2cv_reg3(double T, double d); 27 | double Td2w_reg3(double T, double d); 28 | 29 | // the extended 30 | double Td2e_reg3(double T, double d); 31 | double Td2k_reg3(double T, double d); 32 | double Td2f_reg3(double T, double d); 33 | double Td2g_reg3(double T, double d); 34 | double Td2z_reg3(double T, double d); 35 | double Td2kt_reg3(double T, double d); 36 | double Td2dvdpct_reg3(double T, double d); 37 | double Td2dvdtcp_reg3(double T, double d); 38 | double Td2dpdtcv_reg3(double T, double d); 39 | double Td2ipcec_reg3(double T, double d); 40 | double Td2joule_reg3(double T, double d); 41 | double Td2ijoule_reg3(double T, double d); 42 | // 43 | 44 | 45 | // -------- p,h ->T v-------------------------- 46 | double ph2T3a_reg3(double p, double h); 47 | double ph2T3b_reg3(double p, double h); 48 | 49 | double ph2v3a_reg3(double p, double h); 50 | double ph2v3b_reg3(double p, double h); 51 | 52 | double ph2T_reg3(double p, double h); 53 | double ph2v_reg3(double p, double h); 54 | 55 | // -------- p,s -> T,v -------------------------- 56 | double ps2T3a_reg3(double p, double s); 57 | double ps2T3b_reg3(double p, double s); 58 | 59 | double ps2v3a_reg3(double p, double s); 60 | double ps2v3b_reg3(double p, double s); 61 | 62 | double ps2T_reg3(double p, double s); 63 | double ps2v_reg3(double p, double s); 64 | 65 | // --- p(h,s) ------------------ 66 | double hs2p3a_reg3(double h, double s); 67 | double hs2p3b_reg3(double h, double s); 68 | 69 | double hs2p_reg3(double h, double s); 70 | 71 | // --- v(p T) ------------------ 72 | // TODO: pT2vSatreg3待测试 73 | double Vpt_3subreg(double p, double t, char subreg); 74 | 75 | double pT2vSat_reg3(double p, double T, double x); 76 | double pT2v_reg3(double p, double T); 77 | 78 | // (T,d) ->properties 79 | double Td_thermal_reg3(double T, double d, int o_id); 80 | double Td_ext_reg3(double T, double d, int o_id); 81 | double Td_transport_reg3(double T, double d, int o_id); 82 | 83 | // the extend input pairs 84 | double pv2T_reg3(double p, double v); 85 | double Th2d_reg3(double T, double h); 86 | double Ts2d_reg3(double T, double s); 87 | 88 | // input pairs 89 | double Td_reg3(double T, double d, int o_id); 90 | 91 | double pT_reg3(double p, double T, int o_id); 92 | double ph_reg3(double p, double h, int o_id); 93 | double ps_reg3(double p, double s, int o_id); 94 | double hs_reg3(double h, double s, int o_id); 95 | 96 | // the extend input pairs 97 | double pv_reg3(double p, double v, int o_id); 98 | double Tv_reg3(double T, double v, int o_id); 99 | double Th_reg3(double T, double h, int o_id); 100 | double Ts_reg3(double T, double s, int o_id); 101 | 102 | -------------------------------------------------------------------------------- /src/r3/region3_Td.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "../algo/algorithm.h" 5 | #include "../common/constand.h" 6 | #include "../common/common.h" 7 | #include "region3_solo_ij.h" 8 | #include "region3_coff.h" 9 | #include "region3.h" 10 | #include "../common/propertry_id.h" 11 | 12 | double Td_thermal_reg3(double T, double d, int o_id) 13 | // o_id: output propertry 14 | { 15 | double value; 16 | switch (o_id) 17 | { 18 | case OT: 19 | value = T; 20 | break; 21 | case OD: 22 | value = d; 23 | break; 24 | case OV: 25 | value = 1 / d; 26 | break; 27 | case OP: 28 | value = Td2p_reg3(T, d); 29 | break; 30 | case OH: 31 | value = Td2h_reg3(T, d); 32 | break; 33 | case OS: 34 | value = Td2s_reg3(T, d); 35 | break; 36 | case OU: 37 | value = Td2u_reg3(T, d); 38 | break; 39 | case OCV: 40 | value = Td2cv_reg3(T, d); 41 | break; 42 | case OCP: 43 | value = Td2cp_reg3(T, d); 44 | break; 45 | case OW: 46 | value = Td2w_reg3(T, d); 47 | break; 48 | default: 49 | value = INVALID_OUTID; 50 | break; 51 | } 52 | return value; 53 | } 54 | 55 | double Td2p_reg3(double T, double d) 56 | // 57 | // pressure in region 3 58 | // preg3 in bar 59 | // T: temperature in K 60 | // density in kg/m^3 61 | // 62 | { 63 | double tau = tc_water / T; 64 | double delta = d / dc_water; 65 | // return 0.001 * d * rgas_water * T * delta * phidelta_reg3(delta,tau); 66 | double phidelta = phi_delta_reg3(delta, tau); 67 | return 0.001 * d * rgas_water * T * delta * phidelta; 68 | } 69 | 70 | double Td2u_reg3(double T, double d) 71 | // speciphic internal energy in region 3 72 | // energyreg3 in kJ/kg 73 | { 74 | double tau = tc_water / T; 75 | double delta = d / dc_water; 76 | // return rgas_water * T * tau * phi_tau_reg3(delta,tau); 77 | double phi_tau = phi_tau_reg3(delta, tau); 78 | return rgas_water * T * tau * phi_tau; 79 | } 80 | 81 | double Td2s_reg3(double T, double d) 82 | // speciphic entropy in region 3 83 | // entropyreg3 in kJ/(kg K) 84 | { 85 | double tau = tc_water / T; 86 | double delta = d / dc_water; 87 | // return rgas_water * (tau * phi_tau_reg3(delta,tau) - phi_reg3(delta,tau)); 88 | 89 | double phi = 0.0; 90 | double phi_tau = 0.0; 91 | polys_solo_0_j_reg3(delta, tau, &phi, &phi_tau); 92 | return rgas_water * (tau * phi_tau - phi); 93 | } 94 | 95 | double Td2h_reg3(double T, double d) 96 | // speciphic enthalpy in region 3 97 | // enthalpyreg3 in kJ/kg 98 | { 99 | double tau = tc_water / T; 100 | double delta = d / dc_water; 101 | // return rgas_water * T * (tau * phi_tau_reg3(delta,tau) + delta * phidelta_reg3(delta,tau)); 102 | double phidelta = 0.0; 103 | double phi_tau = 0.0; 104 | polys_solo_i_j_reg3(delta, tau, &phidelta, &phi_tau); 105 | return rgas_water * T * (tau * phi_tau + delta * phidelta); 106 | } 107 | 108 | double Td2cp_reg3(double T, double d) 109 | // speciphic isobaric heat capacity in region 3 110 | // cpreg3 in kJ/(kg K) 111 | { 112 | double tau = tc_water / T; 113 | double delta = d / dc_water; 114 | 115 | // double a = delta * (phidelta_reg3(delta,tau) - tau * phideltatau_reg3(delta,tau)); 116 | // a *= a; 117 | // double b = delta * (2.0 * phidelta_reg3(delta,tau) + delta * phideltadelta_reg3(delta,tau)); 118 | // return rgas_water * (-tau * tau * phi_tautau_reg3(delta,tau) + a / b); 119 | 120 | double poly_delta = 0; 121 | double poly_deltatau = 0; 122 | double poly_deltadelta = 0; 123 | double poly_tautau = 0; 124 | polys_solo_i_ii_ij_jj_reg3(delta, tau, &poly_delta, &poly_deltadelta, &poly_deltatau, &poly_tautau); 125 | 126 | double a = delta * (poly_delta - tau * poly_deltatau); 127 | a *= a; 128 | double b = delta * (2.0 * poly_delta + delta * poly_deltadelta); 129 | return rgas_water * (-tau * tau * poly_tautau + a / b); 130 | } 131 | 132 | double Td2cv_reg3(double T, double d) 133 | // speciphic isochoric heat capacity in region 3 134 | // cvreg3 in kJ/(kg K) 135 | { 136 | double tau = tc_water / T; 137 | double delta = d / dc_water; 138 | // return rgas_water * (-tau * tau * phi_tautau_reg3(delta,tau)); 139 | 140 | double phi_tautau = phi_tautau_reg3(delta, tau); 141 | return rgas_water * (-tau * tau * phi_tautau); 142 | } 143 | 144 | double Td2w_reg3(double T, double d) 145 | // speed of sound in region 3 in m/s 146 | { 147 | double tau = tc_water / T; 148 | double delta = d / dc_water; 149 | /* 150 | 151 | double a = delta * phidelta_reg3(delta,tau) - delta * tau * phideltatau_reg3(delta,tau); 152 | a *= a; 153 | double r=1000.0 * rgas_water * T * (2 * delta * phidelta_reg3(delta,tau) + delta * delta * phideltadelta_reg3(delta,tau) - a / (tau * tau * phi_tautau_reg3(delta,tau))); 154 | return sqrt(1000.0 * rgas_water * T * (2 * delta * phidelta_reg3(delta,tau) + delta * delta * phideltadelta_reg3(delta,tau) - a / (tau * tau * phi_tautau_reg3(delta,tau)))); 155 | */ 156 | double poly_delta = 0; 157 | double poly_deltatau = 0; 158 | double poly_deltadelta = 0; 159 | double poly_tautau = 0; 160 | 161 | polys_solo_i_ii_ij_jj_reg3(delta, tau, &poly_delta, &poly_deltadelta, &poly_deltatau, &poly_tautau); 162 | double a = delta * (poly_delta - tau * poly_deltatau); 163 | a *= a; 164 | double r = 1000.0 * rgas_water * T * (delta * (2.0 * poly_delta + delta * poly_deltadelta) - a / (tau * tau * poly_tautau)); 165 | return sqrt(r); 166 | } 167 | -------------------------------------------------------------------------------- /src/r3/region3_Td_ext.c: -------------------------------------------------------------------------------- 1 | // Region3: The extended Properties 2 | // 3 | // Td_ext_reg3(T: f64, d: f64, o_id: i32) -> f64 4 | // 5 | #include "../common/constand.h" 6 | #include "../common/propertry_id.h" 7 | #include "../algo/algorithm.h" 8 | #include "region3.h" 9 | #include "region3_coff.h" 10 | #include "region3_solo_ij.h" 11 | 12 | double Td_ext_reg3(double T, double d, int o_id) 13 | { 14 | double r = 0.0; 15 | switch (o_id) 16 | { 17 | case OE: 18 | r = Td2e_reg3(T, d); 19 | break; 20 | case OKISE: 21 | r = Td2k_reg3(T, d); 22 | break; 23 | case OF: 24 | r = Td2f_reg3(T, d); 25 | break; 26 | case OG: 27 | r = Td2g_reg3(T, d); 28 | break; 29 | case OZ: 30 | r = Td2z_reg3(T, d); 31 | break; 32 | case OKT: 33 | r = Td2kt_reg3(T, d); 34 | break; 35 | case OIPCEC: 36 | r = Td2ipcec_reg3(T, d); 37 | break; 38 | case ODVDP: 39 | r = Td2dvdpct_reg3(T, d); 40 | break; 41 | 42 | case ODVDT: 43 | r = Td2dvdtcp_reg3(T, d); 44 | break; 45 | case ODPDT: 46 | r = Td2dpdtcv_reg3(T, d); 47 | break; 48 | case OJTC: 49 | r = Td2joule_reg3(T, d); 50 | break; 51 | case OIJTC: 52 | r = Td2ijoule_reg3(T, d); 53 | break; 54 | default: 55 | r = INVALID_OUTID; 56 | } 57 | return r; 58 | } 59 | 60 | // the specific Gibbs free energy, 61 | // g=R*T*(phi+delta* phi_delta ) 62 | double Td2g_reg3(double T, double d) 63 | { 64 | double tau = tc_water / T; 65 | double delta = d / dc_water; 66 | double phi = phi_reg3(delta, tau); 67 | double phi_delta = phi_delta_reg3(delta, tau); 68 | return rgas_water * T * (phi + delta * phi_delta); 69 | } 70 | 71 | // the Helmholtz Specific free energy 72 | double Td2f_reg3(double T, double d) 73 | { 74 | double tau = tc_water / T; 75 | double delta = d / dc_water; 76 | double phi = phi_reg3(delta, tau); 77 | return rgas_water * T * phi; 78 | } 79 | 80 | // k: Isentropic exponent 81 | // k= -(v/p)*/1000*(dp/dv) The book 2019 Page 37 82 | double Td2k_reg3(double T, double d) 83 | { 84 | double w = Td2w_reg3(T, d); 85 | double p = Td2p_reg3(T, d); 86 | return 1.0E-6 * w * w * d / p; 87 | } 88 | 89 | /// z: Compressibility factor 90 | double Td2z_reg3(double T, double d) 91 | { 92 | double v = 1.0 / d; 93 | double p = Td2p_reg3(T, d); 94 | return 1000.0 * p * v / rgas_water / T; 95 | } 96 | 97 | // (dv/dp)T 98 | double Td2dvdpct_reg3(double T, double d) 99 | { 100 | double tau = tc_water / T; 101 | double delta = d / dc_water; 102 | double ddeltadpi = 2.0 * phi_delta_reg3(delta, tau) + delta * phi_deltadelta_reg3(delta, tau); 103 | ddeltadpi = d * rgas_water * T * ddeltadpi; 104 | return -1000.0 * dc_water / d / d / ddeltadpi; 105 | } 106 | 107 | /// (dv/dt)p 108 | double Td2dvdtcp_reg3(double T, double d) 109 | { 110 | double tau = tc_water / T; 111 | double delta = d / dc_water; 112 | double ddelta = phi_delta_reg3(delta, tau); 113 | double d1 = ddelta - tau * phi_deltatau_reg3(delta, tau); 114 | double d2 = 2.0 * ddelta + delta * phi_deltadelta_reg3(delta, tau); 115 | return d1 / d2 / T / d; 116 | } 117 | 118 | // kT: Isothermal compressibility, 1/MPa 119 | double Td2kt_reg3(double T, double d) 120 | { 121 | return -d * Td2dvdpct_reg3(T, d); 122 | } 123 | 124 | /// ipcec-Isobaric cubic expansion coefficient 1/K 125 | double Td2ipcec_reg3(double T, double d) 126 | { 127 | return d * Td2dvdtcp_reg3(T, d); 128 | } 129 | 130 | /// e: Specific exergy kJ/kg 131 | double Td2e_reg3(double T, double d) 132 | { 133 | double tau = tc_water / T; 134 | double delta = d / dc_water; 135 | double phi = phi_reg3(delta, tau); 136 | double phi_delta = phi_delta_reg3(delta, tau); 137 | double phi_tau = phi_tau_reg3(delta, tau); 138 | return rgas_water * (T * (phi + delta * phi_delta) + (T - Tt) * tau * (phi_tau - phi)); 139 | } 140 | 141 | // (dp/dT)v 142 | double Td2dpdtcv_reg3(double T, double d) 143 | { 144 | double tau = tc_water / T; 145 | double delta = d / dc_water; 146 | return 0.001 * rgas_water * d * delta * (phi_delta_reg3(delta, tau) - tau * phi_deltatau_reg3(delta, tau)); 147 | } 148 | 149 | // joule : Joule-Thomson coefficient K/MPa 150 | // * (dt/dp)h 151 | double Td2joule_reg3(double T, double d) 152 | { 153 | double tau = tc_water / T; 154 | double delta = d / dc_water; 155 | 156 | double v = 1.0 / d; 157 | double ddelta = phi_delta_reg3(delta, tau); 158 | double ddeltatau = phi_deltatau_reg3(delta, tau); 159 | double ddeltadelta = phi_deltadelta_reg3(delta, tau); 160 | 161 | double cp1 = delta * (ddelta - tau * ddeltatau); 162 | cp1 *= cp1; 163 | double cp2 = delta * (2.0 * ddelta + delta * ddeltadelta); 164 | double cp = rgas_water * (-1.0 * tau * tau * phi_tautau_reg3(delta, tau) + cp1 / cp2); 165 | 166 | double d1 = ddelta - tau * ddeltatau; // dpdtcv 167 | double d2 = 2.0 * ddelta + delta * ddeltadelta; // dvdpct 168 | double cex = d1 / d2 / T; 169 | return 1000.0 * (v / cp) * (T * cex - 1.0); 170 | } 171 | 172 | // Isothermal throttling coefficient 173 | // iJTC Isothermal Joule-Thomson coefficient kJ/(kg·MPa) 174 | // * (dh/dp)t 175 | double Td2ijoule_reg3(double T, double d) 176 | { 177 | return -Td2cp_reg3(T, d) * Td2joule_reg3(T, d) / 1000.0; 178 | } 179 | -------------------------------------------------------------------------------- /src/r3/region3_coff.h: -------------------------------------------------------------------------------- 1 | 2 | // the coefficients and 3 | // exponents of the dimensionless Helmholtz free energy 4 | // for Region 3 (Table 30, page 30) 5 | // Initialize coefphicients and exponents for region 3 6 | #pragma once 7 | #include "../common/common.h" 8 | static const double n1 = 0.10658070028513e1; 9 | // 39 10 | static IJnData IJn[] = { 11 | {0, 0, -0.15732845290239E+02}, 12 | {0, 1, 0.20944396974307E+02}, 13 | {0, 2, -0.76867707878716E+01}, 14 | {0, 7, 0.26185947787954E+01} 15 | 16 | , 17 | {0, 10, -0.28080781148620E+01}, 18 | {0, 12, 0.12053369696517E+01}, 19 | {0, 23, -0.84566812812502E-02}, 20 | {1, 2, -0.12654315477714E+01}, 21 | {1, 6, -0.11524407806681E+01} 22 | 23 | , 24 | {1, 15, 0.88521043984318E+00}, 25 | {1, 17, -0.64207765181607E+00}, 26 | {2, 0, 0.38493460186671E+00}, 27 | {2, 2, -0.85214708824206E+00}, 28 | {2, 6, 0.48972281541877E+01} 29 | 30 | , 31 | {2, 7, -0.30502617256965E+01}, 32 | {2, 22, 0.39420536879154E-01}, 33 | {2, 26, 0.12558408424308E+00}, 34 | {3, 0, -0.27999329698710E+00}, 35 | {3, 2, 0.13899799569460E+01} 36 | 37 | , 38 | {3, 4, -0.20189915023570E+01}, 39 | {3, 16, -0.82147637173963E-02}, 40 | {3, 26, -0.47596035734923E+00}, 41 | {4, 0, 0.43984074473500E-01}, 42 | {4, 2, -0.44476435428739E+00} 43 | 44 | , 45 | {4, 4, 0.90572070719733E+00}, 46 | {4, 26, 0.70522450087967E+00}, 47 | {5, 1, 0.10770512626332E+00}, 48 | {5, 3, -0.32913623258954E+00}, 49 | {5, 26, -0.50871062041158E+00} 50 | 51 | , 52 | {6, 0, -0.22175400873096E-01}, 53 | {6, 2, 0.94260751665092E-01}, 54 | {6, 26, 0.16436278447961E+00}, 55 | {7, 2, -0.13503372241348E-01}, 56 | {8, 26, -0.14834345352472E-01} 57 | 58 | , 59 | {9, 2, 0.57922953628084E-03}, 60 | {9, 26, 0.32308904703711E-02}, 61 | {10, 0, 0.80964802996215E-04}, 62 | {10, 1, -0.16557679795037E-03}, 63 | {11, 26, -0.44923899061815E-04}}; -------------------------------------------------------------------------------- /src/r3/region3_hfe.c: -------------------------------------------------------------------------------- 1 | /* 2 | Speciphic Helmholtz free energy and derivatives 3 | 4 | */ 5 | #include 6 | #include "../algo/algorithm.h" 7 | #include "../common/constand.h" 8 | #include "../common/propertry_id.h" 9 | #include "../algo/algorithm.h" 10 | #include "region3.h" 11 | #include "region3_coff.h" 12 | #include "region3_solo_ij.h" 13 | 14 | /* 15 | * Speciphic Helmholtz free energy. 16 | * tau :dimensionless temperature [K] 17 | * delta: dimensionless density [kg/m3] 18 | 19 | */ 20 | double phi_reg3(double delta, double tau) 21 | // Fundamental equation for region 3 22 | { 23 | // double phi = n1 * log(delta); 24 | // for (int k = 0; k < 39; k++) 25 | // phi += IJn[k].n * pow(delta, IJn[k].I) * pow(tau, IJn[k].J); 26 | // return phi; 27 | return n1 * log(delta) + poly_solo(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3); 28 | } 29 | 30 | double phi_delta_reg3(double delta, double tau) 31 | // first derivative in delta of fundamental equation for region 3 32 | { 33 | // double phi_delta = n1 / delta; 34 | // for (int k = 0; k < 39; k++) 35 | // phi_delta += IJn[k].n * IJn[k].I * pow(delta, IJn[k].I - 1) * pow(tau, IJn[k].J); 36 | // return phi_delta; 37 | return (n1 / delta) + poly_solo_i(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3); 38 | } 39 | 40 | double phi_deltadelta_reg3(double delta, double tau) 41 | // Second derivative in delta of fundamental equation for region 3 42 | { 43 | // double phi_deltadelta = -n1 / delta / delta; 44 | // for (int k = 0; k < 39; k++) 45 | // phi_deltadelta += IJn[k].n * IJn[k].I * (IJn[k].I - 1) * pow(delta, IJn[k].I - 2) * pow(tau, IJn[k].J); 46 | // return phi_deltadelta; 47 | 48 | return (-n1 / delta / delta) + poly_solo_ii(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3); 49 | } 50 | 51 | double phi_tau_reg3(double delta, double tau) 52 | // phirst derivative in tau of fundamental equation for region 3 53 | { 54 | // double phi_tau = 0.0; 55 | // for (int k = 0; k < 39; k++) 56 | // phi_tau += IJn[k].n * pow(delta, IJn[k].I) * IJn[k].J * pow(tau, IJn[k].J - 1); 57 | // return phi_tau; 58 | 59 | return poly_solo_j(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3); 60 | } 61 | 62 | double phi_tautau_reg3(double delta, double tau) 63 | // Second derivative in tau of fundamental equation for region 3 64 | { 65 | // double phi_tautau = 0.0; 66 | // for (int k = 0; k < 39; k++) 67 | // phi_tautau += IJn[k].n * pow(delta, IJn[k].I) * IJn[k].J * (IJn[k].J - 1) * pow(tau, IJn[k].J - 2); 68 | // return phi_tautau; 69 | 70 | return poly_solo_jj(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3); 71 | } 72 | 73 | double phi_deltatau_reg3(double delta, double tau) 74 | // Second derivative in delta and tau of fundamental equation for region 3 75 | { 76 | // double phi_deltatau = 0.0; 77 | // for (int k = 0; k < 39; k++) 78 | // phi_deltatau += IJn[k].n * IJn[k].I * pow(delta, IJn[k].I - 1) * IJn[k].J * pow(tau, IJn[k].J - 1); 79 | // return phi_deltatau; 80 | 81 | return poly_solo_ij(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3); 82 | } 83 | 84 | //------------------------------------------------------------------------------------ 85 | // mutiple polys 86 | //----------------------------------------------------------------------------------------- 87 | void polys_solo_0_j_reg3(double delta, double tau, 88 | double *poly, 89 | double *poly_tau) 90 | { 91 | polys_solo_0_j(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3, poly, poly_tau); 92 | *poly += n1 * log(delta); 93 | } 94 | 95 | void polys_solo_i_j_reg3(double delta, double tau, 96 | double *poly_delta, 97 | double *poly_tau) 98 | { 99 | polys_solo_i_j(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3, poly_delta, poly_tau); 100 | 101 | *poly_delta += n1 / delta; 102 | } 103 | 104 | void polys_solo_i_ii_ij_jj_reg3(double delta, double tau, 105 | double *poly_delta, double *poly_deltadelta, double *poly_deltatau, 106 | double *poly_tautau) 107 | { 108 | polys_solo_i_ii_ij_jj(delta, tau, 39, IJn, i2soI, j2soJ, solo_i_j_power_reg3, poly_delta, poly_deltadelta, 109 | poly_deltatau, poly_tautau); 110 | 111 | *poly_delta += n1 / delta; 112 | *poly_deltadelta += (-n1 / delta / delta); 113 | } -------------------------------------------------------------------------------- /src/r3/region3_out.c: -------------------------------------------------------------------------------- 1 | /* 2 | Tha API of region3 3 | 4 | */ 5 | #include "region3.h" 6 | #include "../common/propertry_id.h" 7 | #include "../common/common.h" 8 | #include "../common/constand.h" 9 | 10 | double Td_reg3(double T, double d, int o_id) 11 | // o_id: output propertry 12 | { 13 | double value; 14 | switch (o_id) 15 | { 16 | case OX: 17 | value = 1.0; 18 | break; 19 | case OR: 20 | value = 3.0; 21 | break; 22 | case OT: 23 | value = T; 24 | break; 25 | case OD: 26 | value = d; 27 | break; 28 | case OV: 29 | value = 1.0 / d; 30 | break; 31 | case OP: 32 | case OH: 33 | case OS: 34 | case OU: 35 | case OCV: 36 | case OCP: 37 | case OW: 38 | value = Td_thermal_reg3(T, d, o_id); 39 | break; 40 | case ODV: 41 | case OKV: 42 | case OTC: 43 | case OTD: 44 | case OPR: 45 | case OST: 46 | value = Td_transport_reg3(T, d, o_id); 47 | break; 48 | default: 49 | value = Td_ext_reg3(T, d, o_id); 50 | break; 51 | } 52 | return value; 53 | } 54 | 55 | double Td_transport_reg3(double T, double d, int o_id) 56 | { 57 | double value; 58 | double cp; 59 | double tc; 60 | double dv; 61 | switch (o_id) 62 | { 63 | case ODV: 64 | { 65 | value = viscosity(d, T); 66 | break; 67 | } 68 | case OKV: 69 | { 70 | value = kinematic_viscosity(d, T); 71 | break; 72 | } 73 | case OTC: 74 | { 75 | value = thCond(d, T); 76 | break; 77 | } 78 | case OTD: 79 | { 80 | cp = Td2cp_reg3(T, d); 81 | tc = thCond(d, T); 82 | value = thermal_diffusivity(tc, cp, d); 83 | break; 84 | } 85 | case OPR: 86 | { 87 | dv = viscosity(d, T); 88 | cp = Td2cp_reg3(T, d); 89 | tc = thCond(d, T); 90 | value = prandtl_number(dv, cp, tc); 91 | break; 92 | } 93 | case OST: 94 | { 95 | value = tension(T); 96 | break; 97 | } 98 | default: 99 | { 100 | value = INVALID_OUTID; 101 | break; 102 | } 103 | } 104 | return value; 105 | } 106 | 107 | double pT_reg3(double p, double T, int o_id) 108 | // o_id: output propertry 109 | { 110 | if (o_id == OP) 111 | return p; 112 | if (o_id == OT) 113 | return T; 114 | double d; 115 | d = 1.0 / pT2v_reg3(p, T); 116 | return Td_reg3(T, d, o_id); 117 | } 118 | 119 | double ph_reg3(double p, double h, int o_id) 120 | // o_id: output propertry 121 | { 122 | if (o_id == OP) 123 | return p; 124 | if (o_id == OH) 125 | return h; 126 | 127 | double d, T; 128 | d = 1.0 / ph2v_reg3(p, h); 129 | T = ph2T_reg3(p, h); 130 | return Td_reg3(T, d, o_id); 131 | } 132 | 133 | double ps_reg3(double p, double s, int o_id) 134 | // o_id: output propertry 135 | { 136 | if (o_id == OP) 137 | return p; 138 | if (o_id == OS) 139 | return s; 140 | 141 | double d, T; 142 | d = 1.0 / ps2v_reg3(p, s); 143 | T = ps2T_reg3(p, s); 144 | return Td_reg3(T, d, o_id); 145 | } 146 | 147 | double hs_reg3(double h, double s, int o_id) 148 | // o_id: output propertry 149 | { 150 | if (o_id == OH) 151 | return h; 152 | if (o_id == OS) 153 | return s; 154 | 155 | double p, T, d; 156 | p = hs2p_reg3(h, s); 157 | 158 | T = ph2T_reg3(p, h); 159 | d = 1.0 / ph2v_reg3(p, h); 160 | 161 | return Td_reg3(T, d, o_id); 162 | } 163 | 164 | // IAPWS-IF97 Region3: The extended input pair 165 | // * (p,v) (t,v), (t,h),(t,s) 166 | 167 | /// Region3: (p,v) T 168 | double pv_reg3(double p, double v, int o_id) 169 | { 170 | double d = 1.0 / v; 171 | if (o_id == OD) 172 | { 173 | return d; 174 | }; 175 | double T = pv2T_reg3(p, v); 176 | if (o_id == OT) 177 | { 178 | return T; 179 | }; 180 | return Td_reg3(T, d, o_id); 181 | } 182 | 183 | /// Region3: (T,v) 184 | double Tv_reg3(double T, double v, int o_id) 185 | { 186 | double d = 1.0 / v; 187 | if (o_id == OD) 188 | { 189 | return d; 190 | }; 191 | return Td_reg3(T, d, o_id); 192 | } 193 | 194 | // Region3: (T,h) 195 | double Th_reg3(double T, double h, int o_id) 196 | { 197 | double d = Th2d_reg3(T, h); 198 | if (o_id == OD) 199 | { 200 | return d; 201 | }; 202 | if (o_id == OV) 203 | { 204 | return 1.0 / d; 205 | }; 206 | return Td_reg3(T, d, o_id); 207 | } 208 | 209 | // Region3: (T,s) 210 | double Ts_reg3(double T, double s, int o_id) 211 | { 212 | double d = Ts2d_reg3(T, s); 213 | if (o_id == OD) 214 | { 215 | return d; 216 | }; 217 | if (o_id == OV) 218 | { 219 | return 1.0 / d; 220 | }; 221 | return Td_reg3(T, d, o_id); 222 | } -------------------------------------------------------------------------------- /src/r3/region3_p_hs.c: -------------------------------------------------------------------------------- 1 | /* 2 | Backward Equation for Region 3: 3 | * IAPWS-IF97-S04rev :Supp-phs3-2014.pdf 4 | (h,s)->p (3a,3b,3c) 5 | */ 6 | #include 7 | #include "../common/constand.h" 8 | #include "../algo/algorithm.h" 9 | #include "region3.h" 10 | 11 | double hs2p3a_reg3(double h, double s) 12 | /* Backward equation for region 3a, P=f(h,s) 13 | h : Specific enthalpy [kJ/kg] 14 | s : Specific entropy [kJ/kgK] 15 | P : Pressure [MPa] */ 16 | { 17 | IJnData IJn[33] = {{0, 0, 0.770889828326934e1}, 18 | {0, 1, -0.260835009128688e2}, 19 | {0, 5, 0.267416218930389e3}, 20 | {1, 0, 0.172221089496844e2}, 21 | {1, 3, -0.293542332145970e3}, 22 | {1, 4, 0.614135601882478e3}, 23 | {1, 8, -0.610562757725674e5}, 24 | {1, 14, -0.651272251118219e8}, 25 | {2, 6, 0.735919313521937e5}, 26 | {2, 16, -0.116646505914191e11}, 27 | {3, 0, 0.355267086434461e2}, 28 | {3, 2, -0.596144543825955e3}, 29 | {3, 3, -0.475842430145708e3}, 30 | {4, 0, 0.696781965359503e2}, 31 | {4, 1, 0.335674250377312e3}, 32 | {4, 4, 0.250526809130882e5}, 33 | {4, 5, 0.146997380630766e6}, 34 | {5, 28, 0.538069315091534e20}, 35 | {6, 28, 0.143619827291346e22}, 36 | {7, 24, 0.364985866165994e20}, 37 | {8, 1, -0.254741561156775e4}, 38 | {10, 32, 0.240120197096563e28}, 39 | {10, 36, -0.393847464679496e30}, 40 | {14, 22, 0.147073407024852e25}, 41 | {18, 28, -0.426391250432059e32}, 42 | {20, 36, 0.194509340621077e39}, 43 | {22, 16, 0.666212132114896e24}, 44 | {22, 28, 0.706777016552858e34}, 45 | {24, 36, 0.175563621975576e42}, 46 | {28, 16, 0.108408607429124e29}, 47 | {28, 36, 0.730872705175151e44}, 48 | {32, 10, 0.159145847398870e25}, 49 | {32, 28, 0.377121605943324e41}}; 50 | 51 | double nu = h / 2300 - 1.01; 52 | double sigma = s / 4.4 - 0.75; 53 | // double suma = 0; 54 | // for (int i = 0; i < 33; i++) 55 | // { 56 | // suma += n[i] * pow(nu, I[i]) * pow(sigma, J[i]); 57 | // } 58 | double suma = poly(nu, sigma, 33, IJn); 59 | return (99 * suma); 60 | } 61 | 62 | double hs2p3b_reg3(double h, double s) 63 | /*Backward equation for region 3b, P=f(h,s) 64 | h : Specific enthalpy [kJ/kg] 65 | s : Specific entropy [kJ/kgK] 66 | P : Pressure [MPa]*/ 67 | { 68 | IJnData IJn[35] = { 69 | {-12, 2, 0.125244360717979e-12}, 70 | {-12, 10, -0.126599322553713e-1}, 71 | {-12, 12, 0.506878030140626e1}, 72 | {-12, 14, 0.317847171154202e2}, 73 | {-12, 20, -0.391041161399932e6}, 74 | {-10, 2, -0.975733406392044e-10}, 75 | {-10, 10, -0.186312419488279e2}, 76 | {-10, 14, 0.510973543414101e3}, 77 | {-10, 18, 0.373847005822362e6}, 78 | {-8, 2, 0.299804024666572e-7}, 79 | {-8, 8, 0.200544393820342e2}, 80 | {-6, 2, -0.498030487662829e-5}, 81 | {-6, 6, -0.102301806360030e2}, 82 | {-6, 7, 0.552819126990325e2}, 83 | {-6, 8, -0.206211367510878e3}, 84 | {-5, 10, -0.794012232324823e4}, 85 | {-4, 4, 0.782248472028153e1}, 86 | {-4, 5, -0.586544326902468e2}, 87 | {-4, 8, 0.355073647696481e4}, 88 | {-3, 1, -0.115303107290162e-3}, 89 | {-3, 3, -0.175092403171802e1}, 90 | {-3, 5, 0.257981687748160e3}, 91 | {-3, 6, -0.727048374179467e3}, 92 | {-2, 0, 0.121644822609198e-3}, 93 | {-2, 1, 0.393137871762692e-1}, 94 | {-1, 0, 0.704181005909296e-2}, 95 | {0, 3, -0.829108200698110e2}, 96 | {2, 0, -0.265178818131250}, 97 | {2, 1, 0.137531682453991e2}, 98 | {5, 0, -0.522394090753046e2}, 99 | {6, 1, 0.240556298941048e4}, 100 | {8, 1, -0.227361631268929e5}, 101 | {10, 1, 0.890746343932567e5}, 102 | {14, 3, -0.239234565822486e8}, 103 | {14, 7, 0.568795808129714e10}, 104 | }; 105 | 106 | double nu = h / 2800 - 0.681; 107 | double sigma = s / 5.3 - 0.792; 108 | // double suma = 0; 109 | // for (int i = 0; i < 35; i++) 110 | //{ 111 | // suma += n[i] * pow(nu, I[i]) * pow(sigma, J[i]); 112 | // } 113 | double suma = poly(nu, sigma, 35, IJn); 114 | return (16.6 / suma); 115 | } 116 | 117 | double hs2p_reg3(double h, double s) 118 | /* Backward equation for region 3, P=f(h,s) 119 | h : Specific enthalpy [kJ/kg] 120 | s : Specific entropy [kJ/kgK] 121 | P : Pressure [MPa] 122 | */ 123 | { 124 | 125 | double p; 126 | if (s <= sc_water) 127 | p = hs2p3a_reg3(h, s); 128 | else 129 | p = hs2p3b_reg3(h, s); 130 | 131 | return (p); 132 | } 133 | -------------------------------------------------------------------------------- /src/r3/region3_pair.ext.c: -------------------------------------------------------------------------------- 1 | /* 2 | The extended pairs: 3 | (p,v) ->t 4 | (T,h) ->d (T,s)->d 5 | */ 6 | #include 7 | #include 8 | #include "../common/constand.h" 9 | #include "../common/propertry_id.h" 10 | #include "../algo/algorithm.h" 11 | #include "region3.h" 12 | #include "region3_coff.h" 13 | 14 | // Region 3 (p,v)->T using the secant method and refine adjust 15 | // * p: pressure MPa 16 | // * v: specific volume m^3/kg 17 | // * T: temperature K 18 | double pv2T_reg3(double p, double v) 19 | { 20 | double T1, T2, d, f1, f2; 21 | T1 = TMIN3; 22 | T2 = B23_p2T(p); 23 | d = 1.0 / v; 24 | f1 = p - Td2p_reg3(T1, d); 25 | f2 = p - Td2p_reg3(T2, d); 26 | return rtsec1(Td2p_reg3, d, p, T1, T2, f1, f2, xacc, iMAX); 27 | } 28 | 29 | // (t,h) ->d 30 | double Th2d_reg3(double T, double h) 31 | { 32 | double p1 = B23_T2p(T); 33 | double d1 = 1.0 / pT2v_reg3(p1, T); 34 | double p2 = PMAX3; 35 | double d2 = 1.0 / pT2v_reg3(p2, T); 36 | double f1 = h - Td2h_reg3(T, d1); 37 | double f2 = h - Td2h_reg3(T, d2); 38 | return rtsec2(Td2h_reg3, T, h, d1, d2, f1, f2, xacc, iMAX); 39 | } 40 | 41 | // Region 3 (T,s)->d using the secant method 42 | // * T: temperature K 43 | // * s: specific entropy kJ/(kg K) 44 | // * d: density kg/m^3 45 | double Ts2d_reg3(double T, double s) 46 | { 47 | double d1 = 100.0; 48 | double d2 = 1.1 * d1; 49 | double ft = s - Td2s_reg3(T, d1); 50 | double f = s - Td2s_reg3(T, d2); 51 | return rtsec2(Td2s_reg3, T, s, d1, d2, ft, f, xacc, iMAX); 52 | } 53 | -------------------------------------------------------------------------------- /src/r3/region3_solo_ij.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../algo/algorithm.h" 3 | #include "../common/common.h" 4 | #include "region3_coff.h" 5 | 6 | static const int soI[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 7 | 8 | static int i2soI[39] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 9 | 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 10 | 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 10, 10, 11}; 11 | 12 | static const int soJ[15] = {0, 1, 2, 7, 10, 12, 23, 6, 15, 17, 22, 26, 4, 16, 3}; 13 | static int j2soJ[39] = {0, 1, 2, 3, 4, 5, 6, 2, 7, 8, 9, 0, 2, 14 | 7, 3, 10, 11, 0, 2, 12, 13, 11, 0, 2, 12, 11, 1, 14, 11, 15 | 0, 2, 11, 2, 11, 2, 11, 0, 1, 11}; 16 | 17 | void solo_i_j_power_reg3(double vi, double vj, double soI_pow[], double soJ_pow[]); -------------------------------------------------------------------------------- /src/r3/region3_solo_power.c: -------------------------------------------------------------------------------- 1 | /* 2 | The solo power in region 3 3 | - use Horner’s rule to get the soI_pow,soJ_pow quickly 4 | */ 5 | void solo_i_j_power_reg3(double vi, double vj, double soI_pow[], double soJ_pow[]) 6 | { 7 | // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; 8 | soI_pow[0] = 1.0; 9 | for (int k = 1; k <= 12; k++) 10 | { 11 | soI_pow[k] = soI_pow[k - 1] * vi; 12 | } 13 | 14 | // j [0, 1, 2, 7, 10, 12, 23, 6, 15, 17, 22, 26, 4, 16, 3]; 15 | soJ_pow[0] = 1.0; 16 | soJ_pow[1] = vj; 17 | soJ_pow[2] = vj * vj; 18 | 19 | double J_pow3 = soJ_pow[1] * soJ_pow[2]; 20 | double J_pow4 = soJ_pow[2] * soJ_pow[2]; 21 | 22 | soJ_pow[3] = J_pow3 * J_pow4; // 7 23 | soJ_pow[4] = J_pow3 * soJ_pow[3]; // 10 24 | soJ_pow[5] = soJ_pow[4] * soJ_pow[2]; // 12 25 | 26 | double J_pow22 = soJ_pow[5] * soJ_pow[4]; 27 | 28 | soJ_pow[6] = J_pow22 * vj; // 23 29 | soJ_pow[7] = J_pow3 * J_pow3; // 6 30 | soJ_pow[8] = J_pow3 * soJ_pow[5]; // 15 31 | soJ_pow[9] = soJ_pow[8] * soJ_pow[2]; // 17 32 | soJ_pow[10] = J_pow22; // 22 33 | 34 | soJ_pow[11] = J_pow22 * J_pow4; // 26 35 | soJ_pow[12] = J_pow4; // 4 36 | soJ_pow[13] = soJ_pow[8] * vj; // 16 37 | soJ_pow[14] = J_pow3; // 3 38 | } 39 | -------------------------------------------------------------------------------- /src/r4/region4.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------- 2 | #pragma once 3 | 4 | #include "../common/common.h" 5 | 6 | double pSat(double T); 7 | double TSat(double p); 8 | 9 | double p2SatWater(double p, int o_id); 10 | double p2SatSteam(double p, int o_id); 11 | 12 | double T2SatWater(double T, int o_id); 13 | double T2SatSteam(double T, int o_id); 14 | 15 | double hs2T_reg4(double h, double s); 16 | 17 | // input pairss 18 | double px_reg4(double p, double x, int o_id); 19 | double Tx_reg4(double T, double x, int o_id); 20 | 21 | double ph_reg4(double p, double h, int o_id); 22 | double ps_reg4(double p, double s, int o_id); 23 | double hs_reg4(double h, double s, int o_id); 24 | 25 | double pT_reg4(double p, double T, int o_id); 26 | 27 | // the extend input pairs 28 | // (p,v) (T,v)p (T,s) (T,h) 29 | double pv2x_reg4(double p,double v); 30 | double Tv2x_reg4(double T,double v); 31 | double Th2x_reg4(double T,double h); 32 | double Ts2x_reg4(double T,double s); 33 | 34 | double pv_reg4(double p, double v, int o_id); 35 | double Tv_reg4(double T, double v, int o_id); 36 | double Ts_reg4(double T, double s, int o_id); 37 | double Th_reg4(double T, double h, int o_id); 38 | // 39 | double hx_reg4(double h, double x, int o_id); 40 | double sx_reg4(double s, double x, int o_id); 41 | 42 | -------------------------------------------------------------------------------- /src/r4/region4_T_hs.c: -------------------------------------------------------------------------------- 1 |  2 | /* 3 | Region4 : http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 9 4 | Page30 Supp-phs3-2014.pdf Page25 5 | 5.3 Backward Equation Tsat(h,s) 6 | s> 5.210 887 825 7 | temperature range is T (273.15 , 623.15 ) 8 | */ 9 | 10 | #include 11 | #include 12 | #include "../algo/algorithm.h" 13 | #include "../common/common.h" 14 | #include "../common/constand.h" 15 | #include "../r1/region1.h" 16 | #include "../r2/region2.h" 17 | #include "../r3/region3.h" 18 | #include "region4.h" 19 | 20 | static double s4L_623 = 3.778281340; // T=623.16 ,Sature Liquid s 21 | static double s4V_623 = 5.210887825; // T=623.16 ,Sature steam s 22 | static double h4V_623 = 2.5635920043 + 03; // Page 25 Sature steam h 23 | static double s4L_273 = -1.545495919e-04; // T=273.15 ,Sature Liquid 24 | static double s4V_273 = 9.155759395; // T=273.15 ,Sature steam 25 | 26 | double hs2T_reg43(double h, double s) 27 | /* Backward equation for region 4, T=f(h,s) 28 | h : Specific enthalpy [kJ/kg] 29 | s : Specific entropy [kJ/kgK] 30 | */ 31 | { 32 | IJnData IJn[] = { 33 | {0, 0, .179882673606601}, 34 | {0, 3, -.267507455199603}, 35 | {0, 12, .116276722612600e1}, 36 | {1, 0, .147545428713616}, 37 | {1, 1, -.512871635973248}, 38 | {1, 2, .421333567697984}, 39 | {1, 5, .563749522189870}, 40 | {2, 0, .429274443819153}, 41 | {2, 5, -.335704552142140e1}, 42 | {2, 8, .108890916499278e2}, 43 | {3, 0, -.248483390456012}, 44 | {3, 2, .304153221906390}, 45 | {3, 3, -.494819763939905}, 46 | {3, 4, .107551674933261e1}, 47 | {4, 0, .733888415457688e-1}, 48 | {4, 1, .140170545411085e-1}, 49 | {5, 1, -.106110975998808}, 50 | {5, 2, .168324361811875e-1}, 51 | {5, 4, .125028363714877e1}, 52 | {5, 16, .101316840309509e4}, 53 | {6, 6, -.151791558000712e1}, 54 | {6, 8, .524277865990866e2}, 55 | {6, 22, .230495545563912e5}, 56 | {8, 1, .249459806365456e-1}, 57 | {10, 20, .210796467412137e7}, 58 | {10, 36, .366836848613065e9}, 59 | {12, 24, -.144814105365163e9}, 60 | {14, 1, -.179276373003590e-2}, 61 | {14, 28, .489955602100459e10}, 62 | {16, 12, .471262212070518e3}, 63 | {16, 32, -.829294390198652e11}, 64 | {18, 14, -.171545662263191e4}, 65 | {18, 22, .355777682973575e7}, 66 | {18, 36, .586062760258436e12}, 67 | {20, 24, -.129887635078195e8}, 68 | {28, 36, .317247449371057e11}}; 69 | 70 | if (s < s4V_623) 71 | return INVALID_S; 72 | 73 | double nu = h / 2800; 74 | double sigma = s / 9.2; 75 | // double suma = 0; 76 | // for (int i = 0; i < 36; i++) 77 | // suma += IJn[i].n * IPOW(nu - 0.119, IJn[i].I) * IPOW(sigma - 1.07, IJn[i].J); 78 | return 550.0 * poly(nu - 0.119, sigma - 1.07, 36, IJn); 79 | } 80 | 81 | double hs2T_reg4(double h, double s) 82 | { 83 | 84 | double T; 85 | if (s > s4V_623 && s < s4V_273) 86 | { 87 | T = hs2T_reg43(h, s); 88 | return T; 89 | }; 90 | 91 | // The if97 function hs2Treg43 is only valid for part of region4. Use iteration outsida. 92 | double Low_Bound; 93 | double High_Bound; 94 | double PL, Ts; 95 | 96 | if (s > s4L_273 && s <= s4L_623) 97 | { 98 | Low_Bound = Pmin; 99 | High_Bound = Ps_623; 100 | 101 | double hL = -1000; 102 | while (fabs(hL - h) > 1.0e-04 && fabs(High_Bound - Low_Bound) > 1.0e-4) 103 | { 104 | PL = (Low_Bound + High_Bound) / 2; 105 | Ts = TSat(PL); 106 | hL = pT2h_reg1(PL, Ts); 107 | if (hL > h) 108 | High_Bound = PL; 109 | else 110 | Low_Bound = PL; 111 | } 112 | }; 113 | 114 | if (s > s4L_623 && s <= sc_water) 115 | { 116 | PL = h2pSat_reg3(h); // liquid 117 | Low_Bound = Pmin; 118 | High_Bound = PL; 119 | } 120 | if (s > sc_water && s <= s4V_623) 121 | { 122 | PL = h2pSat_reg3(h); // steam 123 | Low_Bound = Pmin; 124 | High_Bound = PL; 125 | } 126 | 127 | double sss = -1000; 128 | double p, xs, s4v, s4L, v4v, v4L; 129 | 130 | while (fabs(s - sss) > 1.0e-6) 131 | { 132 | p = 0.5 * (Low_Bound + High_Bound); 133 | 134 | Ts = TSat(p); 135 | xs = ph_reg4(p, h, OX); 136 | 137 | if (p < Ps_623) 138 | { 139 | s4v = pT2s_reg2(p, Ts); 140 | s4L = pT2s_reg1(p, Ts); 141 | } 142 | else 143 | { 144 | v4v = ph_reg3(p, p2SatSteam(p, OH), OV); 145 | s4v = Td2s_reg3(Ts, 1 / v4v); 146 | v4L = ph_reg3(p, p2SatWater(p, OH), OV); 147 | s4L = Td2s_reg3(Ts, 1 / v4L); 148 | }; 149 | 150 | sss = (xs * s4v + (1 - xs) * s4L); 151 | 152 | if (sss < s) 153 | { 154 | High_Bound = p; 155 | Low_Bound = (1 + (sss - s) / s) * p; 156 | } 157 | else 158 | { 159 | Low_Bound = p; 160 | High_Bound = (1 + (sss - s) / s) * p; 161 | } 162 | } // end of while (fabs(s - sss) > 1.0e-6) 163 | 164 | T = TSat(p); 165 | return T; 166 | } -------------------------------------------------------------------------------- /src/r4/region4_hxsx.c: -------------------------------------------------------------------------------- 1 | /* 2 | Region 4 - The extended input pairs: (h,x),(s,x) 3 | x: Steam quality 4 | */ 5 | #include 6 | #include 7 | #include "../algo/algorithm.h" 8 | #include "../common/common.h" 9 | #include "../common/constand.h" 10 | #include "../r1/region1.h" 11 | #include "../r2/region2.h" 12 | #include "../r3/region3.h" 13 | #include "region4.h" 14 | 15 | // function for getting the steam quality,residuals: x(T,y)-x 16 | double Ty2x_residuals(double T, double x, double y, int y_id) 17 | { 18 | double sw = T2SatWater(T, y_id); 19 | double ss = T2SatSteam(T, y_id); 20 | return (y - sw) / (ss - sw) - x; 21 | } 22 | 23 | /// Bisection for the root : Ty2x_residuals(T,x, y, y_id)=0 24 | double bisection_reg4(double x, double y, int y_id, double Tl, double Tr, double tol, int maxiter) 25 | { 26 | double T = 0.0; 27 | double fl = Ty2x_residuals(Tl, x, y, y_id); // residual for left bound 28 | double fr = Ty2x_residuals(Tr, x, y, y_id); // resdiual for right bound 29 | double f = 0.0; 30 | int numIters = 0; 31 | 32 | for (int i = 0; i < maxiter; i++) 33 | { 34 | numIters += 1; 35 | // get midpoint 36 | T = 0.5 * (Tl + Tr); 37 | // evaluate resdiual at midpoint 38 | f = Ty2x_residuals(T, x, y, y_id); 39 | // check for convergence 40 | if (fabs(f) < tol) 41 | { 42 | break; 43 | }; 44 | 45 | // reset the bounds 46 | if (f * fl < 0.0) 47 | { 48 | // move right bound info to mid 49 | Tr = T; 50 | fr = f; 51 | } 52 | else 53 | { 54 | // move left bound info to mid 55 | Tl = T; 56 | fl = f; 57 | } 58 | }; 59 | return T; 60 | } 61 | 62 | // (h,x,o_id) T 63 | double hx_reg4(double h, double x, int o_id) 64 | { 65 | double Tl = TMIN4; 66 | double Tr = TMAX4; 67 | double T = bisection_reg4(x, h, OH, Tl, Tr, 0.00001, 1000); 68 | if (o_id == OT) 69 | return T; 70 | return Tx_reg4(T, x, o_id); 71 | }; 72 | 73 | /// (s,x,o_id) 74 | double sx_reg4(double s, double x, int o_id) 75 | { 76 | double Tl = TMIN4; 77 | double Tr = TMAX4; 78 | double T = bisection_reg4(x, s, OS, Tl, Tr, 0.00001, 1000); 79 | if (o_id == OT) 80 | return T; 81 | return Tx_reg4(T, x, o_id); 82 | } 83 | -------------------------------------------------------------------------------- /src/r4/region4_pair_ext.c: -------------------------------------------------------------------------------- 1 | /* 2 | Region 4 - The extended input pairs: (p,v)->x, (t,v),(t,h),(t,s) ->x 3 | x: Steam quality 4 | */ 5 | #include 6 | #include 7 | #include "../algo/algorithm.h" 8 | #include "../common/common.h" 9 | #include "../common/constand.h" 10 | #include "../r1/region1.h" 11 | #include "../r2/region2.h" 12 | #include "../r3/region3.h" 13 | #include "region4.h" 14 | 15 | /// Region 4: (p,v)-> x 16 | double pv2x_reg4(double p, double v) 17 | { 18 | double v_sat_w = p2SatWater(p, OV); 19 | double v_sat_s = p2SatSteam(p, OV); 20 | return (v - v_sat_w) / (v_sat_s - v_sat_w); 21 | } 22 | 23 | /// Region 4: (T,v)-> x 24 | double Tv2x_reg4(double T, double v) 25 | { 26 | double v_sat_w = T2SatWater(T, OV); 27 | double v_sat_s = T2SatSteam(T, OV); 28 | return (v - v_sat_w) / (v_sat_s - v_sat_w); 29 | } 30 | 31 | /// Region 4: (T,h)-> x 32 | double Th2x_reg4(double T, double h) 33 | { 34 | double h_sat_w = T2SatWater(T, OH); 35 | double h_sat_s = T2SatSteam(T, OH); 36 | return (h - h_sat_w) / (h_sat_s - h_sat_w); 37 | } 38 | 39 | /// Region 4: (T,s)-> x 40 | double Ts2x_reg4(double T, double s) 41 | { 42 | double s_sat_w = T2SatWater(T, OS); 43 | double s_sat_s = T2SatSteam(T, OS); 44 | return (s - s_sat_w) / (s_sat_s - s_sat_w); 45 | } 46 | -------------------------------------------------------------------------------- /src/r4/region4_sat_pT.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | saturation pressure of water 4 | saturation temperature of water 5 | */ 6 | #include 7 | #include "region4.h" 8 | #include "../algo/algorithm.h" 9 | // 10 | // Initialize coefficients for region 4 11 | // 12 | static double n[11] = {0, 0.11670521452767E+04, -0.72421316703206E+06, -0.17073846940092E+02, 13 | 0.12020824702470E+05, -0.32325550322333E+07, 0.14915108613530E+02, 14 | -0.48232657361591E+04, 0.40511340542057E+06, -0.23855557567849E+00, 15 | 0.65017534844798E+03}; 16 | 17 | double pSat(double T) 18 | // saturation pressure of water 19 | // pSatW in bar 20 | // T :temperaturein K 21 | // 22 | // pSat = -1: temperature outside range 23 | // 24 | { 25 | double pS; 26 | if (T < 273.15 || T > 647.096) // tc_water=647.096 27 | pS = -1.0; 28 | else 29 | { 30 | double del = T + n[9] / (T - n[10]); 31 | double aco = del * (del + n[1]) + n[2]; 32 | double bco = del * (n[3] * del + n[4]) + n[5]; 33 | double cco = del * (n[6] * del + n[7]) + n[8]; 34 | pS = IPOW(2 * cco / (-bco + sqrt(bco * bco - 4 * aco * cco)), 4); 35 | } 36 | return pS; 37 | } 38 | 39 | double TSat(double p) 40 | // 41 | // saturation temperature of water 42 | // tSatW in K 43 | // p :pressure in bar 44 | // 45 | // tSatW=-1: pressure outside range 46 | // 47 | { 48 | double TS; 49 | if (p < 0.000611212677 || p > 22.064) 50 | TS = -1.0; 51 | else 52 | { 53 | double bet = pow(p, 0.25); 54 | double eco = bet * (bet + n[3]) + n[6]; 55 | double fco = bet * (n[1] * bet + n[4]) + n[7]; 56 | double gco = bet * (n[2] * bet + n[5]) + n[8]; 57 | double dco = 2.0 * gco / (-fco - sqrt(fco * fco - 4.0 * eco * gco)); 58 | TS = 0.5 * (n[10] + dco - sqrt((n[10] + dco) * (n[10] + dco) - 4.0 * (n[9] + n[10] * dco))); 59 | } 60 | return TS; 61 | } 62 | -------------------------------------------------------------------------------- /src/r5/region5.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | 5 | double gamma0_reg5(double pi, double tau); 6 | double gamma0_pi_reg5(double pi); 7 | double gamma0_pipi_reg5(double pi); 8 | double gamma0_pitau_reg5(); 9 | double gamma0_tau_reg5(double tau); 10 | double gamma0_tautau_reg5(double tau); 11 | 12 | double gammar_reg5(double pi, double tau); 13 | double gammar_pi_reg5(double pi, double tau); 14 | double gammar_pipi_reg5(double pi, double tau); 15 | double gammar_pitau_reg5(double pi, double tau); 16 | double gammar_tau_reg5(double pi, double tau); 17 | double gammar_tautau_reg5(double pi, double tau); 18 | 19 | 20 | // IF97 fundamental :(p,t) 21 | double pT2h_reg5(double p, double T); 22 | double pT2s_reg5(double p, double T); 23 | double pT2v_reg5(double p, double T); 24 | double pT2u_reg5(double p, double T); 25 | double pT2cv_reg5(double p, double T); 26 | double pT2cp_reg5(double p, double T); 27 | double pT2w_reg5(double p, double T); 28 | // extend 29 | double pT2k_reg5(double p, double T); 30 | double pT2g_reg5(double p, double T); 31 | double pT2f_reg5(double p, double T); 32 | double pT2e_reg5(double p, double T); 33 | double pT2joule_reg5(double p, double T); 34 | double pT2ijoule_reg5(double p, double T); 35 | double pT2z_reg5(double p, double T); 36 | double pT2kt_reg5(double p, double T); 37 | double pT2ipcec_reg5(double p, double T); 38 | double pT2dpdtcv_reg5(double p, double T); 39 | double pT2dvdpct_reg5(double p, double T); 40 | double pT2dvdtcp_reg5(double p, double T); 41 | 42 | 43 | 44 | 45 | // IF97 backward:(p,h)->T 46 | double ph2T_reg5(double p, double h); 47 | // IF97 backward: (p,s)->T 48 | double ps2T_reg5(double p, double s); 49 | // Supp:backward(h,s)->p 50 | double hs2p_reg5(double h, double s); 51 | 52 | // the extend input pairs 53 | // (p,v)->T (T,v)->p (T,s)->p (T,h)->p 54 | double pv2T_reg5(double p, double v); 55 | double Tv2p_reg5(double T, double v); 56 | double Ts2p_reg5(double T, double s); 57 | double Th2p_reg5(double T, double s); 58 | 59 | 60 | // (p,T) ->properties 61 | double pT_thermal_reg5(double p, double T, int o_id); 62 | double pT_ext_reg5(double p, double T, int o_id); 63 | 64 | // input pairs 65 | double pT_reg5(double p, double T, int o_id); 66 | 67 | double ph_reg5(double p, double h, int o_id); 68 | double ps_reg5(double p, double h, int o_id); 69 | double hs_reg5(double p, double h, int o_id); 70 | 71 | // the extend input pairs 72 | // (p,v) (T,v)p (T,s) 73 | double pv_reg5(double p, double v, int o_id); 74 | double Tv_reg5(double T, double v, int o_id); 75 | double Ts_reg5(double T, double s, int o_id); 76 | double Th_reg5(double T, double h, int o_id); -------------------------------------------------------------------------------- /src/r5/region5_coff.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "../common/common.h" 4 | 5 | static const double r5Pstar = 1.0; // MPa 6 | static const double r5Tstar = 1000.0; // K 7 | 8 | static const int Jo[6] = {0, 1, -3, -2, -1, 2}; 9 | 10 | static const double no[6] = { 11 | -0.13179983674201e+2, 12 | 0.68540841634434e+1, 13 | -0.24805148933466e-1, 14 | 0.36901534980333, 15 | -0.31161318213925e+1, 16 | -0.32961626538917}; 17 | 18 | // Table 38. coefficients and exponents of the residual part r of the dimensionless Gibbs free energy for region 5, Eq.(34) 19 | static IJnData IJn[] = { 20 | {1, 1, 0.15736404855259e-2}, 21 | {1, 2, 0.90153761673944e-3}, 22 | {1, 3, -0.50270077677648e-2}, 23 | {2, 3, 0.22440037409485e-5}, 24 | {2, 9, -0.41163275453471e-5}, 25 | {3, 7, 0.37919454822955e-7}}; -------------------------------------------------------------------------------- /src/r5/region5_gfe.c: -------------------------------------------------------------------------------- 1 | /* 2 | Region 5 3 | * http://www.iapws.org/relguide/IF97-Rev.html, 4 | P39 Eq 32-34: 5 | (p,T)->v,h,s,cp,cv,w 6 | */ 7 | #include 8 | #include "region5.h" 9 | #include "region5_coff.h" 10 | #include "../algo/algorithm.h" 11 | 12 | // P37 Table 37 13 | // Ideal properties for Region 5 14 | // Table 37. Numerical values of the coefficients and exponents of ideal-gas part of the 15 | // dimensionless Gibbs free energy for region 5, Eq. (33) 16 | 17 | // P36 The equation for the ideal-gas part of the dimensionless Gibbs free energy reads eq33 18 | double gamma0_reg5(double pi, double tau) 19 | { 20 | double value = log(pi); 21 | for (unsigned i = 0; i < 6; i++) 22 | value += no[i] * IPOW(tau, Jo[i]); 23 | return value; 24 | } 25 | 26 | // 38p 27 | double gamma0_pi_reg5(double pi) 28 | { 29 | return 1.0 / pi; 30 | } 31 | 32 | // 38p 33 | double gamma0_pipi_reg5(double pi) 34 | { 35 | return -1.0 / pi / pi; 36 | } 37 | 38 | double gamma0_tau_reg5(double tau) 39 | { 40 | double value = 0.0; 41 | for (unsigned i = 0; i < 6; i++) 42 | value += no[i] * Jo[i] * IPOW(tau, Jo[i] - 1); 43 | return value; 44 | } 45 | 46 | double gamma0_tautau_reg5(double tau) 47 | { 48 | double value = 0.0; 49 | for (unsigned i = 0; i < 6; i++) 50 | value += no[i] * Jo[i] * (Jo[i] - 1) * IPOW(tau, Jo[i] - 2); 51 | return value; 52 | } 53 | 54 | double gamma0_pitau_reg5() 55 | { 56 | return 0.0; 57 | } 58 | 59 | double gammar_reg5(double pi, double tau) 60 | { 61 | double value = 0.0; 62 | for (int i = 0; i < 6; i++) 63 | value += IJn[i].n * IPOW(pi, IJn[i].I) * IPOW(tau, IJn[i].J); 64 | return value; 65 | } 66 | 67 | // Table 41. The residual part  r of the dimensionless Gibbs free energy and its 68 | // derivatives valueaccording to Eq. (34) 69 | double gammar_pi_reg5(double pi, double tau) 70 | { 71 | double value = 0.0; 72 | for (unsigned i = 0; i < 6; i++) 73 | value += IJn[i].n * IJn[i].I * IPOW(pi, IJn[i].I - 1) * IPOW(tau, IJn[i].J); 74 | return value; 75 | } 76 | 77 | double gammar_pipi_reg5(double pi, double tau) 78 | { 79 | double value = 0.0; 80 | for (unsigned i = 0; i < 6; i++) 81 | value += IJn[i].n * IJn[i].I * (IJn[i].I - 1) * IPOW(pi, IJn[i].I - 2) * IPOW(tau, IJn[i].J); 82 | return value; 83 | } 84 | 85 | double gammar_tau_reg5(double pi, double tau) 86 | { 87 | double value = 0.0; 88 | for (unsigned i = 0; i < 6; i++) 89 | value += IJn[i].n * IPOW(pi, IJn[i].I) * IJn[i].J * IPOW(tau, IJn[i].J - 1); 90 | return value; 91 | } 92 | 93 | // 39p 94 | double gammar_tautau_reg5(double pi, double tau) 95 | { 96 | double value = 0.0; 97 | for (unsigned i = 0; i < 6; i++) 98 | value += IJn[i].n * IPOW(pi, IJn[i].I) * IJn[i].J * (IJn[i].J - 1) * IPOW(tau, IJn[i].J - 2); 99 | return value; 100 | } 101 | 102 | double gammar_pitau_reg5(double pi, double tau) 103 | { 104 | double value = 0.0; 105 | for (unsigned i = 0; i < 6; i++) 106 | value += IJn[i].n * IJn[i].I * IPOW(pi, IJn[i].I - 1) * IJn[i].J * IPOW(tau, IJn[i].J - 1); 107 | return value; 108 | } 109 | -------------------------------------------------------------------------------- /src/r5/region5_out.c: -------------------------------------------------------------------------------- 1 | /* 2 | The API of region5 3 | 4 | */ 5 | #include "region5.h" 6 | #include "../common/propertry_id.h" 7 | #include "../common/constand.h" 8 | 9 | double pT_reg5(double p, double T, int o_id) 10 | // o_id: output propertry 11 | { 12 | double value = 0.0; 13 | switch (o_id) 14 | { 15 | case OX: 16 | value = 2.0; 17 | break; 18 | case OR: 19 | value = 5.0; 20 | break; 21 | default: 22 | value = pT_reg(p, T, o_id, pT_thermal_reg5, pT_ext_reg5); 23 | break; 24 | } 25 | return value; 26 | } 27 | 28 | double ph_reg5(double p, double h, int o_id) 29 | // o_id: output propertry 30 | { 31 | double T, value; 32 | switch (o_id) 33 | { 34 | case OP: 35 | value = p; 36 | break; 37 | case OH: 38 | value = h; 39 | break; 40 | case OT: 41 | value = ph2T_reg5(p, h); 42 | break; 43 | case OV: 44 | T = ph2T_reg5(p, h); 45 | value = pT2v_reg5(p, T); 46 | break; 47 | case OD: 48 | T = ph2T_reg5(p, h); 49 | value = 1.0 / pT2v_reg5(p, T); 50 | break; 51 | case OS: 52 | T = ph2T_reg5(p, h); 53 | value = pT2s_reg5(p, T); 54 | break; 55 | case OCV: 56 | T = ph2T_reg5(p, h); 57 | value = pT2cv_reg5(p, T); 58 | break; 59 | case OCP: 60 | T = ph2T_reg5(p, h); 61 | value = pT2cp_reg5(p, T); 62 | break; 63 | case OW: 64 | T = ph2T_reg5(p, h); 65 | value = pT2w_reg5(p, T); 66 | break; 67 | default: 68 | value = INVALID_OUTID; 69 | break; 70 | } 71 | return value; 72 | } 73 | 74 | double ps_reg5(double p, double s, int o_id) 75 | // o_id: output propertry 76 | { 77 | double T, value; 78 | switch (o_id) 79 | { 80 | case OP: 81 | value = p; 82 | break; 83 | case OS: 84 | value = s; 85 | break; 86 | case OT: 87 | value = ps2T_reg5(p, s); 88 | break; 89 | case OV: 90 | T = ps2T_reg5(p, s); 91 | value = pT2v_reg5(p, T); 92 | break; 93 | case OD: 94 | T = ps2T_reg5(p, s); 95 | value = 1.0 / pT2v_reg5(p, T); 96 | break; 97 | case OH: 98 | T = ps2T_reg5(p, s); 99 | value = pT2h_reg5(p, T); 100 | break; 101 | case OCV: 102 | T = ps2T_reg5(p, s); 103 | value = pT2cv_reg5(p, T); 104 | break; 105 | case OCP: 106 | T = ps2T_reg5(p, s); 107 | value = pT2cp_reg5(p, T); 108 | break; 109 | case OW: 110 | T = ph2T_reg5(p, s); 111 | value = pT2w_reg5(p, T); 112 | break; 113 | default: 114 | value = INVALID_OUTID; 115 | break; 116 | } 117 | return value; 118 | } 119 | 120 | double hs_reg5(double h, double s, int o_id) 121 | // o_id: output propertry 122 | { 123 | double p, value; 124 | switch (o_id) 125 | { 126 | case OH: 127 | value = h; 128 | break; 129 | case OS: 130 | value = s; 131 | break; 132 | case OP: 133 | value = hs2p_reg5(h, s); 134 | break; 135 | case OT: 136 | case OV: 137 | case OCP: 138 | case OCV: 139 | case OW: 140 | case OU: 141 | p = hs2p_reg5(h, s); 142 | value = ph_reg5(p, h, o_id); 143 | break; 144 | default: 145 | value = INVALID_OUTID; 146 | break; 147 | } 148 | return value; 149 | } 150 | 151 | //----------------------------------------------------- 152 | // Region 5 : The extended input pair: (p,v), (t,v),(t,h),(t,s) 153 | //----------------------------------------------- 154 | // Region 5 :(p,v) T 155 | double pv_reg5(double p, double v, int o_id) 156 | { 157 | double T = pv2T_reg5(p, v); 158 | if (o_id == OT) 159 | { 160 | return T; 161 | }; 162 | return pT_reg5(p, T, o_id); 163 | } 164 | 165 | // Region 5 : (T,v) 166 | double Tv_reg5(double T, double v, int o_id) 167 | { 168 | if (o_id == OD) 169 | { 170 | return 1.0 / v; 171 | }; 172 | double p = Tv2p_reg5(T, v); 173 | if (o_id == OP) 174 | { 175 | return p; 176 | }; 177 | return pT_reg5(p, T, o_id); 178 | } 179 | 180 | /// Region 5 :(T,h) 181 | double Th_reg5(double T, double h, int o_id) 182 | { 183 | double p = Th2p_reg5(T, h); 184 | if (o_id == OP) 185 | { 186 | return p; 187 | }; 188 | return pT_reg5(p, T, o_id); 189 | } 190 | 191 | /// Region 5 : (T,s) 192 | double Ts_reg5(double T, double s, int o_id) 193 | { 194 | double p = Ts2p_reg5(T, s); 195 | if (o_id == OP) 196 | { 197 | return p; 198 | }; 199 | return pT_reg5(p, T, o_id); 200 | } 201 | -------------------------------------------------------------------------------- /src/r5/region5_pT.c: -------------------------------------------------------------------------------- 1 | /* 2 | Region 5 : Basic Eq (p,T)->v,h,s,cp,cv,w, 3 | http://www.iapws.org/relguide/IF97-Rev.html, Eq 32-34P39 4 | 5 | */ 6 | 7 | #include 8 | #include "region5.h" 9 | #include "../common/constand.h" 10 | #include "../common/propertry_id.h" 11 | #include "region5_coff.h" 12 | 13 | double pT_thermal_reg5(double p, double T, int o_id) 14 | // o_id: output propertry 15 | { 16 | double value; 17 | switch (o_id) 18 | { 19 | case OT: 20 | value = T; 21 | break; 22 | case OP: 23 | value = p; 24 | break; 25 | case OV: 26 | value = pT2v_reg5(p, T); 27 | break; 28 | case OD: 29 | value = 1.0/pT2v_reg5(p, T); 30 | break; 31 | case OH: 32 | value = pT2h_reg5(p, T); 33 | break; 34 | case OU: 35 | value = pT2u_reg5(p, T); 36 | break; 37 | case OS: 38 | value = pT2s_reg5(p, T); 39 | break; 40 | case OCV: 41 | value = pT2cv_reg5(p, T); 42 | break; 43 | case OCP: 44 | value = pT2cp_reg5(p, T); 45 | break; 46 | case OW: 47 | value = pT2w_reg5(p, T); 48 | break; 49 | default: 50 | value = INVALID_OUTID; 51 | break; 52 | } 53 | return value; 54 | 55 | } 56 | 57 | 58 | double pT2v_reg5(double p, double T) 59 | { // t[K], p[MPa] 60 | double pi = p / r5Pstar; 61 | double tau = r5Tstar / T; 62 | double a, v; 63 | a = pi * (gamma0_pi_reg5(pi) + gammar_pi_reg5(pi, tau)); 64 | v = rgas_water * T / p * a; 65 | return v * 0.001; 66 | } 67 | 68 | double pT2u_reg5(double p, double T) 69 | { // t[K], p[MPa] 70 | double pi = p / r5Pstar; 71 | double tau = r5Tstar / T; 72 | double a, u; 73 | a = tau * (gamma0_tau_reg5(tau) + gammar_tau_reg5(pi, tau)) - pi * (gamma0_pi_reg5(pi) + gammar_pi_reg5(pi, tau)); 74 | u = rgas_water * T * a; 75 | return u; 76 | } 77 | 78 | double pT2s_reg5(double p, double T) 79 | { // t[K], p[MPa] 80 | double pi = p / r5Pstar; 81 | double tau = r5Tstar / T; 82 | double a, s; 83 | a = tau * (gamma0_tau_reg5(tau) + gammar_tau_reg5(pi, tau)) - (gamma0_reg5(pi, tau) + gammar_reg5(pi, tau)); 84 | s = rgas_water * a; 85 | return s; 86 | } 87 | 88 | double pT2h_reg5(double p, double T) 89 | { // t[K], p[MPa] 90 | double pi = p / r5Pstar; 91 | double tau = r5Tstar / T; 92 | double a, h; 93 | a = tau * (gamma0_tau_reg5(tau) + gammar_tau_reg5(pi, tau)); 94 | h = rgas_water * T * a; 95 | return h; 96 | } 97 | 98 | double pT2cp_reg5(double p, double T) 99 | { // t[K], p[MPa] 100 | double pi = p / r5Pstar; 101 | double tau = r5Tstar / T; 102 | double a, cp; 103 | a = -tau*tau * (gamma0_tautau_reg5(tau) + gammar_tautau_reg5(pi, tau)); 104 | cp = rgas_water * a; 105 | return cp; 106 | } 107 | 108 | double pT2cv_reg5(double p, double T) 109 | { // t[K], p[MPa] 110 | double pi = p / r5Pstar; 111 | double tau = r5Tstar / T; 112 | double a, b, c; // for temp 113 | double cv; 114 | a = (-pow(tau, 2.0)) * (gamma0_tautau_reg5(tau) + gammar_tautau_reg5(pi, tau)); 115 | b = 1.0 + pi * gammar_pi_reg5(pi, tau) - tau * pi * gammar_pitau_reg5(pi, tau); 116 | c = 1.0 - pow(pi, 2.0) * gammar_pipi_reg5(pi, tau); 117 | cv = rgas_water * (a - pow(b, 2.0) / c); 118 | return cv; 119 | } 120 | 121 | double pT2w_reg5(double p, double T) 122 | { 123 | double w; 124 | double a, b, c, d, w2; 125 | double tau = r5Tstar / T; 126 | double pi = p / r5Pstar; 127 | double dgammar_pi = gammar_pi_reg5(pi, tau); 128 | 129 | a = pow(1.0 + pi * dgammar_pi, 2.0); 130 | b = 1.0 - pi * pi * gammar_pipi_reg5(pi, tau); 131 | c = 1.0 + pi * dgammar_pi - tau * pi * gammar_pitau_reg5(pi, tau); 132 | d = tau * tau * (gamma0_tautau_reg5(tau) + gammar_tautau_reg5(pi, tau)); 133 | w2 = rgas_water * T * a / (b + (c * c) / d) * 1000.0; 134 | if (w2 < 0.0) 135 | w2 = 0.0; 136 | w = sqrt(w2); 137 | return w; 138 | } 139 | -------------------------------------------------------------------------------- /src/r5/region5_pair.ext.c: -------------------------------------------------------------------------------- 1 | /* 2 | The extended pairs 3 | (p,v)->T 4 | (T,v)->p (T,h)->p (T,s)->p 5 | */ 6 | #include 7 | #include 8 | #include "../common/constand.h" 9 | #include "../common/propertry_id.h" 10 | #include "../algo/algorithm.h" 11 | #include "region5.h" 12 | #include "region5_coff.h" 13 | 14 | // Region 5 (p,v)->T using the secant method and refine adjust 15 | // * p: pressure MPa 16 | // * v: specific volume m^3/kg 17 | // * T: temperature K 18 | double pv2T_reg5(double p, double v) 19 | { 20 | double T1, T2, f1, f, v1, v2, T; 21 | T1 = TMIN5; 22 | v1 = pT2v_reg5(p, T1); 23 | T2 = TMAX5; 24 | v2 = pT2v_reg5(p, T2); 25 | f = v - pT2v_reg5(p, T2); 26 | if ((v2 - v1) != 0.0) 27 | { 28 | T1 = T1 + (T2 - T1) * (v - v1) / (v2 - v1); 29 | } 30 | f1 = v - pT2v_reg5(p, T1); 31 | T = rtsec2(pT2v_reg5, p, v, T1, T2, f1, f, xacc, iMAX); 32 | if (T < TMIN5) 33 | { 34 | T = TMIN5; 35 | } 36 | else 37 | { 38 | if (T > TMAX5) 39 | { 40 | T = TMAX5; 41 | }; 42 | }; 43 | return (T); 44 | } 45 | 46 | // Region 5 (T,v)->p using the secant method 47 | // T: temperature K 48 | // v: specific volume m^3/kg 49 | // p: pressure MPa 50 | double Tv2p_reg5(double T, double v) 51 | { 52 | double p, p1, p2, v1, v2, f1, f2; 53 | int vbounded = 0; 54 | p1 = PMIN5; // 55 | v1 = pT2v_reg5(p1, T); 56 | if (v == v1) 57 | return (p1); 58 | p2 = 10 * p1; 59 | v2 = pT2v_reg5(p2, T); 60 | if (v == v2) 61 | return (p2); 62 | if ((v > v2) && (v < v1)) 63 | vbounded = 1; 64 | while (vbounded == 0) 65 | { 66 | p1 = p2; 67 | v1 = v2; 68 | p2 = 5 * p1; 69 | if (p2 >= PMAX5) 70 | { 71 | p2 = PMAX5; 72 | vbounded = 1; 73 | } 74 | v2 = pT2v_reg5(p2, T); 75 | if (v == v2) 76 | return (p2); 77 | if ((v > v2) && (v < v1)) 78 | vbounded = 1; 79 | } 80 | f2 = v - v2; 81 | p1 = p2 - (p2 - p1) * (v - v2) / (v1 - v2); 82 | if (p1 < PMIN5) 83 | p1 = PMIN5; 84 | f1 = v - pT2v_reg5(p1, T); 85 | if (fabs(f1) < xacc) 86 | return (p1); 87 | p = rtsec1(pT2v_reg5, T, v, p1, p2, f1, f2, xacc, iMAX); 88 | if (p > PMAX5) 89 | p = PMAX5; 90 | if (p < PMIN5) 91 | p = PMIN5; 92 | return (p); 93 | } 94 | 95 | //---------------------------------------------- 96 | // (T,s)->p 97 | //---------------------------------------------- 98 | double Ts2p_reg5(double T, double s) 99 | { 100 | double p, p1, p2, s1, s2, f1, f2; 101 | p1 = PMIN5; // 102 | s1 == pT2s_reg5(p1, T); 103 | f1 = s - s1; 104 | p2 = PMAX5; 105 | s2 = pT2s_reg5(p2, T); 106 | f2 = s - s2; 107 | p1 = p2 - (p2 - p1) * (s - s2) / (s1 - s2); 108 | if (p1 < PMIN5) 109 | p1 = PMIN5; 110 | s1 = pT2s_reg5(p1, T); 111 | f1 = s - s1; 112 | if (fabs(f1) < xacc) 113 | return (p1); 114 | p = rtsec1(pT2s_reg5, T, s, p1, p2, f1, f2, xacc, iMAX); 115 | if (p > PMAX5) 116 | p = PMAX5; 117 | if (p < PMIN5) 118 | p = PMIN5; 119 | return (p); 120 | } 121 | 122 | // Region 5 (T,h)->p using the secant method 123 | // * T: temperature K 124 | // * h: specific enthalpy kJ/kg 125 | // * p: pressure MPa 126 | double Th2p_reg5(double T, double h) 127 | { 128 | double p, p1, p2, h1, h2, f1, f2; 129 | p1 = PMIN5; 130 | h1 = pT2h_reg5(p1, T); 131 | p2 = PMAX5; // 132 | h2 = pT2h_reg5(p2, T); 133 | f2 = h - h2; 134 | p1 = p2 - (p2 - p1) * fabs(h - h2) / (h1 - h2); 135 | f1 = h - pT2h_reg5(p1, T); 136 | if (fabs(f1) < xacc) 137 | return (p1); 138 | p = rtsec1(pT2h_reg5, T, h, p1, p2, f1, f2, xacc, iMAX); 139 | if (p > PMAX5) 140 | p = PMAX5; 141 | if (p < PMIN5) 142 | p = PMIN5; 143 | return (p); 144 | } 145 | -------------------------------------------------------------------------------- /src/r5/region5_ph_ps_hs.c: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------- 2 | 3 | Region 5: (p,h) (p,s) (h,s) 4 | ---------------------------------------------------------------------------*/ 5 | #include 6 | #include "region5.h" 7 | #include "../r2/region2.h" 8 | #include "../algo/algorithm.h" 9 | 10 | static double TMAX5 = 2273.15; 11 | static double TMIN5 = 1073.15; 12 | 13 | static double PMAX5 = 50; 14 | static double PMIN5 = 0.000611212677444; 15 | 16 | double ph2T_reg5(double p, double h) 17 | { 18 | double T, T1, T2; 19 | double f1, f2; 20 | 21 | // TODO: 插值求迭代初值方法 22 | //double hmin =pT2hreg2(p,1073.15); 23 | //double hmax = pT2h_reg5(p,2273.15); 24 | //T1=1073.15+(2273.15-1073.15)*(h-hmin)/(hmax-hmin); 25 | // 求迭代初值方法2: 以三相点为起点,采用与理想气体的对比关系求迭代初值 26 | 27 | T = -1000; 28 | 29 | T1 = 0.5 * (2273.15 + 1073.15); 30 | 31 | f1 = h - pT2h_reg5(p, T1); 32 | if (fabs(f1) > xacc) 33 | { 34 | if (f1 > 0) 35 | T2 = (1.0 + f1 / h) * T1; 36 | else 37 | T2 = (1.0 - f1 / h) * T1; 38 | 39 | f2 = h - pT2h_reg5(p, T2); 40 | 41 | T = rtsec2(pT2h_reg5, p, h, T1, T2, f1, f2, xacc, iMAX); 42 | } 43 | else 44 | T = T1; 45 | 46 | if (T < TMIN5) 47 | T = TMIN5; 48 | else if (T > TMAX5) 49 | T = TMAX5; 50 | 51 | return (T); 52 | } 53 | 54 | double ps2T_reg5(double p, double s) 55 | { 56 | double T, T1, T2, f1, f; 57 | //RODO: 插值求迭代初值方法1 58 | //double smin =pT2sreg2(p,1073.15); 59 | //double smax = pT2s_reg5(p,2273.15); 60 | //T1=1073.15+(2273.15-1073.15)*(s-smin)/(smax-smin); 61 | 62 | T = -1000; 63 | 64 | T1 = 0.5 * (2273.15 + 1073.15); // ,Get initial value 65 | 66 | f1 = s - pT2s_reg5(p, T1); 67 | 68 | if (fabs(f1) > xacc) 69 | { 70 | if (f1 > 0) 71 | T2 = (1.0 + f1 / s) * T1; 72 | else 73 | T2 = (1.0 - f1 / s) * T1; 74 | 75 | f = s - pT2s_reg5(p, T2); 76 | T = rtsec2(pT2s_reg5, p, s, T1, T2, f1, f, xacc, iMAX); 77 | } 78 | else 79 | T = T1; 80 | 81 | if (T < TMIN5) 82 | T = TMIN5; 83 | else if (T > TMAX5) 84 | T = TMAX5; 85 | 86 | return T; 87 | } 88 | 89 | // helper for hs2preg5 90 | double ph2s_reg5(double p, double h) 91 | { 92 | double T = ph2T_reg5(p, h); 93 | double s = pT2s_reg5(p, T); 94 | return s; 95 | } 96 | 97 | double hs2p_reg5(double h, double s) 98 | { 99 | double p, p1, p2, f1, f2; 100 | 101 | // TODO: 迭代初始值,可测试那个更好? 102 | // 也可以计算smin,smax,2元插值得到更接近的p1 103 | 104 | // 测试表明:更复杂的方法计算迭代初始数值并不更好 105 | //double hmin =pT2h_reg5(PMIN5,1073.15); 106 | //double hmax =pT2h_reg5(PMAX5,2273.15); 107 | //p1=PMIN5+(PMAX5-PMIN5)*(h-hmin)/(hmax-hmin); 108 | 109 | p1 = 0.5 * (PMIN5 + PMAX5); 110 | 111 | f1 = s - ph2s_reg5(p1, h); 112 | 113 | if (fabs(f1) > xacc) 114 | { 115 | if (f1 > 0) 116 | p2 = (1.0 + f1 / s) * p1; 117 | else 118 | p2 = (1.0 - f1 / s) * p1; 119 | 120 | f2 = s - ph2s_reg5(p2, h); 121 | 122 | p = rtsec1(ph2s_reg5, h, s, p1, p2, f1, f2, xacc, iMAX); 123 | } 124 | else 125 | p = p1; 126 | 127 | return (p); 128 | } 129 | -------------------------------------------------------------------------------- /test/makefile: -------------------------------------------------------------------------------- 1 | # the general makefile for each test 2 | # make FILE=test_hs.c 3 | ifneq ($(OS),Windows_NT) 4 | UNAME_S := $(shell uname -s) 5 | ifeq ($(UNAME_S),Linux) 6 | LIBFLAGS =-lm 7 | endif 8 | endif 9 | 10 | CC=gcc 11 | FLAG=-O3 -march=native 12 | 13 | INC = -I ../src/common/ \ 14 | -I ../algo/ \ 15 | -I ../src/r1/ \ 16 | -I ../src/r2/ \ 17 | -I ../src/r3/ \ 18 | -I ../src/r4/ \ 19 | -I ../src/r5/ 20 | 21 | SRCS= ../src/algo/*.c \ 22 | ../src/common/*.c \ 23 | ../src/r1/*.c \ 24 | ../src/r2/*.c \ 25 | ../src/r3/*.c \ 26 | ../src/r4/*.c \ 27 | ../src/r5/*.c 28 | 29 | OUT=../bin/test 30 | 31 | all: test 32 | $(OUT) 33 | 34 | test: $(SRCS) 35 | $(CC) -o $(OUT) $(FLAG) $(SRCS) $(FILE) ../unity/unity.c $(INC) $(LIBFLAGS) 36 | 37 | -------------------------------------------------------------------------------- /test/test_hs.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "if97_data.h" 5 | 6 | void setUp(void) {} 7 | 8 | void tearDown(void) {} 9 | 10 | void test_hs_reg1(void) 11 | { 12 | 13 | for (int i = 0; i < 3; i++) 14 | { 15 | double h = r1_hspT[i].h; 16 | double s = r1_hspT[i].s; 17 | double t = r1_hspT[i].T - 273.15; 18 | TEST_ASSERT_FLOAT_WITHIN(1.0e-1, t, hs(h, s, OT)); 19 | TEST_ASSERT_FLOAT_WITHIN(1.0e-1, r1_hspT[i].p, hs(h, s, OP)); 20 | } 21 | } 22 | 23 | void test_hs_reg2(void) 24 | { 25 | // table15,Page17: p,T,v,h,u,s,cp,ws 26 | 27 | for (int i = 0; i < 3; i++) 28 | { 29 | double h = r2a_hsP[i].h; 30 | double s = r2a_hsP[i].s; 31 | TEST_ASSERT_EQUAL_FLOAT(r2a_hsP[i].p, hs(h, s, OP)); 32 | 33 | h = r2b_hsP[i].h; 34 | s = r2b_hsP[i].s; 35 | TEST_ASSERT_EQUAL_FLOAT(r2b_hsP[i].p, hs(h, s, OP)); 36 | 37 | h = r2c_hsP[i].h; 38 | s = r2c_hsP[i].s; 39 | TEST_ASSERT_EQUAL_FLOAT(r2c_hsP[i].p, hs(h, s, OP)); 40 | } 41 | } 42 | 43 | void test_hs_reg3(void) 44 | { 45 | double h, s; 46 | for (int i = 0; i < 3; i++) 47 | { 48 | h = r3a_hsP[i].h; 49 | s = r3a_hsP[i].s; 50 | TEST_ASSERT_FLOAT_WITHIN(1.0e-2,r3a_hsP[i].p, hs(h, s, OP)); 51 | h = r3b_hsP[i].h; 52 | s = r3b_hsP[i].s; 53 | TEST_ASSERT_FLOAT_WITHIN(1.0e-1,r3b_hsP[i].p, hs(h, s, OP)); 54 | } 55 | } 56 | 57 | void test_hs_reg4(void) 58 | { 59 | 60 | for (int i = 0; i < 3; i++) 61 | { 62 | double h = r4_hsT[i].h; 63 | double s = r4_hsT[i].s; 64 | TEST_ASSERT_EQUAL_FLOAT(r4_hsT[i].T - 273.15, hs(h, s, OT)); 65 | } 66 | } 67 | 68 | void test_hs_reg5(void) 69 | { 70 | for (int i = 0; i < 3; i++) 71 | { 72 | double h = r5_pT[i].h; 73 | double s = r5_pT[i].s; 74 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].T - 273.15, hs(h, s, OT)); 75 | } 76 | } 77 | 78 | int main(void) 79 | { 80 | UNITY_BEGIN(); 81 | RUN_TEST(test_hs_reg1); 82 | RUN_TEST(test_hs_reg2); 83 | RUN_TEST(test_hs_reg3); 84 | RUN_TEST(test_hs_reg4); 85 | RUN_TEST(test_hs_reg5); 86 | return UNITY_END(); 87 | } -------------------------------------------------------------------------------- /test/test_hxsx.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "if97_data.h" 5 | 6 | void setUp(void) {} 7 | 8 | void tearDown(void) {} 9 | 10 | void test_hx(void) 11 | { 12 | double t, h, x; 13 | x = 0.35; 14 | for (int i = 0; i < 3; i++) 15 | { 16 | t = r4_Tp[i].T - 273.15; 17 | h = tx(t, x, OH); 18 | TEST_ASSERT_FLOAT_WITHIN(1.0e-1, t, hx(h, x, OT)); 19 | } 20 | } 21 | 22 | void test_sx(void) 23 | { 24 | double t, s, x; 25 | x = 0.35; 26 | for (int i = 0; i < 3; i++) 27 | { 28 | t = r4_Tp[i].T - 273.15; 29 | s = tx(t, x, OS); 30 | TEST_ASSERT_FLOAT_WITHIN(1.0e-1, t, sx(s, x, OT)); 31 | } 32 | } 33 | 34 | int main(void) 35 | { 36 | UNITY_BEGIN(); 37 | RUN_TEST(test_hx); 38 | RUN_TEST(test_sx); 39 | return UNITY_END(); 40 | } -------------------------------------------------------------------------------- /test/test_ph.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "if97_data.h" 5 | 6 | void setUp(void) {} 7 | 8 | void tearDown(void) {} 9 | 10 | void test_ph_reg1(void) 11 | { 12 | 13 | for (int i = 0; i < 3; i++) 14 | { 15 | double p = r1_phT[i].p; 16 | double h = r1_phT[i].h; 17 | TEST_ASSERT_FLOAT_WITHIN(1.0e-1, r1_phT[i].T - 273.15, ph(p, h, OT)); 18 | } 19 | } 20 | 21 | void test_ph_reg2(void) 22 | { 23 | for (int i = 0; i < 3; i++) 24 | { 25 | double p = r2a_phT[i].p; 26 | double h = r2a_phT[i].h; 27 | TEST_ASSERT_EQUAL_FLOAT(r2a_phT[i].T - 273.15, ph(p, h, OT)); 28 | 29 | p = r2b_phT[i].p; 30 | h = r2b_phT[i].h; 31 | TEST_ASSERT_EQUAL_FLOAT(r2b_phT[i].T - 273.15, ph(p, h, OT)); 32 | 33 | p = r2c_phT[i].p; 34 | h = r2c_phT[i].h; 35 | TEST_ASSERT_EQUAL_FLOAT(r2c_phT[i].T - 273.15, ph(p, h, OT)); 36 | } 37 | } 38 | 39 | void test_ph_reg3(void) 40 | { 41 | 42 | double p, h; 43 | for (int i = 0; i < 3; i++) 44 | { 45 | double p = r3a_phTv[i].p; 46 | double h = r3a_phTv[i].h; 47 | TEST_ASSERT_EQUAL_FLOAT(r3a_phTv[i].T - 273.15, ph(p, h, OT)); 48 | TEST_ASSERT_EQUAL_FLOAT(r3a_phTv[i].v, ph(p, h, OV)); 49 | p = r3b_phTv[i].p; 50 | h = r3b_phTv[i].h; 51 | TEST_ASSERT_EQUAL_FLOAT(r3b_phTv[i].T - 273.15, ph(p, h, OT)); 52 | TEST_ASSERT_EQUAL_FLOAT(r3b_phTv[i].v, ph(p, h, OV)); 53 | } 54 | } 55 | 56 | void test_ph_reg4(void) 57 | { 58 | 59 | double h, p, t, x; 60 | for (int i = 0; i < 3; i++) 61 | { 62 | double p = r4_pT[1].p; 63 | x = 0.36; 64 | h = px(p, x, OH); 65 | TEST_ASSERT_EQUAL_FLOAT(x, ph(p, h, OX)); 66 | } 67 | 68 | for (int i = 0; i < 3; i++) 69 | { 70 | p = r4_Tp[1].p; 71 | x = 0.36; 72 | h = px(p, x, OH); 73 | TEST_ASSERT_EQUAL_FLOAT(x, ph(p, h, OX)); 74 | } 75 | } 76 | 77 | void test_ph_reg5(void) 78 | { 79 | 80 | for (int i = 0; i < 3; i++) 81 | { 82 | double p = r5_pT[i].p; 83 | double h = r5_pT[i].h; 84 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].T - 273.15, ph(p, h, OT)); 85 | } 86 | } 87 | 88 | int main(void) 89 | { 90 | UNITY_BEGIN(); 91 | RUN_TEST(test_ph_reg1); 92 | RUN_TEST(test_ph_reg2); 93 | RUN_TEST(test_ph_reg3); 94 | RUN_TEST(test_ph_reg4); 95 | RUN_TEST(test_ph_reg5); 96 | return UNITY_END(); 97 | } -------------------------------------------------------------------------------- /test/test_process.c: -------------------------------------------------------------------------------- 1 | 2 | #include "../src/common/seuif97.h" 3 | #include "../unity/unity.h" 4 | 5 | void setUp(void) {} 6 | 7 | void tearDown(void) {} 8 | 9 | void test_proc(void) 10 | { 11 | double p1 = 16.1; 12 | double t1 = 535.2; 13 | double p2 = 3.56; 14 | double t2 = 315.1; 15 | 16 | TEST_ASSERT_EQUAL_FLOAT(426.30304, ishd(p1, t1, p2)); 17 | TEST_ASSERT_FLOAT_WITHIN(1.0e-2,89.45, ief(p1, t1, p2, t2)); 18 | } 19 | 20 | int main(void) 21 | { 22 | UNITY_BEGIN(); 23 | RUN_TEST(test_proc); 24 | return UNITY_END(); 25 | } -------------------------------------------------------------------------------- /test/test_ps.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "if97_data.h" 5 | 6 | void setUp(void) {} 7 | 8 | void tearDown(void) {} 9 | 10 | void test_ps_reg1(void) 11 | { 12 | for (int i = 0; i < 3; i++) 13 | { 14 | double p = r1_psT[i].p; 15 | double s = r1_psT[i].s; 16 | TEST_ASSERT_FLOAT_WITHIN(1.0e-1,r1_psT[i].T - 273.15, ps(p, s, OT)); 17 | } 18 | } 19 | 20 | void test_ps_reg2(void) 21 | { 22 | // table15,Page17: p,T,v,h,u,s,cp,ws 23 | 24 | for (int i = 0; i < 3; i++) 25 | { 26 | 27 | double p = r2a_psT[i].p; 28 | double s = r2a_psT[i].s; 29 | TEST_ASSERT_EQUAL_FLOAT(r2a_psT[i].T - 273.15, ps(p, s, OT)); 30 | p = r2b_psT[i].p; 31 | s = r2b_psT[i].s; 32 | TEST_ASSERT_EQUAL_FLOAT(r2b_psT[i].T - 273.15, ps(p, s, OT)); 33 | p = r2c_psT[i].p; 34 | s = r2c_psT[i].s; 35 | TEST_ASSERT_EQUAL_FLOAT(r2c_psT[i].T - 273.15, ps(p, s, OT)); 36 | } 37 | } 38 | 39 | void test_ps_reg3(void) 40 | { 41 | 42 | double p, s; 43 | for (int i = 0; i < 3; i++) 44 | { 45 | p = r3a_psTv[i].p; 46 | s = r3a_psTv[i].s; 47 | TEST_ASSERT_EQUAL_FLOAT(r3a_psTv[i].T - 273.15, ps(p, s, OT)); 48 | TEST_ASSERT_EQUAL_FLOAT(r3a_psTv[i].v, ps(p, s, OV)); 49 | p = r3b_psTv[i].p; 50 | s = r3b_psTv[i].s; 51 | TEST_ASSERT_EQUAL_FLOAT(r3b_psTv[i].T - 273.15, ps(p, s, OT)); 52 | TEST_ASSERT_EQUAL_FLOAT(r3b_psTv[i].v, ps(p, s, OV)); 53 | } 54 | } 55 | 56 | void test_ps_reg4(void) 57 | { 58 | 59 | double p, s, x; 60 | for (int i = 0; i < 3; i++) 61 | { 62 | double p = r4_pT[i].p; 63 | x = 0.35; 64 | s = px(p, x, OS); 65 | TEST_ASSERT_EQUAL_FLOAT(x, ps(p, s, OX)); 66 | } 67 | 68 | for (int i = 0; i < 3; i++) 69 | { 70 | p = r4_Tp[1].p; 71 | x = 0.36; 72 | s = px(p, x, OS); 73 | TEST_ASSERT_EQUAL_FLOAT(x, ps(p, s, OX)); 74 | } 75 | } 76 | 77 | void test_ps_reg5(void) 78 | { 79 | for (int i = 0; i < 3; i++) 80 | { 81 | double p = r5_pT[i].p; 82 | double s = r5_pT[i].s; 83 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].T - 273.15, ps(p, s, OT)); 84 | } 85 | } 86 | 87 | int main(void) 88 | { 89 | UNITY_BEGIN(); 90 | RUN_TEST(test_ps_reg1); 91 | RUN_TEST(test_ps_reg2); 92 | RUN_TEST(test_ps_reg3); 93 | RUN_TEST(test_ps_reg4); 94 | RUN_TEST(test_ps_reg5); 95 | return UNITY_END(); 96 | } -------------------------------------------------------------------------------- /test/test_pt.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "if97_data.h" 5 | 6 | void setUp(void) {} 7 | 8 | void tearDown(void) {} 9 | 10 | void test_pt_reg1(void) 11 | { 12 | 13 | for (int i = 0; i < 3; i++) 14 | { 15 | double p = r1_pT[i].p; 16 | double t = r1_pT[i].T - 273.15; 17 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].v, pt(p, t, OV)); 18 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].h, pt(p, t, OH)); 19 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].s, pt(p, t, OS)); 20 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].u, pt(p, t, OU)); 21 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].cv, pt(p, t, OCV)); 22 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].cp, pt(p, t, OCP)); 23 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].w, pt(p, t, OW)); 24 | } 25 | } 26 | 27 | void test_pt_reg2(void) 28 | { 29 | // table15,Page17: p,T,v,h,u,s,cp,ws 30 | 31 | for (int i = 0; i < 3; i++) 32 | { 33 | double p = r2_pT[i].p; 34 | double t = r2_pT[i].T - 273.15; 35 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].v, pt(p, t, OV)); 36 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].h, pt(p, t, OH)); 37 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].s, pt(p, t, OS)); 38 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].u, pt(p, t, OU)); 39 | // TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].cv, pt(p,t,OCV)); 40 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].cp, pt(p, t, OCP)); 41 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].w, pt(p, t, OW)); 42 | } 43 | } 44 | 45 | void test_pt_reg3(void) 46 | { 47 | double p, t; 48 | for (int i = 0; i < 52; i++) 49 | { 50 | p = r3_pTv[i].p; 51 | t = r3_pTv[i].T - 273.15; 52 | TEST_ASSERT_EQUAL_FLOAT(r3_pTv[i].v, pt(p, t, OV)); 53 | } 54 | } 55 | 56 | void test_pt_reg4(void) 57 | { 58 | double p, t; 59 | for (int i = 0; i < 3; i++) 60 | { 61 | p = r4_pT[i].p; 62 | TEST_ASSERT_EQUAL_FLOAT(r4_pT[i].T - 273.15, px(p, 0.0, OT)); 63 | } 64 | 65 | for (int i = 0; i < 3; i++) 66 | { 67 | t = r4_Tp[i].T - 273.15; 68 | TEST_ASSERT_EQUAL_FLOAT(r4_Tp[i].p, tx(t, 0.0, OP)); 69 | } 70 | } 71 | 72 | void test_pt_reg5(void) 73 | { 74 | 75 | for (int i = 0; i < 3; i++) 76 | { 77 | double p = r5_pT[i].p; 78 | double t = r5_pT[i].T - 273.15; 79 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].v, pt(p, t, OV)); 80 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].h, pt(p, t, OH)); 81 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].u, pt(p, t, OU)); 82 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].s, pt(p, t, OS)); 83 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].cp, pt(p, t, OCP)); 84 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].w, pt(p, t, OW)); 85 | } 86 | } 87 | 88 | void test_pt_critical(void) 89 | { 90 | // critical point 91 | double tc_water = 647.096 - 273.15; // critical temperature in K 92 | double pc_water = 22.064; // critical p in Mpa 93 | double dc_water = 322.0; // critical density in kg/m**3 94 | double sc_water = 4.41202148223476; // Critic entropy 95 | double hc_water = 2.087546845e+03; // Critic entropy h 96 | TEST_ASSERT_EQUAL_FLOAT(sc_water, pt(pc_water, tc_water, OS)); 97 | TEST_ASSERT_EQUAL_FLOAT(hc_water, pt(pc_water, tc_water, OH)); 98 | TEST_ASSERT_EQUAL_FLOAT(dc_water, pt(pc_water, tc_water, OD)); 99 | TEST_ASSERT_EQUAL_FLOAT(tc_water, pt(pc_water, tc_water, OT)); 100 | TEST_ASSERT_EQUAL_FLOAT(pc_water, pt(pc_water, tc_water, OP)); 101 | } 102 | 103 | int main(void) 104 | { 105 | UNITY_BEGIN(); 106 | RUN_TEST(test_pt_reg1); 107 | RUN_TEST(test_pt_reg2); 108 | RUN_TEST(test_pt_reg3); 109 | RUN_TEST(test_pt_reg4); 110 | RUN_TEST(test_pt_reg5); 111 | RUN_TEST(test_pt_critical); 112 | return UNITY_END(); 113 | } -------------------------------------------------------------------------------- /test/test_pv.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "../src/r1/region1.h" 5 | #include "../src/r2/region2.h" 6 | #include "../src/r3/region3.h" 7 | #include "../src/r4/region4.h" 8 | #include "../src/r5/region5.h" 9 | #include "if97_data.h" 10 | 11 | void setUp(void) {} 12 | 13 | void tearDown(void) {} 14 | 15 | void test_pv_reg1(void) 16 | { 17 | 18 | for (int i = 0; i < 3; i++) 19 | { 20 | double p = r1_pT[i].p; 21 | double v = r1_pT[i].v; 22 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].T - 273.15, pv(p, v, OT)); 23 | } 24 | } 25 | 26 | void test_pv_reg2(void) 27 | { 28 | 29 | for (int i = 0; i < 3; i++) 30 | { 31 | double p = r2_pT[i].p; 32 | double v = r2_pT[i].v; 33 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].T - 273.15, pv(p, v, OT)); 34 | } 35 | } 36 | 37 | void test_pv_reg3(void) 38 | { 39 | 40 | for (int i = 0; i < 3; i++) 41 | { 42 | double p = r3_Td[i].p; 43 | double v = 1.0 / r3_Td[i].d; 44 | TEST_ASSERT_EQUAL_FLOAT(r3_Td[i].T - 273.15, pv(p, v, OT)); 45 | } 46 | } 47 | 48 | void test_pv_reg4(void) 49 | { 50 | double p, v, x; 51 | for (int i = 0; i < 3; i++) 52 | { 53 | double p = r4_pT[1].p; 54 | x = 0.36; 55 | v = px(p, x, OV); 56 | TEST_ASSERT_EQUAL_FLOAT(x, pv(p, v, OX)); 57 | } 58 | 59 | for (int i = 0; i < 3; i++) 60 | { 61 | p = r4_Tp[1].p; 62 | x = 0.36; 63 | v = px(p, x, OV); 64 | TEST_ASSERT_EQUAL_FLOAT(x, pv(p, v, OX)); 65 | } 66 | } 67 | 68 | void test_pv_reg5(void) 69 | { 70 | 71 | for (int i = 0; i < 3; i++) 72 | { 73 | double p = r5_pT[i].p; 74 | double v = r5_pT[i].v; 75 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].T - 273.15, pv(p, v, OT)); 76 | } 77 | } 78 | 79 | int main(void) 80 | { 81 | UNITY_BEGIN(); 82 | RUN_TEST(test_pv_reg1); 83 | RUN_TEST(test_pv_reg2); 84 | RUN_TEST(test_pv_reg3); 85 | RUN_TEST(test_pv_reg4); 86 | RUN_TEST(test_pv_reg5); 87 | return UNITY_END(); 88 | } -------------------------------------------------------------------------------- /test/test_th.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "../src/r1/region1.h" 5 | #include "../src/r2/region2.h" 6 | #include "../src/r3/region3.h" 7 | #include "../src/r4/region4.h" 8 | #include "../src/r5/region5.h" 9 | #include "if97_data.h" 10 | 11 | void setUp(void) {} 12 | 13 | void tearDown(void) {} 14 | 15 | void test_th_reg1(void) 16 | { 17 | 18 | for (int i = 0; i < 3; i++) 19 | { 20 | double t = r1_pT[i].T-273.15; 21 | double h = r1_pT[i].h; 22 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].p, th(t,h,OP)); 23 | } 24 | } 25 | 26 | void test_th_reg2(void) 27 | { 28 | 29 | for (int i = 0; i < 3; i++) 30 | { 31 | double t = r2_pT[i].T-273.15; 32 | double h = r2_pT[i].h; 33 | TEST_ASSERT_FLOAT_WITHIN(1.0e-3, r2_pT[i].p, th(t,h,OP)); 34 | } 35 | } 36 | 37 | void test_th_reg3(void) 38 | { 39 | 40 | for (int i = 0; i < 3; i++) 41 | { 42 | double t = r3_Td[i].T-273.15; 43 | double h = r3_Td[i].h; 44 | TEST_ASSERT_FLOAT_WITHIN(1.0e-6, r3_Td[i].d, th(t,h,OD)); 45 | } 46 | } 47 | 48 | void test_th_reg4(void) 49 | { 50 | 51 | double h, p, t, x; 52 | for (int i = 0; i < 3; i++) 53 | { 54 | t = r4_pT[1].T-273.15; 55 | x = 0.36; 56 | h = tx(t, x, OH); 57 | TEST_ASSERT_EQUAL_FLOAT(x, th(t, h, OX)); 58 | } 59 | 60 | for (int i = 0; i < 3; i++) 61 | { 62 | t = r4_Tp[1].T-273.15; 63 | x = 0.36; 64 | h = tx(t, x, OH); 65 | TEST_ASSERT_EQUAL_FLOAT(x, th(t, h, OX)); 66 | } 67 | } 68 | 69 | void test_th_reg5(void) 70 | { 71 | 72 | for (int i = 0; i < 3; i++) 73 | { 74 | double t = r5_pT[i].T-273.15; 75 | double h = r5_pT[i].h; 76 | TEST_ASSERT_FLOAT_WITHIN(1.0e-3, r5_pT[i].p, th(t,h,OP)); 77 | } 78 | } 79 | 80 | int main(void) 81 | { 82 | UNITY_BEGIN(); 83 | RUN_TEST(test_th_reg1); 84 | RUN_TEST(test_th_reg2); 85 | RUN_TEST(test_th_reg3); 86 | RUN_TEST(test_th_reg4); 87 | RUN_TEST(test_th_reg5); 88 | return UNITY_END(); 89 | } -------------------------------------------------------------------------------- /test/test_ts.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "../src/r1/region1.h" 5 | #include "../src/r2/region2.h" 6 | #include "../src/r3/region3.h" 7 | #include "../src/r4/region4.h" 8 | #include "../src/r5/region5.h" 9 | #include "if97_data.h" 10 | 11 | void setUp(void) {} 12 | 13 | void tearDown(void) {} 14 | 15 | void test_ts_reg1(void) 16 | { 17 | 18 | for (int i = 0; i < 3; i++) 19 | { 20 | double t = r1_pT[i].T - 273.15; 21 | double s = r1_pT[i].s; 22 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].p, ts(t, s, OP)); 23 | } 24 | } 25 | 26 | void test_ts_reg2(void) 27 | { 28 | 29 | for (int i = 0; i < 3; i++) 30 | { 31 | double t = r2_pT[i].T - 273.15; 32 | double s = r2_pT[i].s; 33 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].p, ts(t, s, OP)); 34 | } 35 | } 36 | 37 | void test_ts_reg3(void) 38 | { 39 | for (int i = 0; i < 3; i++) 40 | { 41 | double t = r3_Td[i].T - 273.15; 42 | double s = r3_Td[i].s; 43 | TEST_ASSERT_EQUAL_FLOAT(r3_Td[i].d, ts(t, s, OD)); 44 | } 45 | } 46 | void test_ts_reg4(void) 47 | { 48 | 49 | double s, t, x; 50 | for (int i = 0; i < 3; i++) 51 | { 52 | t = r4_pT[1].T - 273.15; 53 | x = 0.36; 54 | s = tx(t, x, OS); 55 | TEST_ASSERT_EQUAL_FLOAT(x, ts(t, s, OX)); 56 | } 57 | 58 | for (int i = 0; i < 3; i++) 59 | { 60 | t = r4_Tp[1].T - 273.15; 61 | x = 0.36; 62 | s = tx(t, x, OS); 63 | TEST_ASSERT_EQUAL_FLOAT(x, ts(t, s, OX)); 64 | } 65 | } 66 | 67 | void test_ts_reg5(void) 68 | { 69 | 70 | for (int i = 0; i < 3; i++) 71 | { 72 | double t = r5_pT[i].T - 273.15; 73 | double s = r5_pT[i].s; 74 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].p, ts(t, s, OP)); 75 | } 76 | } 77 | 78 | int main(void) 79 | { 80 | UNITY_BEGIN(); 81 | RUN_TEST(test_ts_reg1); 82 | RUN_TEST(test_ts_reg2); 83 | RUN_TEST(test_ts_reg3); 84 | RUN_TEST(test_ts_reg4); 85 | RUN_TEST(test_ts_reg5); 86 | return UNITY_END(); 87 | } -------------------------------------------------------------------------------- /test/test_tv.c: -------------------------------------------------------------------------------- 1 | #include "../src/common/seuif97.h" 2 | #include "../src/common/propertry_id.h" 3 | #include "../Unity/unity.h" 4 | #include "../src/r1/region1.h" 5 | #include "../src/r2/region2.h" 6 | #include "../src/r3/region3.h" 7 | #include "../src/r4/region4.h" 8 | #include "../src/r5/region5.h" 9 | #include "if97_data.h" 10 | 11 | void setUp(void) {} 12 | 13 | void tearDown(void) {} 14 | 15 | void test_tv_reg1(void) 16 | { 17 | 18 | for (int i = 0; i < 3; i++) 19 | { 20 | double t = r1_pT[i].T - 273.15; 21 | double v = r1_pT[i].v; 22 | TEST_ASSERT_EQUAL_FLOAT(r1_pT[i].p, tv(t, v, OP)); 23 | } 24 | } 25 | 26 | void test_tv_reg2(void) 27 | { 28 | 29 | for (int i = 0; i < 3; i++) 30 | { 31 | double t = r2_pT[i].T - 273.15; 32 | double v = r2_pT[i].v; 33 | TEST_ASSERT_EQUAL_FLOAT(r2_pT[i].p, tv(t, v, OP)); 34 | } 35 | } 36 | 37 | void test_tv_reg3(void) 38 | { 39 | for (int i = 0; i < 3; i++) 40 | { 41 | double t = r3_Td[i].T - 273.15; 42 | double v = 1.0 / r3_Td[i].d; 43 | TEST_ASSERT_EQUAL_FLOAT(r3_Td[i].p, tv(t, v, OP)); 44 | } 45 | } 46 | 47 | void test_tv_reg4(void) 48 | { 49 | 50 | double v, t, x; 51 | for (int i = 0; i < 3; i++) 52 | { 53 | t = r4_pT[1].T - 273.15; 54 | x = 0.36; 55 | v = tx(t, x, OV); 56 | TEST_ASSERT_EQUAL_FLOAT(x, tv(t, v, OX)); 57 | } 58 | 59 | for (int i = 0; i < 3; i++) 60 | { 61 | t = r4_Tp[1].T - 273.15; 62 | x = 0.36; 63 | v = tx(t, x, OV); 64 | TEST_ASSERT_EQUAL_FLOAT(x, tv(t, v, OX)); 65 | } 66 | } 67 | void test_tv_reg5(void) 68 | { 69 | 70 | for (int i = 0; i < 3; i++) 71 | { 72 | double t = r5_pT[i].T - 273.15; 73 | double v = r5_pT[i].v; 74 | TEST_ASSERT_EQUAL_FLOAT(r5_pT[i].p, tv(t, v, OP)); 75 | } 76 | } 77 | 78 | int main(void) 79 | { 80 | UNITY_BEGIN(); 81 | RUN_TEST(test_tv_reg1); 82 | RUN_TEST(test_tv_reg2); 83 | RUN_TEST(test_tv_reg3); 84 | RUN_TEST(test_tv_reg4); 85 | RUN_TEST(test_tv_reg5); 86 | return UNITY_END(); 87 | } --------------------------------------------------------------------------------