| 2082 | } |
| 2083 | |
| 2084 | double PCSAFTBackend::outerPQ(double t_guess, PCSAFTBackend& PCSAFT) { |
| 2085 | // Based on the algorithm proposed in H. A. J. Watson, M. Vikse, T. Gundersen, and P. I. Barton, “Reliable Flash Calculations: Part 1. Nonsmooth Inside-Out Algorithms,” Ind. Eng. Chem. Res., vol. 56, no. 4, pp. 960–973, Feb. 2017, doi: 10.1021/acs.iecr.6b03956. |
| 2086 | auto ncomp = N; // number of components |
| 2087 | double TOL = 1e-8; |
| 2088 | int MAXITER = 200; |
| 2089 | |
| 2090 | // Define the residual to be driven to zero |
| 2091 | class SolverInnerResid : public FuncWrapper1D |
| 2092 | { |
| 2093 | public: |
| 2094 | PCSAFTBackend& PCSAFT; |
| 2095 | CoolPropDbl kb0; |
| 2096 | vector<CoolPropDbl> u; |
| 2097 | |
| 2098 | SolverInnerResid(PCSAFTBackend& PCSAFT, CoolPropDbl kb0, vector<CoolPropDbl> u) : PCSAFT(PCSAFT), kb0(kb0), u(std::move(u)) {} |
| 2099 | CoolPropDbl call(CoolPropDbl R) override { |
| 2100 | auto ncomp = PCSAFT.components.size(); |
| 2101 | double error = 0; |
| 2102 | |
| 2103 | vector<double> pp(ncomp, 0); |
| 2104 | double L = 0; |
| 2105 | for (auto i = 0U; i < ncomp; i++) { |
| 2106 | if (!PCSAFT.ion_term || PCSAFT.components[i].getZ() == 0) { |
| 2107 | pp[i] = PCSAFT.mole_fractions[i] / (1 - R + kb0 * R * exp(u[i])); |
| 2108 | L += pp[i]; |
| 2109 | } else { |
| 2110 | L += PCSAFT.mole_fractions[i]; |
| 2111 | } |
| 2112 | } |
| 2113 | L = (1 - R) * L; |
| 2114 | |
| 2115 | error = pow((L + PCSAFT._Q - 1), 2.); |
| 2116 | return error; |
| 2117 | }; |
| 2118 | }; |
| 2119 | |
| 2120 | double x_ions = 0.; // overall mole fraction of ions in the system |
| 2121 | for (size_t i = 0; i < ncomp; i++) { |
| 2122 | if (PCSAFT.ion_term && PCSAFT.components[i].getZ() != 0) { |
| 2123 | x_ions += PCSAFT.mole_fractions[i]; |
| 2124 | } |
| 2125 | } |
| 2126 | |
| 2127 | // initialize variables |
| 2128 | vector<double> k(ncomp, 0), u(ncomp, 0), kprime(ncomp, 0), uprime(ncomp, 0); |
| 2129 | double Tref = t_guess - 1; |
| 2130 | double Tprime = t_guess + 1; |
| 2131 | double t = t_guess; |
| 2132 | |
| 2133 | PCSAFT.SatL->_T = t; // _T must be updated because the density calculation depends on it |
| 2134 | PCSAFT.SatV->_T = t; |
| 2135 | |
| 2136 | // calculate sigma for water, if it is present |
| 2137 | if (PCSAFT.water_present) { |
| 2138 | PCSAFT.components[water_idx].calc_water_sigma(t); |
| 2139 | PCSAFT.SatL->components[water_idx].calc_water_sigma(t); |
| 2140 | PCSAFT.SatV->components[water_idx].calc_water_sigma(t); |
| 2141 | PCSAFT.dielc = |
nothing calls this directly
no test coverage detected