Cantera  3.1.0a1
utilities.h
Go to the documentation of this file.
1 /**
2  * @file utilities.h
3  * Various templated functions that carry out common vector and polynomial operations
4  * (see @ref mathTemplates).
5  */
6 
7 // This file is part of Cantera. See License.txt in the top-level directory or
8 // at https://cantera.org/license.txt for license and copyright information.
9 
10 /**
11  * @defgroup mathTemplates Templated Array and Polynomial Operations
12  *
13  * These are templates to perform various simple operations on arrays. Note that
14  * the compiler will inline these, so using them carries no performance penalty.
15  *
16  * @ingroup numerics
17  */
18 
19 #ifndef CT_UTILITIES_H
20 #define CT_UTILITIES_H
21 
22 #include "ct_defs.h"
23 #include <numeric>
24 
25 namespace Cantera
26 {
27 //! @addtogroup mathTemplates
28 //! @{
29 
30 //! Templated Inner product of two vectors of length 4.
31 /*!
32  * If either @e x or @e y has length greater than 4, only the first 4 elements
33  * will be used.
34  *
35  * @param x first reference to the templated class V
36  * @param y second reference to the templated class V
37  * @return This class returns a hard-coded type, double.
38  */
39 template<class V>
40 inline double dot4(const V& x, const V& y)
41 {
42  return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3];
43 }
44 
45 //! Templated Inner product of two vectors of length 5
46 /*!
47  * If either @e x or @e y has length greater than 4, only the first 4 elements
48  * will be used.
49  *
50  * @param x first reference to the templated class V
51  * @param y second reference to the templated class V
52  * @return This class returns a hard-coded type, double.
53  */
54 template<class V>
55 inline double dot5(const V& x, const V& y)
56 {
57  return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3] +
58  x[4]*y[4];
59 }
60 
61 //! Function that calculates a templated inner product.
62 /*!
63  * This inner product is templated twice. The output variable is hard coded
64  * to return a double.
65  *
66  * template<class InputIter, class InputIter2>
67  *
68  * @code
69  * double x[8], y[8];
70  * double dsum = dot<double *,double *>(x, &x+7, y);
71  * @endcode
72  *
73  * @param x_begin Iterator pointing to the beginning, belonging to the
74  * iterator class InputIter.
75  * @param x_end Iterator pointing to the end, belonging to the
76  * iterator class InputIter.
77  * @param y_begin Iterator pointing to the beginning of y, belonging to the
78  * iterator class InputIter2.
79  * @return The return is hard-coded to return a double.
80  */
81 template<class InputIter, class InputIter2>
82 inline double dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
83 {
84  return std::inner_product(x_begin, x_end, y_begin, 0.0);
85 }
86 
87 //! Multiply elements of an array by a scale factor.
88 /*!
89  * @code
90  * vector<double> in(8, 1.0), out(8);
91  * scale(in.begin(), in.end(), out.begin(), factor);
92  * @endcode
93  *
94  * @param begin Iterator pointing to the beginning, belonging to the
95  * iterator class InputIter.
96  * @param end Iterator pointing to the end, belonging to the
97  * iterator class InputIter.
98  * @param out Iterator pointing to the beginning of out, belonging to the
99  * iterator class OutputIter. This is the output variable
100  * for this routine.
101  * @param scale_factor input scale factor belonging to the class S.
102  */
103 template<class InputIter, class OutputIter, class S>
104 inline void scale(InputIter begin, InputIter end,
105  OutputIter out, S scale_factor)
106 {
107  std::transform(begin, end, out,
108  [scale_factor](double x) { return x * scale_factor; });
109 }
110 
111 //! Templated evaluation of a polynomial of order 6
112 /*!
113  * @param x Value of the independent variable - First template parameter
114  * @param c Pointer to the polynomial - Second template parameter
115  */
116 template<class D, class R>
117 R poly6(D x, R* c)
118 {
119  return ((((((c[6]*x + c[5])*x + c[4])*x + c[3])*x +
120  c[2])*x + c[1])*x + c[0]);
121 }
122 
123 //! Templated evaluation of a polynomial of order 8
124 /*!
125  * @param x Value of the independent variable - First template parameter
126  * @param c Pointer to the polynomial - Second template parameter
127  */
128 template<class D, class R>
129 R poly8(D x, R* c)
130 {
131  return ((((((((c[8]*x + c[7])*x + c[6])*x + c[5])*x + c[4])*x + c[3])*x +
132  c[2])*x + c[1])*x + c[0]);
133 }
134 
135 //! Templated evaluation of a polynomial of order 5
136 /*!
137  * @param x Value of the independent variable - First template parameter
138  * @param c Pointer to the polynomial - Second template parameter
139  */
140 template<class D, class R>
141 R poly5(D x, R* c)
142 {
143  return (((((c[5]*x + c[4])*x + c[3])*x +
144  c[2])*x + c[1])*x + c[0]);
145 }
146 
147 //! Evaluates a polynomial of order 4.
148 /*!
149  * @param x Value of the independent variable.
150  * @param c Pointer to the polynomial coefficient array.
151  */
152 template<class D, class R>
153 R poly4(D x, R* c)
154 {
155  return ((((c[4]*x + c[3])*x +
156  c[2])*x + c[1])*x + c[0]);
157 }
158 
159 //! Templated evaluation of a polynomial of order 3
160 /*!
161  * @param x Value of the independent variable - First template parameter
162  * @param c Pointer to the polynomial - Second template parameter
163  */
164 template<class D, class R>
165 R poly3(D x, R* c)
166 {
167  return (((c[3]*x + c[2])*x + c[1])*x + c[0]);
168 }
169 
170 //! @}
171 
172 //! Check to see that a number is finite (not NaN, +Inf or -Inf)
173 void checkFinite(const double tmp);
174 
175 //! Check to see that all elements in an array are finite
176 /*!
177  * Throws an exception if any element is NaN, +Inf, or -Inf
178  * @param name Name to be used in the exception message if the check fails
179  * @param values Array of *N* values to be checked
180  * @param N Number of elements in *values*
181  */
182 void checkFinite(const string& name, double* values, size_t N);
183 
184 //! Const accessor for a value in a map.
185 /*
186  * Similar to map.at(key), but returns *default_val* if the key is not
187  * found instead of throwing an exception.
188  */
189 template <class T, class U>
190 const U& getValue(const map<T, U>& m, const T& key, const U& default_val) {
191  typename map<T,U>::const_iterator iter = m.find(key);
192  return (iter == m.end()) ? default_val : iter->second;
193 }
194 
195 //! Get the size of a container, cast to a signed integer type
196 //! @ingroup mathTemplates
197 template <class T, class U=int>
198 U len(const T& container) {
199  return static_cast<U>(container.size());
200 }
201 
202 //! A macro for generating member function detectors, which can then be used in
203 //! combination with `if constexpr` to condition behavior on the availability of that
204 //! member function. See MultiRate for examples of use.
205 #define CT_DEFINE_HAS_MEMBER(detector_name, func_name) \
206  template<class T, class=void> \
207  struct detector_name : std::false_type {}; \
208  template<class T> \
209  struct detector_name<T, std::void_t<decltype(&T::func_name)>> : std::true_type {};
210 
211 }
212 
213 #endif
This file contains definitions of constants, types and terms that are used in internal routines and a...
U len(const T &container)
Get the size of a container, cast to a signed integer type.
Definition: utilities.h:198
double dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
Definition: utilities.h:82
double dot5(const V &x, const V &y)
Templated Inner product of two vectors of length 5.
Definition: utilities.h:55
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
Definition: utilities.h:104
R poly5(D x, R *c)
Templated evaluation of a polynomial of order 5.
Definition: utilities.h:141
R poly8(D x, R *c)
Templated evaluation of a polynomial of order 8.
Definition: utilities.h:129
R poly3(D x, R *c)
Templated evaluation of a polynomial of order 3.
Definition: utilities.h:165
R poly4(D x, R *c)
Evaluates a polynomial of order 4.
Definition: utilities.h:153
R poly6(D x, R *c)
Templated evaluation of a polynomial of order 6.
Definition: utilities.h:117
double dot4(const V &x, const V &y)
Templated Inner product of two vectors of length 4.
Definition: utilities.h:40
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
Definition: checkFinite.cpp:15
const U & getValue(const map< T, U > &m, const T &key, const U &default_val)
Const accessor for a value in a map.
Definition: utilities.h:190