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_MICRO_THERMO_BASE_H
28 #define ANTIOCH_MICRO_THERMO_BASE_H
29 
30 // Antioch
31 #include "antioch/chemical_mixture.h"
32 
33 namespace Antioch
34 {
35 
36   template<typename CoeffType, typename Subclass>
37   class MacroMicroThermoBase
38   {
39   public:
40 
MacroMicroThermoBase(const ChemicalMixture<CoeffType> & chem_mixture)41     MacroMicroThermoBase( const ChemicalMixture<CoeffType>& chem_mixture )
42       : _chem_mixture(chem_mixture)
43     {}
44 
45     //! Pure virtual destructor
46     /*! This is pure virtual to force this object to be abstract. */
47     virtual ~MacroMicroThermoBase() =0;
48 
49     /*!
50      * @returns species translational specific heat at constant volume, [J/kg-K].
51      * Since the translational modes are assumed to be fully polulated
52      * this is simply
53      * \f[
54      *   C^{trans}_{v,s} \equiv \frac{\partial e^{trans}_s}{\partial T} = \frac{3}{2} R_s
55      * \f]
56      */
57     CoeffType cv_trans( const unsigned int species ) const;
58 
59     /*!
60      * @returns species translational specific over R heat at constant volume.
61      * Since the translational modes are assumed to be fully polulated
62      * this is simply
63      * \f[
64      *   \frac{C^{trans}_{v,s}}{\mathrm{R}} = \frac{3}{2}
65      * \f]
66      */
67     CoeffType cv_trans_over_R( const unsigned int species ) const;
68 
69     /*!
70      * @returns species rotational specific heat at constant volume, [J/kg-K].
71      * By convention, we lump the translational/rotational components
72      * \f[
73      *   C^{tr}_{v,s} \equiv C^{trans}_{v,s} + C^{rot}_{v,s}
74      * \f]
75      * so then
76      * \f[
77      *   C^{rot}_{v,s} \equiv C^{tr}_{v,s} - C^{trans}_{v,s}
78      * \f]
79      */
80     CoeffType cv_rot( const unsigned int species ) const;
81 
82     /*!
83      * @returns species rotational specific heat at constant volume, normalized
84      * by the species gas constant.
85      * By convention, we lump the translational/rotational components
86      * \f[
87      *   C^{tr}_{v,s} \equiv C^{trans}_{v,s} + C^{rot}_{v,s}
88      * \f]
89      * so then
90      * \f[
91      *   \frac{C^{rot}_{v,s}}{\mathrm{R}} \equiv \frac{C^{tr}_{v,s}}{\mathrm{R}} - \frac{C^{trans}_{v,s}}{\mathrm{R}}
92      * \f]
93      */
94     CoeffType cv_rot_over_R( const unsigned int species ) const;
95 
96     /*!
97      * @returns species translational+rotational specific heat at
98      * constant volume, [J/kg-K].
99      */
100     CoeffType cv_tr (const unsigned int species) const;
101 
102     /*!
103      * @returns mixture translational+rotational specific heat at
104      * constant volume, [J/kg-K]. The return type depends on the value type
105      * of the incoming mas fraction vector type. If the mass_fractions are vector
106      * of scalar types, the return type will be that scalar type, etc.
107      */
108     template<typename VectorStateType>
109     typename enable_if_c<
110       has_size<VectorStateType>::value,
111       typename Antioch::value_type<VectorStateType>::type
112     >::type
113     cv_tr (const VectorStateType& mass_fractions) const;
114 
115     /*!
116      * @returns species translational+rotational specific heat at
117      * constant volume, normalized by the species gas constant.
118      */
119     CoeffType cv_tr_over_R (const unsigned int species) const;
120 
121     /*!
122      * @returns species vibrational specific heat at constant volume in [J/kg-K]
123      * at the given temperature. This is a CRTP shim, subclasses are required
124      * to implement this function.
125      */
126     template<typename StateType>
127     StateType cv_vib (const unsigned int species, const StateType & T) const;
128 
129     /*!
130      * @returns species vibrational specific heat at constant volume,
131      * normalized by species gas constant, at the given temperature.
132      * This is a CRTP shim, subclasses are required to implement this
133      * function.
134      */
135     template<typename StateType>
136     StateType cv_vib_over_R (const unsigned int species, const StateType & T) const;
137 
138     /*!
139      * @returns mixture vibrational specific heat at constant volume in [J/kg-K]
140      * at the given temperature. The return type is based on the type of T:
141      * if T is a scalar type, the return type will also be the scalar type;
142      * if T is a vector type, the return type will be the vector type, etc.
143      */
144     template<typename VectorStateType>
145     typename enable_if_c<
146       has_size<VectorStateType>::value,
147       typename Antioch::value_type<VectorStateType>::type
148     >::type
149     cv_vib (const typename Antioch::value_type<VectorStateType>::type& T,
150             const VectorStateType& mass_fractions) const;
151 
152     /*!
153      * @returns species electronic specific heat at constant volume in [J/kg-K]
154      * at the given temperature. This is a CRTP shim, subclasses are required to
155      * implement this function.
156      */
157     template<typename StateType>
158     StateType cv_el (const unsigned int species, const StateType& T) const;
159 
160     /*!
161      * @returns mixture electronic specific heat at constant volume in [J/kg-K]
162      * at the given temperature. The return type is based on the type of T:
163      * if T is a scalar type, the return type will also be the scalar type;
164      * if T is a vector type, the return type will be the vector type, etc.
165      */
166     template<typename VectorStateType>
167     typename enable_if_c<
168       has_size<VectorStateType>::value,
169       typename Antioch::value_type<VectorStateType>::type
170     >::type
171     cv_el (const typename Antioch::value_type<VectorStateType>::type& T,
172            const VectorStateType& mass_fractions) const;
173 
174   protected:
175 
176     const ChemicalMixture<CoeffType> & _chem_mixture;
177 
178   private:
179 
180     //! Default constructor
181     /*! Private to force to user to supply a ChemicalMixture object.*/
182     MacroMicroThermoBase();
183   };
184 
185   /* ------------------------- Inline Functions -------------------------*/
186   template<typename CoeffType, typename Subclass>
187   inline
~MacroMicroThermoBase()188   MacroMicroThermoBase<CoeffType,Subclass>::~MacroMicroThermoBase(){}
189 
190   template<typename CoeffType, typename Subclass>
191   inline
cv_trans(const unsigned int species)192   CoeffType MacroMicroThermoBase<CoeffType,Subclass>::cv_trans( const unsigned int species ) const
193   {
194     return CoeffType(1.5)*this->_chem_mixture.R(species);
195   }
196 
197   template<typename CoeffType, typename Subclass>
198   inline
cv_trans_over_R(const unsigned int)199   CoeffType MacroMicroThermoBase<CoeffType,Subclass>::cv_trans_over_R( const unsigned int /*species*/ ) const
200   {
201     return CoeffType(1.5);
202   }
203 
204   template<typename CoeffType, typename Subclass>
205   inline
cv_rot(const unsigned int species)206   CoeffType MacroMicroThermoBase<CoeffType,Subclass>::cv_rot( const unsigned int species ) const
207   {
208     using std::max;
209 
210     return max(this->cv_tr(species) - this->cv_trans(species), CoeffType(0) );
211   }
212 
213    template<typename CoeffType, typename Subclass>
214    inline
cv_rot_over_R(const unsigned int species)215   CoeffType MacroMicroThermoBase<CoeffType,Subclass>::cv_rot_over_R( const unsigned int species ) const
216   {
217     using std::max;
218 
219     return max(this->cv_tr_over_R(species) - this->cv_trans_over_R(species), CoeffType(0) );
220   }
221 
222   template<typename CoeffType, typename Subclass>
223   inline
cv_tr(const unsigned int species)224   CoeffType MacroMicroThermoBase<CoeffType,Subclass>::cv_tr (const unsigned int species) const
225   {
226     return this->_chem_mixture.R(species)*(this->_chem_mixture.chemical_species()[species])->n_tr_dofs();
227   }
228 
229   template<typename CoeffType, typename Subclass>
230   inline
cv_tr_over_R(const unsigned int species)231   CoeffType MacroMicroThermoBase<CoeffType,Subclass>::cv_tr_over_R (const unsigned int species) const
232   {
233     return (this->_chem_mixture.chemical_species()[species])->n_tr_dofs();
234   }
235 
236   template<typename CoeffType, typename Subclass>
237   template<typename VectorStateType>
238   inline
239   typename enable_if_c<
240     has_size<VectorStateType>::value,
241     typename Antioch::value_type<VectorStateType>::type
242   >::type
cv_tr(const VectorStateType & mass_fractions)243   MacroMicroThermoBase<CoeffType,Subclass>::cv_tr (const VectorStateType& mass_fractions) const
244   {
245     typename Antioch::value_type<VectorStateType>::type
246       cv_tr = mass_fractions[0]*this->cv_tr(0);
247 
248     for( unsigned int s = 1; s < this->_chem_mixture.n_species(); s++ )
249       cv_tr += mass_fractions[s]*this->cv_tr(s);
250 
251     return cv_tr;
252   }
253 
254   template<typename CoeffType, typename Subclass>
255   template<typename VectorStateType>
256   inline
257   typename enable_if_c<
258     has_size<VectorStateType>::value,
259     typename Antioch::value_type<VectorStateType>::type
260   >::type
cv_vib(const typename Antioch::value_type<VectorStateType>::type & T,const VectorStateType & mass_fractions)261   MacroMicroThermoBase<CoeffType,Subclass>::cv_vib (const typename Antioch::value_type<VectorStateType>::type& T,
262                                       const VectorStateType& mass_fractions) const
263   {
264     typename Antioch::value_type<VectorStateType>::type
265       cv_vib = mass_fractions[0]*this->cv_vib(0, T);
266 
267     for( unsigned int s = 1; s < this->_chem_mixture.n_species(); s++ )
268       cv_vib += mass_fractions[s]*this->cv_vib(s, T);
269 
270     return cv_vib;
271   }
272 
273   template<typename CoeffType, typename Subclass>
274   template<typename VectorStateType>
275   inline
276   typename enable_if_c<
277     has_size<VectorStateType>::value,
278     typename Antioch::value_type<VectorStateType>::type
279   >::type
cv_el(const typename Antioch::value_type<VectorStateType>::type & T,const VectorStateType & mass_fractions)280   MacroMicroThermoBase<CoeffType,Subclass>::cv_el (const typename Antioch::value_type<VectorStateType>::type& T,
281                                               const VectorStateType& mass_fractions) const
282   {
283     typename Antioch::value_type<VectorStateType>::type
284       cv_el = mass_fractions[0]*this->cv_el(0, T);
285 
286     for( unsigned int s = 1; s < this->_chem_mixture.n_species(); s++ )
287       cv_el += mass_fractions[s]*this->cv_el(s, T);
288 
289     return cv_el;
290   }
291 
292   /* ------------------------- CRTP Shims -------------------------*/
293   template<typename CoeffType, typename Subclass>
294   template<typename StateType>
295   inline
296   StateType
cv_vib(const unsigned int species,const StateType & T)297   MacroMicroThermoBase<CoeffType,Subclass>::cv_vib (const unsigned int species, const StateType& T) const
298   {
299     return static_cast<const Subclass*>(this)->cv_vib_impl(species,T);
300   }
301 
302   template<typename CoeffType, typename Subclass>
303   template<typename StateType>
304   inline
305   StateType
cv_vib_over_R(const unsigned int species,const StateType & T)306   MacroMicroThermoBase<CoeffType,Subclass>::cv_vib_over_R (const unsigned int species, const StateType& T) const
307   {
308     return static_cast<const Subclass*>(this)->cv_vib_over_R_impl(species,T);
309   }
310 
311   template<typename CoeffType, typename Subclass>
312   template<typename StateType>
313   inline
314   StateType
cv_el(const unsigned int species,const StateType & T)315   MacroMicroThermoBase<CoeffType,Subclass>::cv_el (const unsigned int species, const StateType& T) const
316   {
317     return static_cast<const Subclass*>(this)->cv_el_impl(species,T);
318   }
319 
320 } // end namespace Antioch
321 
322 #endif // ANTIOCH_MICRO_THERMO_BASE_H
323