Cantera  3.1.0
Loading...
Searching...
No Matches
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
25namespace 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 */
39template<class V>
40inline 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 */
54template<class V>
55inline 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 */
81template<class InputIter, class InputIter2>
82inline 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 */
103template<class InputIter, class OutputIter, class S>
104inline 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 */
116template<class D, class R>
117R 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 */
128template<class D, class R>
129R 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 */
140template<class D, class R>
141R 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 */
152template<class D, class R>
153R 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 */
164template<class D, class R>
165R 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)
173void 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 */
182void 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 */
189template <class T, class U>
190const 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
197template <class T, class U=int>
198U 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 dot5(const V &x, const V &y)
Templated Inner product of two vectors of length 5.
Definition utilities.h:55
R poly4(D x, R *c)
Evaluates a polynomial of order 4.
Definition utilities.h:153
double dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
Definition utilities.h:82
R poly6(D x, R *c)
Templated evaluation of a polynomial of order 6.
Definition utilities.h:117
R poly8(D x, R *c)
Templated evaluation of a polynomial of order 8.
Definition utilities.h:129
R poly5(D x, R *c)
Templated evaluation of a polynomial of order 5.
Definition utilities.h:141
R poly3(D x, R *c)
Templated evaluation of a polynomial of order 3.
Definition utilities.h:165
double dot4(const V &x, const V &y)
Templated Inner product of two vectors of length 4.
Definition utilities.h:40
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
Definition utilities.h:104
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
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