Esempio n. 1
0
 status_t DLL_EXPORT kin_getdestructionrates_(const integer* n, doublereal* ddot) {
     try {
         Kinetics* k = _fkin(n);
         k->getDestructionRates(ddot);
         return 0;
     }
     catch (CanteraError) {handleError(); return -1;}
 }
Esempio n. 2
0
 status_t DLL_EXPORT kin_getfwdratesofprogress_(const integer* n, doublereal* fwdROP) {
     Kinetics* k = _fkin(n);
     try {
         k->getFwdRatesOfProgress(fwdROP);
         return 0;
     }
     catch (CanteraError) {handleError(); return -1;}
 }
Esempio n. 3
0
 status_t DLL_EXPORT kin_getnetratesofprogress_(const integer* n, doublereal* netROP) {
     try {
         Kinetics* k = _fkin(n);
         k->getNetRatesOfProgress(netROP);
         return 0;
     }
     catch (CanteraError) {handleError(); return -1;}
 }
Esempio n. 4
0
 status_t kin_getnetratesofprogress_(const integer* n, doublereal* netROP)
 {
     try {
         Kinetics* k = _fkin(n);
         k->getNetRatesOfProgress(netROP);
     } catch (...) {
         return handleAllExceptions(-1, ERR);
     }
     return 0;
 }
Esempio n. 5
0
 status_t kin_getdestructionrates_(const integer* n, doublereal* ddot)
 {
     try {
         Kinetics* k = _fkin(n);
         k->getDestructionRates(ddot);
     } catch (...) {
         return handleAllExceptions(-1, ERR);
     }
     return 0;
 }
Esempio n. 6
0
 status_t kin_getnetproductionrates_(const integer* n, doublereal* wdot)
 {
     try {
         Kinetics* k = _fkin(n);
         k->getNetProductionRates(wdot);
     } catch (...) {
         return handleAllExceptions(-1, ERR);
     }
     return 0;
 }
Esempio n. 7
0
 status_t kin_getequilibriumconstants_(const integer* n, doublereal* kc)
 {
     try {
         Kinetics* k = _fkin(n);
         k->getEquilibriumConstants(kc);
     } catch (...) {
         return handleAllExceptions(-1, ERR);
     }
     return 0;
 }
Esempio n. 8
0
 status_t DLL_EXPORT kin_getreactionstring_(const integer* n, integer* i, char* buf, ftnlen lenbuf) {
     try {
         Kinetics* k = _fkin(n);
         std::string r = k->reactionString(*i-1);
         int lout = min(lenbuf,r.size());
         std::copy(r.c_str(), r.c_str() + lout, buf);
         for (int nn = lout; nn < lenbuf; nn++) buf[nn] = ' ';
         return 0;
     }
     catch (CanteraError) {handleError(); return -1;}
 }
Esempio n. 9
0
 status_t DLL_EXPORT kin_advancecoverages_(const integer* n, doublereal* tstep) {
     try {
         Kinetics* k = _fkin(n);
         if (k->type() == cInterfaceKinetics) {
             ((InterfaceKinetics*)k)->advanceCoverages(*tstep);
         }
         else {
             throw CanteraError("kin_advanceCoverages",
                 "wrong kinetics manager type");
         }
         return 0;
     }
     catch (CanteraError) {handleError(); return -1;}
 }
Esempio n. 10
0
 status_t kin_advancecoverages_(const integer* n, doublereal* tstep)
 {
     try {
         Kinetics* k = _fkin(n);
         if (k->type() == cInterfaceKinetics) {
             ((InterfaceKinetics*)k)->advanceCoverages(*tstep);
         } else {
             throw CanteraError("kin_advanceCoverages",
                                "wrong kinetics manager type");
         }
     } catch (...) {
         return handleAllExceptions(-1, ERR);
     }
     return 0;
 }
Esempio n. 11
0
 status_t kin_getreactionstring_(const integer* n, integer* i, char* buf, ftnlen lenbuf)
 {
     try {
         Kinetics* k = _fkin(n);
         std::string r = k->reactionString(*i-1);
         int lout = std::min(lenbuf, (int) r.size());
         std::copy(r.c_str(), r.c_str() + lout, buf);
         for (int nn = lout; nn < lenbuf; nn++) {
             buf[nn] = ' ';
         }
     } catch (...) {
         return handleAllExceptions(-1, ERR);
     }
     return 0;
 }
Esempio n. 12
0
    status_t ctbuildsolutionfromxml(char* src, integer* ixml, char* id,
                                    integer* ith, integer* ikin, ftnlen lensrc, ftnlen lenid)
    {
        try {
            XML_Node* root = 0;
            if (*ixml > 0) {
                root = _xml(ixml);
            }

            thermo_t* t = _fth(ith);
            Kinetics* k = _fkin(ikin);

            XML_Node* x, *r=0;
            if (root) {
                r = &root->root();
            }
            std::string srcS = f2string(src, lensrc);
            std::string idS  = f2string(id, lenid);
            if (srcS != "") {
                x = get_XML_Node(srcS, r);
            } else {
                x = get_XML_Node(idS, r);
            }
            if (!x) {
                return 0;
            }
            importPhase(*x, t);
            k->addPhase(*t);
            k->init();
            installReactionArrays(*x, *k, x->id());
            t->setState_TP(300.0, OneAtm);
            if (r) {
                if (&x->root() != &r->root()) {
                    delete &x->root();
                }
            } else {
                delete &x->root();
            }
        } catch (...) {
            return handleAllExceptions(-1, ERR);
        }
        return 0;
    }
double Reactor::evalSurfaces(double t, double* ydot)
{
    const vector_fp& mw = m_thermo->molecularWeights();

    fill(m_sdot.begin(), m_sdot.end(), 0.0);
    size_t loc = 0; // offset into ydot
    double mdot_surf = 0.0; // net mass flux from surface

    for (size_t i = 0; i < m_wall.size(); i++) {
        Kinetics* kin = m_wall[i]->kinetics(m_lr[i]);
        SurfPhase* surf = m_wall[i]->surface(m_lr[i]);
        if (surf && kin) {
            double rs0 = 1.0/surf->siteDensity();
            size_t nk = surf->nSpecies();
            double sum = 0.0;
            surf->setTemperature(m_state[0]);
            m_wall[i]->syncCoverages(m_lr[i]);
            kin->getNetProductionRates(&m_work[0]);
            size_t ns = kin->surfacePhaseIndex();
            size_t surfloc = kin->kineticsSpeciesIndex(0,ns);
            for (size_t k = 1; k < nk; k++) {
                ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k);
                sum -= ydot[loc + k];
            }
            ydot[loc] = sum;
            loc += nk;

            double wallarea = m_wall[i]->area();
            for (size_t k = 0; k < m_nsp; k++) {
                m_sdot[k] += m_work[k]*wallarea;
                mdot_surf += m_sdot[k] * mw[k];
            }
        }
    }
    return mdot_surf;
}
Esempio n. 14
0
bool checkElectrochemReaction(const XML_Node& p, Kinetics& kin, const XML_Node& r)
{
    // If other phases are involved in the reaction mechanism, they must be
    // listed in a 'phaseArray' child element. Homogeneous mechanisms do not
    // need to include a phaseArray element.
    vector<string> phase_ids;
    if (p.hasChild("phaseArray")) {
        const XML_Node& pa = p.child("phaseArray");
        getStringArray(pa, phase_ids);
    }
    phase_ids.push_back(p["id"]);

    // Get reaction product and reactant information
    Composition reactants = parseCompString(r.child("reactants").value());
    Composition products = parseCompString(r.child("products").value());


    // If the reaction has undeclared species don't perform electrochemical check
    for (const auto& sp : reactants) {
        if (kin.kineticsSpeciesIndex(sp.first) == npos) {
            return true;
        }
    }

    for (const auto& sp : products) {
        if (kin.kineticsSpeciesIndex(sp.first) == npos) {
            return true;
        }
    }

    // Initialize the electron counter for each phase
    std::vector<double> e_counter(phase_ids.size(), 0.0);

    // Find the amount of electrons in the products for each phase
    for (const auto& sp : products) {
        const ThermoPhase& ph = kin.speciesPhase(sp.first);
        size_t k = ph.speciesIndex(sp.first);
        double stoich = sp.second;
        for (size_t m = 0; m < phase_ids.size(); m++) {
            if (phase_ids[m] == ph.id()) {
                e_counter[m] += stoich * ph.charge(k);
                break;
            }
        }
    }

    // Subtract the amount of electrons in the reactants for each phase
    for (const auto& sp : reactants) {
        const ThermoPhase& ph = kin.speciesPhase(sp.first);
        size_t k = ph.speciesIndex(sp.first);
        double stoich = sp.second;
        for (size_t m = 0; m < phase_ids.size(); m++) {
            if (phase_ids[m] == ph.id()) {
                e_counter[m] -= stoich * ph.charge(k);
                break;
            }
        }
    }

    // If the electrons change phases then the reaction is electrochemical
    bool echemical = false;
    for(size_t m = 0; m < phase_ids.size(); m++) {
        if (fabs(e_counter[m]) > 1e-4) {
            echemical = true;
            break;
        }
    }

    // If the reaction is electrochemical, ensure the reaction is identified as
    // electrochemical. If not already specified beta is assumed to be 0.5
    std::string type = ba::to_lower_copy(r["type"]);
    if (!r.child("rateCoeff").hasChild("electrochem")) {
        if ((type != "butlervolmer_noactivitycoeffs" &&
             type != "butlervolmer" &&
             type != "surfaceaffinity") &&
             echemical) {
            XML_Node& f = r.child("rateCoeff").addChild("electrochem","");
            f.addAttribute("beta",0.5);
        }
    }
    return true;
}
void IdealGasConstPressureReactor::evalEqs(doublereal time, doublereal* y,
                                   doublereal* ydot, doublereal* params)
{
    size_t nk;
    m_thermo->restoreState(m_state);

    Kinetics* kin;
    size_t npar, ploc;
    double mult;

    // process sensitivity parameters
    if (params) {

        npar = m_pnum.size();
        for (size_t n = 0; n < npar; n++) {
            mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult*params[n]);
        }
        ploc = npar;
        for (size_t m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->setSensitivityParameters(m_lr[m], params + ploc);
                ploc += m_nsens_wall[m];
            }
        }
    }

    m_Q = 0.0;

    // compute wall terms
    doublereal rs0, sum, wallarea;
    double mcpdTdt = 0.0; // m * c_p * dT/dt
    double dmdt = 0.0; // dm/dt (gas phase)
    double* dYdt = ydot + 2;
    m_thermo->getPartialMolarEnthalpies(&m_hk[0]);

    SurfPhase* surf;
    size_t lr, ns, loc = m_nsp+2, surfloc;
    fill(m_sdot.begin(), m_sdot.end(), 0.0);
    for (size_t i = 0; i < m_nwalls; i++) {
        lr = 1 - 2*m_lr[i];
        m_Q += lr*m_wall[i]->Q(time);
        kin = m_wall[i]->kinetics(m_lr[i]);
        surf = m_wall[i]->surface(m_lr[i]);
        if (surf && kin) {
            rs0 = 1.0/surf->siteDensity();
            nk = surf->nSpecies();
            sum = 0.0;
            surf->setTemperature(m_state[0]);
            m_wall[i]->syncCoverages(m_lr[i]);
            kin->getNetProductionRates(DATA_PTR(m_work));
            ns = kin->surfacePhaseIndex();
            surfloc = kin->kineticsSpeciesIndex(0,ns);
            for (size_t k = 1; k < nk; k++) {
                ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k);
                sum -= ydot[loc + k];
            }
            ydot[loc] = sum;
            loc += nk;

            wallarea = m_wall[i]->area();
            for (size_t k = 0; k < m_nsp; k++) {
                m_sdot[k] += m_work[k]*wallarea;
            }
        }
    }

    const vector_fp& mw = m_thermo->molecularWeights();
    const doublereal* Y = m_thermo->massFractions();

    if (m_chem) {
        m_kin->getNetProductionRates(&m_wdot[0]); // "omega dot"
    }

    double mdot_surf = 0.0; // net mass flux from surface
    for (size_t k = 0; k < m_nsp; k++) {
        // production in gas phase and from surfaces
        dYdt[k] = (m_wdot[k] * m_vol + m_sdot[k]) * mw[k] / m_mass;
        mdot_surf += m_sdot[k] * mw[k];
    }
    dmdt += mdot_surf;

    // external heat transfer
    mcpdTdt -= m_Q;

    for (size_t n = 0; n < m_nsp; n++) {
        // heat release from gas phase and surface reations
        mcpdTdt -= m_wdot[n] * m_hk[n] * m_vol;
        mcpdTdt -= m_sdot[n] * m_hk[n];
        // dilution by net surface mass flux
        dYdt[n] -= Y[n] * mdot_surf / m_mass;
    }

    // add terms for open system
    if (m_open) {
        // outlets
        for (size_t i = 0; i < m_nOutlets; i++) {
            dmdt -= m_outlet[i]->massFlowRate(time); // mass flow out of system
        }

        // inlets
        for (size_t i = 0; i < m_nInlets; i++) {
            double mdot_in = m_inlet[i]->massFlowRate(time);
            dmdt += mdot_in; // mass flow into system
            mcpdTdt += m_inlet[i]->enthalpy_mass() * mdot_in;
            for (size_t n = 0; n < m_nsp; n++) {
                double mdot_spec = m_inlet[i]->outletSpeciesMassFlowRate(n);
                // flow of species into system and dilution by other species
                dYdt[n] += (mdot_spec - mdot_in * Y[n]) / m_mass;
                mcpdTdt -= m_hk[n] / mw[n] * mdot_spec;
            }
        }
    }

    ydot[0] = dmdt;
    if (m_energy) {
        ydot[1] = mcpdTdt / (m_mass * m_thermo->cp_mass());
    } else {
        ydot[1] = 0.0;
    }

    // reset sensitivity parameters
    if (params) {
        npar = m_pnum.size();
        for (size_t n = 0; n < npar; n++) {
            mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult/params[n]);
        }
        ploc = npar;
        for (size_t m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->resetSensitivityParameters(m_lr[m]);
                ploc += m_nsens_wall[m];
            }
        }
    }
}
Esempio n. 16
0
void IdealGasReactor::evalEqs(doublereal time, doublereal* y,
                      doublereal* ydot, doublereal* params)
{
    m_thermo->restoreState(m_state);

    // process sensitivity parameters
    if (params) {
        size_t npar = m_pnum.size();
        for (size_t n = 0; n < npar; n++) {
            double mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult*params[n]);
        }
        size_t ploc = npar;
        for (size_t m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->setSensitivityParameters(m_lr[m], params + ploc);
                ploc += m_nsens_wall[m];
            }
        }
    }

    m_vdot = 0.0;
    m_Q    = 0.0;
    double mcvdTdt = 0.0; // m * c_v * dT/dt
    double dmdt = 0.0; // dm/dt (gas phase)
    double* dYdt = ydot + 3;

    m_thermo->getPartialMolarIntEnergies(&m_uk[0]);

    // compute wall terms
    size_t loc = m_nsp+3;
    fill(m_sdot.begin(), m_sdot.end(), 0.0);
    for (size_t i = 0; i < m_nwalls; i++) {
        int lr = 1 - 2*m_lr[i];
        double vdot = lr*m_wall[i]->vdot(time);
        m_vdot += vdot;
        m_Q += lr*m_wall[i]->Q(time);
        Kinetics* kin = m_wall[i]->kinetics(m_lr[i]);
        SurfPhase* surf = m_wall[i]->surface(m_lr[i]);
        if (surf && kin) {
            double rs0 = 1.0/surf->siteDensity();
            size_t nk = surf->nSpecies();
            double sum = 0.0;
            surf->setTemperature(m_state[0]);
            m_wall[i]->syncCoverages(m_lr[i]);
            kin->getNetProductionRates(DATA_PTR(m_work));
            size_t ns = kin->surfacePhaseIndex();
            size_t surfloc = kin->kineticsSpeciesIndex(0,ns);
            for (size_t k = 1; k < nk; k++) {
                ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k);
                sum -= ydot[loc + k];
            }
            ydot[loc] = sum;
            loc += nk;

            double wallarea = m_wall[i]->area();
            for (size_t k = 0; k < m_nsp; k++) {
                m_sdot[k] += m_work[k]*wallarea;
            }
        }
    }

    const vector_fp& mw = m_thermo->molecularWeights();
    const doublereal* Y = m_thermo->massFractions();

    if (m_chem) {
        m_kin->getNetProductionRates(&m_wdot[0]); // "omega dot"
    }

    double mdot_surf = 0.0; // net mass flux from surfaces
    for (size_t k = 0; k < m_nsp; k++) {
        // production in gas phase and from surfaces
        dYdt[k] = (m_wdot[k] * m_vol + m_sdot[k]) * mw[k] / m_mass;
        mdot_surf += m_sdot[k] * mw[k];
    }
    dmdt += mdot_surf;

    // compression work and external heat transfer
    mcvdTdt += - m_pressure * m_vdot - m_Q;

    for (size_t n = 0; n < m_nsp; n++) {
        // heat release from gas phase and surface reations
        mcvdTdt -= m_wdot[n] * m_uk[n] * m_vol;
        mcvdTdt -= m_sdot[n] * m_uk[n];
        // dilution by net surface mass flux
        dYdt[n] -= Y[n] * mdot_surf / m_mass;
    }

    // add terms for open system
    if (m_open) {
        // outlets
        for (size_t i = 0; i < m_nOutlets; i++) {
            double mdot_out = m_outlet[i]->massFlowRate(time);
            dmdt -= mdot_out; // mass flow out of system
            mcvdTdt -= mdot_out * m_pressure * m_vol / m_mass; // flow work
        }

        // inlets
        for (size_t i = 0; i < m_nInlets; i++) {
            double mdot_in = m_inlet[i]->massFlowRate(time);
            dmdt += mdot_in; // mass flow into system
            mcvdTdt += m_inlet[i]->enthalpy_mass() * mdot_in;
            for (size_t n = 0; n < m_nsp; n++) {
                double mdot_spec = m_inlet[i]->outletSpeciesMassFlowRate(n);
                // flow of species into system and dilution by other species
                dYdt[n] += (mdot_spec - mdot_in * Y[n]) / m_mass;

                // In combintion with h_in*mdot_in, flow work plus thermal
                // energy carried with the species
                mcvdTdt -= m_uk[n] / mw[n] * mdot_spec;
            }
        }
    }

    ydot[0] = dmdt;
    ydot[1] = m_vdot;
    if (m_energy) {
        ydot[2] = mcvdTdt / (m_mass * m_thermo->cv_mass());
    } else {
        ydot[2] = 0;
    }

    for (size_t i = 0; i < m_nv; i++) {
        AssertFinite(ydot[i], "IdealGasReactor::evalEqs",
                     "ydot[" + int2str(i) + "] is not finite");
    }

    // reset sensitivity parameters
    if (params) {
        size_t npar = m_pnum.size();
        for (size_t n = 0; n < npar; n++) {
            double mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult/params[n]);
        }
        size_t ploc = npar;
        for (size_t m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->resetSensitivityParameters(m_lr[m]);
                ploc += m_nsens_wall[m];
            }
        }
    }
}
Esempio n. 17
0
  /*
   *  This virtual routine can be used to duplicate %Kinetics objects
   *  inherited from %Kinetics even if the application only has
   *  a pointer to %Kinetics to work with.
   *
   *  These routines are basically wrappers around the derived copy
   *  constructor.
   */
  Kinetics *Kinetics::duplMyselfAsKinetics(const std::vector<thermo_t*> & tpVector) const {
    Kinetics* ko = new Kinetics(*this);

    ko->assignShallowPointers(tpVector);
    return ko;
  }
Esempio n. 18
0
/*
 * Called by the integrator to evaluate ydot given y at time 'time'.
 */
void Reactor::evalEqs(doublereal time, doublereal* y,
                      doublereal* ydot, doublereal* params)
{
    m_time = time;
    m_thermo->restoreState(m_state);

    // process sensitivity parameters
    if (params) {
        size_t npar = m_pnum.size();
        for (size_t n = 0; n < npar; n++) {
            double mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult*params[n]);
        }
        size_t ploc = npar;
        for (size_t m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->setSensitivityParameters(m_lr[m], params + ploc);
                ploc += m_nsens_wall[m];
            }
        }
    }

    m_vdot = 0.0;
    m_Q    = 0.0;

    // compute wall terms
    size_t loc = m_nsp+2;
    fill(m_sdot.begin(), m_sdot.end(), 0.0);
    for (size_t i = 0; i < m_nwalls; i++) {
        int lr = 1 - 2*m_lr[i];
        double vdot = lr*m_wall[i]->vdot(time);
        m_vdot += vdot;
        m_Q += lr*m_wall[i]->Q(time);
        Kinetics* kin = m_wall[i]->kinetics(m_lr[i]);
        SurfPhase* surf = m_wall[i]->surface(m_lr[i]);
        if (surf && kin) {
            double rs0 = 1.0/surf->siteDensity();
            size_t nk = surf->nSpecies();
            double sum = 0.0;
            surf->setTemperature(m_state[0]);
            m_wall[i]->syncCoverages(m_lr[i]);
            kin->getNetProductionRates(DATA_PTR(m_work));
            size_t ns = kin->surfacePhaseIndex();
            size_t surfloc = kin->kineticsSpeciesIndex(0,ns);
            for (size_t k = 1; k < nk; k++) {
                ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k);
                sum -= ydot[loc + k];
            }
            ydot[loc] = sum;
            loc += nk;

            double wallarea = m_wall[i]->area();
            for (size_t k = 0; k < m_nsp; k++) {
                m_sdot[k] += m_work[k]*wallarea;
            }
        }
    }

    // volume equation
    ydot[1] = m_vdot;

    /* species equations
     *  Equation is:
     *  \dot M_k = \hat W_k \dot\omega_k + \dot m_{in} Y_{k,in}
     *             - \dot m_{out} Y_{k} + A \dot s_k.
     */
    const vector_fp& mw = m_thermo->molecularWeights();
    if (m_chem) {
        m_kin->getNetProductionRates(ydot+2);   // "omega dot"
    } else {
        fill(ydot + 2, ydot + 2 + m_nsp, 0.0);
    }
    for (size_t n = 0; n < m_nsp; n++) {
        ydot[n+2] *= m_vol;     //           moles/s/m^3 -> moles/s
        ydot[n+2] += m_sdot[n];
        ydot[n+2] *= mw[n];
    }

    /*
     *  Energy equation.
     *  \f[
     *  \dot U = -P\dot V + A \dot q + \dot m_{in} h_{in}
     * - \dot m_{out} h.
     * \f]
     */
    if (m_energy) {
        ydot[0] = - m_thermo->pressure() * m_vdot - m_Q;
    } else {
        ydot[0] = 0.0;
    }

    // add terms for open system
    if (m_open) {
        const doublereal* mf = m_thermo->massFractions();
        doublereal enthalpy = m_thermo->enthalpy_mass();

        // outlets
        for (size_t i = 0; i < m_nOutlets; i++) {
            double mdot_out = m_outlet[i]->massFlowRate(time);
            for (size_t n = 0; n < m_nsp; n++) {
                ydot[2+n] -= mdot_out * mf[n];
            }
            if (m_energy) {
                ydot[0] -= mdot_out * enthalpy;
            }
        }

        // inlets
        for (size_t i = 0; i < m_nInlets; i++) {
            double mdot_in = m_inlet[i]->massFlowRate(time);
            for (size_t n = 0; n < m_nsp; n++) {
                ydot[2+n] += m_inlet[i]->outletSpeciesMassFlowRate(n);
            }
            if (m_energy) {
                ydot[0] += mdot_in * m_inlet[i]->enthalpy_mass();
            }
        }
    }

    // reset sensitivity parameters
    if (params) {
        size_t npar = m_pnum.size();
        for (size_t n = 0; n < npar; n++) {
            double mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult/params[n]);
        }
        size_t ploc = npar;
        for (size_t m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->resetSensitivityParameters(m_lr[m]);
                ploc += m_nsens_wall[m];
            }
        }
    }
}
Esempio n. 19
0
bool installReactionArrays(const XML_Node& p, Kinetics& kin,
                           std::string default_phase, bool check_for_duplicates)
{
    int itot = 0;

    // Search the children of the phase element for the XML element named
    // reactionArray. If we can't find it, then return signaling having not
    // found any reactions. Apparently, we allow multiple reactionArray elements
    // here Each one will be processed sequentially, with the end result being
    // purely additive.
    vector<XML_Node*> rarrays = p.getChildren("reactionArray");
    if (rarrays.empty()) {
        return false;
    }
    for (size_t n = 0; n < rarrays.size(); n++) {
        // Go get a reference to the current XML element, reactionArray. We will
        // process this element now.
        const XML_Node& rxns = *rarrays[n];

        // The reactionArray element has an attribute called, datasrc. The value
        // of the attribute is the XML element comprising the top of the tree of
        // reactions for the phase. Find this datasrc element starting with the
        // root of the current XML node.
        const XML_Node* rdata = get_XML_Node(rxns["datasrc"], &rxns.root());

        // If the reactionArray element has a child element named "skip", and if
        // the attribute of skip called "species" has a value of "undeclared",
        // we will set rxnrule.skipUndeclaredSpecies to 'true'. rxnrule is
        // passed to the routine that parses each individual reaction so that
        // the parser will skip all reactions containing an undefined species
        // without throwing an error.
        //
        // Similarly, an attribute named "third_bodies" with the value of
        // "undeclared" will skip undeclared third body efficiencies (while
        // retaining the reaction and any other efficiencies).
        if (rxns.hasChild("skip")) {
            const XML_Node& sk = rxns.child("skip");
            if (sk["species"] == "undeclared") {
                kin.skipUndeclaredSpecies(true);
            }
            if (sk["third_bodies"] == "undeclared") {
                kin.skipUndeclaredThirdBodies(true);
            }
        }

        // Search for child elements called include. We only include a reaction
        // if it's tagged by one of the include fields. Or, we include all
        // reactions if there are no include fields.
        vector<XML_Node*> incl = rxns.getChildren("include");
        vector<XML_Node*> allrxns = rdata->getChildren("reaction");
        // if no 'include' directive, then include all reactions
        if (incl.empty()) {
            for (size_t i = 0; i < allrxns.size(); i++) {
                checkElectrochemReaction(p,kin,*allrxns[i]);
                kin.addReaction(newReaction(*allrxns[i]));
                ++itot;
            }
        } else {
            for (size_t nii = 0; nii < incl.size(); nii++) {
                const XML_Node& ii = *incl[nii];
                string imin = ii["min"];
                string imax = ii["max"];

                string::size_type iwild = string::npos;
                if (imax == imin) {
                    iwild = imin.find("*");
                    if (iwild != string::npos) {
                        imin = imin.substr(0,iwild);
                        imax = imin;
                    }
                }

                for (size_t i = 0; i < allrxns.size(); i++) {
                    const XML_Node* r = allrxns[i];
                    string rxid;
                    if (r) {
                        rxid = r->attrib("id");
                        if (iwild != string::npos) {
                            rxid = rxid.substr(0,iwild);
                        }

                        // To decide whether the reaction is included or not we
                        // do a lexical min max and operation. This sometimes
                        // has surprising results.
                        if ((rxid >= imin) && (rxid <= imax)) {
                            checkElectrochemReaction(p,kin,*r);
                            kin.addReaction(newReaction(*r));
                            ++itot;
                        }
                    }
                }
            }
        }
    }

    if (check_for_duplicates) {
        kin.checkDuplicates();
    }

    return true;
}