Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#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;
const DepartureFunction depfunc;
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), depfunc(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) + depfunc.alphar(tau, delta, molefrac);
return forceeval(val);
}
};
template<class Model>
auto build_multifluid_mutant(Model& model, const nlohmann::json& jj) {
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) {
for (auto j = i; j < N; ++j) {
// Extract the given entry
auto entry = jj[std::to_string(i)][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) {
for (auto j = i; j < N; ++j) {
// Extract the given entry
auto entry = jj[std::to_string(i)][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));
}
};
ReducingFunctions newred = get_reducing(jj.at("0").at("1"));
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;
}
}