Commit 179d9fd6 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: correct pow(complex, ..) functions (fixes #1638)

* Use cast for std::pow(??, z).
* No cast for std::pow(z, ??) - already properly specialized.
parent 5f115371
......@@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -39,11 +39,6 @@ Description
using namespace Foam;
void print1(const complex& z)
{
Info<< "r: " << z.real() << " i: " << z.imag() << nl;
}
// * * * * * * * * * * * * * * * Main Program * * * * * * * * * * * * * * * //
......@@ -66,14 +61,15 @@ int main(int argc, char *argv[])
for (complex c : { complex{1, 0}, complex{1, 2}} )
{
Info<< nl;
print1(c);
Info<< nl << "complex : " << c << nl;
Info<< "sin: " << sin(c) << nl;
Info<< "pow(3): " << pow(c, 3) << nl;
Info<< "pow3: " << pow3(c) << nl;
Info<< "log: " << log(c) << nl;
Info<< "pow025: " << pow025(c) << nl;
Info<< "sin: " << sin(c) << nl
<< "pow(3.0f): " << pow(c, 3.0f) << nl
<< "pow(3): " << pow(c, 3) << nl
<< "pow3: " << pow3(c) << nl
<< "log: " << log(c) << nl
<< "pow025: " << pow025(c) << nl
;
// TDB: allow implicit construct from scalar?
//
......@@ -83,6 +79,40 @@ int main(int argc, char *argv[])
// }
}
// Test powers of zero
#if 1
{
const complex complex0{0, 0};
const std::complex<scalar> std0{0, 0};
const label label0{0};
const scalar scalar0{0};
Info<< nl
<< "# std::pow(0, 0)" << nl
<< " (label, label) = " << std::pow(label0, label0) << nl
<< " (scalar, scalar) = " << std::pow(scalar0, scalar0) << nl
<< " (label, scalar) = " << std::pow(label0, scalar0) << nl
<< " (scalar, label) = " << std::pow(scalar0, label0) << nl
<< " (std::complex, label) = " << std::pow(std0, label0) << nl
<< " (std::complex, scalar) = " << std::pow(std0, scalar0) << nl
<< " (label, std::complex) = " << std::pow(label0, std0) << nl
<< " (scalar, std::complex) = " << std::pow(scalar0, std0) << nl
;
Info<< nl
<< "# Foam::pow(0, 0)" << nl
<< " (label, label) = " << Foam::pow(label0, label0) << nl
<< " (scalar, scalar) = " << Foam::pow(scalar0, scalar0) << nl
<< " (label, scalar) = " << Foam::pow(label0, scalar0) << nl
<< " (scalar, label) = " << Foam::pow(scalar0, label0) << nl
<< " (complex, label) = " << Foam::pow(complex0, label0) << nl
<< " (complex, scalar) = " << Foam::pow(complex0, scalar0) << nl
<< " (label, complex) = " << Foam::pow(label0, complex0) << nl
<< " (scalar, complex) = " << Foam::pow(scalar0, complex0) << nl
;
}
#endif
// Test zip/unzip
{
......@@ -163,7 +193,7 @@ int main(int argc, char *argv[])
const complex a(6, 1);
complex b = a;
Info << "# Compound assignment operations:" << nl;
Info<< "# Compound assignment operations:" << nl;
Info<< "a = " << a << ", b = " << b << nl;
......@@ -192,7 +222,7 @@ int main(int argc, char *argv[])
const scalar a = 5;
complex b(6, 1);
Info << "# Non-assignment operations:" << nl;
Info<< "# Non-assignment operations:" << nl;
Info<< "(scalar) a = " << a << ", b = " << b << nl;
......@@ -225,7 +255,7 @@ int main(int argc, char *argv[])
Info<< "b = b/a: " << tab << b << nl;
Info << "# Compound assignment operations:" << nl;
Info<< "# Compound assignment operations:" << nl;
Info<< "(scalar) a = " << a << ", b = " << b << nl;
......@@ -244,7 +274,6 @@ int main(int argc, char *argv[])
// Division: complex/scalar
b /= a;
Info<< "b /= a (real and imag parts):" << tab << b << nl;
}
#endif
......@@ -282,7 +311,6 @@ int main(int argc, char *argv[])
Info<< "log(a) = " << log(a) << ", "
<< "log(b) = " << log(b) << ", "
<< "log(c) = " << log(c) << nl;
}
#endif
......
......@@ -119,10 +119,10 @@ public:
//- Construct from real and imaginary parts
inline constexpr complex(const scalar r, const scalar i) noexcept;
//- Construct from std::complex
//- Implicit construct from std::complex
inline complex(const std::complex<float>& c);
//- Construct from std::complex
//- Implicit construct from std::complex
inline complex(const std::complex<double>& c);
//- Construct from Istream
......@@ -178,8 +178,8 @@ public:
// Member Operators
//- Conversion to std::complex
inline operator std::complex<scalar>() const
//- Implicit conversion to std::complex
operator std::complex<scalar>() const
{
return std::complex<scalar>(re, im);
}
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -389,9 +389,9 @@ inline complex operator/(const scalar s, const complex& c)
namespace Foam
{
#define transFunc(func) \
inline complex func(const Foam::complex& z) \
inline complex func(const complex& c) \
{ \
return std:: func (std::complex<scalar>(z)); \
return std:: func (static_cast<std::complex<scalar>>(c)); \
}
transFunc(sqrt)
......@@ -414,27 +414,34 @@ transFunc(atanh)
// Special treatment for pow()
inline complex pow(const complex& x, const complex& y)
{
return std::pow(std::complex<scalar>(x), std::complex<scalar>(y));
return std::pow
(
static_cast<std::complex<scalar>>(x),
static_cast<std::complex<scalar>>(y)
);
}
// Combinations of complex and real
// Combinations of complex and integral/float
#define powFuncs(type2) \
inline complex pow(const complex& x, const type2& y) \
inline complex pow(const complex& x, const type2 y) \
{ \
return std::pow(std::complex<scalar>(x), scalar(y)); \
return std::pow(static_cast<std::complex<scalar>>(x), y); \
} \
\
inline Foam::complex pow(const type2& x, const complex& y) \
inline complex pow(const type2 x, const complex& y) \
{ \
return std::pow(scalar(x), std::complex<scalar>(y)); \
return std::pow \
( \
static_cast<std::complex<scalar>>(x), \
static_cast<std::complex<scalar>>(y) \
); \
}
powFuncs(float)
powFuncs(double)
powFuncs(int)
powFuncs(long)
powFuncs(float)
powFuncs(double)
inline complex pow3(const complex& c)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment