32 #include "antioch_config.h"
34 #ifdef ANTIOCH_HAVE_METAPHYSICL
35 #include "metaphysicl/dualnumber.h"
36 #include "metaphysicl/dynamicsparsenumberarray.h"
43 template <
typename Scalar>
44 int tester(
const std::string& testname)
49 using MetaPhysicL::DualNumber;
51 typedef MetaPhysicL::DynamicSparseNumberArray<Scalar, int> DNSA;
52 typedef DualNumber<Scalar, DNSA> DN;
56 const Scalar Cf = 1.4;
57 const Scalar Ea = 5.0;
58 const Scalar rscale = Antioch::Constants::R_universal<Scalar>();
61 DNSA unit_Cf, unit_Ea, unit_rscale;
63 unit_Cf.raw_index(0) = 0;
64 unit_Cf.raw_at(0) = 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;
72 const DN Cf_DN(Cf, unit_Cf);
73 const DN Ea_DN(Ea, unit_Ea);
74 const DN rscale_DN(rscale, unit_rscale);
76 const DN partsum_DN = Ea_DN + Cf_DN;
77 const DN fullsum_DN = Ea_DN + Cf_DN + rscale_DN;
79 const Scalar T = 1500.1;
83 const Scalar rate = arrhenius_rate(T);
86 arrhenius_param_sensitivity(Cf_DN, Ea_DN, rscale_DN);
88 const Scalar perturb =
89 std::pow(std::numeric_limits<Scalar>::epsilon(), (1./3.)) * 100;
92 arrhenius_rate_Cf_plus(Cf + perturb, Ea, rscale);
94 arrhenius_rate_Cf_minus(Cf - perturb, Ea, rscale);
97 arrhenius_rate_Ea_plus(Cf, Ea + perturb, rscale);
99 arrhenius_rate_Ea_minus(Cf, Ea - perturb, rscale);
102 arrhenius_rate_rscale_plus(Cf, Ea, rscale + perturb);
104 arrhenius_rate_rscale_minus(Cf, Ea, rscale - perturb);
108 const DN rate_DN = arrhenius_param_sensitivity(DN(T));
110 const Scalar dR_dCf = (arrhenius_rate_Cf_plus(T) -
111 arrhenius_rate_Cf_minus(T)) / (2 * perturb);
113 const Scalar dR_dEa = (arrhenius_rate_Ea_plus(T) -
114 arrhenius_rate_Ea_minus(T)) / (2 * perturb);
116 const Scalar dR_drscale = (arrhenius_rate_rscale_plus(T) -
117 arrhenius_rate_rscale_minus(T)) / (2 * perturb);
119 if( abs( (rate - rate_DN.value())/rate) >
120 std::numeric_limits<Scalar>::epsilon() * 100)
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;
131 if( abs( (dR_dCf - rate_DN.derivatives()[0])/dR_dCf) >
132 perturb * perturb * 100)
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;
144 if( abs( (dR_dEa - rate_DN.derivatives()[1])/dR_dEa) >
145 perturb * perturb * 100)
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;
157 if( abs( (dR_drscale - rate_DN.derivatives()[2])/dR_drscale) >
158 perturb * perturb * 100)
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;
176 #ifdef ANTIOCH_HAVE_METAPHYSICL
177 return (tester<double>(
"double") ||
178 tester<long double>(
"long double") ||
179 tester<float>(
"float"));
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)