15#include "nlohmann/json.hpp"
33struct AdvancedPRaEOptions{
36 double CEoS = -sqrt(2.0)/2.0*log(1.0 + sqrt(2.0));
40inline void from_json(
const json& j, AdvancedPRaEOptions& o) {
41 j.at(
"brule").get_to(o.brule);
42 j.at(
"s").get_to(o.s);
43 j.at(
"CEoS").get_to(o.CEoS);
44 if (j.contains(
"R / J/mol/K")){
45 o.R_JmolK = j.at(
"R / J/mol/K");
53template <
typename NumType,
typename AlphaFunctions = std::vector<AlphaFunctionOptions>>
60 const NumType
OmegaA = 0.45723552892138218938;
61 const NumType
OmegaB = 0.077796073903888455972;
69 std::valarray<NumType>
ai,
bi;
82 template<
typename TType,
typename IndexType>
83 auto get_ai(TType& T, IndexType i)
const {
84 auto alphai = std::visit([&](
auto& t) {
return t(T); },
alphas[i]);
88 template<
typename TType,
typename IndexType>
89 auto get_bi(TType& , IndexType i)
const {
return bi[i]; }
91 template<
typename IndexType>
94 throw teqp::InvalidArgument(
"lmat rows [" + std::to_string(
lmat.rows()) +
"] and columns [" + std::to_string(
lmat.cols()) +
"] are not identical");
96 if (
lmat.cols() == 0) {
99 else if (
lmat.cols() !=
static_cast<Eigen::Index
>(N)) {
100 throw teqp::InvalidArgument(
"lmat needs to be a square matrix the same size as the number of components [" + std::to_string(N) +
"]");
110 for (
auto i = 0U; i <
Tc_K.size(); ++i) {
124 const NumType
OmegaB = 0.077796073903888455972;
125 const NumType
R = 8.31446261815324;
133 auto superanc_rhoLV(
double T, std::optional<std::size_t> ifluid = std::nullopt)
const {
135 std::valarray<double> molefracs(
ai.size()); molefracs = 1.0;
142 if (ifluid.value() >
ai.size()-1){
146 molefracs[ifluid.value()] = 1.0;
149 auto b =
get_b(T, molefracs);
151 auto Ttilde =
R(molefracs)*T*b/a;
152 return std::make_tuple(
158 template<
class VecType>
159 auto R(
const VecType& )
const {
163 template<
typename TType,
typename CompType>
164 auto get_a(TType T,
const CompType& molefracs)
const {
168 template<
typename TType,
typename CompType>
170 auto aEresRT = std::visit([&](
auto& aresRTfunc) {
return aresRTfunc(T, molefracs); },
ares);
171 std::common_type_t<TType,
decltype(molefracs[0])> summer = aEresRT*
R_JmolK*T/
CEoS;
172 for (
auto i = 0U; i < molefracs.size(); ++i) {
178 template<
typename TType,
typename CompType>
179 auto get_b(TType T,
const CompType& molefracs)
const {
180 std::common_type_t<TType,
decltype(molefracs[0])> b_ = 0.0;
184 for (
auto i = 0U; i < molefracs.size(); ++i) {
186 for (
auto j = 0U; j < molefracs.size(); ++j) {
189 auto bij = (1 -
lmat(i,j)) *
pow((
pow(bi_, 1.0/
s) +
pow(bj_, 1.0/
s))/2.0,
s);
190 b_ += molefracs[i] * molefracs[j] * bij;
195 for (
auto i = 0U; i < molefracs.size(); ++i) {
196 b_ += molefracs[i] *
get_bi(T, i);
205 template<
typename TType,
typename RhoType,
typename MoleFracType>
208 const MoleFracType& molefrac)
const
210 if (
static_cast<std::size_t
>(molefrac.size()) !=
alphas.size()) {
211 throw std::invalid_argument(
"Sizes do not match");
213 auto b =
get_b(T, molefrac);
215 auto Psiminus = -log(1.0 - b * rho);
217 auto val = Psiminus - a / (
R_JmolK * T) * Psiplus;
224 std::valarray<double> Tc_K = j.at(
"Tcrit / K");
225 std::valarray<double> pc_Pa = j.at(
"pcrit / Pa");
231 std::string type = armodel.at(
"type");
232 if (type ==
"Wilson"){
233 std::vector<double> b;
234 for (
auto i = 0U; i < Tc_K.size(); ++i){
245 auto aresmodel = get_ares_model(j.at(
"aresmodel"));
247 AdvancedPRaEOptions options = j.at(
"options");
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
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_AdvancedPRaEres(const nlohmann::json &j)
void from_json(const json &j, AdvancedPRaEOptions &o)
decltype(make_AdvancedPRaEres({})) advancedPRaEres_t
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)