openfoam/applications/test/complex/Test-complex.C
Mark Olesen 179d9fd61d ENH: correct pow(complex, ..) functions (fixes #1638)
* Use cast for std::pow(??, z).
* No cast for std::pow(z, ??) - already properly specialized.
2020-03-19 12:31:49 +01:00

354 lines
9.9 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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
Tests for complex numbers
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "complex.H"
#include "complexFields.H"
#include "scalarField.H"
#include "ListOps.H"
#include "ops.H"
using namespace Foam;
// * * * * * * * * * * * * * * * Main Program * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
Info<< "complex() : " << complex() << nl
<< "complex(zero) : " << complex(Zero) << nl
<< "pTraits<complex>::zero : " << pTraits<complex>::zero << nl
<< "pTraits<complex>::one : " << pTraits<complex>::one << nl
<< "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 << "complex : " << 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?
//
// if (c == 1.0)
// {
// Info<< c << " == " << 1 << nl;
// }
}
// 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
{
scalarField reals(4);
scalarField imags(4);
forAll(reals, i)
{
reals[i] = i;
}
forAll(imags, i)
{
imags[i] = (i % 2) ? -i : i;
}
complexField cmplx(4);
zip(cmplx, reals, imags);
Info<< nl
<< "zip " << reals << nl
<< " " << imags << nl
<< " => " << cmplx << nl;
reverse(cmplx);
Info<< "reverse order: " << cmplx << nl;
unzip(cmplx, reals, imags);
Info<< "unzip " << cmplx << nl
<< " => " << reals << nl
<< " => " << imags << nl;
}
complexField fld1(3, complex(2.0, 1.0));
complexField fld2(fld1);
for (complex& c : fld2)
{
c = ~c;
}
Info<< nl
<< "Field " << flatOutput(fld1) << nl
<< "Conjugate: " << flatOutput(fld2) << nl;
// Some arbitrary change
for (complex& c : fld2)
{
c.Im() *= 5;
}
Info<< "sumProd: " << sumProd(fld1, fld2) << nl;
fld1 *= 10;
Info<< "scalar multiply: " << flatOutput(fld1) << nl;
fld1 /= 10;
Info<< "scalar divide: " << flatOutput(fld1) << nl;
Info<< "sin: " << sin(fld1) << nl;
Info<< "operator + : " << (fld1 + fld2) << nl;
Info<< "operator + : " << (fld1 + fld2 + complex(1,0)) << nl;
// Some operators are still incomplete
// Info<< "operator * : " << (fld1 * fld2) << nl;
// Info<< "operator / : " << (fld1 / fld2) << nl;
// Info<< "operator / : " << (fld1 / 2) << nl;
// Info<< "operator / : " << (fld1 / fld2) << nl;
// Info<< "sqrt : " << sqrt(fld1) << nl;
// Info<< "pow(2) : " << pow(fld1, 2) << nl;
#if 1
Info<< nl << "## Elementary complex-complex arithmetic operations:" << nl;
{
const complex a(6, 1);
complex b = a;
Info<< "# Compound assignment operations:" << nl;
Info<< "a = " << a << ", b = " << b << nl;
// Addition
b += a;
Info<< "b += a:" << tab << "b =" << b << nl;
// Subtraction
b -= a;
Info<< "b -= a:" << tab << "b =" << b << nl;
// Multiplication
b *= a;
Info<< "b *= a:" << tab << "b =" << b << nl;
// Division
b /= a;
Info<< "b /= a:" << tab << "b =" << b << nl;
}
#endif
#if 1
Info<< nl << "## Elementary complex-scalar arithmetic operations:" << nl;
{
const scalar a = 5;
complex b(6, 1);
Info<< "# Non-assignment operations:" << nl;
Info<< "(scalar) a = " << a << ", b = " << b << nl;
// Addition
b = a + b;
Info<< "b = a + b: " << tab << b << nl;
b = b + a;
Info<< "b = b + a: " << tab << b << nl;
// Subtraction
b = a - b;
Info<< "b = a - b: " << tab << b << nl;
b = b - a;
Info<< "b = b - a: " << tab << b << nl;
// Multiplication
b = a*b;
Info<< "b = a*b: " << tab << b << nl;
b = b*a;
Info<< "b = b*a: " << tab << b << nl;
// Division
b = a/b;
Info<< "b = a/b = scalar(a)/b = complex(a)/b:" << tab << b << nl;
b = b/a;
Info<< "b = b/a: " << tab << b << nl;
Info<< "# Compound assignment operations:" << nl;
Info<< "(scalar) a = " << a << ", b = " << b << nl;
// Addition: complex+scalar
b += a;
Info<< "b += a (only real part):" << tab << b << nl;
// Subtraction: complex-scalar
b -= a;
Info<< "b -= a (only real part):" << tab << b << nl;
// Multiplication: complex*scalar
b *= a;
Info<< "b *= a (real and imag parts):" << tab << b << nl;
// Division: complex/scalar
b /= a;
Info<< "b /= a (real and imag parts):" << tab << b << nl;
}
#endif
#if 1
Info<< nl << "## Other mathematical expressions:" << nl;
{
const complex a(4.3, -3.14);
const complex b(0, -4.3);
const complex c(-4.3, 0);
Info<< "a = " << a << ", b = " << b << ", c = " << c << nl;
// Square-root
Info<< "sqrt(a) = " << Foam::sqrt(a) << ", "
<< "sqrt(b) = " << Foam::sqrt(b) << ", "
<< "sqrt(c) = " << Foam::sqrt(c) << nl;
// Square
Info<< "sqr(a) = " << sqr(a) << ", "
<< "sqr(b) = " << sqr(b) << ", "
<< "sqr(c) = " << sqr(c) << nl;
// n^th power
Info<< "pow(a, -1) = " << pow(a, -1) << ", "
<< "pow(b, -1) = " << pow(b, -1) << ", "
<< "pow(c, -1) = " << pow(c, -1) << nl;
// Exponential
Info<< "exp(a) = " << exp(a) << ", "
<< "exp(b) = " << exp(b) << ", "
<< "exp(c) = " << exp(c) << nl;
// Natural logarithm
Info<< "log(a) = " << log(a) << ", "
<< "log(b) = " << log(b) << ", "
<< "log(c) = " << log(c) << nl;
}
#endif
// Make some changes
{
label i = 1;
for (complex& c : fld1)
{
c.Re() += i;
c.Im() -= 10 - i;
++i;
}
}
Info<< nl
<< "field = " << fld1 << nl;
Info<< "magSqr = "
<< ListOps::create<scalar>
(
fld1,
[](const complex& c) { return magSqr(c); }
)
<< nl;
Info
<< "sum = " << sum(fld1) << nl
<< "min = " << min(fld1) << nl
<< "max = " << max(fld1) << nl;
// MinMax fails since there is no less comparison operator
// Info<< "min/max = " << MinMax<complex>(fld1) << nl;
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //