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