1 | /*
|
---|
2 | * vmg - a versatile multigrid solver
|
---|
3 | * Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
|
---|
4 | *
|
---|
5 | * vmg is free software: you can redistribute it and/or modify
|
---|
6 | * it under the terms of the GNU General Public License as published by
|
---|
7 | * the Free Software Foundation, either version 3 of the License, or
|
---|
8 | * (at your option) any later version.
|
---|
9 | *
|
---|
10 | * vmg is distributed in the hope that it will be useful,
|
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
13 | * GNU General Public License for more details.
|
---|
14 | *
|
---|
15 | * You should have received a copy of the GNU General Public License
|
---|
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
---|
17 | */
|
---|
18 |
|
---|
19 | /**
|
---|
20 | * @file helper.hpp
|
---|
21 | * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
|
---|
22 | * @date Tue Apr 5 21:03:47 2011
|
---|
23 | *
|
---|
24 | * @brief Provides various helper functions.
|
---|
25 | *
|
---|
26 | */
|
---|
27 |
|
---|
28 | #ifndef HELPER_HPP_
|
---|
29 | #define HELPER_HPP_
|
---|
30 |
|
---|
31 | #include <cassert>
|
---|
32 | #include <cmath>
|
---|
33 | #include <cstdio>
|
---|
34 | #include <limits>
|
---|
35 | #include <sstream>
|
---|
36 | #include <string>
|
---|
37 |
|
---|
38 | namespace VMG
|
---|
39 | {
|
---|
40 |
|
---|
41 | class Grid;
|
---|
42 | class Vector;
|
---|
43 |
|
---|
44 | namespace Helper
|
---|
45 | {
|
---|
46 | char* GetCharArray(const std::string& str);
|
---|
47 | std::string ReplaceWhitespaces(const char* buffer, const char* replace);
|
---|
48 |
|
---|
49 | template <class T>
|
---|
50 | std::string ToString(const T& val)
|
---|
51 | {
|
---|
52 | std::stringstream str;
|
---|
53 | str << std::scientific << val;
|
---|
54 | return str.str();
|
---|
55 | }
|
---|
56 |
|
---|
57 | template <class T>
|
---|
58 | T ToVal(const char* val_str)
|
---|
59 | {
|
---|
60 | T val;
|
---|
61 | std::stringstream str;
|
---|
62 | str << val_str;
|
---|
63 | str >> val;
|
---|
64 |
|
---|
65 | return val;
|
---|
66 | }
|
---|
67 |
|
---|
68 | template <class T>
|
---|
69 | T ToValWithDefault(const char* val_str, const T& def)
|
---|
70 | {
|
---|
71 | T val;
|
---|
72 | std::stringstream str(val_str);
|
---|
73 | str >> val;
|
---|
74 |
|
---|
75 | if (str.fail() || str.bad() || !str.eof()) val = def;
|
---|
76 |
|
---|
77 | return val;
|
---|
78 | }
|
---|
79 |
|
---|
80 | /**
|
---|
81 | * Checks a number for validity, i.e. it is neither nan nor inf.
|
---|
82 | */
|
---|
83 | template <class T>
|
---|
84 | inline bool CheckNumber(const T& number)
|
---|
85 | {
|
---|
86 | bool valid = true;
|
---|
87 | /*
|
---|
88 | if (std::numeric_limits<vmg_float>::has_quiet_NaN) {
|
---|
89 | valid &= number != std::numeric_limits<vmg_float>::quiet_NaN();
|
---|
90 | assert(number != std::numeric_limits<vmg_float>::quiet_NaN());
|
---|
91 | }
|
---|
92 |
|
---|
93 | if (std::numeric_limits<vmg_float>::has_signaling_NaN) {
|
---|
94 | valid &= number != std::numeric_limits<vmg_float>::signaling_NaN();
|
---|
95 | assert(number != std::numeric_limits<vmg_float>::signaling_NaN());
|
---|
96 | }
|
---|
97 | */
|
---|
98 | valid &= number == number;
|
---|
99 | assert(number == number);
|
---|
100 |
|
---|
101 | if (std::numeric_limits<vmg_float>::has_infinity) {
|
---|
102 | valid &= number != std::numeric_limits<vmg_float>::infinity();
|
---|
103 | valid &= number != -1 * std::numeric_limits<vmg_float>::infinity();
|
---|
104 | assert(number != std::numeric_limits<vmg_float>::infinity());
|
---|
105 | assert(number != -1 * std::numeric_limits<vmg_float>::infinity());
|
---|
106 | }
|
---|
107 |
|
---|
108 | return valid;
|
---|
109 | }
|
---|
110 |
|
---|
111 | inline int intpow(int base, unsigned int power)
|
---|
112 | {
|
---|
113 | int result = 1;
|
---|
114 | while (power != 0) {
|
---|
115 | if (power & 1)
|
---|
116 | result *= base;
|
---|
117 | base *= base;
|
---|
118 | power >>= 1;
|
---|
119 | }
|
---|
120 | return result;
|
---|
121 | }
|
---|
122 |
|
---|
123 | inline vmg_float pow(vmg_float base, unsigned int power)
|
---|
124 | {
|
---|
125 | vmg_float result = 1.0;
|
---|
126 | while (power != 0) {
|
---|
127 | if (power & 1)
|
---|
128 | result *= base;
|
---|
129 | base *= base;
|
---|
130 | power >>= 1;
|
---|
131 | }
|
---|
132 | return result;
|
---|
133 | }
|
---|
134 |
|
---|
135 | inline unsigned int fact(unsigned int number)
|
---|
136 | {
|
---|
137 | unsigned int result = 1;
|
---|
138 | for (unsigned int i=2; i<=number; ++i)
|
---|
139 | result *= i;
|
---|
140 | return result;
|
---|
141 | }
|
---|
142 |
|
---|
143 | inline vmg_float pow_2(vmg_float val)
|
---|
144 | {
|
---|
145 | return val*val;
|
---|
146 | }
|
---|
147 |
|
---|
148 | inline vmg_float pow_3(vmg_float val)
|
---|
149 | {
|
---|
150 | return val*val*val;
|
---|
151 | }
|
---|
152 |
|
---|
153 | inline int log_2(int val)
|
---|
154 | {
|
---|
155 | assert(val > 0);
|
---|
156 | int log2 = 0;
|
---|
157 | int x = 1;
|
---|
158 |
|
---|
159 | while (x < val) {
|
---|
160 | x <<= 1;
|
---|
161 | ++log2;
|
---|
162 | }
|
---|
163 |
|
---|
164 | return log2;
|
---|
165 | }
|
---|
166 |
|
---|
167 | inline int RoundUpToNextMultiple(int number, int multiple)
|
---|
168 | {
|
---|
169 | return static_cast<int>(ceil((static_cast<vmg_float>(number)-0.5) / multiple)) * multiple;
|
---|
170 | }
|
---|
171 |
|
---|
172 | inline int RoundDownToNextMultiple(int number, int multiple)
|
---|
173 | {
|
---|
174 | return static_cast<int>(floor((static_cast<vmg_float>(number)+0.5) / multiple)) * multiple;
|
---|
175 | }
|
---|
176 |
|
---|
177 |
|
---|
178 | /**
|
---|
179 | * Tests two arbitrary objects for equality and prints
|
---|
180 | * a warning if they differ.
|
---|
181 | */
|
---|
182 | template <class T>
|
---|
183 | bool IsEq(const T& val1, const T& val2, const char name[])
|
---|
184 | {
|
---|
185 | bool rval = (val1 == val2);
|
---|
186 |
|
---|
187 | #ifdef DEBUG
|
---|
188 | if (!rval)
|
---|
189 | printf("Equality test failed (%s)\n", name);
|
---|
190 | assert(rval);
|
---|
191 | #endif /* DEBUG */
|
---|
192 |
|
---|
193 | return rval;
|
---|
194 | }
|
---|
195 |
|
---|
196 | bool AssertVectorsEqual(const Vector& pos_1, const Vector& pos_2, const vmg_float& tol);
|
---|
197 |
|
---|
198 | vmg_float InterpolateTrilinear(const Vector& point, const Grid& grid);
|
---|
199 |
|
---|
200 | }
|
---|
201 |
|
---|
202 | }
|
---|
203 |
|
---|
204 | #endif /* HELPER_HPP_ */
|
---|