void ThermoPhase::getdlnActCoeffdlnN_numderiv(const size_t ld, doublereal* const dlnActCoeffdlnN) { double deltaMoles_j = 0.0; double pres = pressure(); // Evaluate the current base activity coefficients if necessary vector_fp ActCoeff_Base(m_kk); getActivityCoefficients(ActCoeff_Base.data()); vector_fp Xmol_Base(m_kk); getMoleFractions(Xmol_Base.data()); // Make copies of ActCoeff and Xmol_ for use in taking differences vector_fp ActCoeff(m_kk); vector_fp Xmol(m_kk); double v_totalMoles = 1.0; double TMoles_base = v_totalMoles; // Loop over the columns species to be deltad for (size_t j = 0; j < m_kk; j++) { // Calculate a value for the delta moles of species j // -> Note Xmol_[] and Tmoles are always positive or zero quantities. // -> experience has shown that you always need to make the deltas // greater than needed to change the other mole fractions in order // to capture some effects. double moles_j_base = v_totalMoles * Xmol_Base[j]; deltaMoles_j = 1.0E-7 * moles_j_base + v_totalMoles * 1.0E-13 + 1.0E-150; // Now, update the total moles in the phase and all of the mole // fractions based on this. v_totalMoles = TMoles_base + deltaMoles_j; for (size_t k = 0; k < m_kk; k++) { Xmol[k] = Xmol_Base[k] * TMoles_base / v_totalMoles; } Xmol[j] = (moles_j_base + deltaMoles_j) / v_totalMoles; // Go get new values for the activity coefficients. // -> Note this calls setState_PX(); setState_PX(pres, Xmol.data()); getActivityCoefficients(ActCoeff.data()); // Calculate the column of the matrix double* const lnActCoeffCol = dlnActCoeffdlnN + ld * j; for (size_t k = 0; k < m_kk; k++) { lnActCoeffCol[k] = (2*moles_j_base + deltaMoles_j) *(ActCoeff[k] - ActCoeff_Base[k]) / ((ActCoeff[k] + ActCoeff_Base[k]) * deltaMoles_j); } // Revert to the base case Xmol_, v_totalMoles v_totalMoles = TMoles_base; Xmol = Xmol_Base; } setState_PX(pres, Xmol_Base.data()); }
void IdealGasPhase::setToEquilState(const doublereal* mu_RT) { const vector_fp& grt = gibbs_RT_ref(); /* * Within the method, we protect against inf results if the * exponent is too high. * * If it is too low, we set * the partial pressure to zero. This capability is needed * by the elemental potential method. */ doublereal pres = 0.0; for (size_t k = 0; k < m_kk; k++) { double tmp = -grt[k] + mu_RT[k]; if (tmp < -600.) { m_pp[k] = 0.0; } else if (tmp > 300.0) { double tmp2 = tmp / 300.; tmp2 *= tmp2; m_pp[k] = m_p0 * exp(300.) * tmp2; } else { m_pp[k] = m_p0 * exp(tmp); } pres += m_pp[k]; } // set state setState_PX(pres, &m_pp[0]); }
void IdealSolnGasVPSS::setToEquilState(const doublereal* mu_RT) { double tmp, tmp2; updateStandardStateThermo(); const array_fp& grt = m_VPSS_ptr->Gibbs_RT_ref(); /* * Within the method, we protect against inf results if the * exponent is too high. * * If it is too low, we set * the partial pressure to zero. This capability is needed * by the elemental potential method. */ doublereal pres = 0.0; double m_p0 = m_VPSS_ptr->refPressure(); for (int k = 0; k < m_kk; k++) { tmp = -grt[k] + mu_RT[k]; if (tmp < -600.) { m_pp[k] = 0.0; } else if (tmp > 500.0) { tmp2 = tmp / 500.; tmp2 *= tmp2; m_pp[k] = m_p0 * exp(500.) * tmp2; } else { m_pp[k] = m_p0 * exp(tmp); } pres += m_pp[k]; } // set state setState_PX(pres, &m_pp[0]); }
void IdealSolidSolnPhase::setToEquilState(const doublereal* lambda_RT) { const vector_fp& grt = gibbs_RT_ref(); // set the pressure and composition to be consistent with // the temperature, doublereal pres = 0.0; for (size_t k = 0; k < m_kk; k++) { m_pp[k] = -grt[k]; for (size_t m = 0; m < nElements(); m++) { m_pp[k] += nAtoms(k,m)*lambda_RT[m]; } m_pp[k] = m_Pref * exp(m_pp[k]); pres += m_pp[k]; } setState_PX(pres, &m_pp[0]); }