91 Eigen::Index min_ileft = 51, max_iright = 0;
92 for (
auto i = 0U; i < profiles.size(); ++i) {
93 const Eigen::ArrayXd psigma = profiles[i].nhb.psigma(A_COSMO_A2[i]);
94 Eigen::Index ileft = 0, iright = psigma.size();
95 for (
auto ii = 0; ii < psigma.size(); ++ii) {
if (std::abs(psigma(ii)) > 1e-16) { ileft = ii;
break; } }
96 for (
auto ii = psigma.size() - 1; ii > ileft; --ii) {
if (std::abs(psigma(ii)) > 1e-16) { iright = ii;
break; } }
97 if (ileft < min_ileft) { min_ileft = ileft; }
98 if (iright > max_iright) { max_iright = iright; }
100 return std::make_tuple(min_ileft, max_iright);
166 auto delta_sigma = 2 * 0.025 / 50;
167 Eigen::ArrayXX<TType> DELTAW(51, 51); DELTAW.setZero();
168 double cc =
get_c_hb(type_t, type_s);
169 for (
auto m = ileft; m < ileft+w+1; ++m) {
170 for (
auto n = ileft; n < ileft+w+1; ++n) {
171 double sigma_m = -0.025 + delta_sigma*m,
172 sigma_n = -0.025 + delta_sigma*n,
173 c_hb = (sigma_m*sigma_n >= 0) ? 0 : cc;
174 auto c_ES = m_consts.
A_ES + m_consts.
B_ES / (T*T);
175 DELTAW(m, n) = c_ES*
POW2(sigma_m + sigma_n) - c_hb*
POW2(sigma_m - sigma_n);
203 auto get_Gamma(
const TType& T, PSigmaType psigmas)
const {
206 using TXType = std::decay_t<std::common_type_t<TType,
decltype(psigmas[0])>>;
208 double R = m_consts.
R;
209 Eigen::ArrayX<TXType> Gamma(153), Gammanew(153); Gamma.setOnes(); Gammanew.setOnes();
212 auto to_scientific = [](
double val) { std::ostringstream out; out << std::scientific << val;
return out.str(); };
219 Eigen::ArrayXX<TType> DELTAW(153, 153);
221 for (
auto i = 0; i < 3; ++i) {
222 for (
auto j = 0; j < 3; ++j) {
223 DELTAW.matrix().block(51*i, 51*j, 51, 51) =
get_DELTAW(T, types[i], types[j]);
227 auto AA = (Eigen::exp(-DELTAW / (R*T)).template cast<TXType>().rowwise()*psigmas.template cast<TXType>().transpose()).eval();
228 for (
auto counter = 0; counter <= max_iter; ++counter) {
229 Gammanew = 1 / (AA.rowwise()*Gamma.transpose()).rowwise().sum();
230 Gamma = (Gamma + Gammanew) / 2;
231 double maxdiff =
getbaseval(((Gamma - Gammanew) / Gamma).cwiseAbs().real().maxCoeff());
235 if (counter == max_iter) {
236 throw std::invalid_argument(
"Could not obtain the desired tolerance of "
239 + std::to_string(max_iter)
240 +
" iterations in get_Gamma; current value is "
241 + to_scientific(maxdiff));
253 std::vector<Eigen::Index> offsets = {0*51, 1*51, 2*51};
254 Eigen::ArrayXX<TXType> AA(153, 153);
255 for (
auto i = 0; i < 3; ++i) {
256 for (
auto j = 0; j < 3; ++j) {
257 Eigen::Index rowoffset = offsets[i], coloffset = offsets[j];
258 AA.matrix().block(rowoffset + ileft, coloffset + ileft, w, w) = Eigen::exp(-
get_DELTAW_fast(T, types[i], types[j]).block(ileft, ileft, w, w).array() / (R*T)).template cast<TXType>().rowwise()*psigmas.template cast<TXType>().segment(coloffset+ileft,w).transpose();
263 for (
auto counter = 0; counter <= max_iter; ++counter) {
264 for (Eigen::Index offset : {51*0, 51*1, 51*2}){
265 Gammanew.segment(offset + ileft, w) = 1 / (
266 AA.matrix().block(offset+ileft,51*0+ileft,w,w).array().rowwise()*Gamma.segment(51*0+ileft, w).transpose()
267 + AA.matrix().block(offset+ileft,51*1+ileft,w,w).array().rowwise()*Gamma.segment(51*1+ileft, w).transpose()
268 + AA.matrix().block(offset+ileft,51*2+ileft,w,w).array().rowwise()*Gamma.segment(51*2+ileft, w).transpose()
271 for (Eigen::Index offset : {51 * 0, 51 * 1, 51 * 2}) {
272 Gamma.segment(offset + ileft, w) = (Gamma.segment(offset + ileft, w) + Gammanew.segment(offset + ileft, w)) / 2;
274 double maxdiff =
getbaseval(((Gamma - Gammanew) / Gamma).cwiseAbs().real().maxCoeff());
278 if (!std::isfinite(maxdiff)){
281 if (counter == max_iter){
282 throw std::invalid_argument(
"Could not obtain the desired tolerance of "
285 +std::to_string(max_iter)
286 +
" iterations in get_Gamma; current value is "
287 + to_scientific(maxdiff));
348 double q0 = m_comb_consts.
q0,
349 r0 = m_comb_consts.
r0,
351 std::decay_t<MoleFractions> q = Eigen::Map<const Eigen::ArrayXd>(&(A_COSMO_A2[0]), A_COSMO_A2.size()) / q0,
352 r = Eigen::Map<const Eigen::ArrayXd>(&(V_COSMO_A3[0]), V_COSMO_A3.size()) / r0,
353 l = z_coordination / 2 * (r - q) - (r - 1),
355 phi = x * phi_over_x,
357 theta = x * theta_over_x,
358 theta_over_phi = theta_over_x/phi_over_x;
361 return ((log(phi_over_x) + z_coordination / 2 * q * log(theta_over_phi) + l - phi_over_x *
contiguous_dotproduct(x, l))).eval();