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