teqp 0.23.1
Loading...
Searching...
No Matches
multifluid_activity.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "teqp/types.hpp"
4
7
9
11
12template<typename M, typename T, typename U>
13concept CallableLnGammaResid = requires(M m, T t, U u) {
14 { m.calc_lngamma_resid(t,u) } -> std::same_as<Eigen::ArrayXd>;
15};
16template<typename M, typename T, typename U>
17concept CallableLnGammaComb = requires(M m, T t, U u) {
18 { m.calc_lngamma_comb(t,u) } -> std::same_as<Eigen::ArrayXd>;
19};
20
21static_assert(!CallableLnGammaResid<NullResidualHelmholtzOverRT<double>, double, Eigen::ArrayXd>);
22static_assert(!CallableLnGammaComb<NullResidualHelmholtzOverRT<double>, double, Eigen::ArrayXd>);
23
26
34private:
35 using multifluid_t = decltype(multifluidfactory(nlohmann::json{}));
36 const multifluid_t m_multifluid;
37 const ResidualHelmholtzOverRTVariant m_activity;
38 const std::vector<double> b;
39 const double u;
40public:
41 MultifluidPlusActivity(const nlohmann::json &spec) :
42 m_multifluid(multifluidfactory(spec.at("multifluid"))),
43 m_activity(ares_model_factory(spec.at("activity").at("aresmodel"))),
44 b(spec.at("activity").at("options").at("b").get<std::vector<double>>()),
45 u(spec.at("activity").at("options").at("u")){}
46
48 auto calc_gER_over_RT(double T, const Eigen::ArrayXd& molefrac) const {
49 return std::visit([T, &molefrac](const auto& mod){return mod(T, molefrac); }, m_activity);
50 }
51
52 auto calc_lngamma_resid(const double T, const Eigen::ArrayXd& molefrac) const {
53 return std::visit([T, &molefrac](const auto& mod) -> Eigen::ArrayXd {
54 if constexpr (CallableLnGammaResid<decltype(mod), decltype(T), decltype(molefrac)>){
55 return mod.calc_lngamma_resid(T, molefrac);
56 }
57 else{
58 throw teqp::NotImplementedError("this method is not implemented");
59 }
60 }, m_activity);
61 }
62
63 Eigen::ArrayXd calc_lngamma_comb(const double T, const Eigen::ArrayXd& molefrac) const {
64 return std::visit([T, &molefrac](const auto& mod) -> Eigen::ArrayXd{
65 if constexpr (CallableLnGammaComb<decltype(mod), decltype(T), decltype(molefrac)>){
66 return mod.calc_lngamma_comb(T, molefrac);
67 }
68 else{
69 throw teqp::NotImplementedError("this method is not implemented");
70 }
71 }, m_activity);
72 }
73
74 template<class VecType>
75 auto R(const VecType& molefrac) const {
77 }
78
79 template <typename TType, typename RhoType, typename MoleFractions>
80 auto alphar_activity(const TType& T, const RhoType& rho, const MoleFractions& molefrac) const {
81 auto gER_over_RT = std::visit([T, &molefrac](const auto& mod){return mod(T, molefrac); }, m_activity); // dimensionless
82 if (static_cast<long>(b.size()) != molefrac.size()){
83 throw teqp::InvalidArgument("Size of mole fractions is incorrect");
84 }
85
86 auto bm = contiguous_dotproduct(b, molefrac);
87
88 const auto& Tcvec = m_multifluid.redfunc.Tc;
89 const auto& vcvec = m_multifluid.redfunc.vc;
90
91 auto rhor = m_multifluid.redfunc.get_rhor(molefrac);
92 auto Tr = m_multifluid.redfunc.get_Tr(molefrac);
93 auto tau = forceeval(Tr/T);
94 auto delta_ref = forceeval(1.0/(u*bm*rhor));
95
96 std::decay_t<std::common_type_t<TType, decltype(molefrac[0])>> summer = 0.0;
97 for (auto i = 0; i < molefrac.size(); ++i){
98 auto delta_i_ref = forceeval(1.0/(u*b[i]/vcvec(i)));
99 auto tau_i = forceeval(Tcvec(i)/T);
100 summer += molefrac(i)*(m_multifluid.alphar_taudeltai(tau, delta_ref, i) - m_multifluid.alphar_taudeltai(tau_i, delta_i_ref, i));
101 }
102 return forceeval(log(1.0+rho*bm)/log(1.0+1.0/u)*(gER_over_RT - summer));
103 }
104
105 template <typename TType, typename RhoType, typename MoleFractions>
106 auto alphar(const TType& T, const RhoType& rho, const MoleFractions& molefrac) const {
107 return forceeval(
108 m_multifluid.alphar(T, rho, molefrac)
109 + alphar_activity(T, rho, molefrac)
110 );
111 }
112};
113
114}; // namespace teqp
Eigen::ArrayXd calc_lngamma_comb(const double T, const Eigen::ArrayXd &molefrac) const
Calculate the value of array from the AC model without any of the AD types.
auto calc_lngamma_resid(const double T, const Eigen::ArrayXd &molefrac) const
Calculate the value of array from the AC model without any of the AD types.
auto alphar(const TType &T, const RhoType &rho, const MoleFractions &molefrac) const
auto calc_gER_over_RT(double T, const Eigen::ArrayXd &molefrac) const
Calculate the dimensionless value of from the AC model.
auto alphar_activity(const TType &T, const RhoType &rho, const MoleFractions &molefrac) const
ResidualHelmholtzOverRTVariant ares_model_factory(const nlohmann::json &armodel)
std::variant< NullResidualHelmholtzOverRT< double >, WilsonResidualHelmholtzOverRT< double >, BinaryInvariantResidualHelmholtzOverRT< double >, COSMOSAC::COSMO3 > ResidualHelmholtzOverRTVariant
auto multifluidfactory(const nlohmann::json &spec)
Load a model from a JSON data structure.
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
auto contiguous_dotproduct(const auto &x, const auto &y)
Take the dot-product of two vector-like objects that have contiguous memory and support the ....
Definition types.hpp:235