void PseudoBinaryVPSSTP::calcPseudoBinaryMoleFractions() const { size_t k; doublereal sumCat; doublereal sumAnion; doublereal sum = 0.0; switch (PBType_) { case PBTYPE_PASSTHROUGH: for (k = 0; k < m_kk; k++) { PBMoleFractions_[k] = moleFractions_[k]; } break; case PBTYPE_SINGLEANION: sumCat = 0.0; sumAnion = 0.0; for (k = 0; k < m_kk; k++) { moleFractionsTmp_[k] = moleFractions_[k]; } for (k = 0; k < cationList_.size(); k++) { sumCat += moleFractions_[cationList_[k]]; } sumAnion = moleFractions_[anionList_[k]]; PBMoleFractions_[0] = sumCat -sumAnion; moleFractionsTmp_[indexSpecialSpecies_] -= PBMoleFractions_[0]; for (k = 0; k < numCationSpecies_; k++) { PBMoleFractions_[1+k] = moleFractionsTmp_[cationList_[k]]; } for (k = 0; k < numPassThroughSpecies_; k++) { PBMoleFractions_[neutralPBindexStart + k] = moleFractions_[cationList_[k]]; } sum = fmaxx(0.0, PBMoleFractions_[0]); for (k = 1; k < numPBSpecies_; k++) { sum += PBMoleFractions_[k]; } for (k = 0; k < numPBSpecies_; k++) { PBMoleFractions_[k] /= sum; } break; case PBTYPE_SINGLECATION: throw CanteraError("eosType", "Unknown type"); break; case PBTYPE_MULTICATIONANION: throw CanteraError("eosType", "Unknown type"); break; default: throw CanteraError("eosType", "Unknown type"); break; } }
void IdealSolnGasVPSS::getPartialMolarEntropies(doublereal* sbar) const { getEntropy_R(sbar); doublereal r = GasConstant; scale(sbar, sbar+m_kk, sbar, r); for (int k = 0; k < m_kk; k++) { doublereal xx = fmaxx(SmallNumber, moleFraction(k)); sbar[k] += r * ( - log(xx)); } }
void IdealSolnGasVPSS::getChemPotentials(doublereal* mu) const { getStandardChemPotentials(mu); doublereal xx; doublereal rt = temperature() * GasConstant; for (int k = 0; k < m_kk; k++) { xx = fmaxx(SmallNumber, moleFraction(k)); mu[k] += rt*(log(xx)); } }
/* * Get the array of partial molar entropies of the species * units = J / kmol / K */ void PecosGasPhase::getPartialMolarEntropies(doublereal* sbar) const { const array_fp& _s = entropy_R_ref(); doublereal r = GasConstant; scale(_s.begin(), _s.end(), sbar, r); doublereal logp = log(pressure()/m_spthermo->refPressure()); for (int k = 0; k < m_kk; k++) { doublereal xx = fmaxx(SmallNumber, moleFraction(k)); sbar[k] += r * (- logp - log(xx)); } }
void PecosGasPhase::getChemPotentials(doublereal* mu) const { getStandardChemPotentials(mu); //doublereal logp = log(pressure()/m_spthermo->refPressure()); doublereal xx; doublereal rt = temperature() * GasConstant; //const array_fp& g_RT = gibbs_RT_ref(); for (int k = 0; k < m_kk; k++) { xx = fmaxx(SmallNumber, moleFraction(k)); mu[k] += rt*(log(xx)); } }
void ConstDensityThermo::getChemPotentials(doublereal* mu) const { doublereal vdp = (pressure() - m_spthermo->refPressure())/ molarDensity(); doublereal xx; doublereal rt = temperature() * GasConstant; const array_fp& g_RT = gibbs_RT(); for (int k = 0; k < m_kk; k++) { xx = fmaxx(SmallNumber, moleFraction(k)); mu[k] = rt*(g_RT[k] + log(xx)) + vdp; } }
void DustyGasTransport::updateTransport_C() { m_thermo->getMoleFractions(DATA_PTR(m_x)); // add an offset to avoid a pure species condition // (check - this may be unnecessary) int k; for (k = 0; k < m_nsp; k++) { m_x[k] = fmaxx(MIN_X, m_x[k]); } }
/* * This is called for every interface call to check whether * the concentrations have changed. Concentrations change * whenever the pressure or the mole fraction has changed. * If it has changed, the recalculations should be done. * * Note this should be a lightweight function since it's * part of all of the interfaces. * * @internal */ void LiquidTransport::update_conc() { // If the pressure has changed then the concentrations // have changed. doublereal pres = m_thermo->pressure(); bool qReturn = true; if (pres != m_press) { qReturn = false; m_press = pres; } int iStateNew = m_thermo->stateMFNumber(); if (iStateNew != m_iStateMF) { qReturn = false; m_thermo->getMoleFractions(DATA_PTR(m_molefracs)); m_thermo->getConcentrations(DATA_PTR(m_concentrations)); concTot_ = 0.0; concTot_tran_ = 0.0; for (size_t k = 0; k < m_nsp; k++) { m_molefracs[k] = fmaxx(0.0, m_molefracs[k]); m_molefracs_tran[k] = fmaxx(MIN_X, m_molefracs[k]); concTot_tran_ += m_molefracs_tran[k]; concTot_ += m_concentrations[k]; } dens_ = m_thermo->density(); meanMolecularWeight_ = m_thermo->meanMolecularWeight(); concTot_tran_ *= concTot_; } if (qReturn) { return; } // signal that concentration-dependent quantities will need to // be recomputed before use, and update the local mole // fractions. m_visc_conc_ok = false; // Mixture stuff needs to be evaluated m_visc_mix_ok = false; m_diff_mix_ok = false; m_cond_mix_ok = false; }
/** * Return a damping coefficient that keeps the solution after taking one * Newton step between specified lower and upper bounds. This function only * considers one domain. */ doublereal bound_step(const doublereal* x, const doublereal* step, Domain1D& r, int loglevel) { char buf[100]; int np = r.nPoints(); int nv = r.nComponents(); Indx index(nv, np); doublereal above, below, val, newval; int m, j; doublereal fbound = 1.0; bool wroteTitle = false; for (m = 0; m < nv; m++) { above = r.upperBound(m); below = r.lowerBound(m); for (j = 0; j < np; j++) { val = x[index(m,j)]; if (loglevel > 0) { if (val > above + 1.0e-12 || val < below - 1.0e-12) { sprintf(buf, "domain %d: %20s(%d) = %10.3e (%10.3e, %10.3e)\n", r.domainIndex(), r.componentName(m).c_str(), j, val, below, above); writelog(string("\nERROR: solution out of bounds.\n")+buf); } } newval = val + step[index(m,j)]; if (newval > above) { fbound = fmaxx( 0.0, fminn( fbound, (above - val)/(newval - val))); } else if (newval < below) { fbound = fminn(fbound, (val - below)/(val - newval)); } if (loglevel > 1 && (newval > above || newval < below)) { if (!wroteTitle) { writelog("\nNewton step takes solution out of bounds.\n\n"); sprintf(buf," %12s %12s %4s %10s %10s %10s %10s\n", "domain","component","pt","value","step","min","max"); wroteTitle = true; writelog(buf); } sprintf(buf, " %4i %12s %4i %10.3e %10.3e %10.3e %10.3e\n", r.domainIndex(), r.componentName(m).c_str(), j, val, step[index(m,j)], below, above); writelog(buf); } } } return fbound; }
/* * @internal This is called the first time any transport property * is requested from Mixture after the concentrations * have changed. */ void MixTransport::update_C() { // signal that concentration-dependent quantities will need to // be recomputed before use, and update the local mole // fractions. m_viscmix_ok = false; m_condmix_ok = false; m_thermo->getMoleFractions(DATA_PTR(m_molefracs)); // add an offset to avoid a pure species condition int k; for (k = 0; k < m_nsp; k++) { m_molefracs[k] = fmaxx(MIN_X, m_molefracs[k]); } }
void MargulesVPSSTP::getChemPotentials(doublereal* mu) const { doublereal xx; /* * First get the standard chemical potentials in * molar form. * -> this requires updates of standard state as a function * of T and P */ getStandardChemPotentials(mu); /* * Update the activity coefficients */ s_update_lnActCoeff(); /* * */ doublereal RT = GasConstant * temperature(); for (int k = 0; k < m_kk; k++) { xx = fmaxx(moleFractions_[k], xxSmall); mu[k] += RT * (log(xx) + lnActCoeff_Scaled_[k]); } }