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 // valarray has to be declared before Antioch or gcc can't find the
28 // right versions of exp() and pow() to use??
29 
30 #include "antioch_config.h"
31 
32 #include <valarray>
33 
34 #ifdef ANTIOCH_HAVE_EIGEN
35 #include "Eigen/Dense"
36 #endif
37 
38 #ifdef ANTIOCH_HAVE_METAPHYSICL
39 #include "metaphysicl/numberarray.h"
40 #endif
41 
42 #ifdef ANTIOCH_HAVE_VEXCL
43 #include "vexcl/vexcl.hpp"
44 #endif
45 
46 #include "antioch/eigen_utils_decl.h"
47 #include "antioch/metaphysicl_utils_decl.h"
48 #include "antioch/valarray_utils_decl.h"
49 #include "antioch/vexcl_utils_decl.h"
50 
51 #include "antioch/berthelot_rate.h"
52 
53 #include "antioch/eigen_utils.h"
54 #include "antioch/metaphysicl_utils.h"
55 #include "antioch/valarray_utils.h"
56 #include "antioch/vexcl_utils.h"
57 
58 #include <cmath>
59 #include <limits>
60 
61 #ifdef ANTIOCH_HAVE_GRVY
62 #include "grvy.h"
63 
64 GRVY::GRVY_Timer_Class gt;
65 #endif
66 
67 template <typename PairScalars>
check_rate_and_derivative(const PairScalars & rate_exact,const PairScalars & derive_exact,const PairScalars & rate,const PairScalars & derive,const PairScalars & T)68 int check_rate_and_derivative(const PairScalars & rate_exact, const PairScalars & derive_exact,
69                               const PairScalars & rate,       const PairScalars & derive, const PairScalars & T)
70 {
71     typedef typename Antioch::value_type<PairScalars>::type  Scalar;
72     const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 2;
73 
74     int return_flag(0);
75 
76    using std::abs;
77 
78    for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
79    {
80     if( abs( (rate[2*tuple] - rate_exact[2*tuple])/rate_exact[2*tuple] ) > tol )
81       {
82         std::cout << std::scientific << std::setprecision(16)
83                   << "Error: Mismatch in rate values." << std::endl
84                   << "T = " << T << " K" << std::endl
85                   << "rate(T) = " << rate[2*tuple] << std::endl
86                   << "rate_exact = " << rate_exact[2*tuple] << std::endl
87                   << "relative difference = " <<  abs( (rate[2*tuple] - rate_exact[2*tuple])/rate_exact[2*tuple] ) << std::endl
88                   << "tolerance = " <<  tol << std::endl;
89 
90         return_flag = 1;
91       }
92     if( abs( (rate[2*tuple+1] - rate_exact[2*tuple+1])/rate_exact[2*tuple+1] ) > tol )
93       {
94         std::cout << std::scientific << std::setprecision(16)
95                   << "Error: Mismatch in rate values." << std::endl
96                   << "T = " << T << " K" << std::endl
97                   << "rate(T) = " << rate[2*tuple] << std::endl
98                   << "rate_exact = " << rate_exact[2*tuple+1] << std::endl
99                   << "relative difference = " <<  abs( (rate[2*tuple] - rate_exact[2*tuple+1])/rate_exact[2*tuple+1] ) << std::endl
100                   << "tolerance = " <<  tol << std::endl;
101 
102         return_flag = 1;
103       }
104     if( abs( (derive[2*tuple] - derive_exact[2*tuple])/derive_exact[2*tuple] ) > tol )
105       {
106         std::cout << std::scientific << std::setprecision(16)
107                   << "Error: Mismatch in rate derivative values." << std::endl
108                   << "T = " << T << " K" << std::endl
109                   << "drate_dT(T) = " << derive[2*tuple] << std::endl
110                   << "derive_exact = " << derive_exact[2*tuple] << std::endl
111                   << "relative difference = " <<  abs( (derive[2*tuple] - derive_exact[2*tuple])/derive_exact[2*tuple] ) << std::endl
112                   << "tolerance = " <<  tol << std::endl;
113 
114         return_flag = 1;
115       }
116     if( abs( (derive[2*tuple+1] - derive_exact[2*tuple+1])/derive_exact[2*tuple+1] ) > tol )
117       {
118         std::cout << std::scientific << std::setprecision(16)
119                   << "Error: Mismatch in rate derivative values." << std::endl
120                   << "T = " << T << " K" << std::endl
121                   << "drate_dT(T) = " << derive[2*tuple+1] << std::endl
122                   << "derive_exact = " << derive_exact[2*tuple+1] << std::endl
123                   << "relative difference = " <<  abs( (derive[2*tuple+1] - derive_exact[2*tuple+1])/derive_exact[2*tuple+1] ) << std::endl
124                   << "tolerance = " <<  tol << std::endl;
125 
126         return_flag = 1;
127       }
128 
129    }
130    return return_flag;
131 }
132 
133 template <typename PairScalars>
vectester(const PairScalars & example,const std::string & testname)134 int vectester(const PairScalars& example, const std::string & testname)
135 {
136   using std::abs;
137   using std::exp;
138 
139   typedef typename Antioch::value_type<PairScalars>::type Scalar;
140 
141   const Scalar Cf = 1.4;
142   const Scalar D = -2.5;
143 
144   Antioch::BerthelotRate<Scalar> berthelot_rate(Cf,D);
145 
146   // Construct from example to avoid resizing issues
147   PairScalars T = example;
148   PairScalars rate_exact = example;
149   PairScalars derive_exact = example;
150   for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
151   {
152     T[2*tuple] = 1500.1;
153     T[2*tuple+1] = 1600.1;
154     rate_exact[2*tuple] = Cf*exp(D*1500.1);
155     rate_exact[2*tuple+1] = Cf*exp(D*1600.1);
156     derive_exact[2*tuple] = D * Cf * exp(D*Scalar(1500.1));
157     derive_exact[2*tuple+1] = D * Cf * exp(D*Scalar(1600.1));
158   }
159   Antioch::KineticsConditions<PairScalars> cond(T);
160 
161   int return_flag = 0;
162 
163 // KineticsConditions
164 #ifdef ANTIOCH_HAVE_GRVY
165   gt.BeginTimer(testname);
166 #endif
167 
168   PairScalars rate = berthelot_rate(cond);
169   PairScalars derive = berthelot_rate.derivative(cond);
170 
171 #ifdef ANTIOCH_HAVE_GRVY
172   gt.EndTimer(testname);
173 #endif
174 
175   return_flag = check_rate_and_derivative(rate_exact, derive_exact, rate, derive,T) || return_flag;
176 
177 #ifdef ANTIOCH_HAVE_GRVY
178   gt.BeginTimer(testname);
179 #endif
180 
181   berthelot_rate.rate_and_derivative(cond,rate,derive);
182 
183 #ifdef ANTIOCH_HAVE_GRVY
184   gt.EndTimer(testname);
185 #endif
186 
187   return_flag = check_rate_and_derivative(rate_exact, derive_exact, rate, derive,T) || return_flag;
188 
189 // T
190 #ifdef ANTIOCH_HAVE_GRVY
191   gt.BeginTimer(testname);
192 #endif
193 
194   rate = berthelot_rate(T);
195   derive = berthelot_rate.derivative(T);
196 
197 #ifdef ANTIOCH_HAVE_GRVY
198   gt.EndTimer(testname);
199 #endif
200 
201   return_flag = check_rate_and_derivative(rate_exact, derive_exact, rate, derive,T) || return_flag;
202 
203 #ifdef ANTIOCH_HAVE_GRVY
204   gt.BeginTimer(testname);
205 #endif
206 
207   berthelot_rate.rate_and_derivative(T,rate,derive);
208 
209 #ifdef ANTIOCH_HAVE_GRVY
210   gt.EndTimer(testname);
211 #endif
212 
213   return_flag = check_rate_and_derivative(rate_exact, derive_exact, rate, derive,T) || return_flag;
214 
215   std::cout << "Berthelot rate: " << berthelot_rate << std::endl;
216 
217   return return_flag;
218 }
219 
220 
main()221 int main()
222 {
223   int returnval = 0;
224 
225   returnval = returnval ||
226     vectester (std::valarray<float>(2*ANTIOCH_N_TUPLES), "valarray<float>");
227   returnval = returnval ||
228     vectester (std::valarray<double>(2*ANTIOCH_N_TUPLES), "valarray<double>");
229   returnval = returnval ||
230     vectester (std::valarray<long double>(2*ANTIOCH_N_TUPLES), "valarray<ld>");
231 #ifdef ANTIOCH_HAVE_EIGEN
232   returnval = returnval ||
233     vectester (Eigen::Array<float, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXf");
234   returnval = returnval ||
235     vectester (Eigen::Array<double, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXd");
236   returnval = returnval ||
237     vectester (Eigen::Array<long double, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXld");
238 #endif
239 #ifdef ANTIOCH_HAVE_METAPHYSICL
240   returnval = returnval ||
241     vectester (MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, float> (0), "NumberArray<float>");
242   returnval = returnval ||
243     vectester (MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, double> (0), "NumberArray<double>");
244   returnval = returnval ||
245     vectester (MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, long double> (0), "NumberArray<ld>");
246 #endif
247 #ifdef ANTIOCH_HAVE_VEXCL
248   vex::Context ctx_f (vex::Filter::All);
249   if (!ctx_f.empty())
250     returnval = returnval ||
251       vectester (vex::vector<float> (ctx_f, 2*ANTIOCH_N_TUPLES), "vex::vector<float>");
252 
253   vex::Context ctx_d (vex::Filter::DoublePrecision);
254   if (!ctx_d.empty())
255     returnval = returnval ||
256       vectester (vex::vector<double> (ctx_d, 2*ANTIOCH_N_TUPLES), "vex::vector<double>");
257 #endif
258 
259 #ifdef ANTIOCH_HAVE_GRVY
260   gt.Finalize();
261   gt.Summarize();
262 #endif
263 
264   return returnval;
265 }
266