4 for (
const auto& isgi : unique_groups) {
5 for (
const auto& jsgi : unique_groups) {
9 int mgi1 =
static_cast<int>(m_sgi_to_mgi.find(isgi)->second);
10 int mgi2 =
static_cast<int>(m_sgi_to_mgi.find(jsgi)->second);
14 interaction.insert(m_pair);
19 interaction.insert(m_pair);
27 if (parameter ==
"aij") {
28 this->interaction[std::pair<int, int>(
static_cast<int>(mgi1),
static_cast<int>(mgi2))].a_ij = value;
29 }
else if (parameter ==
"bij") {
30 this->interaction[std::pair<int, int>(
static_cast<int>(mgi1),
static_cast<int>(mgi2))].b_ij = value;
31 }
else if (parameter ==
"cij") {
32 this->interaction[std::pair<int, int>(
static_cast<int>(mgi1),
static_cast<int>(mgi2))].c_ij = value;
38 auto it = this->interaction.find(std::pair<int, int>(
static_cast<int>(mgi1),
static_cast<int>(mgi2)));
39 if (it == this->interaction.end()) {
42 if (parameter ==
"aij") {
43 return it->second.a_ij;
44 }
else if (parameter ==
"bij") {
45 return it->second.b_ij;
46 }
else if (parameter ==
"cij") {
47 return it->second.c_ij;
60 this->mole_fractions = z;
61 if (this->N != z.size()) {
65 std::map<std::size_t, double>&Xg = m_Xg, &thetag = m_thetag;
71 for (std::size_t i = 0; i < this->mole_fractions.size(); ++i) {
72 X_summer += this->mole_fractions[i] * pure_data[i].group_count;
75 for (
const auto& sgi : unique_groups) {
78 for (std::size_t i = 0; i < this->mole_fractions.size(); ++i) {
79 X += this->mole_fractions[i] * group_count(i, sgi);
84 for (
auto& [key, val] : Xg) {
88 double theta_summer = 0;
89 for (
const auto& sgi : unique_groups) {
90 double cont = Xg.find(sgi)->second * m_Q.find(sgi)->second;
92 thetag.emplace(sgi, cont);
95 for (
auto& [key, val] : thetag) {
103 if (this->interaction.size() == 0) {
106 std::size_t mgi1 = m_sgi_to_mgi.find(sgi1)->second;
107 std::size_t mgi2 = m_sgi_to_mgi.find(sgi2)->second;
111 auto it = this->interaction.find(std::pair<int, int>(
static_cast<int>(mgi1),
static_cast<int>(mgi2)));
112 if (it != this->interaction.end()) {
113 return exp(-(it->second.a_ij / this->m_T + it->second.b_ij + it->second.c_ij * this->m_T));
116 format(
"Could not match mgi[%d]-mgi[%d] interaction in UNIFAC",
static_cast<int>(mgi1),
static_cast<int>(mgi2)));
123 for (
const auto& cg : c.
groups) {
124 if (cg.group.sgi == sgi) {
132 return pure_data[i].theta.find(sgi)->second;
143 if (this->mole_fractions.empty()) {
148 for (
const auto& k : unique_groups) {
149 for (
const auto& m : unique_groups) {
150 Psi_[std::pair<std::size_t, std::size_t>(k, m)] = Psi(k, m);
154 for (std::size_t i = 0; i < this->mole_fractions.size(); ++i) {
156 for (std::size_t k = 0; k < c.
groups.size(); ++k) {
157 double Q = c.
groups[k].group.Q_k;
158 int sgik = c.
groups[k].group.sgi;
160 for (
const auto& group : c.
groups) {
161 int sgim = group.group.sgi;
162 sum1 += theta_pure(i, sgim) * Psi_.find(std::pair<std::size_t, std::size_t>(sgim, sgik))->second;
168 double s = 1 - log(sum1);
169 for (std::size_t m = 0; m < c.
groups.size(); ++m) {
170 int sgim = c.
groups[m].group.sgi;
172 for (
const auto& group : c.
groups) {
173 int sgin = group.group.sgi;
174 sum2 += theta_pure(i, sgin) * Psi_.find(std::pair<std::size_t, std::size_t>(sgin, sgim))->second;
176 s -= theta_pure(i, sgim) * Psi_.find(std::pair<std::size_t, std::size_t>(sgik, sgim))->second / sum2;
178 pure_data[i].lnGamma[sgik] = Q * s;
183 std::map<std::size_t, double>&thetag = m_thetag, &lnGammag = m_lnGammag;
186 for (
const auto& ksgi : unique_groups) {
188 for (
const auto& msgi : unique_groups) {
189 sum1 += thetag.find(msgi)->second * Psi_.find(std::pair<std::size_t, std::size_t>(msgi, ksgi))->second;
191 double s = 1 - log(sum1);
192 for (
const auto& msgi : unique_groups) {
194 for (
const auto& nsgi : unique_groups) {
195 sum3 += thetag.find(nsgi)->second * Psi_.find(std::pair<std::size_t, std::size_t>(nsgi, msgi))->second;
197 s -= thetag.find(msgi)->second * Psi_.find(std::pair<std::size_t, std::size_t>(ksgi, msgi))->second / sum3;
199 lnGammag.emplace(ksgi, m_Q.find(ksgi)->second * s);
206 set_temperature(T_r / tau);
208 for (
const auto& sgi : unique_groups) {
209 std::size_t count = group_count(i, sgi);
211 summer += count * (m_lnGammag.find(sgi)->second - pure_data[i].lnGamma.find(sgi)->second);
217 double dtau = 0.01 * tau;
218 return (ln_gamma_R(tau + dtau, i, itau - 1) - ln_gamma_R(tau - dtau, i, itau - 1)) / (2 * dtau);
222 if (this->N != z.size()) {
225 std::vector<double> r(N), q(N), l(N), phi(N), theta(N), ln_Gamma_C(N);
226 double summerzr = 0, summerzq = 0, summerzl = 0;
227 for (std::size_t i = 0; i < N; ++i) {
228 double summerr = 0, summerq = 0;
230 for (
const auto& cg : c.
groups) {
231 summerr += cg.count * cg.group.R_k;
232 summerq += cg.count * cg.group.Q_k;
236 summerzr += z[i] * r[i];
237 summerzq += z[i] * q[i];
239 for (std::size_t i = 0; i < N; ++i) {
240 phi[i] = z[i] * r[i] / summerzr;
241 theta[i] = z[i] * q[i] / summerzq;
242 l[i] = 10.0 / 2.0 * (r[i] - q[i]) - (r[i] - 1);
243 summerzl += z[i] * l[i];
245 for (std::size_t i = 0; i < N; ++i) {
246 ln_Gamma_C[i] = log(phi[i] / z[i]) + 10.0 / 2.0 * q[i] * log(theta[i] / phi[i]) + l[i] - phi[i] / z[i] * summerzl;
247 gamma[i] = exp(ln_gamma_R(tau, i, 0) + ln_Gamma_C[i]);
253 components.push_back(comp);
254 for (
const auto& cg : comp.
groups) {
255 m_sgi_to_mgi.emplace(cg.group.sgi, cg.group.mgi);
261 N = identifiers.size();
262 if (identifier_type ==
"name") {
264 for (
const auto&
id : identifiers) {
279 unique_groups.clear();
281 for (std::size_t i = 0; i < N; ++i) {
286 for (
const auto& cg : c.
groups) {
287 auto x =
static_cast<double>(cg.count);
288 auto theta =
static_cast<double>(cg.count * cg.group.Q_k);
289 cd.
X.emplace(cg.group.sgi, x);
290 cd.
theta.emplace(cg.group.sgi, theta);
292 summerxq += x * cg.group.Q_k;
293 unique_groups.insert(cg.group.sgi);
294 m_Q.emplace(cg.group.sgi, cg.group.Q_k);
297 for (
auto& [key, val] : cd.
X) {
302 for (
auto& [key, val] : cd.
theta) {
306 pure_data.push_back(cd);
312 for (std::size_t i = 0; i < N; ++i) {
313 for (
auto& group : components[i].groups) {
314 if (group.group.sgi == sgi) {
315 group.group.Q_k = value;
326 for (std::size_t i = 0; i < N; ++i) {
327 for (
const auto& group : components[i].groups) {
328 if (group.group.sgi == sgi) {
329 return group.group.Q_k;