Esempio n. 1
0
    void InterfaceKinetics::checkPartialEquil() {
        int i, irxn;
        vector_fp dmu(nTotalSpecies(), 0.0);
        vector_fp rmu(nReactions(), 0.0);
        vector_fp frop(nReactions(), 0.0);
        vector_fp rrop(nReactions(), 0.0);
        vector_fp netrop(nReactions(), 0.0);
        if (m_nrev > 0) {
            doublereal rt = GasConstant*thermo(0).temperature();
            cout << "T = " << thermo(0).temperature() << " " << rt << endl;
            int n, nsp, k, ik=0;
            //doublereal rt = GasConstant*thermo(0).temperature();
            //            doublereal rrt = 1.0/rt;
            int np = nPhases();
            doublereal delta;
            for (n = 0; n < np; n++) {
                thermo(n).getChemPotentials(DATA_PTR(dmu) + m_start[n]);
                nsp = thermo(n).nSpecies();
                for (k = 0; k < nsp; k++) {
                    delta = Faraday * m_phi[n] * thermo(n).charge(k);
                    //cout << thermo(n).speciesName(k) << "   " << (delta+dmu[ik])/rt << " " << dmu[ik]/rt << endl;
                    dmu[ik] += delta;
                    ik++;
                }
            }

            // compute Delta mu^ for all reversible reactions
            m_rxnstoich.getRevReactionDelta(m_ii, DATA_PTR(dmu), DATA_PTR(rmu));
            getFwdRatesOfProgress(DATA_PTR(frop));
            getRevRatesOfProgress(DATA_PTR(rrop));
            getNetRatesOfProgress(DATA_PTR(netrop));
            for (i = 0; i < m_nrev; i++) {
                irxn = m_revindex[i];
                cout << "Reaction " << reactionString(irxn) 
                     << "  " << rmu[irxn]/rt << endl;
                printf("%12.6e  %12.6e  %12.6e  %12.6e \n", 
                    frop[irxn], rrop[irxn], netrop[irxn], 
                    netrop[irxn]/(frop[irxn] + rrop[irxn]));
            }
        }
    }
Esempio n. 2
0
std::pair<size_t, size_t> Kinetics::checkDuplicates(bool throw_err) const
{
    //! Map of (key indicating participating species) to reaction numbers
    std::map<size_t, std::vector<size_t> > participants;
    std::vector<std::map<int, double> > net_stoich;

    for (size_t i = 0; i < m_reactions.size(); i++) {
        // Get data about this reaction
        unsigned long int key = 0;
        Reaction& R = *m_reactions[i];
        net_stoich.emplace_back();
        std::map<int, double>& net = net_stoich.back();
        for (const auto& sp : R.reactants) {
            int k = static_cast<int>(kineticsSpeciesIndex(sp.first));
            key += k*(k+1);
            net[-1 -k] -= sp.second;
        }
        for (const auto& sp : R.products) {
            int k = static_cast<int>(kineticsSpeciesIndex(sp.first));
            key += k*(k+1);
            net[1+k] += sp.second;
        }

        // Compare this reaction to others with similar participants
        vector<size_t>& related = participants[key];
        for (size_t m = 0; m < related.size(); m++) {
            Reaction& other = *m_reactions[related[m]];
            if (R.reaction_type != other.reaction_type) {
                continue; // different reaction types
            } else if (R.duplicate && other.duplicate) {
                continue; // marked duplicates
            }
            doublereal c = checkDuplicateStoich(net_stoich[i], net_stoich[m]);
            if (c == 0) {
                continue; // stoichiometries differ (not by a multiple)
            } else if (c < 0.0 && !R.reversible && !other.reversible) {
                continue; // irreversible reactions in opposite directions
            } else if (R.reaction_type == FALLOFF_RXN ||
                       R.reaction_type == CHEMACT_RXN) {
                ThirdBody& tb1 = dynamic_cast<FalloffReaction&>(R).third_body;
                ThirdBody& tb2 = dynamic_cast<FalloffReaction&>(other).third_body;
                bool thirdBodyOk = true;
                for (size_t k = 0; k < nTotalSpecies(); k++) {
                    string s = kineticsSpeciesName(k);
                    if (tb1.efficiency(s) * tb2.efficiency(s) != 0.0) {
                        // non-zero third body efficiencies for species `s` in
                        // both reactions
                        thirdBodyOk = false;
                        break;
                    }
                }
                if (thirdBodyOk) {
                    continue; // No overlap in third body efficiencies
                }
            } else if (R.reaction_type == THREE_BODY_RXN) {
                ThirdBody& tb1 = dynamic_cast<ThreeBodyReaction&>(R).third_body;
                ThirdBody& tb2 = dynamic_cast<ThreeBodyReaction&>(other).third_body;
                bool thirdBodyOk = true;
                for (size_t k = 0; k < nTotalSpecies(); k++) {
                    string s = kineticsSpeciesName(k);
                    if (tb1.efficiency(s) * tb2.efficiency(s) != 0.0) {
                        // non-zero third body efficiencies for species `s` in
                        // both reactions
                        thirdBodyOk = false;
                        break;
                    }
                }
                if (thirdBodyOk) {
                    continue; // No overlap in third body efficiencies
                }
            }
            if (throw_err) {
                throw CanteraError("installReaction",
                        "Undeclared duplicate reactions detected:\n"
                        "Reaction {}: {}\nReaction {}: {}\n",
                        i+1, other.equation(), m+1, R.equation());
            } else {
                return {i,m};
            }
        }
        participants[key].push_back(i);
    }
    return {npos, npos};
}