24 params.addClassDescription(
"Class for fluid properties of an arbitrary vapor mixture");
26 params.addRequiredParam<UserObjectName>(
27 "fp_primary",
"Name of fluid properties user object for primary vapor component");
28 params.addRequiredParam<std::vector<UserObjectName>>(
29 "fp_secondary",
"Name of fluid properties user object(s) for secondary vapor component(s)");
30 params.addParam<Real>(
"_T_mix_max", 1300.,
"Maximum temperature of the mixture");
34 params.set<ExecFlagEnum>(
"execute_on") = EXEC_INITIAL;
40 const InputParameters & parameters)
43 _fp_secondary_names(getParam<std::vector<UserObjectName>>(
"fp_secondary")),
44 _n_secondary_vapors(_fp_secondary_names.size()),
45 _T_mix_max(getParam<Real>(
"_T_mix_max"))
47 _fp_primary = &getUserObject<SinglePhaseFluidProperties>(
"fp_primary");
66 const std::vector<Real> & x,
70 std::vector<Real> & dp_dx)
const
74 p_T_from_v_e(v, e, x, p, dp_dv, dp_de, dp_dx, T, dT_dv, dT_de, dT_dx);
89 const std::vector<Real> & x,
93 std::vector<Real> & dT_dx)
const
97 p_T_from_v_e(v, e, x, p, dp_dv, dp_de, dp_dx, T, dT_dv, dT_de, dT_dx);
111 const std::vector<Real> & x,
115 std::vector<Real> & dc_dx)
const
121 Real dc_dT_v, dc_dv_T;
122 std::vector<Real> dc_dx_Tv;
123 c_from_T_v(T, v, x, c, dc_dT_v, dc_dv_T, dc_dx_Tv);
126 Real e_unused, de_dT_v, de_dv_T;
127 std::vector<Real> de_dx_Tv;
128 e_from_T_v(T, v, x, e_unused, de_dT_v, de_dv_T, de_dx_Tv);
131 dc_dv = dc_dv_T - dc_dT_v * de_dv_T / de_dT_v;
132 dc_de = dc_dT_v / de_dT_v;
137 dc_dx[i] = dc_dx_Tv[i] - dc_dT_v * de_dx_Tv[i] / de_dT_v;
150 const std::vector<Real> & x,
154 std::vector<Real> & drho_dx)
const
156 Real v, dv_dp, dv_dT;
157 std::vector<Real> dv_dx;
161 const Real drho_dv = -1.0 / (v * v);
162 drho_dp = drho_dv * dv_dp;
163 drho_dT = drho_dv * dv_dT;
166 drho_dx[i] = drho_dv * dv_dx[i];
175 Real sum = x_primary / M_primary;
178 Real M_star = 1. / sum;
179 Real v_ideal =
R_molar * T / (M_star * p);
184 Real v_spndl, e_spndl;
190 Real lower_spec_volume = v_spndl * x_primary;
191 Real upper_spec_volume = v_ideal;
194 Real p_max =
p_from_T_v(T, lower_spec_volume, x);
195 if (p > p_max || upper_spec_volume < lower_spec_volume)
199 auto pressure_diff = [&T, &p, &x,
this](Real v) {
return this->
p_from_T_v(T, v, x) - p; };
210 const std::vector<Real> & x,
214 std::vector<Real> & dv_dx)
const
216 Real p_unused, dp_dT, dp_dv;
217 std::vector<Real> dp_dx;
221 p_from_T_v(T, v, x, p_unused, dp_dT, dp_dv, dp_dx);
224 dv_dT = -dp_dT / dp_dv;
228 dv_dx[i] = -dp_dx[i] / dp_dv;
241 const std::vector<Real> & x,
245 std::vector<Real> & de_dx)
const
247 Real v, de_dT_v, de_dv_T, p_unused, dp_dT_v, dp_dv_T;
248 std::vector<Real> de_dx_Tv, dp_dx_Tv;
253 e_from_T_v(T, v, x, e, de_dT_v, de_dv_T, de_dx_Tv);
254 p_from_T_v(T, v, x, p_unused, dp_dT_v, dp_dv_T, dp_dx_Tv);
256 de_dp = de_dv_T / dp_dv_T;
257 de_dT = de_dT_v - de_dv_T * dp_dT_v / dp_dv_T;
261 de_dx[i] = -(de_dv_T - de_dx_Tv[i] * dp_dv_T / dp_dx_Tv[i]) * dp_dx_Tv[i] / dp_dv_T;
268 Real p_unused, dp_dT, dp_dv;
269 Real s, ds_dT, ds_dv;
275 Real dp_dv_s = dp_dv - dp_dT * ds_dv / ds_dT;
278 mooseWarning(
name(),
":c_from_p_T(), dp_dv_s = ", dp_dv_s,
". Should be negative.");
279 return v * std::sqrt(-dp_dv_s);
285 const std::vector<Real> & x,
289 std::vector<Real> & dc_dx)
const
291 Real p_perturbed, T_perturbed, c_perturbed;
297 p_perturbed = p + dp;
299 dc_dp = (c_perturbed - c) / (dp);
302 T_perturbed = T + dT;
304 dc_dT = (c_perturbed - c) / (dT);
310 std::vector<Real> x_perturbed(x);
316 x[j] * (1.0 - (x[i] + dx_i)) / (1.0 - x[i]);
318 x_perturbed[i] += dx_i;
320 dc_dx[i] = ((c_perturbed - c) / dx_i);
327 Real p_unused, dp_dT, dp_dv;
328 Real h, dh_dT, dh_dv;
335 _fp_primary->h_from_T_v(T, v / x_primary, h, dh_dT, dh_dv);
336 Real cp = x_primary * (dh_dT - dh_dv * dp_dT / dp_dv);
341 cp += x[i] * (dh_dT - dh_dv * dp_dT / dp_dv);
353 Real cv = x_primary *
_fp_primary->cv_from_T_v(T, v / x_primary);
369 Real sum = x_primary / M_primary;
372 Real M_star = 1. / sum;
374 Real vp = v / x_primary;
376 Real mu = x_primary * M_star / M_primary *
_fp_primary->mu_from_v_e(vp, ep);
383 mu += x[i] * M_star / Mi *
_fp_secondary[i]->mu_from_v_e(vi, ei);
397 Real sum = x_primary / M_primary;
400 Real M_star = 1. / sum;
402 Real vp = v / x_primary;
404 Real k = x_primary * M_star / M_primary *
_fp_primary->k_from_v_e(vp, ep);
411 k += x[i] * M_star / Mi *
_fp_secondary[i]->k_from_v_e(vi, ei);
420 const std::vector<Real> & x)
const
431 const std::vector<Real> & x,
435 std::vector<Real> & de_dx)
const
439 Real p_, dp_dT, dp_dv, de_dT, de_dv;
440 std::vector<Real> dp_dx_Tv;
441 std::vector<Real> de_dx_Tv;
443 p_from_T_v(T, v, x, p_, dp_dT, dp_dv, dp_dx_Tv);
444 e_from_T_v(T, v, x, e, de_dT, de_dv, de_dx_Tv);
446 de_dp = de_dT / dp_dT;
447 de_drho = (-v * v) * (de_dv - de_dT * dp_dv / dp_dT);
452 de_dx[i] = de_dx_Tv[i] - de_dT * dp_dx_Tv[i] / dp_dT;
458 Real v, Real e,
const std::vector<Real> & x, Real & p, Real & T)
const
465 Real lower_temperature, upper_temperature;
469 lower_temperature =
_fp_primary->T_from_v_e(v_primary, e_sat_primary);
472 lower_temperature =
_fp_primary->T_from_v_e(v_primary, ec);
477 auto energy_diff = [&v, &e, &x,
this](Real T) {
return this->
e_from_T_v(T, v, x) - e; };
488 const std::vector<Real> & x,
492 std::vector<Real> & dp_dx,
496 std::vector<Real> & dT_dx)
const
501 Real p_unused, dp_dT_v, dp_dv_T;
502 std::vector<Real> dp_dx_Tv;
503 p_from_T_v(T, v, x, p_unused, dp_dT_v, dp_dv_T, dp_dx_Tv);
506 Real e_unused, de_dT_v, de_dv_T;
507 std::vector<Real> de_dx_Tv;
508 e_from_T_v(T, v, x, e_unused, de_dT_v, de_dv_T, de_dx_Tv);
511 dp_dv = dp_dv_T - dp_dT_v * de_dv_T / de_dT_v;
512 dp_de = dp_dT_v / de_dT_v;
513 dT_dv = -de_dv_T / de_dT_v;
514 dT_de = 1. / de_dT_v;
519 dT_dx[i] = -de_dx_Tv[i] / de_dT_v;
520 dp_dx[i] = dp_dx_Tv[i] + dp_dT_v * dT_dx[i];
532 Real lower_temperature, upper_temperature;
536 lower_temperature =
_fp_primary->T_from_v_e(v_primary, e_sat_primary);
539 lower_temperature =
_fp_primary->T_from_v_e(v_primary, ec);
544 auto pressure_diff = [&p, &v, &x,
this](Real T) {
return this->
p_from_T_v(T, v, x) - p; };
555 const std::vector<Real> & x,
559 std::vector<Real> & dT_dx)
const
564 Real p_unused, dp_dT_v, dp_dv_T;
565 std::vector<Real> dp_dx_Tv;
566 p_from_T_v(T, v, x, p_unused, dp_dT_v, dp_dv_T, dp_dx_Tv);
569 dT_dp = 1. / dp_dT_v;
570 dT_dv = -dp_dv_T / dp_dT_v;
575 dT_dx[i] = -dp_dx_Tv[i] / dp_dT_v;
583 Real p =
_fp_primary->p_from_T_v(T, v / x_primary);
593 Real T, Real v,
const std::vector<Real> & x, Real & p, Real & dp_dT, Real & dp_dv)
const
595 Real p_primary, dp_dT_primary, dp_dv_primary;
596 Real p_sec, dp_dT_sec, dp_dv_sec;
600 _fp_primary->p_from_T_v(T, v / x_primary, p_primary, dp_dT_primary, dp_dv_primary);
602 dp_dT = dp_dT_primary;
603 dp_dv = dp_dv_primary / x_primary;
607 _fp_secondary[i]->p_from_T_v(T, v / x[i], p_sec, dp_dT_sec, dp_dv_sec);
611 dp_dv += dp_dv_sec / x[i];
618 const std::vector<Real> & x,
622 std::vector<Real> & dp_dx)
const
624 Real p_primary, dp_dT_primary, dp_dv_primary, dp_dx_primary, dxi_dx_primary;
625 Real p_sec, dp_dT_sec, dxj_dxi;
626 std::vector<Real> dp_dv_sec;
632 _fp_primary->p_from_T_v(T, v / x_primary, p_primary, dp_dT_primary, dp_dv_primary);
634 dp_dT = dp_dT_primary;
635 dp_dv = dp_dv_primary / x_primary;
636 dp_dx_primary = -dp_dv_primary * v / (x_primary * x_primary);
641 _fp_secondary[i]->p_from_T_v(T, v / x[i], p_sec, dp_dT_sec, dp_dv_sec[i]);
645 dp_dv += dp_dv_sec[i] / x[i];
646 dxi_dx_primary = -x[i] / (1. - x_primary);
647 dp_dx_primary += -dp_dv_sec[i] * v / (x[i] * x[i]) * dxi_dx_primary;
653 dp_dx[i] = -dp_dv_sec[i] * v / (x[i] * x[i]);
658 dxj_dxi = -x[j] / (1. - x[i]);
659 dp_dx[i] += -dp_dv_sec[j] * v / (x[j] * x[j]) * dxj_dxi;
661 dp_dx[i] += -dp_dv_primary * v / (x_primary * x_primary) * (-x_primary / (1. - x[i]));
669 Real e = x_primary *
_fp_primary->e_from_T_v(T, v / x_primary);
680 const std::vector<Real> & x,
684 std::vector<Real> & de_dx)
const
686 Real e_primary, de_dT_primary, de_dv_primary, de_dx_primary, dxi_dx_primary;
687 Real de_dT_sec, dxj_dxi, dx_primary_dxi;
688 std::vector<Real> e_sec, de_dv_sec;
695 _fp_primary->e_from_T_v(T, v / x_primary, e_primary, de_dT_primary, de_dv_primary);
696 e = x_primary * e_primary;
697 de_dT = x_primary * de_dT_primary;
698 de_dv = de_dv_primary;
699 de_dx_primary = e_primary - x_primary * de_dv_primary * v / (x_primary * x_primary);
704 _fp_secondary[i]->e_from_T_v(T, v / x[i], e_sec[i], de_dT_sec, de_dv_sec[i]);
706 e += x[i] * e_sec[i];
707 de_dT += x[i] * de_dT_sec;
708 de_dv += de_dv_sec[i];
709 dxi_dx_primary = -x[i] / (1. - x_primary);
711 dxi_dx_primary * e_sec[i] - x[i] * de_dv_sec[i] * v / (x[i] * x[i]) * dxi_dx_primary;
717 de_dx[i] = e_sec[i] - x[i] * de_dv_sec[i] * v / (x[i] * x[i]);
722 dxj_dxi = -x[j] / (1. - x[i]);
723 de_dx[i] += dxj_dxi * e_sec[j] - x[j] * de_dv_sec[j] * v / (x[j] * x[j]) * dxj_dxi;
725 dx_primary_dxi = -x_primary / (1. - x[i]);
726 de_dx[i] += dx_primary_dxi * e_primary -
727 x_primary * de_dv_primary * v / (x_primary * x_primary) * dx_primary_dxi;
733 Real T, Real v,
const std::vector<Real> & x, Real & s, Real & ds_dT, Real & ds_dv)
const
735 Real s_primary, ds_dT_primary, ds_dv_primary;
736 Real s_sec, ds_dT_sec, ds_dv_sec;
740 _fp_primary->s_from_T_v(T, v / x_primary, s_primary, ds_dT_primary, ds_dv_primary);
741 s = x_primary * s_primary;
742 ds_dT = x_primary * ds_dT_primary;
743 ds_dv = ds_dv_primary;
747 _fp_secondary[i]->s_from_T_v(T, v / x[i], s_sec, ds_dT_sec, ds_dv_sec);
750 ds_dT += x[i] * ds_dT_sec;
758 Real p, dp_dT, dp_dv;
759 Real s, ds_dT, ds_dv;
764 Real dp_dv_s = dp_dv - dp_dT * ds_dv / ds_dT;
767 mooseWarning(
name(),
":c_from_T_v(), dp_dv_s = ", dp_dv_s,
". Should be negative.");
768 return v * std::sqrt(-dp_dv_s);
774 const std::vector<Real> & x,
778 std::vector<Real> & dc_dx)
const
780 Real T_perturbed, v_perturbed, c_perturbed;
786 T_perturbed = T + dT;
788 dc_dT = (c_perturbed - c) / (dT);
791 v_perturbed = v + dv;
793 dc_dv = (c_perturbed - c) / (dv);
799 std::vector<Real> x_perturbed(x);
805 x[j] * (1.0 - (x[i] + dx_i)) / (1.0 - x[i]);
807 x_perturbed[i] += dx_i;
809 dc_dx[i] = ((c_perturbed - c) / dx_i);
816 Real p, dp_dT, dp_dv;
817 Real h, dh_dT, dh_dv;
823 _fp_primary->h_from_T_v(T, v / x_primary, h, dh_dT, dh_dv);
824 Real cp = x_primary * (dh_dT - dh_dv * dp_dT / dp_dv);
829 cp += x[i] * (dh_dT - dh_dv * dp_dT / dp_dv);
839 Real cv = x_primary *
_fp_primary->cv_from_T_v(T, v / x_primary);
853 Real sum = x_primary / M_primary;
856 Real M_star = 1. / sum;
858 Real vp = v / x_primary;
860 Real mu = x_primary * M_star / M_primary *
_fp_primary->mu_from_v_e(vp, ep);
867 mu += x[i] * M_star / Mi *
_fp_secondary[i]->mu_from_v_e(vi, ei);
879 Real sum = x_primary / M_primary;
882 Real M_star = 1. / sum;
884 Real vp = v / x_primary;
886 Real k = x_primary * M_star / M_primary *
_fp_primary->k_from_v_e(vp, ep);
893 k += x[i] * M_star / Mi *
_fp_secondary[i]->k_from_v_e(vi, ei);
902 const std::vector<Real> & x)
const
920 Real v_primary =
_fp_primary->v_from_p_T(pp_sat, T);
921 Real pp_sat_secondary = p - pp_sat;
925 v_secondary =
_fp_secondary[0]->v_from_p_T(pp_sat_secondary, T);
933 x_sec[i] = x[i] / (1. - x_primary);
936 Real M_star = 1. / sum;
937 v_secondary =
R_molar * T / (M_star * pp_sat_secondary);
939 double f = 1., df_dvs, pp_sec, p_sec, dp_dT_sec, dp_dv_sec, dp_dT, dp_dv;
940 double tol_p = 1.e-8;
941 while (std::fabs(f / pp_sat_secondary) > tol_p)
948 _fp_secondary[i]->p_from_T_v(T, v_secondary / x_sec[i], p_sec, dp_dT_sec, dp_dv_sec);
951 dp_dv += dp_dv_sec / x_sec[i];
953 f = pp_sec - pp_sat_secondary;
955 v_secondary -= f / df_dvs;
961 xs = v_secondary / (v_primary + v_secondary);