void GeneralVaporMixtureFluidProperties::e_from_p_T(Real p, Real T, std::vector<Real> x, Real & e, Real & de_dp, Real & de_dT, std::vector<Real> & de_dx) const { const Real x_primary = primaryMassFraction(x); Real ep, dep_dp, dep_dT; _fp_primary->e_from_p_T(p, T, ep, dep_dp, dep_dT); e = x_primary * ep; de_dp = x_primary * dep_dp; de_dT = x_primary * dep_dT; de_dx.resize(_n_secondary_vapors); for (unsigned int i = 0; i < _n_secondary_vapors; ++i) { Real ei, dei_dp, dei_dT; _fp_secondary[i]->e_from_p_T(p, T, ei, dei_dp, dei_dT); e += x[i] * ei; de_dp += x[i] * dei_dp; de_dT += x[i] * dei_dT; de_dx[i] = ei - ep; } }
Real GeneralVaporMixtureFluidProperties::k_from_p_T(Real p, Real T, std::vector<Real> x) const { const Real x_primary = primaryMassFraction(x); Real M_primary = _fp_primary->molarMass(); Real sum = x_primary / M_primary; for (unsigned int i = 0; i < _n_secondary_vapors; ++i) sum += x[i] / _fp_secondary[i]->molarMass(); Real M_star = 1. / sum; Real vp = _fp_primary->v_from_p_T(p, T); Real ep = _fp_primary->e_from_p_T(p, T); Real k = x_primary * M_star / M_primary * _fp_primary->k_from_v_e(vp, ep); for (unsigned int i = 0; i < _n_secondary_vapors; ++i) { Real vi = _fp_secondary[i]->v_from_p_T(p, T); Real ei = _fp_secondary[i]->e_from_p_T(p, T); Real Mi = _fp_secondary[i]->molarMass(); k += x[i] * M_star / Mi * _fp_secondary[i]->k_from_v_e(vi, ei); } return k; }
void GeneralVaporMixtureFluidProperties::v_from_p_T(Real p, Real T, std::vector<Real> x, Real & v, Real & dv_dp, Real & dv_dT, std::vector<Real> & dv_dx) const { const Real x_primary = primaryMassFraction(x); Real vp, dvp_dp, dvp_dT; _fp_primary->v_from_p_T(p, T, vp, dvp_dp, dvp_dT); v = x_primary * vp; dv_dp = x_primary * dvp_dp; dv_dT = x_primary * dvp_dT; dv_dx.resize(_n_secondary_vapors); for (unsigned int i = 0; i < _n_secondary_vapors; ++i) { Real vi, dvi_dp, dvi_dT; _fp_secondary[i]->v_from_p_T(p, T, vi, dvi_dp, dvi_dT); v += x[i] * vi; dv_dp += x[i] * dvi_dp; dv_dT += x[i] * dvi_dT; dv_dx[i] = vi - vp; } }
Real IdealRealGasMixtureFluidProperties::k_from_T_v(Real T, Real v, const std::vector<Real> & x) const { const Real x_primary = primaryMassFraction(x); Real M_primary = _fp_primary->molarMass(); Real sum = x_primary / M_primary; for (unsigned int i = 0; i < _n_secondary_vapors; i++) sum += x[i] / _fp_secondary[i]->molarMass(); Real M_star = 1. / sum; Real vp = v / x_primary; Real ep = _fp_primary->e_from_T_v(T, vp); Real k = x_primary * M_star / M_primary * _fp_primary->k_from_v_e(vp, ep); for (unsigned int i = 0; i < _n_secondary_vapors; i++) { Real vi = v / x[i]; Real ei = _fp_secondary[i]->e_from_T_v(T, vp); Real Mi = _fp_secondary[i]->molarMass(); k += x[i] * M_star / Mi * _fp_secondary[i]->k_from_v_e(vi, ei); } return k; }
void IdealRealGasMixtureFluidProperties::p_T_from_v_e( Real v, Real e, const std::vector<Real> & x, Real & p, Real & T) const { Real v_primary = v / primaryMassFraction(x); static const Real vc = 1. / _fp_primary->criticalDensity(); static const Real ec = _fp_primary->criticalInternalEnergy(); // Initial estimate of a bracketing interval for the temperature Real lower_temperature, upper_temperature; if (v_primary > vc) { Real e_sat_primary = _fp_primary->e_spndl_from_v(v_primary); lower_temperature = _fp_primary->T_from_v_e(v_primary, e_sat_primary); } else lower_temperature = _fp_primary->T_from_v_e(v_primary, ec); upper_temperature = _T_mix_max; // Use BrentsMethod to find temperature auto energy_diff = [&v, &e, &x, this](Real T) { return this->e_from_T_v(T, v, x) - e; }; BrentsMethod::bracket(energy_diff, lower_temperature, upper_temperature); T = BrentsMethod::root(energy_diff, lower_temperature, upper_temperature); p = p_from_T_v(T, v, x); }
Real GeneralVaporMixtureFluidProperties::e_from_p_T(Real p, Real T, std::vector<Real> x) const { const Real x_primary = primaryMassFraction(x); Real e = x_primary * _fp_primary->e_from_p_T(p, T); for (unsigned int i = 0; i < _n_secondary_vapors; ++i) e += x[i] * _fp_secondary[i]->e_from_p_T(p, T); return e; }
Real IdealRealGasMixtureFluidProperties::cv_from_T_v(Real T, Real v, const std::vector<Real> & x) const { const Real x_primary = primaryMassFraction(x); Real cv = x_primary * _fp_primary->cv_from_T_v(T, v / x_primary); for (unsigned int i = 0; i < _n_secondary_vapors; i++) cv += x[i] * _fp_secondary[i]->cv_from_T_v(T, v / x[i]); return cv; }
void IdealRealGasMixtureFluidProperties::e_from_T_v(Real T, Real v, const std::vector<Real> & x, Real & e, Real & de_dT, Real & de_dv, std::vector<Real> & de_dx) const { Real e_primary, de_dT_primary, de_dv_primary, de_dx_primary, dxi_dx_primary; Real de_dT_sec, dxj_dxi, dx_primary_dxi; std::vector<Real> e_sec, de_dv_sec; const Real x_primary = primaryMassFraction(x); de_dx.resize(_n_secondary_vapors); e_sec.resize(_n_secondary_vapors); de_dv_sec.resize(_n_secondary_vapors); _fp_primary->e_from_T_v(T, v / x_primary, e_primary, de_dT_primary, de_dv_primary); e = x_primary * e_primary; de_dT = x_primary * de_dT_primary; de_dv = de_dv_primary; de_dx_primary = e_primary - x_primary * de_dv_primary * v / (x_primary * x_primary); // get the partial pressures and their derivatives first for (unsigned int i = 0; i < _n_secondary_vapors; i++) { _fp_secondary[i]->e_from_T_v(T, v / x[i], e_sec[i], de_dT_sec, de_dv_sec[i]); e += x[i] * e_sec[i]; de_dT += x[i] * de_dT_sec; de_dv += de_dv_sec[i]; dxi_dx_primary = -x[i] / (1. - x_primary); de_dx_primary += dxi_dx_primary * e_sec[i] - x[i] * de_dv_sec[i] * v / (x[i] * x[i]) * dxi_dx_primary; } // get the composition dependent derivatives of the secondary vapors for (unsigned int i = 0; i < _n_secondary_vapors; i++) { de_dx[i] = e_sec[i] - x[i] * de_dv_sec[i] * v / (x[i] * x[i]); for (unsigned int j = 0; j < _n_secondary_vapors; j++) { if (j == i) continue; dxj_dxi = -x[j] / (1. - x[i]); de_dx[i] += dxj_dxi * e_sec[j] - x[j] * de_dv_sec[j] * v / (x[j] * x[j]) * dxj_dxi; } dx_primary_dxi = -x_primary / (1. - x[i]); de_dx[i] += dx_primary_dxi * e_primary - x_primary * de_dv_primary * v / (x_primary * x_primary) * dx_primary_dxi; } }
Real GeneralVaporMixtureFluidProperties::cv_from_p_T(Real p, Real T, std::vector<Real> x) const { const Real x_primary = primaryMassFraction(x); Real vp = _fp_primary->v_from_p_T(p, T); Real ep = _fp_primary->e_from_p_T(p, T); Real cv = x_primary * _fp_primary->cv_from_v_e(vp, ep); for (unsigned int i = 0; i < _n_secondary_vapors; ++i) { Real vi = _fp_secondary[i]->v_from_p_T(p, T); Real ei = _fp_secondary[i]->e_from_p_T(p, T); cv += x[i] * _fp_secondary[i]->cv_from_v_e(vi, ei); } return cv; }
Real IdealRealGasMixtureFluidProperties::cp_from_T_v(Real T, Real v, const std::vector<Real> & x) const { Real p, dp_dT, dp_dv; Real h, dh_dT, dh_dv; p_from_T_v(T, v, x, p, dp_dT, dp_dv); const Real x_primary = primaryMassFraction(x); _fp_primary->h_from_T_v(T, v / x_primary, h, dh_dT, dh_dv); Real cp = x_primary * (dh_dT - dh_dv * dp_dT / dp_dv); for (unsigned int i = 0; i < _n_secondary_vapors; i++) { _fp_secondary[i]->h_from_T_v(T, v / x[i], h, dh_dT, dh_dv); cp += x[i] * (dh_dT - dh_dv * dp_dT / dp_dv); } return cp; }
void IdealRealGasMixtureFluidProperties::s_from_T_v( Real T, Real v, const std::vector<Real> & x, Real & s, Real & ds_dT, Real & ds_dv) const { Real s_primary, ds_dT_primary, ds_dv_primary; Real s_sec, ds_dT_sec, ds_dv_sec; const Real x_primary = primaryMassFraction(x); _fp_primary->s_from_T_v(T, v / x_primary, s_primary, ds_dT_primary, ds_dv_primary); s = x_primary * s_primary; ds_dT = x_primary * ds_dT_primary; ds_dv = ds_dv_primary; for (unsigned int i = 0; i < _n_secondary_vapors; i++) { _fp_secondary[i]->s_from_T_v(T, v / x[i], s_sec, ds_dT_sec, ds_dv_sec); s += x[i] * s_sec; ds_dT += x[i] * ds_dT_sec; ds_dv += ds_dv_sec; } }
void IdealRealGasMixtureFluidProperties::p_from_T_v( Real T, Real v, const std::vector<Real> & x, Real & p, Real & dp_dT, Real & dp_dv) const { Real p_primary, dp_dT_primary, dp_dv_primary; Real p_sec, dp_dT_sec, dp_dv_sec; const Real x_primary = primaryMassFraction(x); _fp_primary->p_from_T_v(T, v / x_primary, p_primary, dp_dT_primary, dp_dv_primary); p = p_primary; dp_dT = dp_dT_primary; dp_dv = dp_dv_primary / x_primary; for (unsigned int i = 0; i < _n_secondary_vapors; i++) { _fp_secondary[i]->p_from_T_v(T, v / x[i], p_sec, dp_dT_sec, dp_dv_sec); p += p_sec; dp_dT += dp_dT_sec; dp_dv += dp_dv_sec / x[i]; } }
Real IdealRealGasMixtureFluidProperties::v_from_p_T(Real p, Real T, const std::vector<Real> & x) const { const Real x_primary = primaryMassFraction(x); Real M_primary = _fp_primary->molarMass(); Real sum = x_primary / M_primary; for (unsigned int i = 0; i < _n_secondary_vapors; i++) sum += x[i] / _fp_secondary[i]->molarMass(); Real M_star = 1. / sum; Real v_ideal = R_molar * T / (M_star * p); // check range of validity for primary (condensable) component static const Real Tc = _fp_primary->criticalTemperature(); static const Real vc = 1. / _fp_primary->criticalDensity(); Real v_spndl, e_spndl; if (T < Tc) _fp_primary->v_e_spndl_from_T(T, v_spndl, e_spndl); else v_spndl = vc; Real lower_spec_volume = v_spndl * x_primary; Real upper_spec_volume = v_ideal; // p*v/(RT) <= 1 // Initial estimate of a bracketing interval for the temperature Real p_max = p_from_T_v(T, lower_spec_volume, x); if (p > p_max || upper_spec_volume < lower_spec_volume) return getNaN(); // Use BrentsMethod to find temperature auto pressure_diff = [&T, &p, &x, this](Real v) { return this->p_from_T_v(T, v, x) - p; }; BrentsMethod::bracket(pressure_diff, lower_spec_volume, upper_spec_volume); Real v = BrentsMethod::root(pressure_diff, lower_spec_volume, upper_spec_volume); return v; }
Real GeneralVaporMixtureFluidProperties::c_from_p_T(Real p, Real T, std::vector<Real> x) const { const Real x_primary = primaryMassFraction(x); Real vp, dvp_dp_T, dvp_dT_p; _fp_primary->v_from_p_T(p, T, vp, dvp_dp_T, dvp_dT_p); Real v = x_primary * vp; Real dv_dp_T = x_primary * dvp_dp_T; Real dv_dT_p = x_primary * dvp_dT_p; Real sp, dsp_dp_T, dsp_dT_p; _fp_primary->s_from_p_T(p, T, sp, dsp_dp_T, dsp_dT_p); Real ds_dp_T = x_primary * dsp_dp_T; Real ds_dT_p = x_primary * dsp_dT_p; for (unsigned int i = 0; i < _n_secondary_vapors; ++i) { Real vi, dvi_dp_T, dvi_dT_p; _fp_secondary[i]->v_from_p_T(p, T, vi, dvi_dp_T, dvi_dT_p); v += x[i] * vi; dv_dp_T += x[i] * dvi_dp_T; dv_dT_p += x[i] * dvi_dT_p; Real si, dsi_dp_T, dsi_dT_p; _fp_secondary[i]->s_from_p_T(p, T, si, dsi_dp_T, dsi_dT_p); ds_dp_T += x[i] * dsi_dp_T; ds_dT_p += x[i] * dsi_dT_p; } Real dv_dp_s = dv_dp_T - dv_dT_p * ds_dp_T / ds_dT_p; if (dv_dp_s >= 0) mooseWarning(name(), ":c_from_p_T(), dv_dp_s = ", dv_dp_s, ". Should be negative."); return v * std::sqrt(-1. / dv_dp_s); }
Real IdealRealGasMixtureFluidProperties::xs_prim_from_p_T(Real p, Real T, const std::vector<Real> & x) const { Real T_c = _fp_primary->criticalTemperature(); Real xs; if (T > T_c) // return 1. to indicate that no water would condense for // given (p,T) xs = 1.; else { Real pp_sat = _fp_primary->pp_sat_from_p_T(p, T); if (pp_sat < 0.) { // return 1. to indicate that no water would condense for // given (p,T) xs = 1.; return xs; } Real v_primary = _fp_primary->v_from_p_T(pp_sat, T); Real pp_sat_secondary = p - pp_sat; Real v_secondary; if (_n_secondary_vapors == 1) v_secondary = _fp_secondary[0]->v_from_p_T(pp_sat_secondary, T); else { std::vector<Real> x_sec(_n_secondary_vapors); const Real x_primary = primaryMassFraction(x); Real sum = 0.; for (unsigned int i = 0; i < _n_secondary_vapors; i++) { x_sec[i] = x[i] / (1. - x_primary); sum += x_sec[i] / _fp_secondary[i]->molarMass(); } Real M_star = 1. / sum; v_secondary = R_molar * T / (M_star * pp_sat_secondary); int it = 0; double f = 1., df_dvs, pp_sec, p_sec, dp_dT_sec, dp_dv_sec, dp_dT, dp_dv; double tol_p = 1.e-8; while (std::fabs(f / pp_sat_secondary) > tol_p) { pp_sec = 0.; dp_dT = 0.; dp_dv = 0.; for (unsigned int i = 0; i < _n_secondary_vapors; i++) { _fp_secondary[i]->p_from_T_v(T, v_secondary / x_sec[i], p_sec, dp_dT_sec, dp_dv_sec); pp_sec += p_sec; dp_dT += dp_dT_sec; dp_dv += dp_dv_sec / x_sec[i]; } f = pp_sec - pp_sat_secondary; df_dvs = dp_dv; v_secondary -= f / df_dvs; if (it++ > 15) return getNaN(); } } xs = v_secondary / (v_primary + v_secondary); } return xs; }