Commit fcba6491 authored by Mark OLESEN's avatar Mark OLESEN Committed by Andrew Heather
Browse files

ENH: conversion and function improvements for complex (#1247)

- add construction from and conversion to std::complex, which allows
  easier wrapping of functions

- add Foam:: functions for complex versions of sin, cos, ...
parent 9cf085a6
......@@ -25,12 +25,13 @@ Application
Description
Some tests for complex numbers
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "complex.H"
#include "complexVector.H"
#include "Field.H"
#include "complexFields.H"
using namespace Foam;
......@@ -52,14 +53,26 @@ int main(int argc, char *argv[])
<< "complex(scalar) : " << complex(3.14519) << nl
<< nl;
std::complex<scalar> c1(10, -3);
Info<< "std::complex : " << c1 << nl;
Info<< "sin: " << std::sin(c1) << nl;
Info<< "complexVector::zero : " << complexVector::zero << nl
<< "complexVector::one : " << complexVector::one << nl
<< nl;
for (complex c : { complex{1, 0}, complex{1, 2}} )
{
Info<< nl;
print1(c);
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;
// TDB: allow implicit construct from scalar?
//
// if (c == 1.0)
......@@ -68,7 +81,7 @@ int main(int argc, char *argv[])
// }
}
Field<complex> fld1(3, complex(2.0, 1.0));
complexField fld1(3, complex(2.0, 1.0));
Info<< "Field " << flatOutput(fld1) << nl;
......@@ -78,6 +91,12 @@ int main(int argc, char *argv[])
fld1 *= 10;
Info<< "Multiply: " << flatOutput(fld1) << nl;
// Not yet:
// #ifdef TEST_FOAM_OVERLOAD
// Info<< "sin: " << sin(fld1) << nl;
// #endif
for (complex& c : fld1)
{
c = ~c;
......
......@@ -55,12 +55,15 @@ Foam::word Foam::name(const complex& c)
Foam::Istream& Foam::operator>>(Istream& is, complex& c)
{
is.readBegin("complex");
is >> c.re >> c.im;
scalar r, i;
is.readBegin("complex");
is >> r >> i;
is.readEnd("complex");
c.real(r);
c.imag(i);
is.check(FUNCTION_NAME);
return is;
}
......@@ -69,7 +72,7 @@ Foam::Istream& Foam::operator>>(Istream& is, complex& c)
Foam::Ostream& Foam::operator<<(Ostream& os, const complex& c)
{
os << token::BEGIN_LIST
<< c.re << token::SPACE << c.im
<< c.real() << token::SPACE << c.imag()
<< token::END_LIST;
return os;
......
......@@ -38,6 +38,7 @@ SourceFiles
#ifndef complex_H
#define complex_H
#include <complex>
#include "scalar.H"
#include "word.H"
#include "zero.H"
......@@ -68,9 +69,6 @@ inline complex operator*(const complex&, const scalar);
inline complex operator/(const complex&, const scalar);
inline complex operator/(const scalar, const complex&);
Istream& operator>>(Istream& is, complex& c);
Ostream& operator<<(Ostream& os, const complex& c);
/*---------------------------------------------------------------------------*\
Class complex Declaration
......@@ -119,6 +117,12 @@ public:
//- Construct from real and imaginary parts
inline constexpr complex(const scalar r, const scalar i) noexcept;
//- Construct from std::complex
inline complex(const std::complex<float>& c);
//- Construct from std::complex
inline complex(const std::complex<double>& c);
//- Construct from Istream
explicit complex(Istream& is);
......@@ -172,6 +176,13 @@ public:
// Member Operators
//- Conversion to std::complex
inline operator std::complex<scalar>() const
{
return std::complex<scalar>(re, im);
}
//- Copy assignment
inline void operator=(const complex& c);
......@@ -218,18 +229,20 @@ public:
friend complex operator*(const complex& c, const scalar s);
friend complex operator/(const complex& c, const scalar s);
friend complex operator/(const scalar s, const complex& c);
};
// IOstream Operators
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
friend Istream& operator>>(Istream& is, complex& c);
friend Ostream& operator<<(Ostream& os, const complex& c);
};
Istream& operator>>(Istream& is, complex& c);
Ostream& operator<<(Ostream& os, const complex& c);
//- Complex conjugate
inline complex operator~(const complex& c);
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
//- Return string representation of complex
word name(const complex& c);
......@@ -238,12 +251,6 @@ template<>
inline bool contiguous<complex>() {return true;}
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
//- Complex conjugate
inline complex operator~(const complex& c);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -55,6 +55,20 @@ inline constexpr Foam::complex::complex(const scalar r, const scalar i) noexcept
{}
inline Foam::complex::complex(const std::complex<float>& c)
:
re(c.real()),
im(c.imag())
{}
inline Foam::complex::complex(const std::complex<double>& c)
:
re(c.real()),
im(c.imag())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline void Foam::complex::real(scalar val)
......@@ -196,7 +210,6 @@ inline Foam::complex Foam::operator~(const complex& c)
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
namespace Foam
{
......@@ -337,9 +350,97 @@ inline complex operator/(const scalar s, const complex& c)
return complex(s/c.re, s/c.im);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Complex transcendental functions
namespace Foam
{
#define transFunc(func) \
inline complex func(const Foam::complex& z) \
{ \
return std:: func (std::complex<scalar>(z)); \
}
transFunc(sqrt)
transFunc(exp)
transFunc(log)
transFunc(log10)
transFunc(sin)
transFunc(cos)
transFunc(tan)
transFunc(asin)
transFunc(acos)
transFunc(atan)
transFunc(sinh)
transFunc(cosh)
transFunc(tanh)
transFunc(asinh)
transFunc(acosh)
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));
}
// Combinations of complex and real
#define powFuncs(type2) \
inline complex pow(const complex& x, const type2& y) \
{ \
return std::pow(std::complex<scalar>(x), scalar(y)); \
} \
\
inline Foam::complex pow(const type2& x, const complex& y) \
{ \
return std::pow(scalar(x), std::complex<scalar>(y)); \
}
powFuncs(float)
powFuncs(double)
powFuncs(int)
powFuncs(long)
inline complex pow3(const complex& c)
{
return c*sqr(c);
}
inline complex pow4(const complex& c)
{
return sqr(sqr(c));
}
inline complex pow5(const complex& c)
{
return c*pow4(c);
}
inline complex pow6(const complex& c)
{
return pow3(sqr(c));
}
inline complex pow025(const complex& c)
{
return sqrt(sqrt(c));
}
} // End namespace Foam
#undef transFunc
#undef powFuncs
// ************************************************************************* //
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