ENH: improve/simplify streaming of exprValue

- ensure that operator<< and operator>> behave symmetrically
This commit is contained in:
Mark Olesen
2023-11-22 14:26:37 +01:00
parent 2ab3490552
commit c5e4b62df7
14 changed files with 739 additions and 42 deletions

View File

@ -0,0 +1,5 @@
exprValueFieldTag.cxx
Test-exprValue2.cxx
EXE = $(FOAM_USER_APPBIN)/Test-exprValue2

View File

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

View File

@ -0,0 +1,143 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2023 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/>.
Description
Test exprValue uniformity checks
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "IOobject.H"
#include "IOstreams.H"
#include "labelList.H"
#include "scalarField.H"
#include "vectorField.H"
#include "DynamicList.H"
#include "Random.H"
#include "exprValue.H"
#include "exprValueFieldTag.H"
using namespace Foam;
Ostream& printInfo(const expressions::exprValueFieldTag& tag)
{
tag.print(Pout);
return Pout;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
using fieldTag = expressions::exprValueFieldTag;
Random rnd(123456);
argList::noCheckProcessorDirectories();
#include "setRootCase.H"
{
scalarField fld1(20);
scalarField fld2a(20, Zero);
scalarField fld2b(10, 3.10);
scalarField fld3;
forAll(fld1, i)
{
fld1[i] = rnd.position<scalar>(0, 20);
}
fieldTag tag1(fld1.begin(), fld1.end());
fieldTag tag2a(fld2a.begin(), fld2a.end());
fieldTag tag2b(fld2b.begin(), fld2b.end());
fieldTag tag3(fld3.begin(), fld3.end());
printInfo(tag1) << nl;
printInfo(tag2a) << nl;
printInfo(tag2b) << nl;
printInfo(tag3) << nl;
fieldTag result;
result = fieldTag::combineOp{}(tag1, tag2a);
printInfo(result) << nl;
Info<< "combine: ";
printInfo(tag2a) << " and ";
printInfo(tag2b) << nl;
result = fieldTag::combineOp{}(tag2a, tag2b);
printInfo(result) << nl;
}
{
vectorField fld2a(20, Foam::zero{});
vectorField fld2b(10, vector::uniform(3.10));
fieldTag tag2a(fld2a.begin(), fld2a.end());
fieldTag tag2b(fld2b.begin(), fld2b.end());
printInfo(tag2a) << nl;
printInfo(tag2b) << nl;
fieldTag result;
Info<< "combine: ";
printInfo(tag2a) << " and ";
printInfo(tag2b) << nl;
result = fieldTag::combineOp{}(tag2a, tag2b);
printInfo(result) << nl;
}
if (UPstream::parRun())
{
scalarField fld;
if (!UPstream::master())
{
fld.resize(UPstream::myProcNo(), UPstream::myProcNo());
}
fieldTag oldTag(fld.begin(), fld.end());
printInfo(oldTag) << " input: " << fld << " <- before reduce" << nl;
fieldTag newTag = returnReduce(oldTag, fieldTag::combineOp());
printInfo(newTag) << " <- after reduce" << nl;
}
Info<< "\nEnd\n" << nl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,170 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2023 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/>.
Class
Foam::expressions::exprValueFieldTag
Description
A polymorphic single-value container for tracking Field content
as uniform etc.
SourceFiles
exprValueFieldTag.cxx
\*---------------------------------------------------------------------------*/
#ifndef Foam_expressions_exprValueFieldTag_H
#define Foam_expressions_exprValueFieldTag_H
#include "exprValue.H"
#include "List.H" // For ListPolicy
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace expressions
{
/*---------------------------------------------------------------------------*\
Class exprValueFieldTag Declaration
\*---------------------------------------------------------------------------*/
class exprValueFieldTag
{
// Private data
//- Uniformity of field
int uniformity_{};
//- Representative (uniform) value for the field
expressions::exprValue value_{};
public:
// Constructors
//- Default construct
exprValueFieldTag() = default;
//- Construct from a range of values
template<class Type>
explicit exprValueFieldTag(const Type* first, const Type* last)
{
set(first, last);
}
// Member Functions
//- True if the uniformity is "empty"
bool empty() const noexcept;
//- True if the uniformity is "uniform"
bool is_uniform() const noexcept;
//- True if the uniformity is "non-uniform"
bool is_nonuniform() const noexcept;
//- Test for equality of the values
bool equal(const exprValueFieldTag& rhs) const;
//- Set value and uniformity from range of data
template<class Type>
void set(const Type* first, const Type* last)
{
uniformity_ =
Foam::Detail::ListPolicy::check_uniformity(first, last);
if (first != last) // or uniformity_ != EMPTY
{
value_.set<Type>(*first);
}
else
{
value_.set<Type>(Foam::zero{});
}
}
//- Set uniform type and value
template<class Type>
void set_uniform(const Type& val)
{
uniformity_ = Foam::Detail::ListPolicy::uniformity::UNIFORM;
value_.set<Type>(val);
}
//- Set as non-uniform
void set_nouniform() noexcept;
// Reduction operations
//- Combine - eg, for global uniformity
void combine(const exprValueFieldTag& b);
//- Binary operator to be used by reduce function for detecting
//- global uniformity
struct combineOp
{
exprValueFieldTag operator()
(
const exprValueFieldTag& a,
const exprValueFieldTag& b
) const
{
exprValueFieldTag result(a);
result.combine(b);
return result;
}
};
// IO Operations
void read(Istream& is);
void write(Ostream& os) const;
//- Print description to Ostream
void print(Ostream& os) const;
};
} // End namespace expressions
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IO
Istream& operator>>(Istream&, expressions::exprValueFieldTag&);
Ostream& operator<<(Ostream&, const expressions::exprValueFieldTag&);
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2023 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/>.
\*---------------------------------------------------------------------------*/
#include "exprValueFieldTag.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::expressions::exprValueFieldTag::empty() const noexcept
{
return
(
uniformity_ == Foam::Detail::ListPolicy::uniformity::EMPTY
);
}
bool Foam::expressions::exprValueFieldTag::is_uniform() const noexcept
{
return
(
uniformity_ == Foam::Detail::ListPolicy::uniformity::UNIFORM
);
}
bool Foam::expressions::exprValueFieldTag::is_nonuniform() const noexcept
{
return
(
uniformity_ == Foam::Detail::ListPolicy::uniformity::NONUNIFORM
);
}
bool Foam::expressions::exprValueFieldTag::equal
(
const exprValueFieldTag& rhs
) const
{
return (value_ == rhs.value_);
}
void Foam::expressions::exprValueFieldTag::set_nouniform() noexcept
{
uniformity_ = Foam::Detail::ListPolicy::uniformity::NONUNIFORM;
value_ = Foam::zero{};
}
void Foam::expressions::exprValueFieldTag::combine
(
const exprValueFieldTag& b
)
{
if (b.empty())
{
// no-op
return;
}
exprValueFieldTag& a = *this;
if (a.empty())
{
a = b;
}
else if (a.is_nonuniform())
{
// Already non-uniform/mixed
// a.uniformity_ |= b.uniformity_;
a.value_ = Foam::zero{};
}
else if (a.is_uniform() && b.is_uniform())
{
// Both are uniform, but are they the same value?
if (!a.equal(b))
{
a.set_nouniform();
}
}
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
void Foam::expressions::exprValueFieldTag::read(Istream& is)
{
label uniformTag;
is >> uniformTag;
uniformity_ = int(uniformTag);
value_.read(is);
}
void Foam::expressions::exprValueFieldTag::write(Ostream& os) const
{
os << label(uniformity_);
value_.write(os, false); // No pruning
}
void Foam::expressions::exprValueFieldTag::print(Ostream& os) const
{
os << "{ uniform:"
<< label(uniformity_)
<< " type:" << label(value_.typeCode())
<< " value: " << value_ << " }";
}
Foam::Istream& Foam::operator>>
(
Istream& is,
expressions::exprValueFieldTag& tag
)
{
tag.read(is);
return is;
}
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const expressions::exprValueFieldTag& tag
)
{
tag.write(os);
return os;
}
// ************************************************************************* //