1 #ifndef TABULAR_BACKENDS_H 2 #define TABULAR_BACKENDS_H 4 #include "AbstractState.h" 6 #include <msgpack/fbuffer.hpp> 7 #include "crossplatform_shared_ptr.h" 8 #include "Exceptions.h" 11 #include "Configuration.h" 12 #include "Backends/Helmholtz/PhaseEnvelopeRoutines.h" 18 #define LIST_OF_MATRICES \ 62 #define LIST_OF_SATURATION_VECTORS \ 104 #define X(name) name = PED.name; 105 PHASE_ENVELOPE_VECTORS
108 #define X(name) name = PED.name; 109 PHASE_ENVELOPE_MATRICES
113 std::map<std::string, std::vector<double>> vectors;
114 std::map<std::string, std::vector<std::vector<double>>> matrices;
116 MSGPACK_DEFINE(revision, vectors, matrices);
121 #define X(name) vectors.insert(std::pair<std::string, std::vector<double>>(#name, name)); 122 PHASE_ENVELOPE_VECTORS
125 #define X(name) matrices.insert(std::pair<std::string, std::vector<std::vector<double>>>(#name, name)); 126 PHASE_ENVELOPE_MATRICES
129 std::map<std::string, std::vector<double>>::iterator get_vector_iterator(
const std::string& name) {
130 std::map<std::string, std::vector<double>>::iterator it = vectors.find(name);
131 if (it == vectors.end()) {
136 std::map<std::string, std::vector<std::vector<double>>>::iterator get_matrix_iterator(
const std::string& name) {
137 std::map<std::string, std::vector<std::vector<double>>>::iterator it = matrices.find(name);
138 if (it == matrices.end()) {
148 #define X(name) name = get_vector_iterator(#name)->second; 149 PHASE_ENVELOPE_VECTORS
154 #define X(name) name = get_matrix_iterator(#name)->second; 155 PHASE_ENVELOPE_MATRICES
158 iTsat_max = std::distance(T.begin(), std::max_element(T.begin(), T.end()));
160 ipsat_max = std::distance(p.begin(), std::max_element(p.begin(), p.end()));
162 void deserialize(msgpack::object& deserialized) {
164 deserialized.convert(temp);
166 if (revision > temp.revision) {
167 throw ValueError(format(
"loaded revision [%d] is older than current revision [%d]", temp.revision, revision));
169 std::swap(*
this, temp);
175 conversion_factor = 1.0;
178 conversion_factor = molar_mass;
182 conversion_factor /= molar_mass;
186 conversion_factor /= molar_mass;
190 conversion_factor /= molar_mass;
194 conversion_factor /= molar_mass;
198 conversion_factor /= molar_mass;
216 throw ValueError(
"TabularBackends::mass_to_molar - I don't know how to convert this parameter");
228 shared_ptr<CoolProp::AbstractState> AS;
236 void build(shared_ptr<CoolProp::AbstractState>& AS);
239 #define X(name) std::vector<double> name; 240 LIST_OF_SATURATION_VECTORS
244 std::map<std::string, std::vector<double>> vectors;
246 MSGPACK_DEFINE(revision, vectors);
261 bool is_inside(
parameters main,
double mainval,
parameters other,
double val, std::size_t& iL, std::size_t& iV, CoolPropDbl& yL,
263 std::vector<double>*yvecL = NULL, *yvecV = NULL;
290 throw ValueError(
"invalid input for other in is_inside");
296 double pmax = this->pV[pV.size() - 1], pmin = this->pV[0];
297 if (mainval > pmax || mainval < pmin) {
300 }
else if (main ==
iT) {
302 double Tmax = this->TV[TV.size() - 1], Tmin = this->TV[0];
303 if (mainval > Tmax || mainval < Tmin) {
307 throw ValueError(
"invalid input for other in is_inside");
311 std::size_t iLplus, iVplus;
316 bisect_vector(pV, mainval, iV);
317 bisect_vector(pL, mainval, iL);
318 }
else if (main ==
iT) {
319 bisect_vector(TV, mainval, iV);
320 bisect_vector(TL, mainval, iL);
322 throw ValueError(format(
"For now, main input in is_inside must be T or p"));
325 iVplus = std::min(iV + 1, N - 1);
326 iLplus = std::min(iL + 1, N - 1);
336 double logp = log(mainval);
338 yV = CubicInterp(logpV, TV, iVplus - 3, iVplus - 2, iVplus - 1, iVplus, logp);
339 yL = CubicInterp(logpL, TL, iLplus - 3, iLplus - 2, iLplus - 1, iLplus, logp);
340 }
else if (main ==
iT) {
342 yV = exp(CubicInterp(TV, logpV, iVplus - 3, iVplus - 2, iVplus - 1, iVplus, mainval));
343 yL = exp(CubicInterp(TL, logpL, iLplus - 3, iLplus - 2, iLplus - 1, iLplus, mainval));
348 double ymin = min4((*yvecL)[iL], (*yvecL)[iLplus], (*yvecV)[iV], (*yvecV)[iVplus]);
349 double ymax = max4((*yvecL)[iL], (*yvecL)[iLplus], (*yvecV)[iV], (*yvecV)[iVplus]);
350 if (val < ymin || val > ymax) {
361 double logp = log(mainval);
362 yV = CubicInterp(logpV, *yvecV, iVplus - 3, iVplus - 2, iVplus - 1, iVplus, logp);
363 yL = CubicInterp(logpL, *yvecL, iLplus - 3, iLplus - 2, iLplus - 1, iLplus, logp);
364 }
else if (main ==
iT) {
365 yV = CubicInterp(TV, *yvecV, iVplus - 3, iVplus - 2, iVplus - 1, iVplus, mainval);
366 yL = CubicInterp(TL, *yvecL, iLplus - 3, iLplus - 2, iLplus - 1, iLplus, mainval);
369 if (!is_in_closed_range(yV, yL, static_cast<CoolPropDbl>(val))) {
382 std::fill(name.begin(), name.end(), _HUGE); 383 LIST_OF_SATURATION_VECTORS
389 #define X(name) vectors.insert(std::pair<std::string, std::vector<double>>(#name, name)); 390 LIST_OF_SATURATION_VECTORS
393 std::map<std::string, std::vector<double>>::iterator get_vector_iterator(
const std::string& name) {
394 std::map<std::string, std::vector<double>>::iterator it = vectors.find(name);
395 if (it == vectors.end()) {
403 #define X(name) name = get_vector_iterator(#name)->second; 404 LIST_OF_SATURATION_VECTORS
408 void deserialize(msgpack::object& deserialized) {
410 deserialized.convert(temp);
413 throw ValueError(format(
"old [%d] and new [%d] sizes don't agree", temp.N, N));
414 }
else if (revision > temp.revision) {
415 throw ValueError(format(
"loaded revision [%d] is older than current revision [%d]", temp.revision, revision));
417 std::swap(*
this, temp);
420 double evaluate(
parameters output,
double p_or_T,
double Q, std::size_t iL, std::size_t iV) {
423 }
else if (iL + 1 == N) {
428 }
else if (iV + 1 == N) {
431 double logp = log(p_or_T);
434 double _logpV = CubicInterp(this->TV, logpV, iV - 2, iV - 1, iV, iV + 1, p_or_T);
435 double _logpL = CubicInterp(this->TL, logpL, iL - 2, iL - 1, iL, iL + 1, p_or_T);
436 return Q * exp(_logpV) + (1 - Q) * exp(_logpL);
439 double TV = CubicInterp(logpV, this->TV, iV - 2, iV - 1, iV, iV + 1, logp);
440 double TL = CubicInterp(logpL, this->TL, iL - 2, iL - 1, iL, iL + 1, logp);
441 return Q * TV + (1 - Q) * TL;
444 double sV = CubicInterp(logpV, smolarV, iV - 2, iV - 1, iV, iV + 1, logp);
445 double sL = CubicInterp(logpL, smolarL, iL - 2, iL - 1, iL, iL + 1, logp);
446 return Q * sV + (1 - Q) * sL;
449 double hV = CubicInterp(logpV, hmolarV, iV - 2, iV - 1, iV, iV + 1, logp);
450 double hL = CubicInterp(logpL, hmolarL, iL - 2, iL - 1, iL, iL + 1, logp);
451 return Q * hV + (1 - Q) * hL;
454 double uV = CubicInterp(logpV, umolarV, iV - 2, iV - 1, iV, iV + 1, logp);
455 double uL = CubicInterp(logpL, umolarL, iL - 2, iL - 1, iL, iL + 1, logp);
456 return Q * uV + (1 - Q) * uL;
459 double rhoV = exp(CubicInterp(logpV, logrhomolarV, iV - 2, iV - 1, iV, iV + 1, logp));
460 double rhoL = exp(CubicInterp(logpL, logrhomolarL, iL - 2, iL - 1, iL, iL + 1, logp));
461 if (!ValidNumber(rhoV)) {
464 if (!ValidNumber(rhoL)) {
467 return 1 / (Q / rhoV + (1 - Q) / rhoL);
470 double kV = CubicInterp(logpV, condV, iV - 2, iV - 1, iV, iV + 1, logp);
471 double kL = CubicInterp(logpL, condL, iL - 2, iL - 1, iL, iL + 1, logp);
472 if (!ValidNumber(kV)) {
475 if (!ValidNumber(kL)) {
478 return Q * kV + (1 - Q) * kL;
481 double muV = exp(CubicInterp(logpV, logviscV, iV - 2, iV - 1, iV, iV + 1, logp));
482 double muL = exp(CubicInterp(logpL, logviscL, iL - 2, iL - 1, iL, iL + 1, logp));
483 if (!ValidNumber(muV)) {
486 if (!ValidNumber(muL)) {
489 return 1 / (Q / muV + (1 - Q) / muL);
492 double cpV = CubicInterp(logpV, cpmolarV, iV - 2, iV - 1, iV, iV + 1, logp);
493 double cpL = CubicInterp(logpL, cpmolarL, iL - 2, iL - 1, iL, iL + 1, logp);
494 if (!ValidNumber(cpV)) {
497 if (!ValidNumber(cpL)) {
500 return Q * cpV + (1 - Q) * cpL;
503 double cvV = CubicInterp(logpV, cvmolarV, iV - 2, iV - 1, iV, iV + 1, logp);
504 double cvL = CubicInterp(logpL, cvmolarL, iL - 2, iL - 1, iL, iL + 1, logp);
505 if (!ValidNumber(cvV)) {
508 if (!ValidNumber(cvL)) {
511 return Q * cvV + (1 - Q) * cvL;
514 double wV = CubicInterp(logpV, speed_soundV, iV - 2, iV - 1, iV, iV + 1, logp);
515 double wL = CubicInterp(logpL, speed_soundL, iL - 2, iL - 1, iL, iL + 1, logp);
516 if (!ValidNumber(wV)) {
519 if (!ValidNumber(wL)) {
522 return Q * wV + (1 - Q) * wL;
525 throw ValueError(
"Output variable for evaluate is invalid");
537 if (i < 2 || i > TL.size() - 2) {
538 throw ValueError(format(
"Invalid index (%d) to calc_first_saturation_deriv in TabularBackends", i));
540 std::vector<double>*x, *y;
544 x = (Q == 0) ? &TL : &TV;
547 x = (Q == 0) ? &pL : &pV;
550 throw ValueError(format(
"Key for Wrt1 is invalid in calc_first_saturation_deriv"));
552 CoolPropDbl factor = 1.0;
555 y = (Q == 0) ? &TL : &TV;
558 y = (Q == 0) ? &pL : &pV;
561 y = (Q == 0) ? &rhomolarL : &rhomolarV;
564 y = (Q == 0) ? &hmolarL : &hmolarV;
567 y = (Q == 0) ? &smolarL : &smolarV;
570 y = (Q == 0) ? &umolarL : &umolarV;
573 y = (Q == 0) ? &rhomolarL : &rhomolarV;
574 factor = AS->molar_mass();
577 y = (Q == 0) ? &hmolarL : &hmolarV;
578 factor = 1 / AS->molar_mass();
581 y = (Q == 0) ? &smolarL : &smolarV;
582 factor = 1 / AS->molar_mass();
585 y = (Q == 0) ? &umolarL : &umolarV;
586 factor = 1 / AS->molar_mass();
589 throw ValueError(format(
"Key for Of1 is invalid in calc_first_saturation_deriv"));
591 return CubicInterpFirstDeriv((*x)[i - 2], (*x)[i - 1], (*x)[i], (*x)[i + 1], (*y)[i - 2], (*y)[i - 1], (*y)[i], (*y)[i + 1], val) * factor;
606 shared_ptr<CoolProp::AbstractState> AS;
607 std::vector<double> xvec, yvec;
608 std::vector<std::vector<std::size_t>> nearest_neighbor_i, nearest_neighbor_j;
610 double xmin, ymin, xmax, ymax;
612 virtual void set_limits() = 0;
618 xkey = INVALID_PARAMETER;
619 ykey = INVALID_PARAMETER;
629 #define X(name) std::vector<std::vector<double>> name; 633 std::map<std::string, std::vector<std::vector<double>>> matrices;
635 void build(shared_ptr<CoolProp::AbstractState>& AS);
637 MSGPACK_DEFINE(revision, matrices, xmin, xmax, ymin, ymax);
639 void resize(std::size_t Nx, std::size_t Ny) {
641 #define X(name) name.resize(Nx, std::vector<double>(Ny, _HUGE)); 649 xvec = logspace(xmin, xmax, Nx);
651 xvec = linspace(xmin, xmax, Nx);
654 yvec = logspace(ymin, ymax, Ny);
656 yvec = linspace(ymin, ymax, Ny);
661 nearest_neighbor_i.resize(Nx, std::vector<std::size_t>(Ny, std::numeric_limits<std::size_t>::max()));
662 nearest_neighbor_j.resize(Nx, std::vector<std::size_t>(Ny, std::numeric_limits<std::size_t>::max()));
663 for (std::size_t i = 0; i < xvec.size(); ++i) {
664 for (std::size_t j = 0; j < yvec.size(); ++j) {
665 nearest_neighbor_i[i][j] = i;
666 nearest_neighbor_j[i][j] = j;
667 if (!ValidNumber(T[i][j])) {
668 int xoffsets[] = {-1, 1, 0, 0, -1, 1, 1, -1};
669 int yoffsets[] = {0, 0, 1, -1, -1, -1, 1, 1};
671 std::size_t N =
sizeof(xoffsets) /
sizeof(xoffsets[0]);
672 for (std::size_t k = 0; k < N; ++k) {
673 std::size_t iplus = i + xoffsets[k];
674 std::size_t jplus = j + yoffsets[k];
675 if (0 < iplus && iplus < Nx - 1 && 0 < jplus && jplus < Ny - 1 && ValidNumber(T[iplus][jplus])) {
676 nearest_neighbor_i[i][j] = iplus;
677 nearest_neighbor_j[i][j] = jplus;
688 #define X(name) matrices.insert(std::pair<std::string, std::vector<std::vector<double>>>(#name, name)); 692 std::map<std::string, std::vector<std::vector<double>>>::iterator get_matrices_iterator(
const std::string& name) {
693 std::map<std::string, std::vector<std::vector<double>>>::iterator it = matrices.find(name);
694 if (it == matrices.end()) {
702 #define X(name) name = get_matrices_iterator(#name)->second; 708 make_good_neighbors();
712 double e = 10 * DBL_EPSILON;
713 return x >= xmin - e && x <= xmax + e && y >= ymin - e && y <= ymax + e;
719 bisect_vector(xvec, x, i);
722 if (x > (xvec[i] + xvec[i + 1]) / 2.0) {
726 if (x > sqrt(xvec[i] * xvec[i + 1])) {
731 bisect_vector(yvec, y, j);
734 if (y > (yvec[j] + yvec[j + 1]) / 2.0) {
738 if (y > sqrt(yvec[j] * yvec[j + 1])) {
746 if (givenkey == ykey) {
747 bisect_vector(yvec, givenval, j);
751 bisect_segmented_vector_slice(
get(otherkey), j, otherval, i);
754 const std::vector<std::vector<double>>&
mat =
get(otherkey);
755 double closest_diff = 1e20;
756 std::size_t closest_i = 0;
757 for (std::size_t index = 0; index < mat.size(); ++index) {
758 double diff = std::abs(mat[index][j] - otherval);
759 if (diff < closest_diff) {
766 }
else if (givenkey == xkey) {
767 bisect_vector(xvec, givenval, i);
769 const std::vector<std::vector<double>>& v =
get(otherkey);
770 bisect_vector(v[i], otherval, j);
777 find_native_nearest_neighbor(x, y, i, j);
779 if (!ValidNumber(T[i][j])) {
782 std::size_t inew = nearest_neighbor_i[i][j];
783 std::size_t jnew = nearest_neighbor_j[i][j];
791 bisect_vector(xvec, x, i);
792 bisect_vector(yvec, y, j);
794 const std::vector<std::vector<double>>&
get(
parameters key) {
813 throw KeyError(format(
"invalid key"));
829 if (this->AS.get() == NULL) {
832 CoolPropDbl Tmin = std::max(AS->Ttriple(), AS->Tmin());
840 CoolPropDbl xmax1 = AS->hmolar();
841 AS->update(
PT_INPUTS, AS->pmax(), 1.499 * AS->Tmax());
842 CoolPropDbl xmax2 = AS->hmolar();
843 xmax = std::max(xmax1, xmax2);
847 void deserialize(msgpack::object& deserialized) {
849 deserialized.convert(temp);
851 if (Nx != temp.Nx || Ny != temp.Ny) {
852 throw ValueError(format(
"old [%dx%d] and new [%dx%d] dimensions don't agree", temp.Nx, temp.Ny, Nx, Ny));
853 }
else if (revision > temp.revision) {
854 throw ValueError(format(
"loaded revision [%d] is older than current revision [%d]", temp.revision, revision));
855 }
else if ((std::abs(xmin) > 1e-10 && std::abs(xmax) > 1e-10)
856 && (std::abs(temp.xmin - xmin) / xmin > 1e-6 || std::abs(temp.xmax - xmax) / xmax > 1e-6)) {
857 throw ValueError(format(
"Current limits for x [%g,%g] do not agree with loaded limits [%g,%g]", xmin, xmax, temp.xmin, temp.xmax));
858 }
else if ((std::abs(ymin) > 1e-10 && std::abs(ymax) > 1e-10)
859 && (std::abs(temp.ymin - ymin) / ymin > 1e-6 || std::abs(temp.ymax - ymax) / ymax > 1e-6)) {
860 throw ValueError(format(
"Current limits for y [%g,%g] do not agree with loaded limits [%g,%g]", ymin, ymax, temp.ymin, temp.ymax));
862 std::swap(*
this, temp);
881 if (this->AS.get() == NULL) {
884 CoolPropDbl Tmin = std::max(AS->Ttriple(), AS->Tmin());
889 xmax = AS->Tmax() * 1.499;
892 void deserialize(msgpack::object& deserialized) {
894 deserialized.convert(temp);
896 if (Nx != temp.Nx || Ny != temp.Ny) {
897 throw ValueError(format(
"old [%dx%d] and new [%dx%d] dimensions don't agree", temp.Nx, temp.Ny, Nx, Ny));
898 }
else if (revision > temp.revision) {
899 throw ValueError(format(
"loaded revision [%d] is older than current revision [%d]", temp.revision, revision));
900 }
else if ((std::abs(xmin) > 1e-10 && std::abs(xmax) > 1e-10)
901 && (std::abs(temp.xmin - xmin) / xmin > 1e-6 || std::abs(temp.xmax - xmax) / xmax > 1e-6)) {
902 throw ValueError(format(
"Current limits for x [%g,%g] do not agree with loaded limits [%g,%g]", xmin, xmax, temp.xmin, temp.xmax));
903 }
else if ((std::abs(ymin) > 1e-10 && std::abs(ymax) > 1e-10)
904 && (std::abs(temp.ymin - ymin) / ymin > 1e-6 || std::abs(temp.ymax - ymax) / ymax > 1e-6)) {
905 throw ValueError(format(
"Current limits for y [%g,%g] do not agree with loaded limits [%g,%g]", ymin, ymax, temp.ymin, temp.ymax));
907 std::swap(*
this, temp);
917 std::size_t alt_i, alt_j;
918 bool _valid, _has_valid_neighbor;
921 double dx_dxhat, dy_dyhat;
924 _has_valid_neighbor =
false;
930 std::vector<double> T, rhomolar, hmolar, p, smolar, umolar;
932 const std::vector<double>&
get(
const parameters params)
const {
947 throw KeyError(format(
"Invalid key to get() function of CellCoeffs"));
972 throw KeyError(format(
"Invalid key to set() function of CellCoeffs"));
991 _has_valid_neighbor =
true;
995 if (_has_valid_neighbor) {
1004 return _has_valid_neighbor;
1017 std::vector<std::vector<CellCoeffs>> coeffs_ph, coeffs_pT;
1020 tables_loaded =
false;
1023 void write_tables(
const std::string& path_to_tables);
1025 void load_tables(
const std::string& path_to_tables, shared_ptr<CoolProp::AbstractState>& AS);
1027 void build_tables(shared_ptr<CoolProp::AbstractState>& AS);
1035 std::map<std::string, TabularDataSet> data;
1039 std::string path_to_tables(shared_ptr<CoolProp::AbstractState>& AS) {
1040 std::vector<std::string> fluids = AS->fluid_names();
1041 std::vector<CoolPropDbl> fractions = AS->get_mole_fractions();
1042 std::vector<std::string> components;
1043 for (std::size_t i = 0; i < fluids.size(); ++i) {
1044 components.push_back(format(
"%s[%0.10Lf]", fluids[i].c_str(), fractions[i]));
1046 std::string table_directory = get_home_dir() +
"/.CoolProp/Tables/";
1047 std::string alt_table_directory =
get_config_string(ALTERNATIVE_TABLES_DIRECTORY);
1048 if (!alt_table_directory.empty()) {
1049 table_directory = alt_table_directory;
1051 return table_directory + AS->backend_name() +
"(" + strjoin(components,
"&") +
")";
1054 TabularDataSet* get_set_of_tables(shared_ptr<AbstractState>& AS,
bool& loaded);
1066 phases imposed_phase_index;
1067 bool tables_loaded, using_single_phase_table, is_mixture;
1068 enum selected_table_options
1070 SELECTED_NO_TABLE = 0,
1074 selected_table_options selected_table;
1075 std::size_t cached_single_phase_i, cached_single_phase_j;
1076 std::size_t cached_saturation_iL, cached_saturation_iV;
1077 std::vector<std::vector<double>>
const* z;
1078 std::vector<std::vector<double>>
const* dzdx;
1079 std::vector<std::vector<double>>
const* dzdy;
1080 std::vector<std::vector<double>>
const* d2zdx2;
1081 std::vector<std::vector<double>>
const* d2zdxdy;
1082 std::vector<std::vector<double>>
const* d2zdy2;
1083 std::vector<CoolPropDbl> mole_fractions;
1086 shared_ptr<CoolProp::AbstractState> AS;
1087 TabularBackend(shared_ptr<CoolProp::AbstractState> AS) : tables_loaded(
false), using_single_phase_table(
false), is_mixture(
false), AS(AS) {
1088 selected_table = SELECTED_NO_TABLE;
1090 cached_single_phase_i = std::numeric_limits<std::size_t>::max();
1091 cached_single_phase_j = std::numeric_limits<std::size_t>::max();
1092 cached_saturation_iL = std::numeric_limits<std::size_t>::max();
1093 cached_saturation_iV = std::numeric_limits<std::size_t>::max();
1101 imposed_phase_index = iphase_not_imposed;
1113 return AS->fluid_names();
1123 d2zdxdy = &table.d2Tdxdy;
1124 d2zdx2 = &table.d2Tdx2;
1125 d2zdy2 = &table.d2Tdy2;
1128 z = &table.rhomolar;
1129 dzdx = &table.drhomolardx;
1130 dzdy = &table.drhomolardy;
1131 d2zdxdy = &table.d2rhomolardxdy;
1132 d2zdx2 = &table.d2rhomolardx2;
1133 d2zdy2 = &table.d2rhomolardy2;
1137 dzdx = &table.dsmolardx;
1138 dzdy = &table.dsmolardy;
1139 d2zdxdy = &table.d2smolardxdy;
1140 d2zdx2 = &table.d2smolardx2;
1141 d2zdy2 = &table.d2smolardy2;
1145 dzdx = &table.dhmolardx;
1146 dzdy = &table.dhmolardy;
1147 d2zdxdy = &table.d2hmolardxdy;
1148 d2zdx2 = &table.d2hmolardx2;
1149 d2zdy2 = &table.d2hmolardy2;
1153 dzdx = &table.dumolardx;
1154 dzdy = &table.dumolardy;
1155 d2zdxdy = &table.d2umolardxdy;
1156 d2zdx2 = &table.d2umolardx2;
1157 d2zdy2 = &table.d2umolardy2;
1171 void recalculate_singlephase_phase() {
1172 if (p() > p_critical()) {
1173 if (T() > T_critical()) {
1179 if (T() > T_critical()) {
1183 if (rhomolar() > rhomolar_critical()) {
1196 imposed_phase_index = phase_index;
1202 imposed_phase_index = iphase_not_imposed;
1205 virtual double evaluate_single_phase_phmolar(
parameters output, std::size_t i, std::size_t j) = 0;
1206 virtual double evaluate_single_phase_pT(
parameters output, std::size_t i, std::size_t j) = 0;
1207 virtual double evaluate_single_phase_phmolar_transport(
parameters output, std::size_t i, std::size_t j) = 0;
1208 virtual double evaluate_single_phase_pT_transport(
parameters output, std::size_t i, std::size_t j) = 0;
1209 virtual double evaluate_single_phase_phmolar_derivative(
parameters output, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny) = 0;
1210 virtual double evaluate_single_phase_pT_derivative(
parameters output, std::size_t i, std::size_t j, std::size_t Nx, std::size_t Ny) = 0;
1213 virtual void find_native_nearest_good_indices(
SinglePhaseGriddedTableData& table,
const std::vector<std::vector<CellCoeffs>>& coeffs,
double x,
1214 double y, std::size_t& i, std::size_t& j) = 0;
1217 const parameters variable1,
const double value1,
const parameters other,
const double otherval, std::size_t& i,
1218 std::size_t& j) = 0;
1221 parameters output,
double x,
double y, std::size_t i, std::size_t j) = 0;
1224 parameters output,
double x,
double y, std::size_t i, std::size_t j) = 0;
1230 return this->AS->T_critical();
1233 return this->AS->Ttriple();
1236 return this->AS->p_triple();
1239 return this->AS->pmax();
1242 return this->AS->Tmax();
1245 return this->AS->Tmin();
1248 return this->AS->p_critical();
1251 return this->AS->rhomolar_critical();
1253 bool using_mole_fractions(
void) {
1256 bool using_mass_fractions(
void) {
1259 bool using_volu_fractions(
void) {
1263 void set_mole_fractions(
const std::vector<CoolPropDbl>& mole_fractions) {
1264 this->AS->set_mole_fractions(mole_fractions);
1266 void set_mass_fractions(
const std::vector<CoolPropDbl>& mass_fractions) {
1270 return AS->get_mole_fractions();
1272 const std::vector<CoolPropDbl> calc_mass_fractions(
void) {
1273 return AS->get_mass_fractions();
1277 return AS->molar_mass();
1280 CoolPropDbl calc_saturated_liquid_keyed_output(
parameters key);
1281 CoolPropDbl calc_saturated_vapor_keyed_output(
parameters key);
1284 std::string path_to_tables(
void);
1287 void pack_matrices() {
1292 single_phase_logph.
pack();
1293 single_phase_logpT.
pack();
1294 pure_saturation.
pack();
1295 phase_envelope.
pack();
1298 void write_tables();
1302 CoolPropDbl yL = PhaseEnvelopeRoutines::evaluate(phase_envelope, output, iInput1, value1, cached_saturation_iL);
1303 CoolPropDbl yV = PhaseEnvelopeRoutines::evaluate(phase_envelope, output, iInput1, value1, cached_saturation_iV);
1304 return _Q * yV + (1 - _Q) * yL;
1307 this->AS->set_T(_T);
1308 return this->AS->cp0molar();
1312 this->AS->set_T(_T);
1313 return this->AS->surface_tension();
1314 this->AS->set_T(_HUGE);
1316 CoolPropDbl calc_p(
void);
1317 CoolPropDbl calc_T(
void);
1318 CoolPropDbl calc_rhomolar(
void);
1319 CoolPropDbl calc_hmolar(
void);
1320 CoolPropDbl calc_smolar(
void);
1321 CoolPropDbl calc_umolar(
void);
1322 CoolPropDbl calc_cpmolar(
void);
1323 CoolPropDbl calc_cvmolar(
void);
1324 CoolPropDbl calc_viscosity(
void);
1325 CoolPropDbl calc_conductivity(
void);
1327 CoolPropDbl calc_speed_sound(
void);
1338 if (!tables_loaded) {
1343 tables_loaded =
true;
1346 std::cout << format(
"Table loading failed with error: %s\n", e.what());
1349 std::string table_path = path_to_tables();
1350 #if defined(__ISWINDOWS__) 1351 double directory_size_in_GB = CalculateDirSize(std::wstring(table_path.begin(), table_path.end())) / POW3(1024.0);
1353 double directory_size_in_GB = CalculateDirSize(table_path) / POW3(1024.0);
1355 double allowed_size_in_GB =
get_config_double(MAXIMUM_TABLE_DIRECTORY_SIZE_IN_GB);
1357 std::cout <<
"Tabular directory size is " << directory_size_in_GB <<
" GB\n";
1359 if (directory_size_in_GB > 1.5 * allowed_size_in_GB) {
1361 format(
"Maximum allowed tabular directory size is %g GB, you have exceeded 1.5 times this limit", allowed_size_in_GB));
1362 }
else if (directory_size_in_GB > allowed_size_in_GB) {
1363 set_warning_string(format(
"Maximum allowed tabular directory size is %g GB, you have exceeded this limit", allowed_size_in_GB));
1372 tables_loaded =
true;
Mass-based internal energy.
Definition: DataStructures.h:116
void pack()
Take all the vectors that are in the class and pack them into the vectors map for easy unpacking usin...
Definition: TabularBackends.h:387
void resize(std::size_t N)
Resize all the vectors.
Definition: TabularBackends.h:378
Supercritical liquid (p > pc, T < Tc)
Definition: DataStructures.h:181
This class holds the data for a two-phase table that is log spaced in p.
Definition: TabularBackends.h:224
std::vector< std::string > calc_fluid_names(void)
Using this backend, get a vector of fluid names.
Definition: TabularBackends.h:1112
void calc_specify_phase(phases phase_index)
Specify the phase - this phase will always be used in calculations.
Definition: TabularBackends.h:1195
void make_axis_vectors(void)
Make vectors for the x-axis values and the y-axis values.
Definition: TabularBackends.h:647
const std::vector< CoolPropDbl > & get_mole_fractions()
Get the mole fractions of the fluid.
Definition: TabularBackends.h:1269
Molar density in mol/m^3, Temperature in K.
Definition: DataStructures.h:289
void unpack()
Take all the matrices that are in the class and pack them into the matrices map for easy unpacking us...
Definition: TabularBackends.h:700
void calc_unspecify_phase()
Unspecify the phase - the phase is no longer imposed, different solvers can do as they like...
Definition: TabularBackends.h:1201
Mass-based enthalpy.
Definition: DataStructures.h:111
void check_tables()
Definition: TabularBackends.h:1337
CoolPropDbl calc_Tmax(void)
Using this backend, calculate the maximum temperature in K.
Definition: TabularBackends.h:1241
This structure holds the coefficients for one cell, the coefficients are stored in matrices and can b...
Definition: TabularBackends.h:914
Subcritical liquid.
Definition: DataStructures.h:178
Supercritical gas (p < pc, T > Tc)
Definition: DataStructures.h:180
double get_config_double(configuration_keys key)
Return the value of a double configuration key.
Definition: Configuration.cpp:92
CoolPropDbl calc_cpmolar_idealgas(void)
Using this backend, calculate the ideal gas molar constant-pressure specific heat in J/mol/K...
Definition: TabularBackends.h:1306
void make_good_neighbors(void)
Make matrices of good neighbors if the current value for i,j corresponds to a bad node...
Definition: TabularBackends.h:660
phases
These are constants for the phases of the fluid.
Definition: DataStructures.h:176
This class contains the data for one set of Tabular data including single-phase and two-phase data...
Definition: TabularBackends.h:1009
void find_nearest_neighbor(parameters givenkey, double givenval, parameters otherkey, double otherval, std::size_t &i, std::size_t &j)
Find the nearest neighbor for one (given) variable native, one variable non-native.
Definition: TabularBackends.h:745
void resize(std::size_t Nx, std::size_t Ny)
Resize all the matrices.
Definition: TabularBackends.h:639
int get_debug_level()
Get the debug level.
Definition: CoolProp.cpp:64
Mass-based density.
Definition: DataStructures.h:110
void set_warning_string(const std::string &warning)
An internal function to set the global warning string.
Definition: CoolProp.cpp:72
std::string get_config_string(configuration_keys key)
Return the value of a string configuration key.
Definition: Configuration.cpp:95
std::vector< std::vector< double > > mat
This class implements bicubic interpolation, as very clearly laid out by the page on wikipedia: http:...
Definition: BicubicBackend.h:60
void set_invalid()
Call this function to set the valid flag to false.
Definition: TabularBackends.h:984
Definition: TabularBackends.h:1032
This class holds the single-phase data for a log(p)-T gridded table.
Definition: TabularBackends.h:867
bool available_in_high_level(void)
A function that says whether the backend instance can be instantiated in the high-level interface In ...
Definition: TabularBackends.h:1105
Mole-based constant-volume specific heat.
Definition: DataStructures.h:101
Pressure in Pa, Temperature in K.
Definition: DataStructures.h:286
The mother of all state classes.
Definition: AbstractState.h:78
CoolPropDbl calc_molar_mass(void)
Using this backend, calculate the molar mass in kg/mol.
Definition: TabularBackends.h:1276
CoolPropDbl calc_T_critical(void)
Using this backend, get the critical point temperature in K.
Definition: TabularBackends.h:1229
Isobaric expansion coefficient.
Definition: DataStructures.h:129
void pack()
Take all the matrices that are in the class and pack them into the matrices map for easy unpacking us...
Definition: TabularBackends.h:686
A data structure to hold the data for a phase envelope.
Definition: PhaseEnvelope.h:36
phases calc_phase(void)
Using this backend, calculate the phase.
Definition: TabularBackends.h:1226
void build_tables(shared_ptr< CoolProp::AbstractState > &AS)
Build the tables (single-phase PH, single-phase PT, phase envelope, etc.)
Definition: TabularBackends.cpp:1280
CoolPropDbl calc_surface_tension(void)
Calculate the surface tension using the wrapped class (fast enough)
Definition: TabularBackends.h:1311
void get_alternate(std::size_t &i, std::size_t &j) const
Get neighboring(alternate) cell to be used if this cell is invalid.
Definition: TabularBackends.h:994
input_pairs
These are input pairs that can be used for the update function (in each pair, input keys are sorted a...
Definition: DataStructures.h:274
bool has_valid_neighbor() const
Returns true if cell is invalid and it has valid neighbor.
Definition: TabularBackends.h:1003
Subcritical gas.
Definition: DataStructures.h:183
Definition: Exceptions.h:45
This class holds the data for a single-phase interpolation table that is regularly spaced...
Definition: TabularBackends.h:600
Mass-based constant-volume specific heat.
Definition: DataStructures.h:115
void set_valid()
Call this function to set the valid flag to true.
Definition: TabularBackends.h:980
Definition: TabularBackends.h:94
Molar quality, Temperature in K.
Definition: DataStructures.h:277
CoolPropDbl calc_pmax(void)
Using this backend, calculate the maximum pressure in Pa.
Definition: TabularBackends.h:1238
Mass-based entropy.
Definition: DataStructures.h:112
Viscosity.
Definition: DataStructures.h:121
std::string calc_name(void)
Using this backend, get the name of the fluid.
Definition: TabularBackends.h:1109
Mole-based density.
Definition: DataStructures.h:96
This class holds the single-phase data for a log(p)-h gridded table.
Definition: TabularBackends.h:819
Mole-based constant-pressure specific heat.
Definition: DataStructures.h:99
Mole-based entropy.
Definition: DataStructures.h:98
CoolPropDbl calc_rhomolar_critical(void)
Using this backend, get the critical point molar density in mol/m^3.
Definition: TabularBackends.h:1250
Pressure.
Definition: DataStructures.h:90
CoolPropDbl calc_Tmin(void)
Using this backend, calculate the minimum temperature in K.
Definition: TabularBackends.h:1244
Speed of sound.
Definition: DataStructures.h:127
Isothermal compressibility.
Definition: DataStructures.h:128
CoolPropDbl calc_p_critical(void)
Using this backend, get the critical point pressure in Pa.
Definition: TabularBackends.h:1247
void unpack()
Take all the vectors that are in the class and unpack them from the vectors map.
Definition: TabularBackends.h:401
void set_alternate(std::size_t i, std::size_t j)
Set the neighboring (alternate) cell to be used if the cell is invalid.
Definition: TabularBackends.h:988
bool valid() const
Returns true if the cell coefficients seem to have been calculated properly.
Definition: TabularBackends.h:976
void find_native_nearest_good_neighbor(double x, double y, std::size_t &i, std::size_t &j)
Find the nearest good neighbor node for inputs that are the same as the grid inputs If the straightfo...
Definition: TabularBackends.h:775
Thermal conductivity.
Definition: DataStructures.h:122
void pack()
Take all the vectors that are in the class and pack them into the vectors map for easy unpacking usin...
Definition: TabularBackends.h:119
Mole-based internal energy.
Definition: DataStructures.h:102
std::size_t ipsat_max
The index of the point corresponding to the maximum pressure for Type-I mixtures. ...
Definition: PhaseEnvelope.h:41
CoolPropDbl calc_Ttriple(void)
Using this backend, get the triple point temperature in K.
Definition: TabularBackends.h:1232
CoolPropDbl calc_p_triple(void)
Using this backend, get the triple point pressure in Pa.
Definition: TabularBackends.h:1235
std::size_t iTsat_max
The index of the point corresponding to the maximum temperature for Type-I mixtures.
Definition: PhaseEnvelope.h:41
double first_saturation_deriv(parameters Of1, parameters Wrt1, int Q, double val, std::size_t i)
Calculate the first derivative ALONG a saturation curve.
Definition: TabularBackends.h:536
This class contains the general code for tabular backends (TTSE, bicubic, etc.)
Definition: TabularBackends.h:1063
bool native_inputs_are_in_range(double x, double y)
Check that the native inputs (the inputs the table is based on) are in range.
Definition: TabularBackends.h:711
void unpack()
Take all the vectors that are in the class and unpack them from the vectors map.
Definition: TabularBackends.h:144
Supercritical (p > pc, T > Tc)
Definition: DataStructures.h:179
This file contains flash routines in which the state is unknown, and a solver of some kind must be us...
Definition: AbstractState.h:19
void mass_to_molar(parameters ¶m, double &conversion_factor, double molar_mass)
Get a conversion factor from mass to molar if needed.
Definition: TabularBackends.h:174
void find_native_nearest_good_cell(double x, double y, std::size_t &i, std::size_t &j)
Find the nearest cell with lower left coordinate (i,j) where (i,j) is a good node, and so are (i+1,j), (i,j+1), (i+1,j+1) This is needed for bicubic interpolation.
Definition: TabularBackends.h:790
parameters
Define some constants that will be used throughout These are constants for the input and output para...
Definition: DataStructures.h:64
Mole-based enthalpy.
Definition: DataStructures.h:97
Temperature.
Definition: DataStructures.h:89
Mass-based constant-pressure specific heat.
Definition: DataStructures.h:113
void find_native_nearest_neighbor(double x, double y, std::size_t &i, std::size_t &j)
Find the nearest neighbor for native inputs (the inputs the table is based on) Does not check whether...
Definition: TabularBackends.h:718
Vapor quality.
Definition: DataStructures.h:91