19#include "nlohmann/json.hpp"
30template<
typename NumType>
38 template<
typename TType>
50template<
typename NumType>
61 template<
typename TType>
63 return forceeval(
pow(T/Tci,c[2]*(c[1]-1))*exp(c[0]*(1.0-
pow(T/Tci, c[1]*c[2]))));
78template<
typename NumType>
89 template<
typename TType>
91 auto x = 1.0 - sqrt(T/Tci);
92 auto paren = 1.0 + c[0]*x + c[1]*x*x + c[2]*x*x*x;
101 std::vector<AlphaFunctionOptions> alphas;
103 if (jalphas.size() != Tc_K.size()){
104 throw teqp::InvalidArgument(
"alpha [size "+std::to_string(jalphas.size())+
"] must be the same size as components [size "+std::to_string(Tc_K.size())+
"]");
106 for (
auto alpha : jalphas){
107 std::string type = alpha.at(
"type");
109 std::valarray<double> c_ = alpha.at(
"c");
110 Eigen::Array3d c = Eigen::Map<Eigen::Array3d>(&(c_[0]), c_.size());
113 else if (type ==
"Mathias-Copeman"){
114 std::valarray<double> c_ = alpha.at(
"c");
115 Eigen::Array3d c = Eigen::Map<Eigen::Array3d>(&(c_[0]), c_.size());
118 else if (type ==
"PR78"){
119 double acentric = alpha.at(
"acentric");
121 if (acentric < 0.491) {
122 mi = 0.37464 + 1.54226*acentric - 0.26992*
pow2(acentric);
125 mi = 0.379642 + 1.48503*acentric -0.164423*
pow2(acentric) + 0.016666*
pow3(acentric);
137template <
typename NumType,
typename AlphaFunctions>
149 template<
typename TType,
typename IndexType>
150 auto get_ai(TType , IndexType i)
const {
return ai[i]; }
152 template<
typename TType,
typename IndexType>
153 auto get_bi(TType , IndexType i)
const {
return bi[i]; }
155 template<
typename IndexType>
158 throw teqp::InvalidArgument(
"kmat rows [" + std::to_string(
kmat.rows()) +
"] and columns [" + std::to_string(
kmat.cols()) +
"] are not identical");
160 if (
kmat.cols() == 0) {
163 else if (
static_cast<std::size_t
>(
kmat.cols()) != N) {
164 throw teqp::InvalidArgument(
"kmat needs to be a square matrix the same size as the number of components [" + std::to_string(N) +
"]");
172 ai.resize(Tc_K.size());
173 bi.resize(Tc_K.size());
174 for (
auto i = 0U; i < Tc_K.size(); ++i) {
189 auto superanc_rhoLV(
double T, std::optional<std::size_t> ifluid = std::nullopt)
const {
191 std::valarray<double> molefracs(
ai.size()); molefracs = 1.0;
198 if (ifluid.value() >
ai.size()-1){
202 molefracs[ifluid.value()] = 1.0;
205 auto b =
get_b(T, molefracs);
206 auto a =
get_a(T, molefracs);
207 auto Ttilde =
R(molefracs)*T*b/a;
208 return std::make_tuple(
214 template<
class VecType>
215 auto R(
const VecType& )
const {
219 template<
typename TType,
typename CompType>
220 auto get_a(TType T,
const CompType& molefracs)
const {
221 std::common_type_t<TType,
decltype(molefracs[0])> a_ = 0.0;
222 for (
auto i = 0U; i < molefracs.size(); ++i) {
223 auto alphai =
forceeval(std::visit([&](
auto& t) {
return t(T); },
alphas[i]));
224 auto ai_ =
forceeval(this->ai[i] * alphai);
225 for (
auto j = 0U; j < molefracs.size(); ++j) {
226 auto alphaj =
forceeval(std::visit([&](
auto& t) {
return t(T); },
alphas[j]));
227 auto aj_ = this->ai[j] * alphaj;
229 a_ = a_ + molefracs[i] * molefracs[j] * aij;
235 template<
typename TType,
typename CompType>
236 auto get_b(TType ,
const CompType& molefracs)
const {
237 std::common_type_t<TType,
decltype(molefracs[0])> b_ = 0.0;
238 for (
auto i = 0U; i < molefracs.size(); ++i) {
239 b_ = b_ + molefracs[i] *
bi[i];
244 template<
typename TType,
typename RhoType,
typename MoleFracType>
247 const MoleFracType& molefrac)
const
249 if (
static_cast<std::size_t
>(molefrac.size()) !=
alphas.size()) {
250 throw std::invalid_argument(
"Sizes do not match");
252 auto b =
get_b(T, molefrac);
253 auto Psiminus = -log(1.0 - b * rho);
255 auto val = Psiminus -
get_a(T, molefrac) / (
m_R_JmolK * T) * Psiplus;
260template <
typename TCType,
typename PCType,
typename AcentricType>
261auto canonical_SRK(TCType Tc_K, PCType pc_Pa, AcentricType acentric,
const std::optional<Eigen::ArrayXXd>& kmat = std::nullopt,
const std::optional<double> R_JmolK = std::nullopt) {
264 AcentricType m = 0.48 + 1.574 * acentric - 0.176 * acentric * acentric;
266 std::vector<AlphaFunctionOptions> alphas;
267 for (
auto i = 0U; i < Tc_K.size(); ++i) {
272 double OmegaA = 1.0 / (9.0 * (cbrt(2) - 1));
273 double OmegaB = (cbrt(2) - 1) / 3;
275 nlohmann::json meta = {
280 {
"kind",
"Soave-Redlich-Kwong"},
283 const std::size_t N = m.size();
284 auto cub =
GenericCubic(Delta1, Delta2, OmegaA, OmegaB,
CubicSuperAncillary::SRK_CODE, Tc_K, pc_Pa, std::move(alphas), kmat.value_or(Eigen::ArrayXXd::Zero(N,N)), R_JmolK.value_or(
constants::R_CODATA2017));
291 std::valarray<double> Tc_K = spec.at(
"Tcrit / K"), pc_Pa = spec.at(
"pcrit / Pa"), acentric = spec.at(
"acentric");
292 Eigen::ArrayXXd kmat(0, 0);
293 if (spec.contains(
"kmat")){
299template <
typename TCType,
typename PCType,
typename AcentricType>
300auto canonical_PR(TCType Tc_K, PCType pc_Pa, AcentricType acentric,
const std::optional<Eigen::ArrayXXd>& kmat = std::nullopt,
const std::optional<double> R_JmolK = std::nullopt) {
301 double Delta1 = 1+sqrt(2.0);
302 double Delta2 = 1-sqrt(2.0);
303 AcentricType m = acentric*0.0;
304 std::vector<AlphaFunctionOptions> alphas;
305 for (
auto i = 0U; i < Tc_K.size(); ++i) {
306 if (acentric[i] < 0.491) {
307 m[i] = 0.37464 + 1.54226*acentric[i] - 0.26992*
pow2(acentric[i]);
310 m[i] = 0.379642 + 1.48503*acentric[i] -0.164423*
pow2(acentric[i]) + 0.016666*
pow3(acentric[i]);
316 double OmegaA = 0.45723552892138218938;
317 double OmegaB = 0.077796073903888455972;
319 nlohmann::json meta = {
324 {
"kind",
"Peng-Robinson"},
328 const std::size_t N = m.size();
329 auto cub =
GenericCubic(Delta1, Delta2, OmegaA, OmegaB,
CubicSuperAncillary::PR_CODE, Tc_K, pc_Pa, std::move(alphas), kmat.value_or(Eigen::ArrayXXd::Zero(N,N)), R_JmolK.value_or(
constants::R_CODATA2017));
336 std::valarray<double> Tc_K = spec.at(
"Tcrit / K"), pc_Pa = spec.at(
"pcrit / Pa"), acentric = spec.at(
"acentric");
337 Eigen::ArrayXXd kmat(0, 0);
338 if (spec.contains(
"kmat")){
347 std::valarray<double> Tc_K = spec.at(
"Tcrit / K"),
348 pc_Pa = spec.at(
"pcrit / Pa"),
349 acentric = spec.at(
"acentric");
352 std::optional<Eigen::ArrayXXd> kmat;
353 if (spec.contains(
"kmat")){
356 std::optional<double> R_JmolK;
357 if (spec.contains(
"R / J/mol/K")){
358 R_JmolK = spec.at(
"R / J/mol/K");
364 std::vector<AlphaFunctionOptions> alphas;
366 double Delta1, Delta2, OmegaA, OmegaB;
367 std::string kind =
"custom";
369 if (spec.at(
"type") ==
"PR" ){
370 Delta1 = 1+sqrt(2.0);
371 Delta2 = 1-sqrt(2.0);
373 OmegaA = 0.45723552892138218938;
374 OmegaB = 0.077796073903888455972;
376 kind =
"Peng-Robinson";
378 if (!spec.contains(
"alpha")){
379 for (
auto i = 0U; i < Tc_K.size(); ++i) {
381 if (acentric[i] < 0.491) {
382 mi = 0.37464 + 1.54226*acentric[i] - 0.26992*
pow2(acentric[i]);
385 mi = 0.379642 + 1.48503*acentric[i] -0.164423*
pow2(acentric[i]) + 0.016666*
pow3(acentric[i]);
391 if (!spec[
"alpha"].is_array()){
397 else if (spec.at(
"type") ==
"SRK"){
400 if (!spec.contains(
"alpha")){
401 for (
auto i = 0U; i < Tc_K.size(); ++i) {
402 double mi = 0.48 + 1.574 * acentric[i] - 0.176 * acentric[i] * acentric[i];
407 if (!spec[
"alpha"].is_array()){
413 OmegaA = 1.0 / (9.0 * (cbrt(2) - 1));
414 OmegaB = (cbrt(2) - 1) / 3;
416 kind =
"Soave-Redlich-Kwong";
420 throw teqp::InvalidArgument(
"Generic cubic EOS are not yet supported (open an issue on github if you want this)");
423 const std::size_t N = Tc_K.size();
424 nlohmann::json meta = {
432 if (spec.contains(
"alpha")){
433 meta[
"alpha"] = spec.at(
"alpha");
436 auto cub =
GenericCubic(Delta1, Delta2, OmegaA, OmegaB, superanc_code, Tc_K, pc_Pa, std::move(alphas), kmat.value_or(Eigen::ArrayXXd::Zero(N,N)), R_JmolK.value_or(
constants::R_CODATA2017));
449struct AdvancedPRaEOptions{
452 double CEoS = -sqrt(2.0)/2.0*log(1.0 + sqrt(2.0));
456inline void from_json(
const json& j, AdvancedPRaEOptions& o) {
457 j.at(
"brule").get_to(o.brule);
458 j.at(
"s").get_to(o.s);
459 j.at(
"CEoS").get_to(o.CEoS);
460 if (j.contains(
"R / J/mol/K")){
461 o.R_JmolK = j.at(
"R / J/mol/K");
469template <
typename NumType,
typename AlphaFunctions = std::vector<AlphaFunctionOptions>>
476 const NumType
OmegaA = 0.45723552892138218938;
477 const NumType
OmegaB = 0.077796073903888455972;
498 template<
typename TType,
typename IndexType>
499 auto get_ai(TType& T, IndexType i)
const {
500 auto alphai = std::visit([&](
auto& t) {
return t(T); },
alphas[i]);
504 template<
typename TType,
typename IndexType>
505 auto get_bi(TType& , IndexType i)
const {
return bi[i]; }
507 template<
typename IndexType>
510 throw teqp::InvalidArgument(
"lmat rows [" + std::to_string(
lmat.rows()) +
"] and columns [" + std::to_string(
lmat.cols()) +
"] are not identical");
512 if (
lmat.cols() == 0) {
515 else if (
lmat.cols() !=
static_cast<Eigen::Index
>(N)) {
516 throw teqp::InvalidArgument(
"lmat needs to be a square matrix the same size as the number of components [" + std::to_string(N) +
"]");
526 for (
auto i = 0U; i <
Tc_K.size(); ++i) {
540 const NumType
OmegaB = 0.077796073903888455972;
541 const NumType
R = 8.31446261815324;
549 auto superanc_rhoLV(
double T, std::optional<std::size_t> ifluid = std::nullopt)
const {
551 std::valarray<double> molefracs(
ai.size()); molefracs = 1.0;
558 if (ifluid.value() >
ai.size()-1){
562 molefracs[ifluid.value()] = 1.0;
565 auto b =
get_b(T, molefracs);
567 auto Ttilde =
R(molefracs)*T*b/a;
568 return std::make_tuple(
574 template<
class VecType>
575 auto R(
const VecType& )
const {
579 template<
typename TType,
typename CompType>
580 auto get_a(TType T,
const CompType& molefracs)
const {
584 template<
typename TType,
typename CompType>
586 auto aEresRT = std::visit([&](
auto& aresRTfunc) {
return aresRTfunc(T, molefracs); },
ares);
587 std::common_type_t<TType,
decltype(molefracs[0])> summer = aEresRT*
R_JmolK*T/
CEoS;
588 for (
auto i = 0U; i < molefracs.size(); ++i) {
594 template<
typename TType,
typename CompType>
595 auto get_b(TType T,
const CompType& molefracs)
const {
596 std::common_type_t<TType,
decltype(molefracs[0])> b_ = 0.0;
600 for (
auto i = 0U; i < molefracs.size(); ++i) {
602 for (
auto j = 0U; j < molefracs.size(); ++j) {
605 auto bij = (1 -
lmat(i,j)) *
pow((
pow(bi_, 1.0/
s) +
pow(bj_, 1.0/
s))/2.0,
s);
606 b_ += molefracs[i] * molefracs[j] * bij;
611 for (
auto i = 0U; i < molefracs.size(); ++i) {
612 b_ += molefracs[i] *
get_bi(T, i);
621 template<
typename TType,
typename RhoType,
typename MoleFracType>
624 const MoleFracType& molefrac)
const
626 if (
static_cast<std::size_t
>(molefrac.size()) !=
alphas.size()) {
627 throw std::invalid_argument(
"Sizes do not match");
629 auto b =
get_b(T, molefrac);
631 auto Psiminus = -log(1.0 - b * rho);
633 auto val = Psiminus - a / (
R_JmolK * T) * Psiplus;
640 std::valarray<double> Tc_K = j.at(
"Tcrit / K");
641 std::valarray<double> pc_Pa = j.at(
"pcrit / Pa");
647 std::string type = armodel.at(
"type");
648 if (type ==
"Wilson"){
649 std::vector<double> b;
650 for (
auto i = 0U; i < Tc_K.size(); ++i){
661 auto aresmodel = get_ares_model(j.at(
"aresmodel"));
663 AdvancedPRaEOptions options = j.at(
"options");
681 const std::vector<double> Tc_K, pc_Pa;
682 const std::vector<AlphaFunctionOptions> alphas;
683 const std::vector<double> As, Bs, cs_m3mol;
684 const Eigen::ArrayXXd kmat, lmat;
687 auto build_alphas(
const nlohmann::json& j){
688 std::vector<AlphaFunctionOptions> alphas_;
689 std::vector<double> L = j.at(
"Ls"), M = j.at(
"Ms"), N = j.at(
"Ns");
690 if (L.size() != M.size() || M.size() != N.size()){
693 for (
auto i = 0U; i < L.size(); ++i){
694 auto coeffs = (Eigen::Array3d() << L[i], M[i], N[i]).finished();
700 std::vector<double> get_(
const nlohmann::json &j,
const std::string& k)
const {
return j.at(k).get<std::vector<double>>(); }
703 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"))), Ru(j.value(
"R / J/mol/K", constants::R_CODATA2017)) {}
707 template<
class VecType>
708 auto R(
const VecType& )
const {
716 template<
typename TType>
717 auto get_bi(std::size_t i,
const TType& T)
const {
718 auto beta =
POW3(1.0 + As[i]/(T+Bs[i]))/
POW3(1.0+As[i]/(Tc_K[i]+Bs[i]));
720 auto b = 0.07780*Tc_K[i]*Ru/pc_Pa[i];
724 template<
typename TType>
725 auto get_ai(std::size_t i,
const TType& T)
const {
726 auto alphai =
forceeval(std::visit([&](
auto& t) {
return t(T); }, alphas[i]));
728 auto OmegaA = 0.45723552892138218938;
729 auto a = OmegaA*
POW2(Tc_K[i]*Ru)/pc_Pa[i];
733 template<
typename TType,
typename FractionsType>
734 auto get_ab(
const TType& T,
const FractionsType& z)
const{
735 using numtype = std::common_type_t<TType,
decltype(z[0])>;
738 std::size_t N = alphas.size();
739 for (
auto i = 0U; i < N; ++i){
742 for (
auto j = 0U; j < N; ++j){
745 b += z[i]*z[j]*(bi + bj)/2.0*(1.0 - lmat(i,j));
746 a += z[i]*z[j]*sqrt(ai*aj)*(1.0 - kmat(i,j));
749 return std::make_tuple(a, b);
751 template<
typename TType,
typename FractionsType>
752 auto get_c(
const TType& ,
const FractionsType& z)
const{
753 using numtype = std::common_type_t<TType,
decltype(z[0])>;
755 std::size_t N = alphas.size();
756 for (
auto i = 0U; i < N; ++i){
757 c += z[i]*cs_m3mol[i];
762 template<
typename TType,
typename RhoType,
typename FractionsType>
763 auto alphar(
const TType& T,
const RhoType& rhoinit,
const FractionsType& molefrac)
const {
764 if (
static_cast<std::size_t
>(molefrac.size()) != alphas.size()) {
765 throw std::invalid_argument(
"Sizes do not match");
768 auto c =
get_c(T, molefrac);
769 auto rho = 1.0/(1.0/rhoinit + c);
770 auto Delta1 = 1.0 + sqrt(2.0);
771 auto Delta2 = 1.0 - sqrt(2.0);
772 auto [a, b] =
get_ab(T, molefrac);
773 auto Psiminus = -log(1.0 - b * rho);
774 auto Psiplus = log((Delta1 * b * rho + 1.0) / (Delta2 * b * rho + 1.0)) / (b * (Delta1 - Delta2));
775 auto val = Psiminus - a / (Ru * T) * Psiplus;
784 auto superanc_rhoLV(
double T,
const std::optional<std::size_t> ifluid = std::nullopt)
const {
785 if (Tc_K.size() != 1) {
786 throw std::invalid_argument(
"function only available for pure species");
789 std::valarray<double> molefracs(Tc_K.size()); molefracs = 1.0;
795 if (ifluid.value() > Tc_K.size()-1){
799 molefracs[ifluid.value()] = 1.0;
802 auto [a, b] =
get_ab(T, molefracs);
803 auto Ttilde =
R(molefracs)*T*b/a;
805 return std::make_tuple(
826 const std::vector<double> delta_1, Tc_K, pc_Pa, k;
827 const Eigen::ArrayXXd kmat, lmat;
829 const std::vector<double> a_c, b_c;
832 std::vector<double> get_(
const nlohmann::json &j,
const std::string& key)
const {
return j.at(key).get<std::vector<double>>(); }
835 auto get_yd1(
double delta_1_){
836 return std::make_tuple(1 + cbrt(2*(1+delta_1_)) + cbrt(4/(1+delta_1_)), (1+delta_1_*delta_1_)/(1+delta_1_));
840 std::vector<double> a_c_(delta_1.size());
841 for (
auto i = 0U; i < delta_1.size(); ++i){
842 auto [y, d_1] = get_yd1(delta_1[i]);
843 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);
844 a_c_[i] = Omega_a*
pow(Ru*Tc_K[i], 2)/pc_Pa[i];
849 std::vector<double> b_c_(delta_1.size());
850 for (
auto i = 0U; i < delta_1.size(); ++i){
851 auto [y, d_1] = get_yd1(delta_1[i]);
852 auto Omega_b = 1.0/(3.0*y + d_1 - 1.0);
853 b_c_[i] = Omega_b*Ru*Tc_K[i]/pc_Pa[i];
859 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"))), Ru(j.value(
"R / J/mol/K", constants::R_CODATA2017)), a_c(build_ac()), b_c(build_bc()) {}
861 template<
class VecType>
862 auto R(
const VecType& )
const {
872 template<
typename TType>
873 auto get_bi(std::size_t i,
const TType& )
const {
877 template<
typename TType>
878 auto get_ai(std::size_t i,
const TType& T)
const {
879 return forceeval(a_c[i]*
pow(3.0/(2.0+T/Tc_K[i]), k[i]));
882 template<
typename TType,
typename FractionsType>
883 auto get_ab(
const TType& T,
const FractionsType& z)
const{
884 using numtype = std::common_type_t<TType,
decltype(z[0])>;
887 std::size_t N = delta_1.size();
888 for (
auto i = 0U; i < N; ++i){
891 for (
auto j = 0U; j < N; ++j){
895 a += z[i]*z[j]*sqrt(ai*aj)*(1.0 - kmat(i,j));
896 b += z[i]*z[j]*(bi + bj)/2.0*(1.0 - lmat(i,j));
900 return std::make_tuple(a, b);
903 template<
typename TType,
typename RhoType,
typename FractionsType>
904 auto alphar(
const TType& T,
const RhoType& rho,
const FractionsType& molefrac)
const {
905 if (
static_cast<std::size_t
>(molefrac.size()) != delta_1.size()) {
906 throw std::invalid_argument(
"Sizes do not match");
910 const auto delta_1_view = Eigen::Map<const Eigen::ArrayXd>(&(delta_1[0]), delta_1.size());
911 const decltype(molefrac[0]) Delta1 = (molefrac*delta_1_view).eval().sum();
913 auto Delta2 = (1.0-Delta1)/(1.0+Delta1);
914 auto [a, b] =
get_ab(T, molefrac);
916 auto Psiminus = -log(1.0 - b*rho);
917 auto Psiplus = log((Delta1 * b * rho + 1.0) / (Delta2 * b * rho + 1.0)) / (b * (Delta1 - Delta2));
918 auto val = Psiminus - a/(this->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
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
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, const double R_JmolK)
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
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
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 get_ai(std::size_t i, const TType &T) const
auto get_ab(const TType &T, const FractionsType &z) 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
auto superanc_rhoLV(double T, const std::optional< std::size_t > ifluid=std::nullopt) const
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)
std::variant< NullResidualHelmholtzOverRT< double >, WilsonResidualHelmholtzOverRT< double >, BinaryInvariantResidualHelmholtzOverRT< double >, COSMOSAC::COSMO3 > ResidualHelmholtzOverRTVariant
const double R_CODATA2017
molar gas constant from CODATA 2017: https://doi.org/10.1103/RevModPhys.84.1527
auto make_generalizedcubic(const nlohmann::json &spec)
A JSON-based factory function for the generalized cubic + alpha.
auto make_AdvancedPRaEres(const nlohmann::json &j)
void from_json(const json &j, AdvancedPRaEOptions &o)
decltype(make_AdvancedPRaEres({})) advancedPRaEres_t
auto canonical_PR(TCType Tc_K, PCType pc_Pa, AcentricType acentric, const std::optional< Eigen::ArrayXXd > &kmat=std::nullopt, const std::optional< double > R_JmolK=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< 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)
auto canonical_SRK(TCType Tc_K, PCType pc_Pa, AcentricType acentric, const std::optional< Eigen::ArrayXXd > &kmat=std::nullopt, const std::optional< double > R_JmolK=std::nullopt)