9namespace SaturationSolvers {
51 std::vector<CoolPropDbl>
x,
y,
K;
67 return log(pci / p) + 5.373 * (1 + omegai) * (1 - Tci / T);
100#if !defined(NO_FMTLIB) && FMT_VERSION >= 90000
102 return fmt::underlying(option);
144 const std::vector<CoolPropDbl>& z, std::vector<CoolPropDbl>& K, mixture_VLE_IO& options);
152void x_and_y_from_K(
CoolPropDbl beta,
const std::vector<CoolPropDbl>& K,
const std::vector<CoolPropDbl>& z, std::vector<CoolPropDbl>& x,
153 std::vector<CoolPropDbl>& y);
165 const std::vector<CoolPropDbl>&
z;
166 std::vector<CoolPropDbl>&
K;
170 const std::vector<CoolPropDbl>&
z, std::vector<CoolPropDbl>&
K)
178 double call(
double input_value) {
185 for (
unsigned int i = 0; i <
z.size(); i++) {
186 K[i] = exp(Wilson_lnK_factor(
HEOS,
T,
p, i));
187 summer +=
z[i] * (
K[i] - 1) / (1 -
beta +
beta *
K[i]);
193 const std::vector<CoolPropDbl>& z) {
194 double ptriple = 0, pcrit = 0, Ttriple = 0, Tcrit = 0;
200 for (
unsigned int i = 0; i < z.size(); i++) {
212 return exp(log(pcrit / ptriple) / (Tcrit - Ttriple) * (input_value - Ttriple) + log(ptriple));
214 return 1 / (1 / Tcrit - (1 / Ttriple - 1 / Tcrit) / log(pcrit / ptriple) * log(input_value / pcrit));
247 const std::vector<CoolPropDbl>& z,
double guess) {
252 if (input_type ==
imposed_T && (std::abs(beta) < 1e-12 || std::abs(beta - 1) < 1e-12)) {
254 bool beta0 = std::abs(beta) < 1e-12;
255 for (
int i = 0; i < static_cast<int>(z.size()); ++i) {
260 out += z[i] * pci * exp(5.373 * (1 + omegai) * (1 - Tci / input_value));
262 out += z[i] / (pci * exp(5.373 * (1 + omegai) * (1 - Tci / input_value)));
268 std::vector<CoolPropDbl>& K = HEOS.
get_K();
269 for (
int i = 0; i < static_cast<int>(z.size()); ++i) {
273 K[i] = pci / out * exp(5.373 * (1 + omegai) * (1 - Tci / input_value));
277 WilsonK_resid Resid(HEOS, beta, input_value, input_type, z, HEOS.
get_K());
279 out =
Brent(Resid, 50, 10000, 1e-10, 1e-10, 100);
281 out =
Secant(Resid, guess, 0.001, 1e-10, 100);
283 throw ValueError(
"saturation_p_Wilson failed to get good output value");
288struct SuccessiveSubstitutionStep
293struct newton_raphson_twophase_options
295 enum imposed_variable_options
297 NO_VARIABLE_IMPOSED = 0,
303 CoolPropDbl beta, omega, rhomolar_liq, rhomolar_vap, pL, pV, p, T, hmolar_liq, hmolar_vap, smolar_liq, smolar_vap;
304 imposed_variable_options imposed_variable;
305 std::vector<CoolPropDbl> x, y, z;
306 newton_raphson_twophase_options()
321 imposed_variable(NO_VARIABLE_IMPOSED) {}
354class newton_raphson_twophase
357 HelmholtzEOSMixtureBackend* HEOS;
358 newton_raphson_twophase_options::imposed_variable_options imposed_variable;
359 CoolPropDbl error_rms, rhomolar_liq, rhomolar_vap, T, p, min_rel_change, beta;
364 Eigen::Vector2d r, err_rel;
365 std::vector<CoolPropDbl> K, x, y, z;
366 std::vector<SuccessiveSubstitutionStep> step_logger;
368 newton_raphson_twophase()
370 imposed_variable(newton_raphson_twophase_options::NO_VARIABLE_IMPOSED),
376 min_rel_change(_HUGE),
382 void resize(
unsigned int N);
392 rhomolar_liq = _HUGE;
393 rhomolar_vap = _HUGE;
407 void call(HelmholtzEOSMixtureBackend& HEOS, newton_raphson_twophase_options& IO);
415struct newton_raphson_saturation_options
417 enum imposed_variable_options
419 NO_VARIABLE_IMPOSED = 0,
427 CoolPropDbl omega, rhomolar_liq, rhomolar_vap, pL, pV, p, T, hmolar_liq, hmolar_vap, smolar_liq, smolar_vap;
428 imposed_variable_options imposed_variable;
429 std::vector<CoolPropDbl> x, y;
430 newton_raphson_saturation_options()
431 : bubble_point(false),
443 imposed_variable(NO_VARIABLE_IMPOSED) {
476class newton_raphson_saturation
479 newton_raphson_saturation_options::imposed_variable_options imposed_variable;
480 CoolPropDbl error_rms, rhomolar_liq, rhomolar_vap, T, p, min_rel_change;
486 HelmholtzEOSMixtureBackend* HEOS;
488 std::vector<CoolPropDbl> K, x, y;
489 Eigen::VectorXd r, err_rel;
490 std::vector<SuccessiveSubstitutionStep> step_logger;
492 newton_raphson_saturation(){};
494 void resize(std::size_t N);
501 rhomolar_liq = _HUGE;
502 rhomolar_vap = _HUGE;
518 void call(HelmholtzEOSMixtureBackend& HEOS,
const std::vector<CoolPropDbl>& z, std::vector<CoolPropDbl>& z_incipient,
519 newton_raphson_saturation_options& IO);
530 void check_Jacobian();
533struct PTflash_twophase_options
537 CoolPropDbl omega, rhomolar_liq, rhomolar_vap, pL, pV, p, T;
538 std::vector<CoolPropDbl> x,
541 PTflash_twophase_options() : omega(_HUGE), rhomolar_liq(_HUGE), rhomolar_vap(_HUGE), pL(_HUGE), pV(_HUGE), p(_HUGE), T(_HUGE) {
547class PTflash_twophase
554 Eigen::VectorXd r, err_rel;
555 HelmholtzEOSMixtureBackend& HEOS;
556 PTflash_twophase_options& IO;
557 std::vector<SuccessiveSubstitutionStep> step_logger;
559 PTflash_twophase(HelmholtzEOSMixtureBackend& HEOS, PTflash_twophase_options& IO) : HEOS(HEOS), IO(IO){};
579namespace StabilityRoutines {
589 const std::vector<double>&
z;
600 z(
HEOS.get_mole_fractions_doubleref()),
647 void get_liq(std::vector<double>&
x,
double& rhomolar) {
652 void get_vap(std::vector<double>&
y,
double& rhomolar) {