Exemple #1
0
void Reactor::updateState(doublereal* y)
{
    // The components of y are [0] the total mass, [1] the total volume,
    // [2] the total internal energy, [3...K+3] are the mass fractions of each
    // species, and [K+3...] are the coverages of surface species on each wall.
    m_mass = y[0];
    m_vol = y[1];
    m_thermo->setMassFractions_NoNorm(y+3);

    if (m_energy) {
        // Use a damped Newton's method to determine the mixture temperature.
        // Tight tolerances are required both for Jacobian evaluation and for
        // sensitivity analysis to work correctly.
        doublereal U = y[2];
        doublereal T = temperature();
        double dT = 100;
        double dUprev = 1e10;
        double dU = 1e10;
        int i = 0;
        double damp = 1.0;
        while (abs(dT / T) > 10 * DBL_EPSILON) {
            dUprev = dU;
            m_thermo->setState_TR(T, m_mass / m_vol);
            double dUdT = m_thermo->cv_mass() * m_mass;
            dU = m_thermo->intEnergy_mass() * m_mass - U;
            dT = dU / dUdT;
            // Reduce the damping coefficient if the magnitude of the error
            // isn't decreasing
            if (std::abs(dU) < std::abs(dUprev)) {
                damp = 1.0;
            } else {
                damp *= 0.8;
            }
            dT = std::min(dT, 0.5 * T) * damp;
            T -= dT;
            i++;
            if (i > 100) {
                throw CanteraError("Reactor::updateState",
                    "no convergence\nU/m = {}\nT = {}\nrho = {}\n",
                    U / m_mass, T, m_mass / m_vol);
            }
        }
    } else {
        m_thermo->setDensity(m_mass/m_vol);
    }

    updateSurfaceState(y + m_nsp + 3);

    // save parameters needed by other connected reactors
    m_enthalpy = m_thermo->enthalpy_mass();
    m_pressure = m_thermo->pressure();
    m_intEnergy = m_thermo->intEnergy_mass();
    m_thermo->saveState(m_state);
}
Exemple #2
0
void IdealGasReactor::updateState(doublereal* y)
{
    // The components of y are [0] the total mass, [1] the total volume,
    // [2] the temperature, [3...K+3] are the mass fractions of each species,
    // and [K+3...] are the coverages of surface species on each wall.
    m_mass = y[0];
    m_vol = y[1];
    m_thermo->setMassFractions_NoNorm(y+3);
    m_thermo->setState_TR(y[2], m_mass / m_vol);
    updateSurfaceState(y + m_nsp + 3);

    // save parameters needed by other connected reactors
    m_enthalpy = m_thermo->enthalpy_mass();
    m_pressure = m_thermo->pressure();
    m_intEnergy = m_thermo->intEnergy_mass();
    m_thermo->saveState(m_state);
}
void ConstPressureReactor::updateState(doublereal* y)
{
    // The components of y are [0] the total mass, [1] the total enthalpy,
    // [2...K+2) are the mass fractions of each species, and [K+2...] are the
    // coverages of surface species on each wall.
    m_mass = y[0];
    m_thermo->setMassFractions_NoNorm(y+2);
    if (m_energy) {
        m_thermo->setState_HP(y[1]/m_mass, m_pressure, 1.0e-4);
    } else {
        m_thermo->setPressure(m_pressure);
    }
    m_vol = m_mass / m_thermo->density();
    updateSurfaceState(y + m_nsp + 2);

    // save parameters needed by other connected reactors
    m_enthalpy = m_thermo->enthalpy_mass();
    m_intEnergy = m_thermo->intEnergy_mass();
    m_thermo->saveState(m_state);
}