1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // Antioch - A Gas Dynamics Thermochemistry Library
5 //
6 // Copyright (C) 2014-2016 Paul T. Bauman, Benjamin S. Kirk,
7 //                         Sylvain Plessis, Roy H. Stonger
8 //
9 // Copyright (C) 2013 The PECOS Development Team
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the Version 2.1 GNU Lesser General
13 // Public License as published by the Free Software Foundation.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
23 // Boston, MA  02110-1301  USA
24 //
25 //-----------------------------------------------------------------------el-
26 
27 #ifndef ANTIOCH_DUPLICATE_REACTION_H
28 #define ANTIOCH_DUPLICATE_REACTION_H
29 
30 // Antioch
31 #include "antioch/reaction.h"
32 #include "antioch/kinetics_conditions.h"
33 
34 //C++
35 #include <string>
36 #include <vector>
37 #include <iostream>
38 
39 namespace Antioch
40 {
41   //!A single reaction mechanism.
42   /*!\class DuplicateReaction
43  *
44     This class encapsulates a duplicate reaction process. A duplicate process
45     rate constant is defined by the equation
46     \f[
47         k(T,[M]) = \sum_n\alpha_n(T)
48     \f]
49     with \f$\alpha_i(T)\f$ being the \f$ith\f$ kinetics model (see base classes Reaction and KineticsType), and \f$[M]\f$
50     the mixture concentration (or pressure, it's equivalent, \f$[M] = \frac{P}{\mathrm{R}T}\f$
51     in an ideal gas model).  It is assumed that all the \f$\alpha_i\f$ are the same kinetics model.
52     All reactions are assumed to be reversible. By default, the kinetics model used is the KooijRate.
53 
54     We have:
55     \f[
56         \begin{split}
57            \frac{\partial k(T,[M])}{\partial T}   & = \sum_n\frac{\partial \alpha_n(T)}{\partial T} \\[10pt]
58            \frac{\partial k(T,[M])}{\partial c_i} & = 0
59         \end{split}
60     \f]
61     with \f$c_i\f$ the concentration of species \f$i\f$.
62   */
63   template <typename CoeffType=double>
64   class DuplicateReaction: public Reaction<CoeffType>
65   {
66   public:
67 
68     //! Construct a single reaction mechanism.
69     DuplicateReaction( const unsigned int n_species,
70                        const std::string &equation,
71                        const bool &reversible = true,
72                        const KineticsModel::KineticsModel kin = KineticsModel::KOOIJ);
73 
74     ~DuplicateReaction();
75 
76     //!
77     template <typename StateType, typename VectorStateType>
78     StateType compute_forward_rate_coefficient( const VectorStateType& molar_densities,
79                                                 const KineticsConditions<StateType,VectorStateType>& conditions ) const;
80 
81     //!
82     template <typename StateType, typename VectorStateType>
83     void compute_forward_rate_coefficient_and_derivatives( const VectorStateType& molar_densities,
84                                                            const KineticsConditions<StateType,VectorStateType>& conditions,
85                                                            StateType& kfwd,
86                                                            StateType& dkfwd_dT,
87                                                            VectorStateType& dkfwd_dX) const;
88 
89   private:
90 
91   };
92 
93   /* ------------------------- Inline Functions -------------------------*/
94   template <typename CoeffType>
95   inline
DuplicateReaction(const unsigned int n_species,const std::string & equation,const bool & reversible,const KineticsModel::KineticsModel kin)96   DuplicateReaction<CoeffType>::DuplicateReaction( const unsigned int n_species,
97                                                    const std::string &equation,
98                                                    const bool &reversible,
99                                                    const KineticsModel::KineticsModel kin)
100     :Reaction<CoeffType>(n_species,equation,reversible,ReactionType::DUPLICATE,kin){}
101 
102 
103   template <typename CoeffType>
104   inline
~DuplicateReaction()105   DuplicateReaction<CoeffType>::~DuplicateReaction()
106   {
107     return;
108   }
109 
110 
111 
112   template <typename CoeffType>
113   template<typename StateType, typename VectorStateType>
114   inline
compute_forward_rate_coefficient(const VectorStateType &,const KineticsConditions<StateType,VectorStateType> & conditions)115   StateType DuplicateReaction<CoeffType>::compute_forward_rate_coefficient
116     ( const VectorStateType& /* molar_densities */,
117       const KineticsConditions<StateType,VectorStateType>& conditions) const
118   {
119     StateType kfwd = (*this->_forward_rate[0])(conditions);
120     for(unsigned int ir = 1; ir < this->_forward_rate.size(); ir++)
121       {
122         kfwd += (*this->_forward_rate[ir])(conditions);
123       }
124 
125     antioch_assert(!has_nan(kfwd));
126 
127     return kfwd;
128   }
129 
130   template <typename CoeffType>
131   template<typename StateType, typename VectorStateType>
132   inline
compute_forward_rate_coefficient_and_derivatives(const VectorStateType &,const KineticsConditions<StateType,VectorStateType> & conditions,StateType & kfwd,StateType & dkfwd_dT,VectorStateType & dkfwd_dX)133   void DuplicateReaction<CoeffType>::compute_forward_rate_coefficient_and_derivatives
134     ( const VectorStateType& /* molar_densities */,
135       const KineticsConditions<StateType,VectorStateType>& conditions,
136       StateType& kfwd,
137       StateType& dkfwd_dT,
138       VectorStateType& dkfwd_dX) const
139   {
140     //dk_dT = sum_p dalpha_p_dT
141     StateType kfwd_tmp = Antioch::zero_clone(conditions.T());
142     StateType dkfwd_dT_tmp = Antioch::zero_clone(conditions.T());
143 
144     this->_forward_rate[0]->compute_rate_and_derivative(conditions,kfwd,dkfwd_dT);
145 
146     for(unsigned int ir = 1; ir < Reaction<CoeffType>::_forward_rate.size(); ir++)
147       {
148         this->_forward_rate[ir]->compute_rate_and_derivative(conditions,kfwd_tmp,dkfwd_dT_tmp);
149         kfwd += kfwd_tmp;
150         dkfwd_dT += dkfwd_dT_tmp;
151       }
152 
153     antioch_assert(!has_nan(kfwd));
154 
155     //dk_dCi = 0
156     antioch_assert_equal_to(dkfwd_dX.size(),this->n_species());
157     Antioch::set_zero(dkfwd_dX);
158 
159     return;
160   }
161 
162 } // namespace Antioch
163 
164 #endif // ANTIOCH_ELEMENTARY_REACTION_H
165