Newer
Older
#pragma once
namespace teqp {
/**
This class holds a lightweight reference to the core parts of the model
The reducing and departure functions are moved into this class, while the donor class is used for the corresponding states portion
*/
template<typename DepartureFunction, typename BaseClass>
class MultiFluidAdapter {
private:
std::string meta = "";
public:
const BaseClass& base;
const ReducingFunctions redfunc;
template<class VecType>
auto R(const VecType& molefrac) const { return base.R(molefrac); }
MultiFluidAdapter(const BaseClass& base, ReducingFunctions&& redfunc, DepartureFunction&& depfunc) : base(base), redfunc(redfunc), dep(depfunc) {};
/// Store some sort of metadata in string form (perhaps a JSON representation of the model?)
void set_meta(const std::string& m) { meta = m; }
/// Get the metadata stored in string form
auto get_meta() const { return meta; }
template<typename TType, typename RhoType, typename MoleFracType>
auto alphar(const TType& T,
const RhoType& rho,
const MoleFracType& molefrac) const
{
auto Tred = forceeval(redfunc.get_Tr(molefrac));
auto rhored = forceeval(redfunc.get_rhor(molefrac));
auto delta = forceeval(rho / rhored);
auto tau = forceeval(Tred / T);
auto val = base.corr.alphar(tau, delta, molefrac) + dep.alphar(tau, delta, molefrac);
return forceeval(val);
}
};
template<class Model>
auto build_multifluid_mutant(const Model& model, const nlohmann::json& jj) {
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
auto N = model.redfunc.Tc.size();
// Allocate the matrices of default models and F factors
Eigen::MatrixXd F(N, N); F.setZero();
std::vector<std::vector<DepartureTerms>> funcs(N);
for (auto i = 0; i < N; ++i) { funcs[i].resize(N); }
// Build the F and departure function matrix
for (auto i = 0; i < N; ++i) {
for (auto j = i; j < N; ++j) {
if (i == j) {
funcs[i][i].add_term(NullEOSTerm());
}
else {
// Extract the given entry
auto entry = jj[std::to_string(i)][std::to_string(j)];
// Set the entry in the matrix of F and departure functions
auto dep = entry.at("departure");
auto BIP = entry.at("BIP");
F(i, j) = BIP.at("Fij");
F(j, i) = F(i, j);
funcs[i][j] = build_departure_function(dep);
funcs[j][i] = build_departure_function(dep);
}
}
}
// Determine what sort of reducing function is to be used
auto get_reducing = [&](const auto& deptype) {
auto red = model.redfunc;
auto Tc = red.Tc, vc = red.vc;
if (deptype == "invariant") {
using mat = std::decay_t<decltype(MultiFluidInvariantReducingFunction::phiT)>;
mat phiT = mat::Zero(N, N), lambdaT = mat::Zero(N, N), phiV = mat::Zero(N, N), lambdaV = mat::Zero(N, N);
for (auto i = 0; i < N; ++i) {
auto entry = jj.at(std::to_string(i)).at(std::to_string(j));
auto BIP = entry.at("BIP");
// Set the reducing function parameters in the copy
phiT(i, j) = BIP.at("phiT");
phiT(j, i) = phiT(i, j);
lambdaT(i, j) = BIP.at("lambdaT");
lambdaT(j, i) = -lambdaT(i, j);
phiV(i, j) = BIP.at("phiV");
phiV(j, i) = phiV(i, j);
lambdaV(i, j) = BIP.at("lambdaV");
lambdaV(j, i) = -lambdaV(i, j);
}
}
return ReducingFunctions(MultiFluidInvariantReducingFunction(phiT, lambdaT, phiV, lambdaV, Tc, vc));
}
else {
using mat = std::decay_t<decltype(MultiFluidReducingFunction::betaT)>;
mat betaT = mat::Zero(N, N), gammaT = mat::Zero(N, N), betaV = mat::Zero(N, N), gammaV = mat::Zero(N, N);
for (auto i = 0; i < N; ++i) {
auto entry = jj.at(std::to_string(i)).at(std::to_string(j));
auto BIP = entry.at("BIP");
// Set the reducing function parameters in the copy
betaT(i, j) = BIP.at("betaT");
betaT(j, i) = 1 / betaT(i, j);
betaV(i, j) = BIP.at("betaV");
betaV(j, i) = 1 / betaV(i, j);
gammaT(i, j) = BIP.at("gammaT"); gammaT(j, i) = gammaT(i, j);
gammaV(i, j) = BIP.at("gammaV"); gammaV(j, i) = gammaV(i, j);
}
}
return ReducingFunctions(MultiFluidReducingFunction(betaT, gammaT, betaV, gammaV, Tc, vc));
}
};
std::string deptype = (jj.at("0").at("1").at("BIP").contains("type")) ? jj.at("0").at("1").at("BIP")["type"] : "";
ReducingFunctions newred = get_reducing(deptype);
auto newdep = DepartureContribution(std::move(F), std::move(funcs));
auto mfa = MultiFluidAdapter(model, std::move(newred), std::move(newdep));
/// Store the model spec in the adapted multifluid class
mfa.set_meta(jj.dump());
return mfa;
}