3#if defined(TEQP_COMPLEXSTEP_ENABLED)
14#if defined(TEQP_MULTICOMPLEX_ENABLED)
15#include "MultiComplex/MultiComplex.hpp"
19#include <autodiff/forward/dual.hpp>
20#include <autodiff/forward/dual/eigen.hpp>
21#include <autodiff/forward/real.hpp>
22#include <autodiff/forward/real/eigen.hpp>
32template <
typename TType,
typename ContainerType,
typename FuncType>
33typename ContainerType::value_type
derivT(
const FuncType& f, TType T,
const ContainerType& rho) {
35 return f(std::complex<TType>(T, h), rho).imag() / h;
38#if defined(TEQP_MULTICOMPLEX_ENABLED)
43template <
typename TType,
typename ContainerType,
typename FuncType>
44typename ContainerType::value_type derivTmcx(
const FuncType& f, TType T,
const ContainerType& rho) {
45 using fcn_t = std::function<mcx::MultiComplex<double>(
const mcx::MultiComplex<double>&)>;
46 fcn_t wrapper = [&rho, &f](
const auto& T_) {
return f(T_, rho); };
47 auto ders = diff_mcx1(wrapper, T, 1);
56template <
typename TType,
typename ContainerType,
typename FuncType,
typename Integer>
57typename ContainerType::value_type
derivrhoi(
const FuncType& f, TType T,
const ContainerType& rho, Integer i) {
59 using comtype = std::complex<typename ContainerType::value_type>;
60 Eigen::ArrayX<comtype> rhocom(rho.size());
61 for (
auto j = 0; j < rho.size(); ++j) {
62 rhocom[j] = comtype(rho[j], 0.0);
64 rhocom[i] = comtype(rho[i], h);
65 return f(T, rhocom).imag() / h;
70template<
typename T,
size_t ... I>
72 return std::make_tuple((
static_cast<void>(I), val)...);
76template<
int N,
typename T>
85 template<
typename... Args>
88 return Wrt<Args&&...>{ std::forward_as_tuple(std::forward<Args>(args)...) };
93#if defined(TEQP_MULTICOMPLEX_ENABLED)
96#if defined(TEQP_COMPLEXSTEP_ENABLED)
101template<
typename T,
typename U,
typename V,
typename W>
106template<
typename T,
typename U,
typename V,
typename W>
111template<
typename T,
typename U,
typename V,
typename W>
113 { t.alphar_taudelta(u,v,w) };
116template<
typename Model,
typename Scalar =
double,
typename VectorType = Eigen::ArrayXd>
119 static auto get_Ar00(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
120 return model.alphar(T, rho, molefrac);
123 template<
typename AlphaWrapper,
typename S1,
typename S2,
typename Vec>
125 return w.alpha(T, rho, molefrac);
127 template<
typename AlphaWrapper,
typename S1,
typename S2,
typename Vec>
129 return w.alphar(T, rho, molefrac);
132 template<
typename AlphaWrapper,
typename S1,
typename S2,
typename Vec>
134 return w.alphar_taudelta(T, rho, molefrac);
136 template<
typename AlphaWrapper,
typename S1,
typename S2,
typename Vec>
139 return std::common_type_t<S1, S2, decltype(molefrac[0])>(1e99);
150 template<
int iT,
int iD, ADBackends be = ADBackends::autodiff,
class AlphaWrapper>
151 static auto get_Agenxy(
const AlphaWrapper& w,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
153 if constexpr (iT == 0 && iD == 0){
156 else if constexpr (iT == 0 && iD > 0) {
159 autodiff::Real<iD, Scalar> rho_ = rho;
160 auto f = [&w, &T, &molefrac](
const auto& rho__) {
return AlphaCaller(w, T, rho__, molefrac); };
161 return powi(rho, iD)*derivatives(f, along(1), at(rho_))[iD];
163#if defined(TEQP_COMPLEXSTEP_ENABLED)
164 else if constexpr (iD == 1 && be == ADBackends::complex_step) {
166 auto rho_ = std::complex<Scalar>(rho, h);
170#if defined(TEQP_MULTICOMPLEX_ENABLED)
171 else if constexpr (be == ADBackends::multicomplex) {
172 using fcn_t = std::function<mcx::MultiComplex<Scalar>(
const mcx::MultiComplex<Scalar>&)>;
173 fcn_t f = [&](
const auto& rhomcx) {
return AlphaCaller(w, T, rhomcx, molefrac); };
174 auto ders = diff_mcx1(f, rho, iD,
true );
175 return powi(rho, iD)*ders[iD];
179 throw std::invalid_argument(
"algorithmic differentiation backend is invalid in get_Agenxy for iT == 0");
182 else if constexpr (iT > 0 && iD == 0) {
183 Scalar Trecip = 1.0 / T;
186 autodiff::Real<iT, Scalar> Trecipad = Trecip;
187 auto f = [&w, &rho, &molefrac](
const auto& Trecip__) {
return AlphaCaller(w,
forceeval(1.0/Trecip__), rho, molefrac); };
188 return powi(Trecip, iT)*derivatives(f, along(1), at(Trecipad))[iT];
190#if defined(TEQP_COMPLEXSTEP_ENABLED)
191 else if constexpr (iT == 1 && be == ADBackends::complex_step) {
193 auto Trecipcsd = std::complex<Scalar>(Trecip, h);
194 return powi(Trecip, iT)* w.alpha(1/Trecipcsd, rho, molefrac).imag()/h;
197#if defined(TEQP_MULTICOMPLEX_ENABLED)
198 else if constexpr (be == ADBackends::multicomplex) {
199 using fcn_t = std::function<mcx::MultiComplex<Scalar>(
const mcx::MultiComplex<Scalar>&)>;
200 fcn_t f = [&](
const auto& Trecipmcx) {
return AlphaCaller(w, 1.0/Trecipmcx, rho, molefrac); };
201 auto ders = diff_mcx1(f, Trecip, iT,
true );
202 return powi(Trecip, iT)*ders[iT];
206 throw std::invalid_argument(
"algorithmic differentiation backend is invalid in get_Agenxy for iD == 0");
211 using adtype = autodiff::HigherOrderDual<iT + iD, double>;
212 adtype Trecipad = 1.0 / T, rhoad = rho;
213 auto f = [&w, &molefrac](
const adtype& Trecip,
const adtype& rho_) {
214 adtype T_ = 1.0/Trecip;
217 auto der = derivatives(f, std::apply(
wrt_helper(), wrts), at(Trecipad, rhoad));
220#if defined(TEQP_MULTICOMPLEX_ENABLED)
221 else if constexpr (be == ADBackends::multicomplex) {
222 using fcn_t = std::function< mcx::MultiComplex<double>(
const std::valarray<mcx::MultiComplex<double>>&)>;
223 const fcn_t func = [&w, &molefrac](
const auto& zs) {
224 auto Trecip = zs[0], rhomolar = zs[1];
225 return AlphaCaller(w, 1.0 / Trecip, rhomolar, molefrac);
227 std::vector<double> xs = { 1.0 / T, rho};
228 std::vector<int> order = { iT, iD };
229 auto der = mcx::diff_mcxN(func, xs, order);
230 return powi(1.0 / T, iT)*
powi(rho, iD)*der;
234 throw std::invalid_argument(
"algorithmic differentiation backend is invalid in get_Agenxy for iD > 0 and iT > 0");
247 template<
int iT,
int iD,
int iXi,
typename AlphaWrapper>
248 static auto get_ATrhoXi(
const AlphaWrapper& w,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac,
int i){
249 using adtype = autodiff::HigherOrderDual<iT + iD + iXi, double>;
250 adtype Trecipad = 1.0 / T, rhoad = rho, xi = molefrac[i];
251 auto f = [&w, &molefrac, &i](
const adtype& Trecip,
const adtype& rho_,
const adtype& xi_) {
252 adtype T_ = 1.0/Trecip;
253 Eigen::ArrayX<adtype> molefracdual = molefrac.template cast<adtype>();
254 molefracdual[i] = xi_;
257 auto der = derivatives(f, std::apply(
wrt_helper(), wrts), at(Trecipad, rhoad, xi));
261 #define get_ATrhoXi_runtime_combinations \
286 template<
typename AlphaWrapper>
287 static auto get_ATrhoXi_runtime(
const AlphaWrapper& w,
const Scalar& T,
int iT,
const Scalar& rho,
int iD,
const VectorType& molefrac,
int i,
int iXi){
288 #define X(a,b,c) if (iT == a && iD == b && iXi == c) { return get_ATrhoXi<a,b,c>(w, T, rho, molefrac, i); }
294 #define get_ATrhoXiXj_runtime_combinations \
311 template<
typename AlphaWrapper>
312 static auto get_ATrhoXiXj_runtime(
const AlphaWrapper& w,
const Scalar& T,
int iT,
const Scalar& rho,
int iD,
const VectorType& molefrac,
int i,
int iXi,
int j,
int iXj){
313 #define X(a,b,c,d) if (iT == a && iD == b && iXi == c && iXj == d) { return get_ATrhoXiXj<a,b,c,d>(w, T, rho, molefrac, i, j); }
319 #define get_ATrhoXiXjXk_runtime_combinations \
333 template<
typename AlphaWrapper>
334 static auto get_ATrhoXiXjXk_runtime(
const AlphaWrapper& w,
const Scalar& T,
int iT,
const Scalar& rho,
int iD,
const VectorType& molefrac,
int i,
int iXi,
int j,
int iXj,
int k,
int iXk){
335 #define X(a,b,c,d,e) if (iT == a && iD == b && iXi == c && iXj == d && iXk == e) { return get_ATrhoXiXjXk<a,b,c,d,e>(w, T, rho, molefrac, i, j, k); }
341 template<
int iT,
int iD,
int iXi,
typename AlphaWrapper>
342 static auto get_AtaudeltaXi(
const AlphaWrapper& w,
const Scalar& tau,
const Scalar& delta,
const VectorType& molefrac,
const int i) {
343 using adtype = autodiff::HigherOrderDual<iT + iD + iXi, double>;
344 adtype tauad = tau, deltaad = delta, xi = molefrac[i];
345 auto f = [&w, &molefrac, &i](
const adtype& tau_,
const adtype& delta_,
const adtype& xi_) {
346 Eigen::ArrayX<adtype> molefracdual = molefrac.template cast<adtype>();
347 molefracdual[i] = xi_;
350 auto der = derivatives(f, std::apply(
wrt_helper(), wrts), at(tauad, deltaad, xi));
351 return powi(tau, iT) *
powi(delta, iD) * der[der.size() - 1];
354 template<
int iT,
int iD,
int iXi,
int iXj,
typename AlphaWrapper>
355 static auto get_AtaudeltaXiXj(
const AlphaWrapper& w,
const Scalar& tau,
const Scalar& delta,
const VectorType& molefrac,
const int i,
const int j) {
356 using adtype = autodiff::HigherOrderDual<iT + iD + iXi + iXj, double>;
360 adtype tauad = tau, deltaad = delta, xi = molefrac[i], xj = molefrac[j];
361 auto f = [&w, &molefrac, i, j](
const adtype& tau_,
const adtype& delta_,
const adtype& xi_,
const adtype& xj_) {
362 Eigen::ArrayX<adtype> molefracdual = molefrac.template cast<adtype>();
363 molefracdual[i] = xi_;
364 molefracdual[j] = xj_;
367 auto der = derivatives(f, std::apply(
wrt_helper(), wrts), at(tauad, deltaad, xi, xj));
368 return powi(tau, iT) *
powi(delta, iD) * der[der.size() - 1];
371 template<
int iT,
int iD,
int iXi,
int iXj,
int iXk,
typename AlphaWrapper>
372 static auto get_AtaudeltaXiXjXk(
const AlphaWrapper& w,
const Scalar& tau,
const Scalar& delta,
const VectorType& molefrac,
const int i,
const int j,
const int k) {
373 using adtype = autodiff::HigherOrderDual<iT + iD + iXi + iXj + iXk, double>;
374 if (i == j || j == k || i == k){
377 adtype tauad = tau, deltaad = delta, xi = molefrac[i], xj = molefrac[j], xk = molefrac[k];
378 auto f = [&w, &molefrac, i, j, k](
const adtype& tau_,
const adtype& delta_,
const adtype& xi_,
const adtype& xj_,
const adtype& xk_) {
379 Eigen::ArrayX<adtype> molefracdual = molefrac.template cast<adtype>();
380 molefracdual[i] = xi_;
381 molefracdual[j] = xj_;
382 molefracdual[k] = xk_;
385 auto der = derivatives(f, std::apply(
wrt_helper(), wrts), at(tauad, deltaad, xi, xj, xk));
386 return powi(tau, iT) *
powi(delta, iD) * der[der.size() - 1];
389 template<
typename AlphaWrapper>
390 static auto get_AtaudeltaXi_runtime(
const AlphaWrapper& w,
const Scalar& tau,
const int iT,
const Scalar& delta,
const int iD,
const VectorType& molefrac,
const int i,
const int iXi){
391 if (iT == 0 && iD == 0 && iXi == 0){
394 #define X(a,b,c) if (iT == a && iD == b && iXi == c) { return get_AtaudeltaXi<a,b,c>(w, tau, delta, molefrac, i); }
400 template<
typename AlphaWrapper>
401 static auto get_AtaudeltaXiXj_runtime(
const AlphaWrapper& w,
const Scalar& tau,
const int iT,
const Scalar& delta,
const int iD,
const VectorType& molefrac,
const int i,
const int iXi,
const int j,
const int iXj){
402 #define X(a,b,c,d) if (iT == a && iD == b && iXi == c && iXj == d) { return get_AtaudeltaXiXj<a,b,c,d>(w, tau, delta, molefrac, i, j); }
408 template<
typename AlphaWrapper>
409 static auto get_AtaudeltaXiXjXk_runtime(
const AlphaWrapper& w,
const Scalar& tau,
const int iT,
const Scalar& delta,
const int iD,
const VectorType& molefrac,
const int i,
int iXi,
const int j,
const int iXj,
const int k,
const int iXk){
410 #define X(a,b,c,d,e) if (iT == a && iD == b && iXi == c && iXj == d && iXk == e) { return get_AtaudeltaXiXjXk<a,b,c,d,e>(w, tau, delta, molefrac, i, j, k); }
423 template<
int iT,
int iD,
int iXi,
int iXj,
typename AlphaWrapper>
424 static auto get_ATrhoXiXj(
const AlphaWrapper& w,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac,
int i,
int j){
428 using adtype = autodiff::HigherOrderDual<iT + iD + iXi + iXj, double>;
429 adtype Trecipad = 1.0 / T, rhoad = rho, xi = molefrac[i], xj = molefrac[j];
430 auto f = [&w, &molefrac, i, j](
const adtype& Trecip,
const adtype& rho_,
const adtype& xi_,
const adtype& xj_) {
431 adtype T_ = 1.0/Trecip;
432 Eigen::ArrayX<adtype> molefracdual = molefrac.template cast<adtype>();
433 molefracdual[i] = xi_;
434 molefracdual[j] = xj_;
437 auto der = derivatives(f, std::apply(
wrt_helper(), wrts), at(Trecipad, rhoad, xi, xj));
448 template<
int iT,
int iD,
int iXi,
int iXj,
int iXk,
typename AlphaWrapper>
449 static auto get_ATrhoXiXjXk(
const AlphaWrapper& w,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac,
int i,
int j,
int k){
450 if (i == j || j == k || i == k){
453 using adtype = autodiff::HigherOrderDual<iT + iD + iXi + iXj + iXk, double>;
454 adtype Trecipad = 1.0 / T, rhoad = rho, xi = molefrac[i], xj = molefrac[j], xk = molefrac[k];
455 auto f = [&w, &molefrac, i, j, k](
const adtype& Trecip,
const adtype& rho_,
const adtype& xi_,
const adtype& xj_,
const adtype& xk_) {
456 adtype T_ = 1.0/Trecip;
457 Eigen::ArrayX<adtype> molefracdual = molefrac.template cast<adtype>();
458 molefracdual[i] = xi_;
459 molefracdual[j] = xj_;
460 molefracdual[k] = xk_;
463 auto der = derivatives(f, std::apply(
wrt_helper(), wrts), at(Trecipad, rhoad, xi, xj, xk));
475 template<
int iT,
int iD, ADBackends be = ADBackends::autodiff>
476 static auto get_Arxy(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
488 template<
int iT,
int iD, ADBackends be = ADBackends::autodiff>
489 static auto get_Aigxy(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
493 template<ADBackends be = ADBackends::autodiff>
494 static auto get_Ar10(
const Model& model,
const Scalar &T,
const Scalar &rho,
const VectorType& molefrac) {
498 template<ADBackends be = ADBackends::autodiff>
499 static Scalar
get_Ar01(
const Model& model,
const Scalar&T,
const Scalar &rho,
const VectorType& molefrac){
503 template<ADBackends be = ADBackends::autodiff>
504 static auto get_Ar02(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
508 template<ADBackends be = ADBackends::autodiff>
509 static auto get_Ar03(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
513 template<ADBackends be = ADBackends::autodiff>
514 static auto get_Ar20(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
518 template<ADBackends be = ADBackends::autodiff>
519 static auto get_Ar30(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
523 template<ADBackends be = ADBackends::autodiff>
524 static auto get_Ar21(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
528 template<ADBackends be = ADBackends::autodiff>
529 static auto get_Ar12(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
533 template<ADBackends be = ADBackends::autodiff>
534 static auto get_Ar11(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
538 template<ADBackends be = ADBackends::autodiff>
539 static auto get_Aig11(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
543 template<
int Nderiv, ADBackends be = ADBackends::autodiff,
class AlphaWrapper>
544 static auto get_Agen0n(
const AlphaWrapper& w,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
545 std::valarray<Scalar> o(Nderiv+1);
548 autodiff::Real<Nderiv, Scalar> rho_ = rho;
549 auto f = [&w, &T, &molefrac](
const auto& rho__) {
return AlphaCaller(w, T, rho__, molefrac); };
550 auto ders = derivatives(f, along(1), at(rho_));
551 for (
auto n = 0; n <= Nderiv; ++n) {
556#if defined(TEQP_MULTICOMPLEX_ENABLED)
558 using fcn_t = std::function<mcx::MultiComplex<Scalar>(
const mcx::MultiComplex<Scalar>&)>;
560 fcn_t f = [&w, &T, &molefrac](
const auto& rhomcx) {
return AlphaCaller(w, T, rhomcx, molefrac); };
561 auto ders = diff_mcx1(f, rho, Nderiv, and_val);
562 for (
auto n = 0; n <= Nderiv; ++n) {
563 o[n] =
powi(rho, n) * ders[n];
571 template<
int Nderiv, ADBackends be = ADBackends::autodiff,
class AlphaWrapper>
572 static auto get_Agenn0(
const AlphaWrapper& w,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
573 std::valarray<Scalar> o(Nderiv+1);
574 Scalar Trecip = 1.0 / T;
577 autodiff::Real<Nderiv, Scalar> Trecipad = Trecip;
578 auto f = [&w, &rho, &molefrac](
const auto& Trecip__) {
return AlphaCaller(w,
forceeval(1.0/Trecip__), rho, molefrac); };
579 auto ders = derivatives(f, along(1), at(Trecipad));
580 for (
auto n = 0; n <= Nderiv; ++n) {
581 o[n] =
powi(Trecip, n) * ders[n];
584#if defined(TEQP_MULTICOMPLEX_ENABLED)
585 else if constexpr (be == ADBackends::multicomplex) {
586 using fcn_t = std::function<mcx::MultiComplex<Scalar>(
const mcx::MultiComplex<Scalar>&)>;
587 fcn_t f = [&](
const auto& Trecipmcx) {
return AlphaCaller(w, 1.0/Trecipmcx, rho, molefrac); };
588 auto ders = diff_mcx1(f, Trecip, Nderiv+1,
true );
589 for (
auto n = 0; n <= Nderiv; ++n) {
590 o[n] =
powi(Trecip, n) * ders[n];
595 throw std::invalid_argument(
"algorithmic differentiation backend is invalid in get_Agenn0");
608 template<
int iT, ADBackends be = ADBackends::autodiff>
609 static auto get_Arn0(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
621 template<
int iD, ADBackends be = ADBackends::autodiff>
622 static auto get_Ar0n(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
627 template<ADBackends be = ADBackends::autodiff>
628 static auto get_Ar(
const int itau,
const int idelta,
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
631 return get_Ar00(model, T, rho, molefrac);
633 else if (idelta == 1) {
634 return get_Ar01(model, T, rho, molefrac);
636 else if (idelta == 2) {
637 return get_Ar02(model, T, rho, molefrac);
639 else if (idelta == 3) {
640 return get_Ar03(model, T, rho, molefrac);
643 throw std::invalid_argument(
"Invalid value for idelta");
648 return get_Ar10(model, T, rho, molefrac);
650 else if (idelta == 1) {
651 return get_Ar11(model, T, rho, molefrac);
653 else if (idelta == 2) {
654 return get_Ar12(model, T, rho, molefrac);
657 throw std::invalid_argument(
"Invalid value for idelta");
660 else if (itau == 2) {
662 return get_Ar20(model, T, rho, molefrac);
664 else if (idelta == 1) {
665 return get_Ar21(model, T, rho, molefrac);
668 throw std::invalid_argument(
"Invalid value for idelta");
671 else if (itau == 3) {
673 return get_Ar30(model, T, rho, molefrac);
676 throw std::invalid_argument(
"Invalid value for idelta");
680 throw std::invalid_argument(
"Invalid value for itau");
684 template<ADBackends be = ADBackends::autodiff>
685 static auto get_neff(
const Model& model,
const Scalar& T,
const Scalar& rho,
const VectorType& molefrac) {
689 return -3*(Ar01-Ar11)/Ar20;
693template<
typename Model,
typename Scalar =
double,
typename VectorType = Eigen::ArrayXd>
696 static auto get_B2vir(
const Model& model,
const Scalar &T,
const VectorType& molefrac) {
699 auto B2 = model.alphar(T, std::complex<Scalar>(0.0, h), molefrac).imag()/h;
713 template <
int Nderiv, ADBackends be = ADBackends::autodiff>
714 static auto get_Bnvir(
const Model& model,
const Scalar &T,
const VectorType& molefrac)
716 std::map<int, double> dnalphardrhon;
718 auto f = [&model, &T, &molefrac](
const auto& rho_) {
return model.alphar(T, rho_, molefrac); };
719 autodiff::Real<Nderiv, Scalar> rhoreal = 0.0;
720 auto derivs = derivatives(f, along(1), at(rhoreal));
722 for (
auto n = 1; n < Nderiv; ++n){
723 dnalphardrhon[n] = derivs[n];
726#if defined(TEQP_MULTICOMPLEX_ENABLED)
727 else if constexpr(be == ADBackends::multicomplex){
729 using fcn_t = std::function<MultiComplex<double>(
const MultiComplex<double>&)>;
730 fcn_t f = [&model, &T, &molefrac](
const auto& rho_) {
return model.alphar(T, rho_, molefrac); };
731 auto derivs = diff_mcx1(f, 0.0, Nderiv,
true );
732 for (
auto n = 1; n < Nderiv; ++n){
733 dnalphardrhon[n] = derivs[n];
739 throw std::invalid_argument(
"algorithmic differentiation backend is invalid in get_Bnvir");
742 std::map<int, Scalar> o;
743 for (
int n = 2; n <= Nderiv; ++n) {
744 o[n] = dnalphardrhon[n-1];
747 auto factorial = [](
int N) {
return tgamma(N + 1); };
748 o[n] /= factorial(n-2);
756 template <ADBackends be = ADBackends::autodiff>
757 static auto get_Bnvir_runtime(
const int Nderiv,
const Model& model,
const Scalar &T,
const VectorType& molefrac) {
767 default:
throw std::invalid_argument(
"Only Nderiv up to 9 is supported, get_Bnvir templated function allows more");
783 template <
int Nderiv,
int NTderiv, ADBackends be = ADBackends::autodiff>
784 static auto get_dmBnvirdTm(
const Model& model,
const Scalar& T,
const VectorType& molefrac)
786 std::map<int, Scalar> o;
787 auto factorial = [](
int N) {
return tgamma(N + 1); };
789 autodiff::HigherOrderDual<NTderiv + Nderiv-1,
double> rhodual = 0.0, Tdual = T;
790 auto f = [&model, &molefrac](
const auto& T_,
const auto& rho_) {
return model.alphar(T_, rho_, molefrac); };
792 auto derivs = derivatives(f, std::apply(
wrt_helper(), wrts), at(Tdual, rhodual));
793 return derivs.back() / factorial(Nderiv - 2);
795#if defined(TEQP_MULTICOMPLEX_ENABLED)
796 else if constexpr (be == ADBackends::multicomplex) {
798 using fcn_t = std::function<MultiComplex<double>(
const std::valarray<MultiComplex<double>>&)>;
799 fcn_t f = [&model, &molefrac](
const auto& zs) {
800 auto T_ = zs[0], rho_ = zs[1];
801 return model.alphar(T_, rho_, molefrac);
803 std::valarray<double> at = { T, 0.0 };
804 auto deriv = diff_mcxN(f, at, { NTderiv, Nderiv-1});
805 return deriv / factorial(Nderiv - 2);
810 throw std::invalid_argument(
"algorithmic differentiation backend is invalid in get_Bnvir");
816 template <ADBackends be = ADBackends::autodiff>
817 static auto get_dmBnvirdTm_runtime(
const int Nderiv,
const int NTderiv,
const Model& model,
const Scalar& T,
const VectorType& molefrac) {
824 default:
throw std::invalid_argument(
"NTderiv is invalid in get_dmBnvirdTm_runtime");
827 else if (Nderiv == 3) {
833 default:
throw std::invalid_argument(
"NTderiv is invalid in get_dmBnvirdTm_runtime");
836 else if (Nderiv == 4) {
842 default:
throw std::invalid_argument(
"NTderiv is invalid in get_dmBnvirdTm_runtime");
846 throw std::invalid_argument(
"Nderiv is invalid in get_dmBnvirdTm_runtime");
856 static auto get_B12vir(
const Model& model,
const Scalar &T,
const VectorType& molefrac) {
857 if (molefrac.size() != 2) {
throw std::invalid_argument(
"length of mole fraction vector must be 2 in get_B12vir"); }
859 const auto xpure0 = (Eigen::ArrayXd(2) << 1,0).finished();
860 const auto xpure1 = (Eigen::ArrayXd(2) << 0,1).finished();
863 auto z0 = molefrac[0];
864 auto B12 = (B2 - z0*z0*B20 - (1-z0)*(1-z0)*B21)/(2*z0*(1-z0));
956template<
typename Model,
typename Scalar =
double,
typename VectorType = Eigen::ArrayXd>
962 static auto get_splus(
const Model& model,
const Scalar &T,
const VectorType& rhovec) {
963 auto rhotot = rhovec.sum();
964 auto molefrac = rhovec / rhotot;
965 return model.alphar(T, rhotot, molefrac) -
get_Ar10(model, T, rhovec);
971 static auto get_pr(
const Model& model,
const Scalar &T,
const VectorType& rhovec)
973 auto rhotot_ = rhovec.sum();
974 auto molefrac = (rhovec / rhotot_).eval();
976 auto Ar01 = model.alphar(T, std::complex<double>(rhotot_, h), molefrac).imag() / h * rhotot_;
977 return Ar01*rhotot_*model.R(molefrac)*T;
980 static auto get_Ar00(
const Model& model,
const Scalar& T,
const VectorType& rhovec) {
981 auto rhotot = rhovec.sum();
982 auto molefrac = (rhovec / rhotot).eval();
983 return model.alphar(T, rhotot, molefrac);
986 static auto get_Ar10(
const Model& model,
const Scalar& T,
const VectorType& rhovec) {
987 auto rhotot = rhovec.sum();
988 auto molefrac = (rhovec / rhotot).eval();
989 return -T *
derivT([&model, &rhotot, &molefrac](
const auto& T,
const auto& ) {
return model.alphar(T, rhotot, molefrac); }, T, rhovec);
992 static auto get_Ar01(
const Model& model,
const Scalar &T,
const VectorType& rhovec) {
993 auto rhotot_ = std::accumulate(std::begin(rhovec), std::end(rhovec), (
decltype(rhovec[0]))0.0);
994 decltype(rhovec[0] * T) Ar01 = 0.0;
995 for (
auto i = 0; i < rhovec.size(); ++i) {
996 auto Ar00 = [&model](
const auto &T,
const auto&rhovec) {
997 auto rhotot = rhovec.sum();
998 auto molefrac = rhovec / rhotot;
999 return model.alphar(T, rhotot, molefrac);
1001 Ar01 += rhovec[i] *
derivrhoi(Ar00, T, rhovec, i);
1009 static auto get_Psir(
const Model& model,
const Scalar &T,
const VectorType& rhovec) {
1010 auto rhotot_ = rhovec.sum();
1011 auto molefrac = rhovec / rhotot_;
1012 return model.alphar(T, rhotot_, molefrac) * model.R(molefrac) * T * rhotot_;
1019 auto rhotot_ = rhovec.sum();
1020 auto molefrac = (rhovec / rhotot_).eval();
1021 autodiff::Real<1, Scalar> Tad = T;
1022 auto f = [&model, &rhotot_, &molefrac](
const auto& T_) {
return rhotot_*model.R(molefrac)*T_*model.alphar(T_, rhotot_, molefrac); };
1023 return derivatives(f, along(1), at(Tad))[1];
1037 ArrayXdual2nd rhovecc(rho.size());
for (
auto i = 0; i < rho.size(); ++i) { rhovecc[i] = rho[i]; }
1038 auto hfunc = [&model, &T](
const ArrayXdual2nd& rho_) {
1039 auto rhotot_ = rho_.sum();
1040 auto molefrac = (rho_ / rhotot_).eval();
1041 return forceeval(model.alphar(T, rhotot_, molefrac) * model.R(molefrac) * T * rhotot_);
1043 return autodiff::hessian(hfunc, wrt(rhovecc), at(rhovecc), u, g).eval();
1057 ArrayXdual2nd rhovecc(rho.size());
for (
auto i = 0; i < rho.size(); ++i) { rhovecc[i] = rho[i]; }
1058 auto hfunc = [&model, &T](
const ArrayXdual2nd& rho_) {
1059 auto rhotot_ = rho_.sum();
1060 auto molefrac = (rho_ / rhotot_).eval();
1061 return forceeval(model.alphar(T, rhotot_, molefrac) * model.R(molefrac) * T * rhotot_);
1064 Eigen::MatrixXd H = autodiff::hessian(hfunc, wrt(rhovecc), at(rhovecc), u, g);
1067 auto gg = g.cast<
double>().eval();
1068 return std::make_tuple(f, gg, H);
1077 auto rhotot_ = rho.sum();
1078 auto molefrac = (rho / rhotot_).eval();
1080 for (
auto i = 0; i < rho.size(); ++i) {
1081 H(i, i) += model.R(molefrac) * T / rho[i];
1086#if defined(TEQP_MULTICOMPLEX_ENABLED)
1092 static auto build_Psir_Hessian_mcx(
const Model& model,
const Scalar& T,
const VectorType& rho) {
1095 using namespace mcx;
1098 using fcn_t = std::function< MultiComplex<double>(
const Eigen::ArrayX<MultiComplex<double>>&)>;
1099 fcn_t func = [&model, &T](
const auto& rhovec) {
1100 auto rhotot_ = rhovec.sum();
1101 auto molefrac = (rhovec / rhotot_).eval();
1102 return model.alphar(T, rhotot_, molefrac) * model.R(molefrac) * T * rhotot_;
1104 using mattype = Eigen::ArrayXXd;
1105 auto H = get_Hessian<mattype, fcn_t, VectorType, HessianMethods::Multiple>(func, rho);
1116 ArrayXdual rhovecc(rho.size());
for (
auto i = 0; i < rho.size(); ++i) { rhovecc[i] = rho[i]; }
1117 auto psirfunc = [&model, &T](
const ArrayXdual& rho_) {
1118 auto rhotot_ = rho_.sum();
1119 auto molefrac = (rho_ / rhotot_).eval();
1120 return forceeval(model.alphar(T, rhotot_, molefrac) * model.R(molefrac) * T * rhotot_);
1122 auto val = autodiff::gradient(psirfunc, wrt(rhovecc), at(rhovecc)).eval();
1126#if defined(TEQP_MULTICOMPLEX_ENABLED)
1132 static auto build_Psir_gradient_multicomplex(
const Model& model,
const Scalar& T,
const VectorType& rho) {
1133 using rho_type =
typename VectorType::value_type;
1134 Eigen::ArrayX<mcx::MultiComplex<rho_type>> rhovecc(rho.size());
1135 auto psirfunc = [&model](
const auto &T,
const auto& rho_) {
1136 auto rhotot_ = rho_.sum();
1137 auto molefrac = (rho_ / rhotot_).eval();
1138 return eval(model.alphar(T, rhotot_, molefrac) * model.R(molefrac) * T * rhotot_);
1140 VectorType out(rho.size());
1141 for (
int i = 0; i < rho.size(); ++i) {
1142 out[i] =
derivrhoi(psirfunc, T, rho, i);
1153 using rho_type =
typename VectorType::value_type;
1154 Eigen::ArrayX<std::complex<rho_type>> rhovecc(rho.size());
for (
auto i = 0; i < rho.size(); ++i) { rhovecc[i] = rho[i]; }
1155 auto psirfunc = [&model](
const auto& T,
const auto& rho_) {
1156 auto rhotot_ = rho_.sum();
1157 auto molefrac = (rho_ / rhotot_).eval();
1158 return forceeval(model.alphar(T, rhotot_, molefrac) * model.R(molefrac) * T * rhotot_);
1160 VectorType out(rho.size());
1161 for (
int i = 0; i < rho.size(); ++i) {
1162 auto rhocopy = rhovecc;
1163 rho_type h = 1e-100;
1164 rhocopy[i] = rhocopy[i] + std::complex<rho_type>(0,h);
1165 auto calc = psirfunc(T, rhocopy);
1166 out[i] = calc.imag /
static_cast<double>(h);
1172 template<ADBackends be = ADBackends::autodiff>
1177#if defined(TEQP_MULTICOMPLEX_ENABLED)
1178 else if constexpr (be == ADBackends::multicomplex) {
1179 return build_Psir_gradient_multicomplex(model, T, rho);
1182#if defined(TEQP_COMPLEXSTEP_ENABLED)
1183 else if constexpr (be == ADBackends::complex_step) {
1197 typename VectorType::value_type rhotot = rho.sum();
1198 auto molefrac = (rho / rhotot).eval();
1199 auto rhorefideal = 1.0;
1208 template<ADBackends be = ADBackends::autodiff>
1211 return exp(lnphi).eval();
1219 template<ADBackends be = ADBackends::autodiff>
1222 auto molefrac = (rhovec / rhotot).eval();
1223 auto R = model.R(molefrac);
1225 auto Z = 1.0 + tdx::template
get_Ar01<be>(model, T, rhotot, molefrac);
1228 auto lnphi = ((grad / RT).array() - log(Z)).eval();
1232 template<ADBackends be = ADBackends::autodiff>
1234 auto R = model.R(molefrac);
1236 auto Z = 1.0 + tdx::template
get_Ar01<be>(model, T, rhotot, molefrac);
1237 auto rhovec = (rhotot*molefrac).eval();
1240 auto lnphi = ((grad / RT).array() - log(Z)).eval();
1244 template<ADBackends be = ADBackends::autodiff>
1247 auto molefrac = (rhovec / rhotot).eval();
1248 auto R = model.R(molefrac);
1251 auto lnphi = ((grad / RT).array()).eval();
1255 template<ADBackends be = ADBackends::autodiff>
1258 auto molefrac = (rhovec / rhotot).eval();
1260 auto Z = 1.0 + tdx::template
get_Ar01<be>(model, T, rhotot, molefrac);
1265 Eigen::ArrayXd deriv(rho.size());
1267 for (
auto i = 0; i < rho.size(); ++i) {
1268 auto psirfunc = [&model, &rho, i](
const auto& T,
const auto& rhoi) {
1269 ArrayXdual2nd rhovecc(rho.size());
for (
auto j = 0; j < rho.size(); ++j) { rhovecc[j] = rho[j]; }
1271 auto rhotot_ = rhovecc.sum();
1272 auto molefrac = (rhovecc / rhotot_).eval();
1273 return forceeval(model.alphar(T, rhotot_, molefrac) * model.R(molefrac) * T * rhotot_);
1275 dual2nd Tdual = T, rhoidual = rho[i];
1276 auto [u00, u10, u11] = derivatives(psirfunc, wrt(Tdual, rhoidual), at(Tdual, rhoidual));
1283 Eigen::ArrayXd deriv(molefrac.size());
1285 for (
auto i = 0; i < molefrac.size(); ++i) {
1286 auto alpharfunc = [&model, &T, &molefrac, i](
const auto& rho,
const auto& xi) {
1287 ArrayXdual2nd molefracdual = molefrac.template cast<autodiff::dual2nd>();
1288 molefracdual[i] = xi;
1289 return forceeval(model.alphar(T, rho, molefracdual));
1291 dual2nd rhodual = rhomolar, xidual = molefrac[i];
1292 auto [u00, u10, u11] = derivatives(alpharfunc, wrt(rhodual, xidual), at(rhodual, xidual));
1306 template<ADBackends be = ADBackends::autodiff>
1309 auto molefrac = (rhovec / rhotot).eval();
1310 auto R = model.R(molefrac);
1312 auto Z = 1.0 + tdx::template
get_Ar01<be>(model, T, rhotot, molefrac);
1313 auto dZdT_Z = tdx::template get_Ar11<be>(model, T, rhotot, molefrac)/(-T)/Z;
1316 return forceeval((1/(R*T)*(Tgrad - 1.0/T*grad)-dZdT_Z).eval());
1324 template<ADBackends be = ADBackends::autodiff>
1327 auto molefrac = (rhovec / rhotot).eval();
1329 auto Ar01 = tdx::template
get_Ar01<be>(model, T, rhotot, molefrac);
1330 auto Ar02 = tdx::template get_Ar02<be>(model, T, rhotot, molefrac);
1331 auto Z = 1.0 + Ar01;
1332 auto dZdrho = (Ar01 + Ar02)/rhotot;
1333 return std::make_tuple(log(Z), Z, dZdrho);
1343 template<ADBackends be = ADBackends::autodiff>
1346 auto molefrac = (rhovec / rhotot).eval();
1347 auto R = model.R(molefrac);
1350 return forceeval((1/(R*T)*(hessian*molefrac.matrix()).array() - dZdrho/Z).eval());
1360 template<ADBackends be = ADBackends::autodiff>
1363 auto drhodv = -rhotot*rhotot;
1374 template<ADBackends be = ADBackends::autodiff>
1377 auto molefrac = (rhovec / rhotot).eval();
1378 auto R = model.R(molefrac);
1381 auto Ar01 = tdx::template
get_Ar01<be>(model, T, rhotot, molefrac);
1382 auto Z = 1.0 + Ar01;
1384 Eigen::RowVector<
decltype(rhotot), Eigen::Dynamic> dZdx_Z = dZdx/Z;
1388 Eigen::ArrayXXd out = rhotot/(R*T)*hessian;
1391 out.rowwise() -= dZdx_Z.array();
1395 template<ADBackends be = ADBackends::autodiff>
1398 auto molefrac = (rhovec / rhotot).eval();
1399 auto R = model.R(molefrac);
1403 Eigen::ArrayXXd out = 1/(R*T)*rhotot*hessian;
1412 auto rhotot = rhovec.sum();
1413 auto molefrac = (rhovec / rhotot).eval();
1414 auto rhorefideal = 1.0;
1422 auto rhotot = rhovec.sum();
1423 auto molefrac = (rhovec / rhotot).eval();
1432 auto rhotot = rhovec.sum();
1433 auto molefrac = (rhovec / rhotot).eval();
1434 auto RT = model.R(molefrac)*T;
1436 return (RT + (hessian*rhovec.matrix()).array()).eval();
1483 auto rhotot = rhovec.sum();
1484 auto molefrac = (rhovec / rhotot).eval();
1486 auto RT = model.R(molefrac)*T;
1489 auto numerator = -rhotot*dpdrhovec;
1491 auto ders = tdx::template get_Ar0n<2>(model, T, rhotot, molefrac);
1492 auto denominator = -
pow2(rhotot)*RT*(1 + 2*ders[1] + ders[2]);
1493 return (numerator/denominator).eval();
1496 static VectorType
get_Psir_sigma_derivs(
const Model& model,
const Scalar& T,
const VectorType& rhovec,
const VectorType& v) {
1497 autodiff::Real<4, double> sigma = 0.0;
1498 auto rhovecad = rhovec.template cast<decltype(sigma)>(),
vad = v.template cast<decltype(sigma)>();
1499 auto wrapper = [&rhovecad, &
vad, &T, &model](
const auto& sigma_1) {
1500 auto rhovecused = (rhovecad + sigma_1 *
vad).eval();
1501 auto rhotot = rhovecused.sum();
1502 auto molefrac = (rhovecused / rhotot).eval();
1503 return forceeval(model.alphar(T, rhotot, molefrac) * model.R(molefrac) * T * rhotot);
1505 auto der = derivatives(wrapper, along(1), at(sigma));
1506 VectorType ret(der.size());
1507 for (
auto i = 0; i < ret.size(); ++i){ ret[i] = der[i];}
1512template<
int Nderivsmax>
1516 Eigen::Array<double, Nderivsmax+1, Nderivsmax+1>
derivs;
1518 template<
typename Model,
typename Scalar,
typename VecType>
1521 static_assert(Nderivsmax == 2,
"It's gotta be 2 for now");
1524 auto AX02 = tdx::template get_Agen0n<2>(model, T, rho, z);
1529 auto AX20 = tdx::template get_Agenn0<2>(model, T, rho, z);
1534 derivs(1, 1) = tdx::template get_Agenxy<1,1>(model, T, rho, z);
DerivativeHolderSquare(const Model &model, const Scalar &T, const Scalar &rho, const VecType &z)
Eigen::Array< double, Nderivsmax+1, Nderivsmax+1 > derivs
#define get_ATrhoXiXjXk_runtime_combinations
#define get_ATrhoXi_runtime_combinations
#define get_ATrhoXiXj_runtime_combinations
ContainerType::value_type derivT(const FuncType &f, TType T, const ContainerType &rho)
Given a function, use complex step derivatives to calculate the derivative with respect to the first ...
auto getbaseval(const T &expr)
T powi(const T &x, int n)
From Ulrich Deiters.
auto build_duplicated_tuple_impl(const T &val, std::index_sequence< I... >)
auto build_duplicated_tuple(const T &val)
A function to generate a tuple of N repeated copies of argument val at compile-time.
ContainerType::value_type derivrhoi(const FuncType &f, TType T, const ContainerType &rho, Integer i)
Given a function, use complex step derivatives to calculate the derivative with respect to the given ...
std::valarray< double > vad
static auto get_dPsirdT_constrhovec(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate derivative w.r.t. T at constant molar concentrations.
static auto get_partial_molar_volumes(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the partial molar volumes of each component.
static auto build_Psir_Hessian_autodiff(const Model &model, const Scalar &T, const VectorType &rho)
Calculate the Hessian of w.r.t. the molar concentrations.
static auto get_d_ln_fugacity_coefficients_dv_constTmolefracs(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the derivative of the natural logarithm of fugacity coefficient of each component w....
static Eigen::ArrayXd build_d2alphardrhodxi_constT(const Model &model, const Scalar &T, const Scalar &rhomolar, const VectorType &molefrac)
static auto get_d_ln_fugacity_coefficients_dmolefracs_constTrho1(const Model &model, const Scalar &T, const VectorType &rhovec)
static auto get_ln_fugacity_coefficients(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the natural logarithm of fugacity coefficient of each component.
static auto get_splus(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the residual entropy ( ) from derivatives of alphar.
static Eigen::ArrayXd build_d2PsirdTdrhoi_autodiff(const Model &model, const Scalar &T, const VectorType &rho)
static auto build_Psi_Hessian_autodiff(const Model &model, const Scalar &T, const VectorType &rho)
Calculate the Hessian of w.r.t. the molar concentrations.
static auto get_d_ln_fugacity_coefficients_drho_constTmolefracs(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the derivative of the natural logarithm of fugacity coefficient of each component w....
static auto build_Psir_fgradHessian_autodiff(const Model &model, const Scalar &T, const VectorType &rho)
Calculate the function value, gradient, and Hessian of w.r.t. the molar concentrations.
static auto get_Ar10(const Model &model, const Scalar &T, const VectorType &rhovec)
static auto build_Psir_gradient_autodiff(const Model &model, const Scalar &T, const VectorType &rho)
Gradient of Psir = ar*rho w.r.t. the molar concentrations.
static auto get_d_ln_fugacity_coefficients_dmolefracs_constTrho(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the derivative of the natural logarithm of fugacity coefficient of each component w....
static auto get_pr(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the residual pressure from derivatives of alphar.
static auto get_lnZ_Z_dZdrho(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate ln(Z), Z, and dZ/drho at constant temperature and mole fractions.
static auto get_Psir(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate .
static auto build_Psir_gradient_complex_step(const Model &model, const Scalar &T, const VectorType &rho)
Gradient of Psir = ar*rho w.r.t. the molar concentrations.
static auto get_d_ln_fugacity_coefficients_dT_constrhovec(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the derivative of the natural logarithm of fugacity coefficient of each component w....
static auto get_Ar01(const Model &model, const Scalar &T, const VectorType &rhovec)
static auto get_dpdT_constrhovec(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the temperature derivative of the pressure at constant molar concentrations.
static auto get_ln_fugacity_coefficients2(const Model &model, const Scalar &T, const VectorType &rhovec)
static auto get_dpdrhovec_constT(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the molar concentration derivatives of the pressure at constant temperature.
static auto get_fugacity_coefficients(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the fugacity coefficient of each component.
static auto get_Ar00(const Model &model, const Scalar &T, const VectorType &rhovec)
static auto get_ln_fugacity_coefficients_Trhomolefracs(const Model &model, const Scalar &T, const Scalar &rhotot, const VectorType &molefrac)
static auto get_ln_fugacity_coefficients1(const Model &model, const Scalar &T, const VectorType &rhovec)
static auto get_chempotVLE_autodiff(const Model &model, const Scalar &T, const VectorType &rho)
Calculate the chemical potential of each component.
static auto get_dchempotdT_autodiff(const Model &model, const Scalar &T, const VectorType &rhovec)
Calculate the temperature derivative of the chemical potential of each component.
static VectorType get_Psir_sigma_derivs(const Model &model, const Scalar &T, const VectorType &rhovec, const VectorType &v)
static auto build_Psir_gradient(const Model &model, const Scalar &T, const VectorType &rho)
static auto get_ATrhoXiXj_runtime(const AlphaWrapper &w, const Scalar &T, int iT, const Scalar &rho, int iD, const VectorType &molefrac, int i, int iXi, int j, int iXj)
static auto get_Agen0n(const AlphaWrapper &w, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Ar11(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_ATrhoXiXj(const AlphaWrapper &w, const Scalar &T, const Scalar &rho, const VectorType &molefrac, int i, int j)
static auto get_Agenn0(const AlphaWrapper &w, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Aig11(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Aigxy(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_ATrhoXiXjXk(const AlphaWrapper &w, const Scalar &T, const Scalar &rho, const VectorType &molefrac, int i, int j, int k)
static auto get_Ar03(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_AtaudeltaXiXj_runtime(const AlphaWrapper &w, const Scalar &tau, const int iT, const Scalar &delta, const int iD, const VectorType &molefrac, const int i, const int iXi, const int j, const int iXj)
static auto get_Ar20(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_ATrhoXi_runtime(const AlphaWrapper &w, const Scalar &T, int iT, const Scalar &rho, int iD, const VectorType &molefrac, int i, int iXi)
static auto AlphaCaller(const AlphaWrapper &w, const S1 &T, const S2 &rho, const Vec &molefrac)
static auto get_Ar(const int itau, const int idelta, const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Ar12(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_AtaudeltaXiXjXk_runtime(const AlphaWrapper &w, const Scalar &tau, const int iT, const Scalar &delta, const int iD, const VectorType &molefrac, const int i, int iXi, const int j, const int iXj, const int k, const int iXk)
static auto get_AtaudeltaXi_runtime(const AlphaWrapper &w, const Scalar &tau, const int iT, const Scalar &delta, const int iD, const VectorType &molefrac, const int i, const int iXi)
static auto AlphaCaller(const AlphaWrapper &w, const S1 &T, const S2 &rho, const Vec &molefrac)
static auto AlpharTauDeltaCaller(const AlphaWrapper &, const S1 &, const S2 &, const Vec &molefrac)
static Scalar get_Ar01(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_neff(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Arn0(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_AtaudeltaXi(const AlphaWrapper &w, const Scalar &tau, const Scalar &delta, const VectorType &molefrac, const int i)
static auto get_Ar02(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto AlpharTauDeltaCaller(const AlphaWrapper &w, const S1 &T, const S2 &rho, const Vec &molefrac)
static auto get_AtaudeltaXiXj(const AlphaWrapper &w, const Scalar &tau, const Scalar &delta, const VectorType &molefrac, const int i, const int j)
static auto get_ATrhoXi(const AlphaWrapper &w, const Scalar &T, const Scalar &rho, const VectorType &molefrac, int i)
static auto get_Ar0n(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Ar10(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Arxy(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Ar00(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_AtaudeltaXiXjXk(const AlphaWrapper &w, const Scalar &tau, const Scalar &delta, const VectorType &molefrac, const int i, const int j, const int k)
static auto get_ATrhoXiXjXk_runtime(const AlphaWrapper &w, const Scalar &T, int iT, const Scalar &rho, int iD, const VectorType &molefrac, int i, int iXi, int j, int iXj, int k, int iXk)
static auto get_Ar30(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Ar21(const Model &model, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_Agenxy(const AlphaWrapper &w, const Scalar &T, const Scalar &rho, const VectorType &molefrac)
static auto get_dmBnvirdTm(const Model &model, const Scalar &T, const VectorType &molefrac)
Temperature derivatives of a virial coefficient.
static auto get_B12vir(const Model &model, const Scalar &T, const VectorType &molefrac)
Calculate the cross-virial coefficient .
static auto get_dmBnvirdTm_runtime(const int Nderiv, const int NTderiv, const Model &model, const Scalar &T, const VectorType &molefrac)
static auto get_Bnvir(const Model &model, const Scalar &T, const VectorType &molefrac)
static auto get_B2vir(const Model &model, const Scalar &T, const VectorType &molefrac)
static auto get_Bnvir_runtime(const int Nderiv, const Model &model, const Scalar &T, const VectorType &molefrac)
auto operator()(Args &&... args) const