-
Notifications
You must be signed in to change notification settings - Fork 0
/
LeeKesler.cpp
281 lines (219 loc) · 6.94 KB
/
LeeKesler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
#include <cmath>
using namespace std;
const double R = 0.00008314; //Gas constant cm^3*bar/mol*K
double M(double x1, double x2, double y1, double y2, double m11, double m12, double m21, double m22, double Pr, double Tr) { //double interpolation formula
double m, m2;
m = (m11 * (x2 - Pr)) / (x2 - x1);
m += (m12 * (Pr - x1)) / (x2 - x1);
m *= (y2 - Tr) / (y2 - y1);
m2 = (m21 * (x2 - Pr)) / (x2 - x1);
m2 += (m22 * (Pr - x1)) / (x2 - x1);
m2 *= (Tr - y1) / (y2 - y1);
m += m2;
return m;
}
double SingleInterpM(double m11, double m21, double x1, double x2, double pr) { //single interpolation formula
double m;
m = (m11 * (x2 - pr)) / (x2 - x1);
m += (m21 * (pr - x1)) / (x2 - x1);
return m;
}
double Z(double Z0, double Z1, double w) { //calculates z value
double z = Z0 + (Z1 * w);
return z;
}
double P(double T,double Z, double V) { //calculates pressure
double p = (R*T*Z)/V;
return p;
}
double Table(double p, double pc, double t, double tc, double w, double v) { //recursive function that uses the Z-tables
ifstream fZ0, fZ1;
fZ0.open("Z0.csv");
fZ1.open("Z1.csv");
double pr = p / pc; //row of Z table
double tr = t / tc; //column of Z table
double x1, x2, y1, y2, m11, m12, m21, m22, mZ0, mZ1;
int countX = 0, countY = 0;
bool flagX = false, flagY = false; //flags to see if the exact values for pr and tr are in the Z tables
string line;
regex delim(",");
getline(fZ0, line);
auto beginX = sregex_token_iterator(line.begin(), line.end(), delim, -1);
auto endX = sregex_token_iterator();
auto prevX = beginX;
if (pr < 0 || pr > 10) { //checks to see if the pr and tr are within the constraints of the Z tables
cout << "Invalid Pr" << endl;
return -1;
}
if (tr < 0 || tr > 10) {
cout << "Invalid Tr" << endl;
return -1;
}
for (sregex_token_iterator data = beginX; data != endX; ++data) { //iterates until it finds the exact pr, or it finds pr's to interpolate between
countX++;
if (pr == stod(*data)) {
x1 = pr;
x2 = pr;
flagX = true;
break;
}
else if (pr < stod(*data)) {
x2 = stod(*data);
x1 = stod(*prevX);
break;
}
prevX = data;
}
double prevY = 0.0;
while (getline(fZ0, line)) { //iterates until it finds the exact tr, or it finds tr's to interpolate between
countY++;
auto tempY = sregex_token_iterator(line.begin(), line.end(), delim, -1);
if (tr == stod(*tempY)) {
y2 = tr;
y1 = tr;
flagY = true;
break;
}
else if (tr < stod(*tempY)) {
y2 = stod(*tempY);
y1 = prevY;
break;
}
prevY = stod(*tempY);
}
auto ym2 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
//Z0 table cases
if (!(flagY || flagX)) { //case for double interpolation
for (int i = 0; i < countX - 2; i++)
ym2++;
m21 = stod(*ym2);
m22 = stod(*(++ym2));
fZ0.clear();
fZ0.seekg(0, ios::beg);
for (int i = 0; i < countY; i++)
getline(fZ0, line);
auto ym1 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
for (int i = 0; i < countX - 2; i++)
ym1++;
m11 = stod(*ym1);
m12 = stod(*(++ym1));
mZ0 = M(x1, x2, y1, y2, m11, m12, m21, m22, pr, tr);
}
else if (flagX && flagY){ //case for pr and tr's exact values being there
for (int i = 0; i < countX - 1; i++)
ym2++;
mZ0 = stod(*ym2);
}
else if (flagY) { //case for tr being exact but not pr
for (int i = 0; i < countX - 2; i++)
ym2++;
m21 = stod(*ym2);
m22 = stod(*(++ym2));
mZ0 = SingleInterpM(m21, m22, x1, x2, pr);
}
else { //case for pr being exact but not tr
for (int i = 0; i < countX - 2; i++)
ym2++;
m21 = stod(*(++ym2));
fZ0.clear();
fZ0.seekg(0, ios::beg);
for (int i = 0; i < countY; i++)
getline(fZ0, line);
auto ym1 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
for (int i = 0; i < countX - 2; i++)
ym1++;
m11 = stod(*(++ym1));
mZ0 = SingleInterpM(m11, m21, y1, y2, tr);
}
fZ0.clear();
fZ0.seekg(0, ios::beg);
getline(fZ1, line);
//Z1 table cases
if (!(flagX || flagY)) { //case for double interpolation
for (int i = 0; i < countY - 1; i++)
getline(fZ1, line);
auto beginYZ1 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
for (int i = 0; i < countX - 2; i++)
beginYZ1++;
m11 = stod(*beginYZ1);
m12 = stod(*(++beginYZ1));
getline(fZ1, line);
auto nextYZ1 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
for (int i = 0; i < countX - 2; i++)
nextYZ1++;
m21 = stod(*nextYZ1);
m22 = stod(*(++nextYZ1));
mZ1 = M(x1, x2, y1, y2, m11, m12, m21, m22, pr, tr);
}
else if (flagY && flagX) { //case for both pr and tr being exact values
for (int i = 0; i < countY; i++)
getline(fZ1, line);
auto nextYZ1 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
for (int i = 0; i < countX - 1; i++)
nextYZ1++;
mZ1 = stod(*nextYZ1);
} //case for tr being exact but not pr
else if (flagY) {
for (int i = 0; i < countY; i++)
getline(fZ1, line);
auto nextYZ1 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
for (int i = 0; i < countX - 2; i++)
nextYZ1++;
m21 = stod(*nextYZ1);
m22 = stod(*(++nextYZ1));
mZ1 = SingleInterpM(m21, m22, x1, x2, pr);
}
else { //case for pr being exact but not tr
for (int i = 0; i < countY - 1; i++)
getline(fZ1, line);
auto beginYZ1 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
for (int i = 0; i < countX - 1; i++)
beginYZ1++;
m12 = stod(*beginYZ1);
getline(fZ1, line);
auto nextYZ1 = sregex_token_iterator(line.begin(), line.end(), delim, -1);
for (int i = 0; i < countX - 1; i++)
nextYZ1++;
m22 = stod(*(++nextYZ1));
mZ1 = SingleInterpM(m12, m22, y1, y2, tr);
}
fZ1.clear();
fZ1.seekg(0, ios::beg);
double z = Z(mZ0, mZ1, w); //recalulates z value
double pNew = P(t, z, v); //calculates new pressure
if (fabs(p - pNew) < 0.0001) //checks to see if there is no difference between the previous pressure and the new pressure
return pNew;
else
return Table(pNew, pc, t, tc, w, v);
}
int main() {
ifstream fZ0, fZ1; //opens both Z tables to be read from
fZ0.open("Z0.csv");
fZ1.open("Z1.csv");
double tc,pc,t,v,p,w,Z0,Z1,pa;
double z = 1;
cout << "Please input critical temperature(K): "; //gets all user inputs
cin >> tc; "/n";
cout << "Please input critical pressure(bar): ";
cin >> pc; "/n";
cout << "Please input fluid omega value: ";
cin >> w; " /n";
cout << "Please input system temperature(K): ";
cin >> t; "/n";
cout << "Please input system volume(cm^3/mol): ";
cin >> v; "/n";
p = P(t, 1, v); //calculates pressure with an inital Z value of 1
double tableValue = Table(p, pc, t, tc, w, v); //runs the recursive algorithm using the Z tables
if (fabs(1 + tableValue) < 0.0001) {//checks to see if the value returned is -1, if so then either pr or tr was invalid
cout << "Invalid values, try again with proper values" << endl;
return -1;
}
std::cout << "Pressure (bar): " << tableValue << endl; //prints out the final pressure
fZ0.close();
fZ1.close();
return 0;
}