19#include "nlohmann/json.hpp"
28template<
typename NumType>
36 template<
typename TType>
48template<
typename NumType>
59 template<
typename TType>
61 return forceeval(
pow(T/Tci,c[2]*(c[1]-1))*exp(c[0]*(1.0-
pow(T/Tci, c[1]*c[2]))));
76template<
typename NumType>
87 template<
typename TType>
89 auto x = 1.0 - sqrt(T/Tci);
90 auto paren = 1.0 + c[0]*x + c[1]*x*x + c[2]*x*x*x;
99 std::vector<AlphaFunctionOptions> alphas;
101 if (jalphas.size() != Tc_K.size()){
104 for (
auto alpha : jalphas){
105 std::string type = alpha.at(
"type");
107 std::valarray<double> c_ = alpha.at(
"c");
108 Eigen::Array3d c = Eigen::Map<Eigen::Array3d>(&(c_[0]), c_.size());
111 else if (type ==
"Mathias-Copeman"){
112 std::valarray<double> c_ = alpha.at(
"c");
113 Eigen::Array3d c = Eigen::Map<Eigen::Array3d>(&(c_[0]), c_.size());
116 else if (type ==
"PR78"){
117 double acentric = alpha.at(
"acentric");
119 if (acentric < 0.491) {
120 mi = 0.37464 + 1.54226*acentric - 0.26992*
pow2(acentric);
123 mi = 0.379642 + 1.48503*acentric -0.164423*
pow2(acentric) + 0.016666*
pow3(acentric);
135template <
typename NumType,
typename AlphaFunctions>
146 template<
typename TType,
typename IndexType>
147 auto get_ai(TType , IndexType i)
const {
return ai[i]; }
149 template<
typename TType,
typename IndexType>
150 auto get_bi(TType , IndexType i)
const {
return bi[i]; }
152 template<
typename IndexType>
155 throw teqp::InvalidArgument(
"kmat rows [" + std::to_string(
kmat.rows()) +
"] and columns [" + std::to_string(
kmat.cols()) +
"] are not identical");
157 if (
kmat.cols() == 0) {
160 else if (
static_cast<std::size_t
>(
kmat.cols()) != N) {
161 throw teqp::InvalidArgument(
"kmat needs to be a square matrix the same size as the number of components [" + std::to_string(N) +
"]");
169 ai.resize(Tc_K.size());
170 bi.resize(Tc_K.size());
171 for (
auto i = 0U; i < Tc_K.size(); ++i) {
186 auto superanc_rhoLV(
double T, std::optional<std::size_t> ifluid = std::nullopt)
const {
188 std::valarray<double> molefracs(
ai.size()); molefracs = 1.0;
195 if (ifluid.value() >
ai.size()-1){
199 molefracs[ifluid.value()] = 1.0;
202 auto b =
get_b(T, molefracs);
203 auto a =
get_a(T, molefracs);
204 auto Ttilde =
R(molefracs)*T*b/a;
205 return std::make_tuple(
211 const NumType
Ru = get_R_gas<double>();
213 template<
class VecType>
214 auto R(
const VecType& )
const {
218 template<
typename TType,
typename CompType>
219 auto get_a(TType T,
const CompType& molefracs)
const {
220 std::common_type_t<TType,
decltype(molefracs[0])> a_ = 0.0;
221 for (
auto i = 0U; i < molefracs.size(); ++i) {
222 auto alphai =
forceeval(std::visit([&](
auto& t) {
return t(T); },
alphas[i]));
223 auto ai_ =
forceeval(this->ai[i] * alphai);
224 for (
auto j = 0U; j < molefracs.size(); ++j) {
225 auto alphaj =
forceeval(std::visit([&](
auto& t) {
return t(T); },
alphas[j]));
226 auto aj_ = this->ai[j] * alphaj;
228 a_ = a_ + molefracs[i] * molefracs[j] * aij;
234 template<
typename TType,
typename CompType>
235 auto get_b(TType ,
const CompType& molefracs)
const {
236 std::common_type_t<TType,
decltype(molefracs[0])> b_ = 0.0;
237 for (
auto i = 0U; i < molefracs.size(); ++i) {
238 b_ = b_ + molefracs[i] *
bi[i];
243 template<
typename TType,
typename RhoType,
typename MoleFracType>
246 const MoleFracType& molefrac)
const
248 if (
static_cast<std::size_t
>(molefrac.size()) !=
alphas.size()) {
249 throw std::invalid_argument(
"Sizes do not match");
251 auto b =
get_b(T, molefrac);
252 auto Psiminus = -log(1.0 - b * rho);
254 auto val = Psiminus -
get_a(T, molefrac) / (
Ru * T) * Psiplus;
259template <
typename TCType,
typename PCType,
typename AcentricType>
260auto canonical_SRK(TCType Tc_K, PCType pc_Pa, AcentricType acentric,
const std::optional<Eigen::ArrayXXd>& kmat = std::nullopt) {
263 AcentricType m = 0.48 + 1.574 * acentric - 0.176 * acentric * acentric;
265 std::vector<AlphaFunctionOptions> alphas;
266 for (
auto i = 0U; i < Tc_K.size(); ++i) {
271 double OmegaA = 1.0 / (9.0 * (cbrt(2) - 1));
272 double OmegaB = (cbrt(2) - 1) / 3;
274 nlohmann::json meta = {
279 {
"kind",
"Soave-Redlich-Kwong"}
281 const std::size_t N = m.size();
289 std::valarray<double> Tc_K = spec.at(
"Tcrit / K"), pc_Pa = spec.at(
"pcrit / Pa"), acentric = spec.at(
"acentric");
290 Eigen::ArrayXXd kmat(0, 0);
291 if (spec.contains(
"kmat")){
297template <
typename TCType,
typename PCType,
typename AcentricType>
298auto canonical_PR(TCType Tc_K, PCType pc_Pa, AcentricType acentric,
const std::optional<Eigen::ArrayXXd>& kmat = std::nullopt) {
299 double Delta1 = 1+sqrt(2.0);
300 double Delta2 = 1-sqrt(2.0);
301 AcentricType m = acentric*0.0;
302 std::vector<AlphaFunctionOptions> alphas;
303 for (
auto i = 0U; i < Tc_K.size(); ++i) {
304 if (acentric[i] < 0.491) {
305 m[i] = 0.37464 + 1.54226*acentric[i] - 0.26992*
pow2(acentric[i]);
308 m[i] = 0.379642 + 1.48503*acentric[i] -0.164423*
pow2(acentric[i]) + 0.016666*
pow3(acentric[i]);
314 double OmegaA = 0.45723552892138218938;
315 double OmegaB = 0.077796073903888455972;
317 nlohmann::json meta = {
322 {
"kind",
"Peng-Robinson"}
325 const std::size_t N = m.size();
333 std::valarray<double> Tc_K = spec.at(
"Tcrit / K"), pc_Pa = spec.at(
"pcrit / Pa"), acentric = spec.at(
"acentric");
334 Eigen::ArrayXXd kmat(0, 0);
335 if (spec.contains(
"kmat")){
344 std::valarray<double> Tc_K = spec.at(
"Tcrit / K"),
345 pc_Pa = spec.at(
"pcrit / Pa"),
346 acentric = spec.at(
"acentric");
349 std::optional<Eigen::ArrayXXd> kmat;
350 if (spec.contains(
"kmat")){
357 std::vector<AlphaFunctionOptions> alphas;
359 double Delta1, Delta2, OmegaA, OmegaB;
360 std::string kind =
"custom";
362 if (spec.at(
"type") ==
"PR" ){
363 Delta1 = 1+sqrt(2.0);
364 Delta2 = 1-sqrt(2.0);
366 OmegaA = 0.45723552892138218938;
367 OmegaB = 0.077796073903888455972;
369 kind =
"Peng-Robinson";
371 if (!spec.contains(
"alpha")){
372 for (
auto i = 0U; i < Tc_K.size(); ++i) {
374 if (acentric[i] < 0.491) {
375 mi = 0.37464 + 1.54226*acentric[i] - 0.26992*
pow2(acentric[i]);
378 mi = 0.379642 + 1.48503*acentric[i] -0.164423*
pow2(acentric[i]) + 0.016666*
pow3(acentric[i]);
384 if (!spec[
"alpha"].is_array()){
390 else if (spec.at(
"type") ==
"SRK"){
393 if (!spec.contains(
"alpha")){
394 for (
auto i = 0U; i < Tc_K.size(); ++i) {
395 double mi = 0.48 + 1.574 * acentric[i] - 0.176 * acentric[i] * acentric[i];
400 if (!spec[
"alpha"].is_array()){
406 OmegaA = 1.0 / (9.0 * (cbrt(2) - 1));
407 OmegaB = (cbrt(2) - 1) / 3;
409 kind =
"Soave-Redlich-Kwong";
413 throw teqp::InvalidArgument(
"Generic cubic EOS are not yet supported (open an issue on github if you want this)");
416 const std::size_t N = Tc_K.size();
417 nlohmann::json meta = {
424 if (spec.contains(
"alpha")){
425 meta[
"alpha"] = spec.at(
"alpha");
428 auto cub =
GenericCubic(Delta1, Delta2, OmegaA, OmegaB, superanc_code, Tc_K, pc_Pa, std::move(alphas), kmat.value_or(Eigen::ArrayXXd::Zero(N,N)));
441struct AdvancedPRaEOptions{
444 double CEoS = -sqrt(2.0)/2.0*log(1.0 + sqrt(2.0));
447inline void from_json(
const json& j, AdvancedPRaEOptions& o) {
448 j.at(
"brule").get_to(o.brule);
449 j.at(
"s").get_to(o.s);
450 j.at(
"CEoS").get_to(o.CEoS);
456template<
typename NumType>
459 template<
typename TType,
typename MoleFractions>
460 auto operator () (
const TType& ,
const MoleFractions& molefracs)
const {
461 std::common_type_t<TType,
decltype(molefracs[0])> val = 0.0;
486template<
typename NumType>
490 const double R = 8.31446261815324;
491 const std::vector<double>
b;
492 const Eigen::ArrayXXd
m,
n;
495 template<
typename TType,
typename MoleFractions>
497 if (
b.size() !=
static_cast<std::size_t
>(molefracs.size())){
501 using TYPE = std::common_type_t<TType,
decltype(molefracs[0])>;
504 for (
auto i = 0U; i < molefracs.size(); ++i){
506 Vtot += molefracs[i]*v_i;
510 for (
auto i = 0U; i < molefracs.size(); ++i){
515 auto phi_i_over_z_i = v_i/Vtot;
516 summer += molefracs[i]*log(phi_i_over_z_i);
521 template<
typename TType>
522 auto get_Aij(std::size_t i, std::size_t j,
const TType& T)
const{
526 template<
typename TType,
typename MoleFractions>
527 auto total(
const TType& T,
const MoleFractions& molefracs)
const {
529 using TYPE = std::common_type_t<TType,
decltype(molefracs[0])>;
531 for (
auto i = 0U; i < molefracs.size(); ++i){
534 for (
auto j = 0U; j < molefracs.size(); ++j){
537 auto Omega_ji = v_j/v_i*exp(-Aij/T);
538 summerj += molefracs[j]*Omega_ji;
540 summer += molefracs[i]*log(summerj);
546 template<
typename TType,
typename MoleFractions>
547 auto operator () (
const TType& T,
const MoleFractions& molefracs)
const {
558template <
typename NumType,
typename AlphaFunctions = std::vector<AlphaFunctionOptions>>
565 const NumType
OmegaA = 0.45723552892138218938;
566 const NumType
OmegaB = 0.077796073903888455972;
586 template<
typename TType,
typename IndexType>
587 auto get_ai(TType& T, IndexType i)
const {
588 auto alphai = std::visit([&](
auto& t) {
return t(T); },
alphas[i]);
592 template<
typename TType,
typename IndexType>
593 auto get_bi(TType& , IndexType i)
const {
return bi[i]; }
595 template<
typename IndexType>
598 throw teqp::InvalidArgument(
"lmat rows [" + std::to_string(
lmat.rows()) +
"] and columns [" + std::to_string(
lmat.cols()) +
"] are not identical");
600 if (
lmat.cols() == 0) {
603 else if (
lmat.cols() !=
static_cast<Eigen::Index
>(N)) {
604 throw teqp::InvalidArgument(
"lmat needs to be a square matrix the same size as the number of components [" + std::to_string(N) +
"]");
614 for (
auto i = 0U; i <
Tc_K.size(); ++i) {
628 const NumType
OmegaB = 0.077796073903888455972;
629 const NumType
R = 8.31446261815324;
637 auto superanc_rhoLV(
double T, std::optional<std::size_t> ifluid = std::nullopt)
const {
639 std::valarray<double> molefracs(
ai.size()); molefracs = 1.0;
646 if (ifluid.value() >
ai.size()-1){
650 molefracs[ifluid.value()] = 1.0;
653 auto b =
get_b(T, molefracs);
655 auto Ttilde =
R(molefracs)*T*b/a;
656 return std::make_tuple(
662 const NumType
Ru = get_R_gas<double>();
664 template<
class VecType>
665 auto R(
const VecType& )
const {
669 template<
typename TType,
typename CompType>
670 auto get_a(TType T,
const CompType& molefracs)
const {
674 template<
typename TType,
typename CompType>
676 auto aEresRT = std::visit([&](
auto& aresRTfunc) {
return aresRTfunc(T, molefracs); },
ares);
677 std::common_type_t<TType,
decltype(molefracs[0])> summer = aEresRT*
Ru*T/
CEoS;
678 for (
auto i = 0U; i < molefracs.size(); ++i) {
684 template<
typename TType,
typename CompType>
685 auto get_b(TType T,
const CompType& molefracs)
const {
686 std::common_type_t<TType,
decltype(molefracs[0])> b_ = 0.0;
690 for (
auto i = 0U; i < molefracs.size(); ++i) {
692 for (
auto j = 0U; j < molefracs.size(); ++j) {
695 auto bij = (1 -
lmat(i,j)) *
pow((
pow(bi_, 1.0/
s) +
pow(bj_, 1.0/
s))/2.0,
s);
696 b_ += molefracs[i] * molefracs[j] * bij;
701 for (
auto i = 0U; i < molefracs.size(); ++i) {
702 b_ += molefracs[i] *
get_bi(T, i);
711 template<
typename TType,
typename RhoType,
typename MoleFracType>
714 const MoleFracType& molefrac)
const
716 if (
static_cast<std::size_t
>(molefrac.size()) !=
alphas.size()) {
717 throw std::invalid_argument(
"Sizes do not match");
719 auto b =
get_b(T, molefrac);
721 auto Psiminus = -log(1.0 - b * rho);
723 auto val = Psiminus - a / (
Ru * T) * Psiplus;
730 std::valarray<double> Tc_K = j.at(
"Tcrit / K");
731 std::valarray<double> pc_Pa = j.at(
"pcrit / Pa");
737 std::string type = armodel.at(
"type");
738 if (type ==
"Wilson"){
739 std::vector<double> b;
740 for (
auto i = 0U; i < Tc_K.size(); ++i){
751 auto aresmodel = get_ares_model(j.at(
"aresmodel"));
753 AdvancedPRaEOptions options = j.at(
"options");
770 const std::vector<double> Tc_K, pc_Pa;
771 const std::vector<AlphaFunctionOptions> alphas;
772 const std::vector<double> As, Bs, cs_m3mol;
773 const Eigen::ArrayXXd kmat, lmat;
775 auto build_alphas(
const nlohmann::json& j){
776 std::vector<AlphaFunctionOptions> alphas_;
777 std::vector<double> L = j.at(
"Ls"), M = j.at(
"Ms"), N = j.at(
"Ns");
778 if (L.size() != M.size() || M.size() != N.size()){
781 for (
auto i = 0U; i < L.size(); ++i){
782 auto coeffs = (Eigen::Array3d() << L[i], M[i], N[i]).finished();
788 std::vector<double> get_(
const nlohmann::json &j,
const std::string& k)
const {
return j.at(k).get<std::vector<double>>(); }
791 QuantumCorrectedPR(
const nlohmann::json &j) : Tc_K(get_(j,
"Tcrit / K")), pc_Pa(get_(j,
"pcrit / Pa")), alphas(build_alphas(j)), As(get_(j,
"As")), Bs(get_(j,
"Bs")), cs_m3mol(get_(j,
"cs / m^3/mol")), kmat(
build_square_matrix(j.at(
"kmat"))), lmat(
build_square_matrix(j.at(
"lmat"))) {}
793 const double Ru = get_R_gas<double>();
795 template<
class VecType>
796 auto R(
const VecType& )
const {
804 template<
typename TType>
805 auto get_bi(std::size_t i,
const TType& T)
const {
806 auto beta =
POW3(1.0 + As[i]/(T+Bs[i]))/
POW3(1.0+As[i]/(Tc_K[i]+Bs[i]));
808 auto b = 0.07780*Tc_K[i]*
Ru/pc_Pa[i];
812 template<
typename TType>
813 auto get_ai(std::size_t i,
const TType& T)
const {
814 auto alphai =
forceeval(std::visit([&](
auto& t) {
return t(T); }, alphas[i]));
816 auto OmegaA = 0.45723552892138218938;
817 auto a = OmegaA*
POW2(Tc_K[i]*
Ru)/pc_Pa[i];
821 template<
typename TType,
typename FractionsType>
822 auto get_ab(
const TType& T,
const FractionsType& z)
const{
823 using numtype = std::common_type_t<TType,
decltype(z[0])>;
826 std::size_t N = alphas.size();
827 for (
auto i = 0U; i < N; ++i){
830 for (
auto j = 0U; j < N; ++j){
833 b += z[i]*z[j]*(bi + bj)/2.0*(1.0 - lmat(i,j));
834 a += z[i]*z[j]*sqrt(ai*aj)*(1.0 - kmat(i,j));
837 return std::make_tuple(a, b);
839 template<
typename TType,
typename FractionsType>
840 auto get_c(
const TType& ,
const FractionsType& z)
const{
841 using numtype = std::common_type_t<TType,
decltype(z[0])>;
843 std::size_t N = alphas.size();
844 for (
auto i = 0U; i < N; ++i){
845 c += z[i]*cs_m3mol[i];
850 template<
typename TType,
typename RhoType,
typename FractionsType>
851 auto alphar(
const TType& T,
const RhoType& rhoinit,
const FractionsType& molefrac)
const {
852 if (
static_cast<std::size_t
>(molefrac.size()) != alphas.size()) {
853 throw std::invalid_argument(
"Sizes do not match");
856 auto c =
get_c(T, molefrac);
857 auto rho = 1.0/(1.0/rhoinit + c);
858 auto Delta1 = 1.0 + sqrt(2.0);
859 auto Delta2 = 1.0 - sqrt(2.0);
860 auto [a, b] =
get_ab(T, molefrac);
861 auto Psiminus = -log(1.0 - b * rho);
862 auto Psiplus = log((Delta1 * b * rho + 1.0) / (Delta2 * b * rho + 1.0)) / (b * (Delta1 - Delta2));
863 auto val = Psiminus - a / (
Ru * T) * Psiplus;
870 if (Tc_K.size() != 1) {
871 throw std::invalid_argument(
"function only available for pure species");
873 const std::valarray<double> z = { 1.0 };
874 auto [a, b] =
get_ab(T, z);
875 auto Ttilde =
R(z)*T*b/a;
877 return std::make_tuple(
898 const double Ru = get_R_gas<double>();
901 const std::vector<double> delta_1, Tc_K, pc_Pa, k;
902 const Eigen::ArrayXXd kmat, lmat;
903 const std::vector<double> a_c, b_c;
906 std::vector<double> get_(
const nlohmann::json &j,
const std::string& key)
const {
return j.at(key).get<std::vector<double>>(); }
909 auto get_yd1(
double delta_1_){
910 return std::make_tuple(1 + cbrt(2*(1+delta_1_)) + cbrt(4/(1+delta_1_)), (1+delta_1_*delta_1_)/(1+delta_1_));
914 std::vector<double> a_c_(delta_1.size());
915 for (
auto i = 0U; i < delta_1.size(); ++i){
916 auto [y, d_1] = get_yd1(delta_1[i]);
917 auto Omega_a = (3*y*y + 3*y*d_1 + d_1*d_1 + d_1 - 1.0)/
pow(3.0*y + d_1 - 1.0, 2);
918 a_c_[i] = Omega_a*
pow(
Ru*Tc_K[i], 2)/pc_Pa[i];
923 std::vector<double> b_c_(delta_1.size());
924 for (
auto i = 0U; i < delta_1.size(); ++i){
925 auto [y, d_1] = get_yd1(delta_1[i]);
926 auto Omega_b = 1.0/(3.0*y + d_1 - 1.0);
927 b_c_[i] = Omega_b*
Ru*Tc_K[i]/pc_Pa[i];
933 RKPRCismondi2005(
const nlohmann::json &j) : delta_1(get_(j,
"delta_1")), Tc_K(get_(j,
"Tcrit / K")), pc_Pa(get_(j,
"pcrit / Pa")), k(get_(j,
"k")), kmat(
build_square_matrix(j.at(
"kmat"))), lmat(
build_square_matrix(j.at(
"lmat"))), a_c(build_ac()), b_c(build_bc()) {}
935 template<
class VecType>
936 auto R(
const VecType& )
const {
946 template<
typename TType>
947 auto get_bi(std::size_t i,
const TType& )
const {
951 template<
typename TType>
952 auto get_ai(std::size_t i,
const TType& T)
const {
953 return forceeval(a_c[i]*
pow(3.0/(2.0+T/Tc_K[i]), k[i]));
956 template<
typename TType,
typename FractionsType>
957 auto get_ab(
const TType& T,
const FractionsType& z)
const{
958 using numtype = std::common_type_t<TType,
decltype(z[0])>;
961 std::size_t N = delta_1.size();
962 for (
auto i = 0U; i < N; ++i){
965 for (
auto j = 0U; j < N; ++j){
969 a += z[i]*z[j]*sqrt(ai*aj)*(1.0 - kmat(i,j));
970 b += z[i]*z[j]*(bi + bj)/2.0*(1.0 - lmat(i,j));
974 return std::make_tuple(a, b);
977 template<
typename TType,
typename RhoType,
typename FractionsType>
978 auto alphar(
const TType& T,
const RhoType& rho,
const FractionsType& molefrac)
const {
979 if (
static_cast<std::size_t
>(molefrac.size()) != delta_1.size()) {
980 throw std::invalid_argument(
"Sizes do not match");
984 const auto delta_1_view = Eigen::Map<const Eigen::ArrayXd>(&(delta_1[0]), delta_1.size());
985 const decltype(molefrac[0]) Delta1 = (molefrac*delta_1_view).eval().sum();
987 auto Delta2 = (1.0-Delta1)/(1.0+Delta1);
988 auto [a, b] =
get_ab(T, molefrac);
990 auto Psiminus = -log(1.0 - b*rho);
991 auto Psiplus = log((Delta1 * b * rho + 1.0) / (Delta2 * b * rho + 1.0)) / (b * (Delta1 - Delta2));
992 auto val = Psiminus - a/(
Ru*T)*Psiplus;
auto get_a(TType T, const CompType &molefracs) const
auto get_b(TType T, const CompType &molefracs) const
AdvancedPRaEres(const std::valarray< NumType > &Tc_K, const std::valarray< NumType > &pc_Pa, const AlphaFunctions &alphas, const ResidualHelmholtzOverRTVariant &ares, const Eigen::ArrayXXd &lmat, const AdvancedPRaEOptions &options={})
void check_lmat(IndexType N)
std::valarray< NumType > Tc_K
static double get_bi(double Tc_K, double pc_Pa)
const ResidualHelmholtzOverRTVariant ares
std::valarray< NumType > ai
auto get_ai(TType &T, IndexType i) const
const AlphaFunctions alphas
const AdvancedPRaEMixingRules brule
void set_meta(const nlohmann::json &j)
std::valarray< NumType > pc_Pa
auto get_bi(TType &, IndexType i) const
std::valarray< NumType > bi
auto R(const VecType &) const
Universal gas constant, exact number.
auto superanc_rhoLV(double T, std::optional< std::size_t > ifluid=std::nullopt) const
auto get_am_over_bm(TType T, const CompType &molefracs) const
auto alphar(const TType &T, const RhoType &rho, const MoleFracType &molefrac) const
The standard alpha function used by Peng-Robinson and SRK.
auto operator()(const TType &T) const
BasicAlphaFunction(NumType Tci, NumType mi)
auto get_ai(TType, IndexType i) const
auto get_b(TType, const CompType &molefracs) const
void set_meta(const nlohmann::json &j)
void check_kmat(IndexType N)
auto alphar(const TType &T, const RhoType &rho, const MoleFracType &molefrac) const
auto get_a(TType T, const CompType &molefracs) const
std::valarray< NumType > ai
GenericCubic(NumType Delta1, NumType Delta2, NumType OmegaA, NumType OmegaB, int superanc_index, const std::valarray< NumType > &Tc_K, const std::valarray< NumType > &pc_Pa, const AlphaFunctions &alphas, const Eigen::ArrayXXd &kmat)
auto superanc_rhoLV(double T, std::optional< std::size_t > ifluid=std::nullopt) const
auto get_bi(TType, IndexType i) const
const AlphaFunctions alphas
std::valarray< NumType > bi
auto R(const VecType &) const
Universal gas constant, exact number.
The Mathias-Copeman alpha function used by Peng-Robinson and SRK.
auto operator()(const TType &T) const
MathiasCopemanAlphaFunction(NumType Tci, const Eigen::Array3d &c)
auto operator()(const TType &, const MoleFractions &molefracs) const
auto get_ai(std::size_t i, const TType &T) const
auto get_ab(const TType &T, const FractionsType &z) const
auto superanc_rhoLV(double T) const
auto alphar(const TType &T, const RhoType &rhoinit, const FractionsType &molefrac) const
QuantumCorrectedPR(const nlohmann::json &j)
auto get_bi(std::size_t i, const TType &T) const
auto R(const VecType &) const
Universal gas constant, exact number.
auto get_c(const TType &, const FractionsType &z) const
RKPRCismondi2005(const nlohmann::json &j)
auto get_bi(std::size_t i, const TType &) const
auto R(const VecType &) const
auto alphar(const TType &T, const RhoType &rho, const FractionsType &molefrac) const
auto get_ab(const TType &T, const FractionsType &z) const
auto get_ai(std::size_t i, const TType &T) const
The Twu alpha function used by Peng-Robinson and SRK.
auto operator()(const TType &T) const
TwuAlphaFunction(NumType Tci, const Eigen::Array3d &c)
const std::vector< double > b
auto operator()(const TType &T, const MoleFractions &molefracs) const
WilsonResidualHelmholtzOverRT(const std::vector< double > &b, const Eigen::ArrayXXd &m, const Eigen::ArrayXXd &n)
auto combinatorial(const TType &, const MoleFractions &molefracs) const
auto total(const TType &T, const MoleFractions &molefracs) const
auto get_Aij(std::size_t i, std::size_t j, const TType &T) const
auto make_generalizedcubic(const nlohmann::json &spec)
A JSON-based factory function for the generalized cubic + alpha.
auto canonical_PR(TCType Tc_K, PCType pc_Pa, AcentricType acentric, const std::optional< Eigen::ArrayXXd > &kmat=std::nullopt)
auto make_AdvancedPRaEres(const nlohmann::json &j)
void from_json(const json &j, AdvancedPRaEOptions &o)
decltype(make_AdvancedPRaEres({})) advancedPRaEres_t
auto canonical_SRK(TCType Tc_K, PCType pc_Pa, AcentricType acentric, const std::optional< Eigen::ArrayXXd > &kmat=std::nullopt)
auto make_canonicalPR(const nlohmann::json &spec)
A JSON-based factory function for the canonical SRK model.
decltype(RKPRCismondi2005({})) RKPRCismondi2005_t
std::variant< NullResidualHelmholtzOverRT< double >, WilsonResidualHelmholtzOverRT< double > > ResidualHelmholtzOverRTVariant
std::variant< BasicAlphaFunction< double >, TwuAlphaFunction< double >, MathiasCopemanAlphaFunction< double > > AlphaFunctionOptions
auto make_canonicalSRK(const nlohmann::json &spec)
A JSON-based factory function for the canonical SRK model.
NLOHMANN_JSON_SERIALIZE_ENUM(AdvancedPRaEMixingRules, { {AdvancedPRaEMixingRules::knotspecified, nullptr}, {AdvancedPRaEMixingRules::kLinear, "Linear"}, {AdvancedPRaEMixingRules::kQuadratic, "Quadratic"}, }) struct AdvancedPRaEOptions
auto pow(const double &x, const double &e)
auto build_alpha_functions(const TC &Tc_K, const nlohmann::json &jalphas)