antioch-0.4.0
arrhenius_rate_multideriv.C
Go to the documentation of this file.
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 // $Id$
28 //
29 //--------------------------------------------------------------------------
30 //--------------------------------------------------------------------------
31 
32 #include "antioch_config.h"
33 
34 #ifdef ANTIOCH_HAVE_METAPHYSICL
35 #include "metaphysicl/dualnumber.h"
36 #include "metaphysicl/dynamicsparsenumberarray.h"
37 
38 #include "antioch/arrhenius_rate.h"
39 
40 #include <iomanip>
41 #include <string>
42 
43 template <typename Scalar>
44 int tester(const std::string& testname)
45 {
46  using std::abs;
47  using std::exp;
48  using std::pow;
49  using MetaPhysicL::DualNumber;
50 
51  typedef MetaPhysicL::DynamicSparseNumberArray<Scalar, int> DNSA;
52  typedef DualNumber<Scalar, DNSA> DN;
53 
54  int return_flag = 0;
55 
56  const Scalar Cf = 1.4;
57  const Scalar Ea = 5.0;
58  const Scalar rscale = Antioch::Constants::R_universal<Scalar>();
59 
60  // Unit vectors for independent variable derivatives
61  DNSA unit_Cf, unit_Ea, unit_rscale;
62  unit_Cf.resize(1);
63  unit_Cf.raw_index(0) = 0;
64  unit_Cf.raw_at(0) = 1;
65  unit_Ea.resize(1);
66  unit_Ea.raw_index(0) = 1;
67  unit_Ea.raw_at(0) = 1;
68  unit_rscale.resize(1);
69  unit_rscale.raw_index(0) = 2;
70  unit_rscale.raw_at(0) = 1;
71 
72  const DN Cf_DN(Cf, unit_Cf);
73  const DN Ea_DN(Ea, unit_Ea);
74  const DN rscale_DN(rscale, unit_rscale);
75 
76  const DN partsum_DN = Ea_DN + Cf_DN;
77  const DN fullsum_DN = Ea_DN + Cf_DN + rscale_DN;
78 
79  const Scalar T = 1500.1;
80 
81  const Antioch::ArrheniusRate<Scalar> arrhenius_rate(Cf, Ea, rscale);
82 
83  const Scalar rate = arrhenius_rate(T);
84 
86  arrhenius_param_sensitivity(Cf_DN, Ea_DN, rscale_DN);
87 
88  const Scalar perturb =
89  std::pow(std::numeric_limits<Scalar>::epsilon(), (1./3.)) * 100;
90 
92  arrhenius_rate_Cf_plus(Cf + perturb, Ea, rscale);
94  arrhenius_rate_Cf_minus(Cf - perturb, Ea, rscale);
95 
97  arrhenius_rate_Ea_plus(Cf, Ea + perturb, rscale);
99  arrhenius_rate_Ea_minus(Cf, Ea - perturb, rscale);
100 
102  arrhenius_rate_rscale_plus(Cf, Ea, rscale + perturb);
104  arrhenius_rate_rscale_minus(Cf, Ea, rscale - perturb);
105 
106  // FIXME - we need to upgrade the return type of templated functions
107  // in the case where the input StateType is *weaker* than CoeffType
108  const DN rate_DN = arrhenius_param_sensitivity(DN(T));
109 
110  const Scalar dR_dCf = (arrhenius_rate_Cf_plus(T) -
111  arrhenius_rate_Cf_minus(T)) / (2 * perturb);
112 
113  const Scalar dR_dEa = (arrhenius_rate_Ea_plus(T) -
114  arrhenius_rate_Ea_minus(T)) / (2 * perturb);
115 
116  const Scalar dR_drscale = (arrhenius_rate_rscale_plus(T) -
117  arrhenius_rate_rscale_minus(T)) / (2 * perturb);
118 
119  if( abs( (rate - rate_DN.value())/rate) >
120  std::numeric_limits<Scalar>::epsilon() * 100)
121  {
122  std::cout << "Error: Mismatch in " << testname << " rate." << std::endl
123  << std::setprecision(25)
124  << "rate = " << rate << std::endl
125  << "rate_DN = " << rate_DN.value() << std::endl;
126 
127  return_flag = 1;
128  }
129 
130 
131  if( abs( (dR_dCf - rate_DN.derivatives()[0])/dR_dCf) >
132  perturb * perturb * 100)
133  {
134  std::cout << "Error: Mismatch in " << testname << " rate derivatives." << std::endl
135  << std::setprecision(25)
136  << "perturb = " << perturb << std::endl
137  << "dR_dCf = " << dR_dCf << std::endl
138  << "drate_DN/dCf' = " << rate_DN.derivatives()[0] << std::endl;
139 
140  return_flag = 1;
141  }
142 
143 
144  if( abs( (dR_dEa - rate_DN.derivatives()[1])/dR_dEa) >
145  perturb * perturb * 100)
146  {
147  std::cout << "Error: Mismatch in " << testname << " rate derivatives." << std::endl
148  << std::setprecision(25)
149  << "perturb = " << perturb << std::endl
150  << "dR_dEa = " << dR_dEa << std::endl
151  << "drate_DN/dEa' = " << rate_DN.derivatives()[1] << std::endl;
152 
153  return_flag = 1;
154  }
155 
156 
157  if( abs( (dR_drscale - rate_DN.derivatives()[2])/dR_drscale) >
158  perturb * perturb * 100)
159  {
160  std::cout << "Error: Mismatch in " << testname << " rate derivatives." << std::endl
161  << std::setprecision(25)
162  << "perturb = " << perturb << std::endl
163  << "dR_drscale = " << dR_drscale << std::endl
164  << "drate_DN/drscale' = " << rate_DN.derivatives()[1] << std::endl;
165 
166  return_flag = 1;
167  }
168 
169 
170  return return_flag;
171 }
172 #endif
173 
174 int main()
175 {
176 #ifdef ANTIOCH_HAVE_METAPHYSICL
177  return (tester<double>("double") ||
178  tester<long double>("long double") ||
179  tester<float>("float"));
180 #else
181  return 77; // automake code for a skipped test
182 #endif
183 }
int tester(const std::string &testname)
Antioch::enable_if_c< Antioch::is_valarray< T >::value, typename Antioch::state_type< T >::type >::type pow(const T &in, const T2 &n)

Generated on Thu Jul 7 2016 11:09:46 for antioch-0.4.0 by  doxygen 1.8.8