teqp 0.22.0
Loading...
Searching...
No Matches
softsaft.hpp
Go to the documentation of this file.
1#pragma once
2
4#include "teqp/types.hpp"
5#include "teqp/constants.hpp"
6
8
9namespace detail{
10
11 const std::valarray<std::valarray<double>> aij_Johnson = {
12 {},
13 {0, 0.49304346593882, 2.1528349894745 ,-15.955682329017, 24.035999666294 , -8.6437958513990},
14 {0,-0.47031983115362, 1.1471647487376 , 37.889828024211, -84.667121491179 , 39.643914108411},
15 {0, 5.0325486243620 ,-25.915399226419 ,-18.862251310090, 107.63707381726 ,-66.602649735720},
16 {0,-7.3633150434385 , 51.553565337453 ,-40.519369256098, -38.796692647218 , 44.605139198378},
17 {0, 2.9043607296043 ,-24.478812869291 , 31.500186765040, -5.3368920371407, -9.5183440180133}
18 };
19
20 template<typename TType, typename RhoType>
21 auto g_LJ(const TType& Tstar, const RhoType& rhostar_monomer){
22 std::common_type_t<TType, RhoType> summer = 1.0;
23 for (auto i = 1; i < 6; ++i){
24 for (auto j = 1; j < 6; ++j){
25 summer += aij_Johnson[i][j]*powi(rhostar_monomer,i)*powi(Tstar, 1-j);
26 }
27 }
28 return summer;
29 }
30}
31
33public:
34 Eigen::ArrayXd m, epsilon_over_k, sigma_m, sigma_m3;
36 Eigen::ArrayXd toEig(const std::vector<double>&x){ return Eigen::Map<const Eigen::ArrayXd>(&x[0], x.size()); }
37
38 SoftSAFT(const Eigen::ArrayXd&m, const Eigen::ArrayXd&epsilon_over_k, const Eigen::ArrayXd&sigma_m) : m(m), epsilon_over_k(epsilon_over_k), sigma_m(sigma_m), sigma_m3(sigma_m.pow(3)) {}
39
40 SoftSAFT(const nlohmann::json& j) : SoftSAFT(toEig(j.at("m")), toEig(j.at("epsilon/kB / K")), toEig(j.at("sigma / m"))) {}
41
42 template<class VecType>
43 auto R(const VecType& molefrac) const {
45 }
46
47 // The mixture is assumed to be formed of homosegmented constituents
48 template <typename TType, typename RhoType, typename MoleFracType>
49 auto alphar(const TType& T, const RhoType& rhomolar, const MoleFracType& molefracs) const{
50 using resulttype = std::decay_t<std::common_type_t<TType,RhoType,decltype(molefracs[0])>>;
51
52 std::size_t N = molefracs.size();
53 auto get_sigma3 = [this](std::size_t i, std::size_t j){
54 double x = (sigma_m[i] + sigma_m[j])/2;
55 return x*x*x;
56 };
57 auto get_epsilon_over_k = [this](std::size_t i, std::size_t j){
58 return sqrt(epsilon_over_k[i]*epsilon_over_k[j]);
59 };
60
61 // Use of vdW-1f rule to get the effective sigma and epsilon/k of the mixture
62 std::decay_t<decltype(molefracs[0])> num1 = 0.0, num2 = 0.0, den = 0.0, m_mix = 0.0;
63 for (auto i = 0U; i < N; ++i){
64 m_mix += m[i]*molefracs[i];
65 for (auto j = 0U; j < N; ++j){
66 auto denentry = m[i]*m[j]*molefracs[i]*molefracs[j];
67 auto num1entry = denentry*get_sigma3(i, j);
68 auto num2entry = num1entry*get_epsilon_over_k(i, j);
69 num1 += num1entry;
70 num2 += num2entry;
71 den += denentry;
72 }
73 }
74 auto sigmamix3 = num1/den;
75 auto epskmix = num2/den/sigmamix3;
76
77 auto rhoN_monomer = rhomolar*m_mix*N_A; // Effective number density of segments (monomers per volume)
78
79 auto Tstar_eff = forceeval(T/epskmix);
80 auto rhostar_monomer_eff = forceeval(rhoN_monomer*sigmamix3);
81
82 // Evaluate the contribution for the monomer based on
83 // reduced temperature & density from vdW-1f mixing rules
84 resulttype alphar_ref = m_mix*Johnson.alphar(Tstar_eff, rhostar_monomer_eff, Eigen::ArrayXd{0});
85
86 // Evaluate the contribution for the chain
87 resulttype alphar_chain = 0.0;
88
89 // This is as in Blas (I think, some subtleties are maybe a bit different)
90// for (auto i = 0; i < N; ++i){
91// auto rhostar_monomer_i = rhomolar_monomer*sigma_m3[i];
92// alphar_chain += molefracs[i]*(1-m[i])*log(detail::g_LJ(Tstar_eff, rhostar_monomer_i));
93// }
94
95 // This is as in Ghonasgi and Chapman, use the bulk effective monomer density
96 alphar_chain = (1.0-m_mix)*log(detail::g_LJ(Tstar_eff, rhostar_monomer_eff));
97
98 return forceeval(alphar_ref + alphar_chain);
99 }
100};
101
102}
auto alphar(const TTYPE &Tstar, const RHOTYPE &rhostar, const MoleFracType &) const
Definition johnson.hpp:274
auto alphar(const TType &T, const RhoType &rhomolar, const MoleFracType &molefracs) const
Definition softsaft.hpp:49
SoftSAFT(const nlohmann::json &j)
Definition softsaft.hpp:40
auto R(const VecType &molefrac) const
Definition softsaft.hpp:43
Eigen::ArrayXd toEig(const std::vector< double > &x)
Definition softsaft.hpp:36
SoftSAFT(const Eigen::ArrayXd &m, const Eigen::ArrayXd &epsilon_over_k, const Eigen::ArrayXd &sigma_m)
Definition softsaft.hpp:38
mie::lennardjones::Johnson::LJ126Johnson1993 Johnson
Definition softsaft.hpp:35
const std::valarray< std::valarray< double > > aij_Johnson
Definition softsaft.hpp:11
auto g_LJ(const TType &Tstar, const RhoType &rhostar_monomer)
Definition softsaft.hpp:21
T powi(const T &x, int n)
From Ulrich Deiters.
Definition types.hpp:139
auto pow(const double &x, const double &e)
Definition types.hpp:195
auto forceeval(T &&expr)
Definition types.hpp:52
auto get_R_gas()
< Gas constant, according to CODATA 2019, in the given number type
Definition constants.hpp:22