ENH: additional construct/assignment methods for complex (#1247)

- construct/assign from Zero
This commit is contained in:
Mark Olesen
2019-03-25 15:17:58 +01:00
committed by Andrew Heather
parent a33f1787b7
commit a1999bc92c
8 changed files with 305 additions and 131 deletions

View File

@ -0,0 +1,3 @@
Test-complex.C
EXE = $(FOAM_USER_APPBIN)/Test-complex

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,93 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM 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.
OpenFOAM 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 OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Description
Some tests for complex numbers
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "complex.H"
#include "complexVector.H"
#include "Field.H"
using namespace Foam;
void print1(const complex& z)
{
Info<<"r: " << z.real() << " i: " << z.imag() << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
Info<< "complex() : " << complex() << nl
<< "complex(zero) : " << complex(Zero) << nl
<< "complex::zero : " << complex::zero << nl
<< "complex::one : " << complex::one << nl
<< "complex(scalar) : " << complex(3.14519) << nl
<< nl;
Info<< "complexVector::zero : " << complexVector::zero << nl
<< "complexVector::one : " << complexVector::one << nl
<< nl;
// Comparison
for (complex c : { complex{1, 0}, complex{1, 2}} )
{
print1(c);
// TDB: allow implicit construct from scalar?
//
// if (c == 1.0)
// {
// Info<< c << " == " << 1 << nl;
// }
}
Field<complex> fld1(3, complex(2.0, 1.0));
Info<< "Field " << flatOutput(fld1) << nl;
Info<< "sum = " << sum(fld1) << nl;
// Not yet Info<< "min = " << min(fld1) << nl;
fld1 *= 10;
Info<< "Multiply: " << flatOutput(fld1) << nl;
for (complex& c : fld1)
{
c = ~c;
}
Info<< "Conjugate: " << flatOutput(fld1) << nl;
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation | Copyright (C) 2011-2016 OpenFOAM Foundation
@ -44,13 +44,13 @@ const char* const Foam::complexVector::vsType::componentNames[] =
template<> template<>
const Foam::complexVector Foam::complexVector::vsType::zero const Foam::complexVector Foam::complexVector::vsType::zero
( (
complexVector::uniform(complex(0, 0)) complexVector::uniform(complex::zero)
); );
template<> template<>
const Foam::complexVector Foam::complexVector::vsType::one const Foam::complexVector Foam::complexVector::vsType::one
( (
complexVector::uniform(complex(1, 1)) complexVector::uniform(complex::one)
); );
template<> template<>

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation | Copyright (C) 2011 OpenFOAM Foundation
@ -28,14 +28,13 @@ License
#include "complex.H" #include "complex.H"
#include "IOstreams.H" #include "IOstreams.H"
#include <sstream>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const char* const Foam::complex::typeName = "complex"; const char* const Foam::complex::typeName = "complex";
const Foam::complex Foam::complex::zero(0, 0); const Foam::complex Foam::complex::zero(0, 0);
const Foam::complex Foam::complex::one(1, 1); const Foam::complex Foam::complex::one(1, 1);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::complex::complex(Istream& is) Foam::complex::complex(Istream& is)
@ -48,9 +47,7 @@ Foam::complex::complex(Istream& is)
Foam::word Foam::name(const complex& c) Foam::word Foam::name(const complex& c)
{ {
std::ostringstream buf; return '(' + std::to_string(c.Re()) + ',' + std::to_string(c.Im()) + ')';
buf << '(' << c.Re() << ',' << c.Im() << ')';
return buf.str();
} }
@ -58,12 +55,10 @@ Foam::word Foam::name(const complex& c)
Foam::Istream& Foam::operator>>(Istream& is, complex& c) Foam::Istream& Foam::operator>>(Istream& is, complex& c)
{ {
// Read beginning of complex
is.readBegin("complex"); is.readBegin("complex");
is >> c.re >> c.im; is >> c.re >> c.im;
// Read end of complex
is.readEnd("complex"); is.readEnd("complex");
is.check(FUNCTION_NAME); is.check(FUNCTION_NAME);

View File

@ -2,10 +2,10 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation | Copyright (C) 2011-2014 OpenFOAM Foundation
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,7 +27,7 @@ Class
Foam::complex Foam::complex
Description Description
Extension to the c++ complex library type. A complex number, similar to the C++ complex type.
SourceFiles SourceFiles
complexI.H complexI.H
@ -39,8 +39,8 @@ SourceFiles
#define complex_H #define complex_H
#include "scalar.H" #include "scalar.H"
#include "bool.H"
#include "word.H" #include "word.H"
#include "zero.H"
#include "contiguous.H" #include "contiguous.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -48,15 +48,14 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of friend functions and operators // Forward Declarations
class complex; class complex;
inline scalar magSqr(const complex&); inline scalar magSqr(const complex&);
inline complex sqr(const complex&);
inline scalar mag(const complex&); inline scalar mag(const complex&);
inline const complex& max(const complex&, const complex&); inline complex sqr(const complex&);
inline const complex& min(const complex&, const complex&); inline const complex& min(const complex&, const complex&);
inline const complex& max(const complex&, const complex&);
inline complex limit(const complex&, const complex&); inline complex limit(const complex&, const complex&);
inline const complex& sum(const complex&); inline const complex& sum(const complex&);
inline complex operator+(const complex&, const complex&); inline complex operator+(const complex&, const complex&);
@ -68,8 +67,9 @@ inline complex operator*(const scalar, const complex&);
inline complex operator*(const complex&, const scalar); inline complex operator*(const complex&, const scalar);
inline complex operator/(const complex&, const scalar); inline complex operator/(const complex&, const scalar);
inline complex operator/(const scalar, const complex&); inline complex operator/(const scalar, const complex&);
Istream& operator>>(Istream&, complex&);
Ostream& operator<<(Ostream&, const complex&); Istream& operator>>(Istream& is, complex& c);
Ostream& operator<<(Ostream& os, const complex& c);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -78,114 +78,166 @@ Ostream& operator<<(Ostream&, const complex&);
class complex class complex
{ {
// private data // Private Data
//- Real and imaginary parts of the complex number //- Real and imaginary parts
scalar re, im; scalar re, im;
public: public:
//- Component type //- Component type
typedef complex cmptType; typedef complex cmptType;
// Static data members // Static Data Members
//- The type name is "complex"
static const char* const typeName; static const char* const typeName;
//- A complex zero (0,0)
static const complex zero; static const complex zero;
//- A complex one (1,1)
static const complex one; static const complex one;
// Constructors // Constructors
//- Construct null //- Construct null as zero-initialized
inline complex(); inline constexpr complex() noexcept;
//- Construct given real and imaginary parts //- Default copy constructor
inline complex(const scalar Re, const scalar Im); complex(const complex&) = default;
//- Construct zero-initialized from zero class
inline constexpr complex(const Foam::zero) noexcept;
//- Construct from real component
inline explicit constexpr complex(const scalar r) noexcept;
//- Construct from real and imaginary parts
inline constexpr complex(const scalar r, const scalar i) noexcept;
//- Construct from Istream //- Construct from Istream
complex(Istream&); explicit complex(Istream& is);
// Member functions // Member Functions
// Access // STL getter/setter
inline scalar Re() const; //- Real part of complex number - STL naming
inline scalar Im() const; constexpr scalar real() const
{
return re;
}
// Edit //- Imaginary part of complex number - STL naming
constexpr scalar imag() const
{
return im;
}
inline scalar& Re(); //- Set real part of complex number - STL naming
inline scalar& Im(); inline void real(scalar val);
// Operators //- Set imaginary part of complex number - STL naming
inline void imag(scalar val);
inline complex conjugate() const;
// Member operators // Access
inline void operator=(const complex&); //- Real part of complex number
inline void operator+=(const complex&); inline scalar Re() const;
inline void operator-=(const complex&);
inline void operator*=(const complex&);
inline void operator/=(const complex&);
inline void operator=(const scalar); //- Imaginary part of complex number
inline void operator+=(const scalar); inline scalar Im() const;
inline void operator-=(const scalar);
inline void operator*=(const scalar);
inline void operator/=(const scalar);
// Edit
//- Real part of complex number
inline scalar& Re();
//- Imaginary part of complex number
inline scalar& Im();
// Operations
//- Complex conjugate
inline complex conjugate() const;
// Member Operators
//- Copy assignment
inline void operator=(const complex& c);
//- Assign zero
inline void operator=(const Foam::zero);
inline void operator+=(const complex& c);
inline void operator-=(const complex& c);
inline void operator*=(const complex& c);
inline void operator/=(const complex& c);
inline void operator=(const scalar s);
inline void operator+=(const scalar s);
inline void operator-=(const scalar s);
inline void operator*=(const scalar s);
inline void operator/=(const scalar s);
//- Conjugate
inline complex operator~() const;
//- Conjugate
inline complex operator!() const; inline complex operator!() const;
inline bool operator==(const complex&) const; inline bool operator==(const complex& c) const;
inline bool operator!=(const complex&) const; inline bool operator!=(const complex& c) const;
// Friend functions // Friend Functions
friend scalar magSqr(const complex& c); friend scalar magSqr(const complex& c);
friend complex sqr(const complex& c);
friend scalar mag(const complex& c); friend scalar mag(const complex& c);
friend const complex& max(const complex&, const complex&); friend complex sqr(const complex& c);
friend const complex& min(const complex&, const complex&); friend const complex& min(const complex&, const complex&);
friend const complex& max(const complex&, const complex&);
friend complex limit(const complex&, const complex&); friend complex limit(const complex&, const complex&);
friend const complex& sum(const complex&); friend const complex& sum(const complex&);
// Friend operators // Friend Operators
friend complex operator+(const complex&, const complex&); friend complex operator+(const complex& c1, const complex& c2);
friend complex operator-(const complex&); friend complex operator-(const complex& c);
friend complex operator-(const complex&, const complex&); friend complex operator-(const complex& c1, const complex& c2);
friend complex operator*(const complex&, const complex&); friend complex operator*(const complex& c1, const complex& c2);
friend complex operator/(const complex&, const complex&); friend complex operator/(const complex& c1, const complex& c2);
friend complex operator*(const scalar, const complex&); friend complex operator*(const scalar s, const complex& c);
friend complex operator*(const complex&, const scalar); friend complex operator*(const complex& c, const scalar s);
friend complex operator/(const complex&, const scalar); friend complex operator/(const complex& c, const scalar s);
friend complex operator/(const scalar, const complex&); friend complex operator/(const scalar s, const complex& c);
// IOstream operators // IOstream Operators
friend Istream& operator>>(Istream&, complex&);
friend Ostream& operator<<(Ostream&, const complex&);
friend Istream& operator>>(Istream& is, complex& c);
friend Ostream& operator<<(Ostream& os, const complex& c);
}; };
// * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
//- Return a string representation of a complex
word name(const complex&);
//- Return string representation of complex
word name(const complex& c);
//- Data associated with complex type are contiguous //- Data associated with complex type are contiguous
template<> template<>

View File

@ -2,10 +2,10 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation | Copyright (C) 2011-2014 OpenFOAM Foundation
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,51 +25,75 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline complex::complex() inline constexpr Foam::complex::complex() noexcept
:
re(0),
im(0)
{} {}
inline complex::complex(const scalar Re, const scalar Im) inline constexpr Foam::complex::complex(const Foam::zero) noexcept
: :
re(Re), re(0),
im(Im) im(0)
{}
inline constexpr Foam::complex::complex(const scalar r) noexcept
:
re(r),
im(0)
{}
inline constexpr Foam::complex::complex(const scalar r, const scalar i) noexcept
:
re(r),
im(i)
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline scalar complex::Re() const inline void Foam::complex::real(scalar val)
{
re = val;
}
inline void Foam::complex::imag(scalar val)
{
im = val;
}
inline Foam::scalar Foam::complex::Re() const
{ {
return re; return re;
} }
inline scalar complex::Im() const inline Foam::scalar Foam::complex::Im() const
{ {
return im; return im;
} }
inline scalar& complex::Re() inline Foam::scalar& Foam::complex::Re()
{ {
return re; return re;
} }
inline scalar& complex::Im() inline Foam::scalar& Foam::complex::Im()
{ {
return im; return im;
} }
inline complex complex::conjugate() const inline Foam::complex Foam::complex::conjugate() const
{ {
return complex(re, -im); return complex(re, -im);
} }
@ -77,85 +101,98 @@ inline complex complex::conjugate() const
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void complex::operator=(const complex& c) inline void Foam::complex::operator=(const complex& c)
{ {
re = c.re; re = c.re;
im = c.im; im = c.im;
} }
inline void complex::operator+=(const complex& c) inline void Foam::complex::operator=(const Foam::zero)
{
re = 0;
im = 0;
}
inline void Foam::complex::operator+=(const complex& c)
{ {
re += c.re; re += c.re;
im += c.im; im += c.im;
} }
inline void complex::operator-=(const complex& c) inline void Foam::complex::operator-=(const complex& c)
{ {
re -= c.re; re -= c.re;
im -= c.im; im -= c.im;
} }
inline void complex::operator*=(const complex& c) inline void Foam::complex::operator*=(const complex& c)
{ {
*this = (*this)*c; *this = (*this)*c;
} }
inline void complex::operator/=(const complex& c) inline void Foam::complex::operator/=(const complex& c)
{ {
*this = *this/c; *this = *this/c;
} }
inline void complex::operator=(const scalar s) inline void Foam::complex::operator=(const scalar s)
{ {
re = s; re = s;
im = 0.0; im = 0;
} }
inline void complex::operator+=(const scalar s) inline void Foam::complex::operator+=(const scalar s)
{ {
re += s; re += s;
} }
inline void complex::operator-=(const scalar s) inline void Foam::complex::operator-=(const scalar s)
{ {
re -= s; re -= s;
} }
inline void complex::operator*=(const scalar s) inline void Foam::complex::operator*=(const scalar s)
{ {
re *= s; re *= s;
im *= s; im *= s;
} }
inline void complex::operator/=(const scalar s) inline void Foam::complex::operator/=(const scalar s)
{ {
re /= s; re /= s;
im /= s; im /= s;
} }
inline complex complex::operator!() const inline Foam::complex Foam::complex::operator~() const
{ {
return conjugate(); return conjugate();
} }
inline bool complex::operator==(const complex& c) const inline Foam::complex Foam::complex::operator!() const
{
return conjugate();
}
inline bool Foam::complex::operator==(const complex& c) const
{ {
return (equal(re, c.re) && equal(im, c.im)); return (equal(re, c.re) && equal(im, c.im));
} }
inline bool complex::operator!=(const complex& c) const inline bool Foam::complex::operator!=(const complex& c) const
{ {
return !operator==(c); return !operator==(c);
} }
@ -164,47 +201,46 @@ inline bool complex::operator!=(const complex& c) const
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
namespace Foam
{
inline scalar magSqr(const complex& c) inline scalar magSqr(const complex& c)
{ {
return (c.re*c.re + c.im*c.im); return (c.re*c.re + c.im*c.im);
} }
inline scalar mag(const complex& c)
{
return sqrt(magSqr(c)); // OR std::hypot(c.re, c.im);
}
inline complex sqr(const complex& c) inline complex sqr(const complex& c)
{ {
return c * c; return c * c;
} }
inline scalar mag(const complex& c) inline const complex& min(const complex& c1, const complex& c2)
{ {
return sqrt(magSqr(c)); if (magSqr(c1) < magSqr(c2))
{
return c1;
}
return c2;
} }
inline const complex& max(const complex& c1, const complex& c2) inline const complex& max(const complex& c1, const complex& c2)
{ {
if (mag(c1) > mag(c2)) if (magSqr(c1) < magSqr(c2))
{
return c1;
}
else
{ {
return c2; return c2;
} }
}
return c1;
inline const complex& min(const complex& c1, const complex& c2)
{
if (mag(c1) < mag(c2))
{
return c1;
}
else
{
return c2;
}
} }
@ -220,8 +256,7 @@ inline const complex& sum(const complex& c)
} }
template<class Cmpt> template<class Cmpt> class Tensor;
class Tensor;
inline complex transform(const Tensor<scalar>&, const complex c) inline complex transform(const Tensor<scalar>&, const complex c)
{ {
@ -273,7 +308,7 @@ inline complex operator*(const complex& c1, const complex& c2)
inline complex operator/(const complex& c1, const complex& c2) inline complex operator/(const complex& c1, const complex& c2)
{ {
scalar sqrC2 = magSqr(c2); const scalar sqrC2 = magSqr(c2);
return complex return complex
( (

View File

@ -51,7 +51,6 @@ complexVector UOprocess::WeinerProcess()
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// from components
UOprocess::UOprocess UOprocess::UOprocess
( (
const Kmesh& kmesh, const Kmesh& kmesh,
@ -85,12 +84,7 @@ UOprocess::UOprocess
} }
else else
{ {
UOfield[i] = complexVector UOfield[i] = complexVector::zero;
(
complex(0, 0),
complex(0, 0),
complex(0, 0)
);
} }
} }
} }