/*
* vmg - a versatile multigrid solver
* Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
*
* vmg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* vmg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* @file helper.hpp
* @author Julian Iseringhausen
* @date Tue Apr 5 21:03:47 2011
*
* @brief Provides various helper functions.
*
*/
#ifndef HELPER_HPP_
#define HELPER_HPP_
#include
#include
#include
#include
#include
#include
namespace VMG
{
class Grid;
class Vector;
namespace Helper
{
char* GetCharArray(const std::string& str);
std::string ReplaceWhitespaces(const char* buffer, const char* replace);
template
std::string ToString(const T& val)
{
std::stringstream str;
str << std::scientific << val;
return str.str();
}
template
T ToVal(const char* val_str)
{
T val;
std::stringstream str;
str << val_str;
str >> val;
return val;
}
template
T ToValWithDefault(const char* val_str, const T& def)
{
T val;
std::stringstream str(val_str);
str >> val;
if (str.fail() || str.bad() || !str.eof()) val = def;
return val;
}
/**
* Checks a number for validity, i.e. it is neither nan nor inf.
*/
template
inline bool CheckNumber(const T& number)
{
bool valid = true;
/*
if (std::numeric_limits::has_quiet_NaN) {
valid &= number != std::numeric_limits::quiet_NaN();
assert(number != std::numeric_limits::quiet_NaN());
}
if (std::numeric_limits::has_signaling_NaN) {
valid &= number != std::numeric_limits::signaling_NaN();
assert(number != std::numeric_limits::signaling_NaN());
}
*/
valid &= number == number;
assert(number == number);
if (std::numeric_limits::has_infinity) {
valid &= number != std::numeric_limits::infinity();
valid &= number != -1 * std::numeric_limits::infinity();
assert(number != std::numeric_limits::infinity());
assert(number != -1 * std::numeric_limits::infinity());
}
return valid;
}
inline int intpow(int base, unsigned int power)
{
int result = 1;
while (power != 0) {
if (power & 1)
result *= base;
base *= base;
power >>= 1;
}
return result;
}
inline vmg_float pow(vmg_float base, unsigned int power)
{
vmg_float result = 1.0;
while (power != 0) {
if (power & 1)
result *= base;
base *= base;
power >>= 1;
}
return result;
}
inline unsigned int fact(unsigned int number)
{
unsigned int result = 1;
for (unsigned int i=2; i<=number; ++i)
result *= i;
return result;
}
inline vmg_float pow_2(vmg_float val)
{
return val*val;
}
inline vmg_float pow_3(vmg_float val)
{
return val*val*val;
}
inline int log_2(int val)
{
assert(val > 0);
int log2 = 0;
int x = 1;
while (x < val) {
x <<= 1;
++log2;
}
return log2;
}
inline int RoundUpToNextMultiple(int number, int multiple)
{
return static_cast(ceil((static_cast(number)-0.5) / multiple)) * multiple;
}
inline int RoundDownToNextMultiple(int number, int multiple)
{
return static_cast(floor((static_cast(number)+0.5) / multiple)) * multiple;
}
/**
* Tests two arbitrary objects for equality and prints
* a warning if they differ.
*/
template
bool IsEq(const T& val1, const T& val2, const char name[])
{
bool rval = (val1 == val2);
#ifdef DEBUG
if (!rval)
printf("Equality test failed (%s)\n", name);
assert(rval);
#endif /* DEBUG */
return rval;
}
bool AssertVectorsEqual(const Vector& pos_1, const Vector& pos_2, const vmg_float& tol);
vmg_float InterpolateTrilinear(const Vector& point, const Grid& grid);
}
}
#endif /* HELPER_HPP_ */