5 #include "HelmholtzEOSMixtureBackend.h" 9 namespace SaturationSolvers {
13 CoolPropDbl omega, rhoL, rhoV, pL, pV;
15 : use_guesses(use_guesses), omega(_HUGE), rhoL(_HUGE), rhoV(_HUGE), pL(_HUGE), pV(_HUGE) {}
19 CoolPropDbl omega, rhoL, rhoV, pL, pV, p, T;
25 enum imposed_rho_options
32 CoolPropDbl omega, rhoL, rhoV, pL, pV;
35 saturation_D_pure_options() : use_guesses(false), rhoL(_HUGE), rhoV(_HUGE), pL(_HUGE), pV(_HUGE), imposed_rho(0), max_iterations(200) {
50 CoolPropDbl rhomolar_liq, rhomolar_vap, p, T, beta;
51 std::vector<CoolPropDbl> x, y, K;
67 return log(pci / p) + 5.373 * (1 + omegai) * (1 - Tci / T);
77 enum specified_variable_options
91 specified_variable_options specified_variable;
92 CoolPropDbl omega, rhoL, rhoV, pL, pV, T, p;
94 specified_variable = IMPOSED_INVALID_INPUT;
100 #if !defined(NO_FMTLIB) && FMT_VERSION >= 90000 101 inline int format_as(saturation_PHSU_pure_options::specified_variable_options option) {
102 return fmt::underlying(option);
144 const std::vector<CoolPropDbl>& z, std::vector<CoolPropDbl>& K,
mixture_VLE_IO& options);
152 void 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);
163 sstype_enum input_type;
165 const std::vector<CoolPropDbl>& z;
166 std::vector<CoolPropDbl>& K;
170 const std::vector<CoolPropDbl>& z, std::vector<CoolPropDbl>& K)
171 : input_type(input_type),
178 double call(
double input_value) {
180 if (input_type == imposed_T) {
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;
196 if (HEOS.get_components().empty()) {
200 for (
unsigned int i = 0; i < z.size(); i++) {
207 if (!ValidNumber(Ttriple) || !ValidNumber(ptriple)) {
211 if (input_type == imposed_T) {
212 return exp(log(pcrit / ptriple) / (Tcrit - Ttriple) * (input_value - Ttriple) + log(ptriple));
213 }
else if (input_type == imposed_p) {
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)) {
253 const std::vector<double> z = HEOS.get_mole_fractions_ref();
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());
278 if (guess < 0 || !ValidNumber(guess))
279 out =
Brent(Resid, 50, 10000, 1e-10, 1e-10, 100);
281 out =
Secant(Resid, guess, 0.001, 1e-10, 100);
282 if (!ValidNumber(out)) {
283 throw ValueError(
"saturation_p_Wilson failed to get good output value");
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;
321 imposed_variable(NO_VARIABLE_IMPOSED) {}
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;
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;
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;
431 : bubble_point(
false),
443 imposed_variable(NO_VARIABLE_IMPOSED) {
479 newton_raphson_saturation_options::imposed_variable_options imposed_variable;
480 CoolPropDbl error_rms, rhomolar_liq, rhomolar_vap, T, p, min_rel_change;
487 CoolPropDbl dTsat_dPsat, dPsat_dTsat;
488 std::vector<CoolPropDbl> K, x, y;
489 Eigen::VectorXd r, err_rel;
490 std::vector<SuccessiveSubstitutionStep> step_logger;
494 void resize(std::size_t N);
501 rhomolar_liq = _HUGE;
502 rhomolar_vap = _HUGE;
530 void check_Jacobian();
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) {
554 Eigen::VectorXd r, err_rel;
557 std::vector<SuccessiveSubstitutionStep> step_logger;
579 namespace StabilityRoutines {
588 std::vector<double> lnK, K, K0, x, y, xL, xH;
589 const std::vector<double>& z;
590 double rhomolar_liq, rhomolar_vap, beta, tpd_liq, tpd_vap, DELTAG_nRT;
600 z(HEOS.get_mole_fractions_doubleref()),
619 void rho_TP_w_guesses();
622 void rho_TP_global();
625 void rho_TP_SRK_translated();
629 void trial_compositions();
632 void successive_substitution(
int num_steps);
637 void check_stability();
641 trial_compositions();
642 successive_substitution(3);
647 void get_liq(std::vector<double>& x,
double& rhomolar) {
649 rhomolar = rhomolar_liq;
652 void get_vap(std::vector<double>& y,
double& rhomolar) {
654 rhomolar = rhomolar_vap;
Definition: VLERoutines.h:10
virtual const double get_fluid_constant(std::size_t i, parameters param) const
Get a constant for one of the fluids forming this mixture.
Definition: HelmholtzEOSMixtureBackend.h:264
Temperature at the critical point.
Definition: DataStructures.h:75
void set_TP(double T, double p)
Specify T&P, otherwise they are loaded the HEOS instance.
Definition: VLERoutines.h:613
Pressure at the critical point.
Definition: DataStructures.h:78
A class to do newton raphson solver for mixture VLE for p,Q or T,Q.
Definition: VLERoutines.h:354
Definition: VLERoutines.h:293
Definition: VLERoutines.h:17
Definition: VLERoutines.h:160
Definition: VLERoutines.h:46
Definition: VLERoutines.h:23
Definition: VLERoutines.h:533
Definition: VLERoutines.h:288
Definition: Exceptions.h:45
Evaluate phase stability Based on the work of Gernert et al., J.
Definition: VLERoutines.h:584
Triple point temperature.
Definition: DataStructures.h:80
double Brent(FuncWrapper1D *f, double a, double b, double macheps, double t, int maxiter)
This function implements a 1-D bounded solver using the algorithm from Brent, R.
Definition: Solvers.cpp:492
Acentric factor.
Definition: DataStructures.h:71
bool use_guesses
true to start off at the values specified by rhoL, rhoV
Definition: VLERoutines.h:12
double m_T
The temperature to be used (if specified, otherwise that from HEOS)
Definition: VLERoutines.h:591
bool use_logdelta
True to use partials with respect to log(delta) rather than delta.
Definition: VLERoutines.h:89
Definition: VLERoutines.h:547
std::vector< CoolPropDbl > z
Bulk mole fractions.
Definition: VLERoutines.h:538
A class to do newton raphson solver mixture bubble point and dew point calculations.
Definition: VLERoutines.h:476
Definition: HelmholtzEOSMixtureBackend.h:58
Triple point pressure.
Definition: DataStructures.h:81
Definition: VLERoutines.h:415
bool is_stable()
Return best estimate for the stability of the point.
Definition: VLERoutines.h:640
This file contains flash routines in which the state is unknown, and a solver of some kind must be us...
Definition: AbstractState.h:19
parameters
Define some constants that will be used throughout These are constants for the input and output para...
Definition: DataStructures.h:64
Definition: VLERoutines.h:75
bool use_logdelta
True to use partials with respect to log(delta) rather than delta.
Definition: VLERoutines.h:30
double Secant(FuncWrapper1D *f, double x0, double dx, double ftol, int maxiter)
In the secant function, a 1-D Newton-Raphson solver is implemented.
Definition: Solvers.cpp:273