14#ifndef CUBICBACKEND_H_
15#define CUBICBACKEND_H_
34class CubicResidualHelmholtz;
39 shared_ptr<AbstractCubic>
cubic;
43 void setup(
bool generate_SatL_and_SatV =
true);
99 return cubic->get_pc()[i];
102 return cubic->get_Tc()[i];
104 return cubic->get_acentric()[i];
125 return cubic->get_R_u();
130 reducing.
T =
cubic->get_Tr();
147 return cubic->get_Tc()[0];
154 return cubic->get_pc()[0];
161 return cubic->get_acentric()[0];
163 throw ValueError(
"acentric factor cannot be calculated for mixtures");
169 double v_c_Lmol = 2.14107171795 * (
cubic->get_Tc()[0] /
cubic->get_pc()[0] * 1000) + 0.00773144012514;
170 return 1 / (v_c_Lmol / 1000.0);
179 const std::vector<double>& pc =
cubic->get_pc();
181 throw ValueError(
"CubicBackend::calc_pmax: Critical pressure vector is empty. Missing cubic parameters.");
183 double pc_max = *std::max_element(pc.begin(), pc.end());
184 return 100.0 * pc_max;
190 const std::vector<double>& pc =
cubic->get_pc();
192 throw ValueError(
"CubicBackend::calc_p_triple: Critical pressure vector is empty. Missing cubic parameters.");
194 double pc_min = *std::min_element(pc.begin(), pc.end());
195 return 0.01 * pc_min;
201 const std::vector<double>& Tc =
cubic->get_Tc();
203 throw ValueError(
"CubicBackend::calc_Tmin: Critical temperature vector is empty. Missing cubic parameters.");
205 double Tc_min = *std::min_element(Tc.begin(), Tc.end());
212 const std::vector<double>& Tc =
cubic->get_Tc();
214 throw ValueError(
"CubicBackend::calc_Tmax: Critical temperature vector is empty. Missing cubic parameters.");
216 double Tc_max = *std::max_element(Tc.begin(), Tc.end());
217 return 10.0 * Tc_max;
311 throw ValueError(
"set_binary_interaction_double not defined for AbstractCubic not defined for CAS #");
314 throw ValueError(
"get_binary_interaction_double not defined for AbstractCubic not defined for CAS #");
330 void set_cubic_alpha_C(
const size_t i,
const std::string& parameter,
const double c1,
const double c2,
const double c3)
override;
357 SRKBackend(
const std::vector<double>& Tc,
const std::vector<double>& pc,
const std::vector<double>& acentric,
double R_u,
358 bool generate_SatL_and_SatV =
true) {
359 cubic = std::make_shared<SRK>(Tc, pc, acentric, R_u);
360 setup(generate_SatL_and_SatV);
362 SRKBackend(
double Tc,
double pc,
double acentric,
double R_u,
bool generate_SatL_and_SatV =
true) {
363 cubic = std::make_shared<SRK>(Tc, pc, acentric, R_u);
364 setup(generate_SatL_and_SatV);
367 bool generate_SatL_and_SatV =
true) {
368 std::vector<double> Tc, pc, acentric;
369 N = fluid_identifiers.size();
371 for (std::size_t i = 0; i < fluid_identifiers.size(); ++i) {
377 cubic = std::make_shared<SRK>(Tc, pc, acentric, R_u);
378 setup(generate_SatL_and_SatV);
398 PengRobinsonBackend(
const std::vector<double>& Tc,
const std::vector<double>& pc,
const std::vector<double>& acentric,
double R_u,
399 bool generate_SatL_and_SatV =
true) {
400 cubic = std::make_shared<PengRobinson>(Tc, pc, acentric, R_u);
401 setup(generate_SatL_and_SatV);
403 PengRobinsonBackend(
double Tc,
double pc,
double acentric,
double R_u,
bool generate_SatL_and_SatV =
true) {
404 cubic = std::make_shared<PengRobinson>(Tc, pc, acentric, R_u);
405 setup(generate_SatL_and_SatV);
408 bool generate_SatL_and_SatV =
true) {
409 std::vector<double> Tc, pc, acentric;
410 N = fluid_identifiers.size();
412 for (std::size_t i = 0; i < fluid_identifiers.size(); ++i) {
418 cubic = std::make_shared<PengRobinson>(Tc, pc, acentric, R_u);
419 setup(generate_SatL_and_SatV);
460 bool cache_values =
false)
override {
466#ifdef COOLPROPDBL_MAPS_TO_DOUBLE
467 const std::vector<double>& z = mole_fractions;
469 std::vector<double> z = std::vector<double>(mole_fractions.begin(), mole_fractions.end());
486 std::array<double, 5> psi_minus{}, psi_plus{}, tau_times_a{};
487 for (std::size_t n = 0; n <= 4; ++n) {
488 psi_minus[n] = cubic->psi_minus(delta, z, 0, n);
489 psi_plus[n] = cubic->psi_plus(delta, z, n);
490 tau_times_a[n] = cubic->tau_times_a(tau, z, n);
492 const double den = cubic->get_R_u() * cubic->get_Tr();
493 a.alphar = psi_minus[0] - tau_times_a[0] / den * psi_plus[0];
494 a.dalphar_dtau = 0.0 - tau_times_a[1] / den * psi_plus[0];
495 a.dalphar_ddelta = psi_minus[1] - tau_times_a[0] / den * psi_plus[1];
496 a.d2alphar_dtau2 = 0.0 - tau_times_a[2] / den * psi_plus[0];
497 a.d2alphar_ddelta_dtau = 0.0 - tau_times_a[1] / den * psi_plus[1];
498 a.d2alphar_ddelta2 = psi_minus[2] - tau_times_a[0] / den * psi_plus[2];
499 a.d3alphar_dtau3 = 0.0 - tau_times_a[3] / den * psi_plus[0];
500 a.d3alphar_ddelta_dtau2 = 0.0 - tau_times_a[2] / den * psi_plus[1];
501 a.d3alphar_ddelta2_dtau = 0.0 - tau_times_a[1] / den * psi_plus[2];
502 a.d3alphar_ddelta3 = psi_minus[3] - tau_times_a[0] / den * psi_plus[3];
503 a.d4alphar_dtau4 = 0.0 - tau_times_a[4] / den * psi_plus[0];
504 a.d4alphar_ddelta_dtau3 = 0.0 - tau_times_a[3] / den * psi_plus[1];
505 a.d4alphar_ddelta2_dtau2 = 0.0 - tau_times_a[2] / den * psi_plus[2];
506 a.d4alphar_ddelta3_dtau = 0.0 - tau_times_a[1] / den * psi_plus[3];
507 a.d4alphar_ddelta4 = psi_minus[4] - tau_times_a[0] / den * psi_plus[4];