11#include "cantera/numerics/eigen_sparse.h"
134 C1(
size_t rxn = 0,
size_t ic0 = 0) :
139 void incrementSpecies(span<const double> R, span<double> S)
const {
143 void decrementSpecies(span<const double> R, span<double> S)
const {
147 void multiply(span<const double> S, span<double> R)
const {
151 void incrementReaction(span<const double> S, span<double> R)
const {
155 void decrementReaction(span<const double> S, span<double> R)
const {
159 void resizeCoeffs(
const map<pair<size_t, size_t>,
size_t>& indices)
164 void derivatives(span<const double> S, span<const double> R,
165 span<double> jac)
const
171 void scale(span<const double> R, span<double> out,
double factor)
const {
192 C2(
size_t rxn = 0,
size_t ic0 = 0,
size_t ic1 = 0)
195 void incrementSpecies(span<const double> R, span<double> S)
const {
197 S[m_ic1] += R[
m_rxn];
200 void decrementSpecies(span<const double> R, span<double> S)
const {
202 S[m_ic1] -= R[
m_rxn];
205 void multiply(span<const double> S, span<double> R)
const {
206 if (S[
m_ic0] < 0 && S[m_ic1] < 0) {
213 void incrementReaction(span<const double> S, span<double> R)
const {
217 void decrementReaction(span<const double> S, span<double> R)
const {
221 void resizeCoeffs(
const map<pair<size_t, size_t>,
size_t>& indices)
227 void derivatives(span<const double> S, span<const double> R,
228 span<double> jac)
const
231 jac[m_jc0] += R[
m_rxn] * S[m_ic1];
238 void scale(span<const double> R, span<double> out,
double factor)
const
261 C3(
size_t rxn = 0,
size_t ic0 = 0,
size_t ic1 = 0,
size_t ic2 = 0)
262 : m_rxn(rxn), m_ic0(ic0), m_ic1(ic1), m_ic2(ic2) {}
264 void incrementSpecies(span<const double> R, span<double> S)
const {
265 S[m_ic0] += R[m_rxn];
266 S[m_ic1] += R[m_rxn];
267 S[m_ic2] += R[m_rxn];
270 void decrementSpecies(span<const double> R, span<double> S)
const {
271 S[m_ic0] -= R[m_rxn];
272 S[m_ic1] -= R[m_rxn];
273 S[m_ic2] -= R[m_rxn];
276 void multiply(span<const double> S, span<double> R)
const {
277 if ((S[m_ic0] < 0 && (S[m_ic1] < 0 || S[m_ic2] < 0)) ||
278 (S[m_ic1] < 0 && S[m_ic2] < 0)) {
281 R[m_rxn] *= S[m_ic0] * S[m_ic1] * S[m_ic2];
285 void incrementReaction(span<const double> S, span<double> R)
const {
286 R[m_rxn] += S[m_ic0] + S[m_ic1] + S[m_ic2];
289 void decrementReaction(span<const double> S, span<double> R)
const {
290 R[m_rxn] -= (S[m_ic0] + S[m_ic1] + S[m_ic2]);
293 void resizeCoeffs(
const map<pair<size_t, size_t>,
size_t>& indices)
295 m_jc0 = indices.at({m_rxn, m_ic0});
296 m_jc1 = indices.at({m_rxn, m_ic1});
297 m_jc2 = indices.at({m_rxn, m_ic2});
300 void derivatives(span<const double> S, span<const double> R,
301 span<double> jac)
const
303 if (S[m_ic1] > 0 && S[m_ic2] > 0) {
304 jac[m_jc0] += R[m_rxn] * S[m_ic1] * S[m_ic2];;
306 if (S[m_ic0] > 0 && S[m_ic2] > 0) {
307 jac[m_jc1] += R[m_rxn] * S[m_ic0] * S[m_ic2];
309 if (S[m_ic0] > 0 && S[m_ic1] > 0) {
310 jac[
m_jc2] += R[m_rxn] * S[m_ic0] * S[m_ic1];
314 void scale(span<const double> R, span<double> out,
double factor)
const
316 out[m_rxn] = 3 * R[m_rxn] * factor;
339 C_AnyN(
size_t rxn, span<const size_t> ic,
340 span<const double> order_, span<const double> stoich_) :
347 for (
size_t n = 0; n <
m_n; n++) {
354 void multiply(span<const double> input, span<double> output)
const {
355 for (
size_t n = 0; n <
m_n; n++) {
358 double c = input[
m_ic[n]];
360 output[
m_rxn] *= std::pow(c, order);
368 void incrementSpecies(span<const double> input, span<double> output)
const {
369 double x = input[
m_rxn];
370 for (
size_t n = 0; n <
m_n; n++) {
375 void decrementSpecies(span<const double> input, span<double> output)
const {
376 double x = input[
m_rxn];
377 for (
size_t n = 0; n <
m_n; n++) {
382 void incrementReaction(span<const double> input, span<double> output)
const {
383 for (
size_t n = 0; n <
m_n; n++) {
388 void decrementReaction(span<const double> input, span<double> output)
const {
389 for (
size_t n = 0; n <
m_n; n++) {
394 void resizeCoeffs(
const map<pair<size_t, size_t>,
size_t>& indices)
396 for (
size_t i = 0; i <
m_n; i++) {
401 for (
size_t n = 0; n <
m_n; ++n) {
406 void derivatives(span<const double> S, span<const double> R,
407 span<double> jac)
const
409 for (
size_t i = 0; i <
m_n; i++) {
411 double prod = R[
m_rxn];
413 if (S[
m_ic[i]] > 0. && order_i != 0.) {
414 prod *= order_i * std::pow(S[
m_ic[i]], order_i - 1);
415 for (
size_t j = 0; j <
m_n; j++) {
417 if (S[
m_ic[j]] > 0) {
428 jac[
m_jc[i]] += prod;
432 void scale(span<const double> R, span<double> out,
double factor)
const
482template<
class InputIter,
class Vec1,
class Vec2>
483inline static void _multiply(InputIter begin, InputIter end,
484 const Vec1& input, Vec2& output)
486 for (; begin != end; ++begin) {
487 begin->multiply(input, output);
491template<
class InputIter,
class Vec1,
class Vec2>
492inline static void _incrementSpecies(InputIter begin,
493 InputIter end,
const Vec1& input, Vec2& output)
495 for (; begin != end; ++begin) {
496 begin->incrementSpecies(input, output);
500template<
class InputIter,
class Vec1,
class Vec2>
501inline static void _decrementSpecies(InputIter begin,
502 InputIter end,
const Vec1& input, Vec2& output)
504 for (; begin != end; ++begin) {
505 begin->decrementSpecies(input, output);
509template<
class InputIter,
class Vec1,
class Vec2>
510inline static void _incrementReactions(InputIter begin,
511 InputIter end,
const Vec1& input, Vec2& output)
513 for (; begin != end; ++begin) {
514 begin->incrementReaction(input, output);
518template<
class InputIter,
class Vec1,
class Vec2>
519inline static void _decrementReactions(InputIter begin,
520 InputIter end,
const Vec1& input, Vec2& output)
522 for (; begin != end; ++begin) {
523 begin->decrementReaction(input, output);
527template<
class InputIter,
class Indices>
528inline static void _resizeCoeffs(InputIter begin, InputIter end, Indices& ix)
530 for (; begin != end; ++begin) {
531 begin->resizeCoeffs(ix);
535template<
class InputIter,
class Vec1,
class Vec2,
class Vec3>
536inline static void _derivatives(InputIter begin, InputIter end,
537 const Vec1& S,
const Vec2& R, Vec3& jac)
539 for (; begin != end; ++begin) {
540 begin->derivatives(S, R, jac);
544template<
class InputIter,
class Vec1,
class Vec2>
545inline static void _scale(InputIter begin, InputIter end,
546 const Vec1& in, Vec2& out,
double factor)
548 for (; begin != end; ++begin) {
549 begin->scale(in, out, factor);
598 m_stoichCoeffs.setZero();
599 m_stoichCoeffs.resize(0, 0);
608 m_stoichCoeffs.resize(nSpc, nRxn);
609 m_stoichCoeffs.reserve(nCoeffs);
613 Eigen::SparseMatrix<double> tmp = m_stoichCoeffs.transpose();
615 for (
int i = 0; i < tmp.outerSize() + 1; i++) {
618 m_innerIndices.resize(nCoeffs);
619 for (
size_t n = 0; n < nCoeffs; n++) {
620 m_innerIndices[n] = tmp.innerIndexPtr()[n];
622 m_values.resize(nCoeffs, 0.);
625 map<pair<size_t, size_t>,
size_t> indices;
627 for (
int i = 0; i < tmp.outerSize(); i++) {
628 for (Eigen::SparseMatrix<double>::InnerIterator it(tmp, i); it; ++it) {
629 indices[{
static_cast<size_t>(it.row()),
630 static_cast<size_t>(it.col())}] = n++;
634 _resizeCoeffs(m_c1_list.begin(), m_c1_list.end(), indices);
635 _resizeCoeffs(m_c2_list.begin(), m_c2_list.end(), indices);
636 _resizeCoeffs(m_c3_list.begin(), m_c3_list.end(), indices);
637 _resizeCoeffs(m_cn_list.begin(), m_cn_list.end(), indices);
649 void add(
size_t rxn, span<const size_t> k) {
650 vector<double> order(k.size(), 1.0);
651 vector<double> stoich(k.size(), 1.0);
652 add(rxn, k, order, stoich);
655 void add(
size_t rxn, span<const size_t> k, span<const double> order) {
656 vector<double> stoich(k.size(), 1.0);
657 add(rxn, k, order, stoich);
676 void add(
size_t rxn, span<const size_t> k, span<const double> order,
677 span<const double> stoich) {
678 if (order.size() != k.size()) {
680 "StoichManagerN::add()",
"size of order and species arrays differ");
682 if (stoich.size() != k.size()) {
684 "StoichManagerN::add()",
"size of stoich and species arrays differ");
687 for (
size_t n = 0; n < stoich.size(); n++) {
689 static_cast<int>(k[n]),
static_cast<int>(rxn), stoich[n]);
690 if (fmod(stoich[n], 1.0) || stoich[n] != order[n]) {
694 if (frac || k.size() > 3) {
695 m_cn_list.emplace_back(rxn, k, order, stoich);
702 for (
size_t n = 0; n < k.size(); n++) {
703 for (
size_t i = 0; i < stoich[n]; i++) {
704 kRep.push_back(k[n]);
708 switch (kRep.size()) {
710 m_c1_list.emplace_back(rxn, kRep[0]);
713 m_c2_list.emplace_back(rxn, kRep[0], kRep[1]);
716 m_c3_list.emplace_back(rxn, kRep[0], kRep[1], kRep[2]);
719 m_cn_list.emplace_back(rxn, k, order, stoich);
725 void multiply(span<const double> input, span<double> output)
const {
726 _multiply(m_c1_list.begin(), m_c1_list.end(), input, output);
727 _multiply(m_c2_list.begin(), m_c2_list.end(), input, output);
728 _multiply(m_c3_list.begin(), m_c3_list.end(), input, output);
729 _multiply(m_cn_list.begin(), m_cn_list.end(), input, output);
732 void incrementSpecies(span<const double> input, span<double> output)
const {
733 _incrementSpecies(m_c1_list.begin(), m_c1_list.end(), input, output);
734 _incrementSpecies(m_c2_list.begin(), m_c2_list.end(), input, output);
735 _incrementSpecies(m_c3_list.begin(), m_c3_list.end(), input, output);
736 _incrementSpecies(m_cn_list.begin(), m_cn_list.end(), input, output);
739 void decrementSpecies(span<const double> input, span<double> output)
const {
740 _decrementSpecies(m_c1_list.begin(), m_c1_list.end(), input, output);
741 _decrementSpecies(m_c2_list.begin(), m_c2_list.end(), input, output);
742 _decrementSpecies(m_c3_list.begin(), m_c3_list.end(), input, output);
743 _decrementSpecies(m_cn_list.begin(), m_cn_list.end(), input, output);
746 void incrementReactions(span<const double> input, span<double> output)
const {
747 _incrementReactions(m_c1_list.begin(), m_c1_list.end(), input, output);
748 _incrementReactions(m_c2_list.begin(), m_c2_list.end(), input, output);
749 _incrementReactions(m_c3_list.begin(), m_c3_list.end(), input, output);
750 _incrementReactions(m_cn_list.begin(), m_cn_list.end(), input, output);
753 void decrementReactions(span<const double> input, span<double> output)
const {
754 _decrementReactions(m_c1_list.begin(), m_c1_list.end(), input, output);
755 _decrementReactions(m_c2_list.begin(), m_c2_list.end(), input, output);
756 _decrementReactions(m_c3_list.begin(), m_c3_list.end(), input, output);
757 _decrementReactions(m_cn_list.begin(), m_cn_list.end(), input, output);
767 throw CanteraError(
"StoichManagerN::stoichCoeffs",
"The object "
768 "is not fully configured; make sure to call resizeCoeffs().");
770 return m_stoichCoeffs;
784 span<const double> rates)
787 std::fill(m_values.begin(), m_values.end(), 0.);
788 _derivatives(m_c1_list.begin(), m_c1_list.end(), conc, rates, m_values);
789 _derivatives(m_c2_list.begin(), m_c2_list.end(), conc, rates, m_values);
790 _derivatives(m_c3_list.begin(), m_c3_list.end(), conc, rates, m_values);
791 _derivatives(m_cn_list.begin(), m_cn_list.end(), conc, rates, m_values);
793 return Eigen::Map<Eigen::SparseMatrix<double>>(
794 m_stoichCoeffs.cols(), m_stoichCoeffs.rows(), m_values.size(),
799 void scale(span<const double> in, span<double> out,
double factor)
const
801 _scale(m_c1_list.begin(), m_c1_list.end(), in, out, factor);
802 _scale(m_c2_list.begin(), m_c2_list.end(), in, out, factor);
803 _scale(m_c3_list.begin(), m_c3_list.end(), in, out, factor);
804 _scale(m_cn_list.begin(), m_cn_list.end(), in, out, factor);
810 vector<C1> m_c1_list;
811 vector<C2> m_c2_list;
812 vector<C3> m_c3_list;
813 vector<C_AnyN> m_cn_list;
817 Eigen::SparseMatrix<double> m_stoichCoeffs;
821 vector<int> m_innerIndices;
822 vector<double> m_values;
Handles one species in a reaction.
size_t m_rxn
Reaction number.
size_t m_jc0
Index in derivative triplet vector.
size_t m_ic0
Species number.
Handles two species in a single reaction.
size_t m_rxn
Reaction index -> index into the ROP vector.
size_t m_ic0
Species index -> index into the species vector for the two species.
size_t m_jc1
Indices in derivative triplet vector.
Handles three species in a reaction.
size_t m_jc2
Indices in derivative triplet vector.
Handles any number of species in a reaction, including fractional stoichiometric coefficients,...
size_t m_rxn
ID of the reaction corresponding to this stoichiometric manager.
vector< double > m_stoich
Stoichiometric coefficients for the reaction, reactant or product side.
double m_sum_order
Sum of reaction order vector.
vector< size_t > m_ic
Vector of species which are involved with this stoichiometric manager calculations.
vector< double > m_order
Reaction orders for the reaction.
vector< size_t > m_jc
Indices in derivative triplet vector.
size_t m_n
Length of the m_ic vector.
Base class for exceptions thrown by Cantera classes.
This class handles operations involving the stoichiometric coefficients on one side of a reaction (re...
vector< int > m_outerIndices
Storage indicies used to build derivatives.
bool m_ready
Boolean flag indicating whether object is fully configured.
Eigen::SparseMatrix< double > derivatives(span< const double > conc, span< const double > rates)
Calculate derivatives with respect to species concentrations.
SparseTriplets m_coeffList
Sparse matrices for stoichiometric coefficients.
void scale(span< const double > in, span< double > out, double factor) const
Scale input by reaction order and factor.
void resizeCoeffs(size_t nSpc, size_t nRxn)
Resize the sparse coefficient matrix.
void add(size_t rxn, span< const size_t > k)
Add a single reaction to the list of reactions that this stoichiometric manager object handles.
void add(size_t rxn, span< const size_t > k, span< const double > order, span< const double > stoich)
Add a single reaction to the list of reactions that this stoichiometric manager object handles.
const Eigen::SparseMatrix< double > & stoichCoeffs() const
Return matrix containing stoichiometric coefficients.
StoichManagerN()
Constructor for the StoichManagerN class.
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"