Compare commits

..

6 Commits

Author SHA1 Message Date
99a3f10729 ENH: AMIInterpolation: make matching more robust 2025-08-06 11:05:43 +01:00
0fa124af45 ENH: subsetMesh: support for mesh maps 2025-05-29 17:27:51 +01:00
b7ce6bf69d CONFIG: inject -no-recursion into the argument list (#3198)
- sourcing a file with '-no-recursion "$@"' does not work with dash.
  Need to modify the argument list directly.
2025-03-19 15:28:57 +01:00
0a53013499 BUG: foamReport mesh quantities are not parallel (fixes #3338) 2025-03-17 11:53:23 +01:00
47f2ff618d COMP: remove obsolete -fsimdmath flag for ARM64 (#3326) 2025-03-17 09:59:42 +01:00
47575aabf2 COMP: compilation with clang (c++17) and older flex files (fixes #3337)
- The register keyword has been removed from c++17 but old flex
  versions (version < 2.6.0) produce code including it, leading to
  compilation errors when using clang (despite disabling the diagnostic).
  gcc compiles but issues warnings.

- use '#define register' as empty as a workaround
2025-03-17 09:58:20 +01:00
1417 changed files with 20031 additions and 31871 deletions

View File

@ -1,13 +1,15 @@
#!/bin/sh #!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
# Run from OPENFOAM top-level directory only # Run from OPENFOAM top-level directory only
cd "${0%/*}" || exit
wmake -check-dir "$WM_PROJECT_DIR" 2>/dev/null || { wmake -check-dir "$WM_PROJECT_DIR" 2>/dev/null || {
echo "Error (${0##*/}) : not located in \$WM_PROJECT_DIR" echo "Error (${0##*/}) : not located in \$WM_PROJECT_DIR"
echo " Check your OpenFOAM environment and installation" echo " Check your OpenFOAM environment and installation"
exit 1 exit 1
} }
if [ -f "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments ] if [ -f "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments ]
then . "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments -no-recursion "$@" || \ then . "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments || \
echo "Argument parse error" echo "Argument parse error"
else else
echo "Error (${0##*/}) : WM_PROJECT_DIR appears to be incorrect" echo "Error (${0##*/}) : WM_PROJECT_DIR appears to be incorrect"

View File

@ -1,13 +1,15 @@
#!/bin/sh #!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
# Run from OPENFOAM top-level directory only # Run from OPENFOAM top-level directory only
cd "${0%/*}" || exit
wmake -check-dir "$WM_PROJECT_DIR" 2>/dev/null || { wmake -check-dir "$WM_PROJECT_DIR" 2>/dev/null || {
echo "Error (${0##*/}) : not located in \$WM_PROJECT_DIR" echo "Error (${0##*/}) : not located in \$WM_PROJECT_DIR"
echo " Check your OpenFOAM environment and installation" echo " Check your OpenFOAM environment and installation"
exit 1 exit 1
} }
if [ -f "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments ] if [ -f "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments ]
then . "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments -no-recursion "$@" || \ then . "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments || \
echo "Argument parse error" echo "Argument parse error"
else else
echo "Error (${0##*/}) : WM_PROJECT_DIR appears to be incorrect" echo "Error (${0##*/}) : WM_PROJECT_DIR appears to be incorrect"

View File

@ -1,2 +1,2 @@
api=2502 api=2412
patch=0 patch=0

View File

@ -13,14 +13,7 @@ volVectorField U
); );
// Initialise the velocity internal field to zero // Initialise the velocity internal field to zero
// Note: explicitly bypass evaluation of contraint patch overrides U = dimensionedVector(U.dimensions(), Zero);
// (e.g. swirlFanVelocity might lookup phi,rho)
//U = dimensionedVector(U.dimensions(), Zero);
{
const dimensionedVector dt(U.dimensions(), Zero);
U.internalFieldRef() = dt;
U.boundaryFieldRef() = dt.value();
}
surfaceScalarField phi surfaceScalarField phi
( (

View File

@ -36,13 +36,11 @@ Description
if (adjustTimeStep) if (adjustTimeStep)
{ {
scalar maxDeltaTFact = maxCo/(CoNum + StCoNum + SMALL); scalar maxDeltaTFact = maxCo/(CoNum + StCoNum + SMALL);
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
const scalar deltaTFact =
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
deltaTFact*runTime.deltaTValue(), deltaTFact*runTime.deltaTValue(),
maxDeltaT maxDeltaT

View File

@ -1,6 +1,5 @@
if (adjustTimeStep) if (adjustTimeStep)
{ {
runTime.setDeltaT(Foam::min(dtChem, maxDeltaT)); runTime.setDeltaT(min(dtChem, maxDeltaT));
Info<< "deltaT = " << runTime.deltaTValue() << endl; Info<< "deltaT = " << runTime.deltaTValue() << endl;
} }

View File

@ -54,18 +54,9 @@ if (adjustTimeStep)
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
dt0 dt0*min(min(TFactorFluid, min(TFactorFilm, TFactorSolid)), 1.2),
* Foam::min
(
Foam::min
(
TFactorFluid,
Foam::min(TFactorFilm, TFactorSolid)
),
1.2
),
maxDeltaT maxDeltaT
) )
); );

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2020,2025 OpenCFD Ltd. Copyright (C) 2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -57,23 +57,11 @@ License
// (relative to reference value) // (relative to reference value)
scalar alphaY(pimpleDict.getOrDefault<scalar>("alphaY", 1.0)); scalar alphaY(pimpleDict.getOrDefault<scalar>("alphaY", 1.0));
// The old reciprocal time scale field, with any damping factor
tmp<volScalarField> rDeltaT0_damped;
// Calculate damped value before applying any other changes
if
(
rDeltaTDampingCoeff < 1
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
)
{
rDeltaT0_damped = (scalar(1) - rDeltaTDampingCoeff)*(rDeltaT);
}
Info<< "Time scales min/max:" << endl; Info<< "Time scales min/max:" << endl;
// Cache old reciprocal time scale field
volScalarField rDeltaT0("rDeltaT0", rDeltaT);
// Flow time scale // Flow time scale
{ {
rDeltaT.ref() = rDeltaT.ref() =
@ -82,14 +70,12 @@ License
/((2*maxCo)*mesh.V()*rho()) /((2*maxCo)*mesh.V()*rho())
); );
// Limit the largest time scale (=> smallest reciprocal time) // Limit the largest time scale
rDeltaT.clamp_min(1/maxDeltaT); rDeltaT.max(1/maxDeltaT);
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Flow = " Info<< " Flow = "
<< limits.min() << ", " << limits.max() << endl; << 1/gMax(rDeltaT.primitiveField()) << ", "
<< 1/gMin(rDeltaT.primitiveField()) << endl;
} }
// Heat release rate time scale // Heat release rate time scale
@ -100,13 +86,11 @@ License
mag(Qdot)/(alphaTemp*rho*thermo.Cp()*T) mag(Qdot)/(alphaTemp*rho*thermo.Cp()*T)
); );
rDeltaT.primitiveFieldRef().clamp_min(rDeltaTT);
auto limits = gMinMax(rDeltaTT.field());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Temperature = " Info<< " Temperature = "
<< limits.min() << ", " << limits.max() << endl; << 1/(gMax(rDeltaTT.field()) + VSMALL) << ", "
<< 1/(gMin(rDeltaTT.field()) + VSMALL) << endl;
rDeltaT.ref() = max(rDeltaT(), rDeltaTT);
} }
// Reaction rate time scale // Reaction rate time scale
@ -154,13 +138,11 @@ License
if (foundY) if (foundY)
{ {
rDeltaT.primitiveFieldRef().clamp_min(rDeltaTY);
auto limits = gMinMax(rDeltaTY.field());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Composition = " Info<< " Composition = "
<< limits.min() << ", " << limits.max() << endl; << 1/(gMax(rDeltaTY.field()) + VSMALL) << ", "
<< 1/(gMin(rDeltaTY.field()) + VSMALL) << endl;
rDeltaT.ref() = max(rDeltaT(), rDeltaTY);
} }
else else
{ {
@ -179,22 +161,28 @@ License
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
} }
// Limit rate of change of time scale (=> smallest reciprocal time) // Limit rate of change of time scale
// - reduce as much as required // - reduce as much as required
// - only increase at a fraction of old time scale // - only increase at a fraction of old time scale
if (rDeltaT0_damped) if
(
rDeltaTDampingCoeff < 1
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
)
{ {
rDeltaT.clamp_min(rDeltaT0_damped()); rDeltaT = max
(
rDeltaT,
(scalar(1) - rDeltaTDampingCoeff)*rDeltaT0
);
} }
// Update tho boundary values of the reciprocal time-step // Update tho boundary values of the reciprocal time-step
rDeltaT.correctBoundaryConditions(); rDeltaT.correctBoundaryConditions();
auto limits = gMinMax(rDeltaT.field());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Overall = " Info<< " Overall = "
<< limits.min() << ", " << limits.max() << endl; << 1/gMax(rDeltaT.primitiveField())
<< ", " << 1/gMin(rDeltaT.primitiveField()) << endl;
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2020,2025 OpenCFD Ltd. Copyright (C) 2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -106,7 +106,7 @@ Foam::smoluchowskiJumpTFvPatchScalarField::smoluchowskiJumpTFvPatchScalarField
if (!this->readValueEntry(dict)) if (!this->readValueEntry(dict))
{ {
// Fallback: set to the internal field // Fallback: set to the internal field
this->extrapolateInternal(); fvPatchField<scalar>::patchInternalField(*this);
} }
refValue() = *this; refValue() = *this;

View File

@ -23,11 +23,7 @@
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
{
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Flow time scale min/max = " Info<< "Flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
} << ", " << gMax(1/rDeltaT.primitiveField()) << endl;
} }

View File

@ -52,26 +52,18 @@
// Update the boundary values of the reciprocal time-step // Update the boundary values of the reciprocal time-step
rDeltaT.correctBoundaryConditions(); rDeltaT.correctBoundaryConditions();
{
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Flow time scale min/max = " Info<< "Flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
} << ", " << gMax(1/rDeltaT.primitiveField()) << endl;
if (rDeltaTSmoothingCoeff < 1.0) if (rDeltaTSmoothingCoeff < 1.0)
{ {
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
} }
{
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Smoothed flow time scale min/max = " Info<< "Smoothed flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
} << ", " << gMax(1/rDeltaT.primitiveField()) << endl;
// Limit rate of change of time scale // Limit rate of change of time scale
// - reduce as much as required // - reduce as much as required
@ -86,10 +78,8 @@
rDeltaT0 rDeltaT0
*max(rDeltaT/rDeltaT0, scalar(1) - rDeltaTDampingCoeff); *max(rDeltaT/rDeltaT0, scalar(1) - rDeltaTDampingCoeff);
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Damped flow time scale min/max = " Info<< "Damped flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
<< ", " << gMax(1/rDeltaT.primitiveField()) << endl;
} }
} }

View File

@ -1,7 +1,7 @@
scalar CoNum = -GREAT; scalar CoNum = -GREAT;
forAll(fluidRegions, regionI) forAll(fluidRegions, regionI)
{ {
CoNum = Foam::max CoNum = max
( (
compressibleCourantNo compressibleCourantNo
( (

View File

@ -78,8 +78,8 @@
} }
rho = thermo.rho(); rho = thermo.rho();
rho = max(rho, rhoMin[i]);
rho.clamp_range(rhoMin[i], rhoMax[i]); rho = min(rho, rhoMax[i]);
rho.relax(); rho.relax();
Info<< "Min/max rho:" << min(rho).value() << ' ' Info<< "Min/max rho:" << min(rho).value() << ' '

View File

@ -387,17 +387,14 @@ updateCoeffs()
{ {
scalar Q = gSum(kappa(Tp)*patch().magSf()*snGrad()); scalar Q = gSum(kappa(Tp)*patch().magSf()*snGrad());
auto limits = gMinMax(Tp);
auto avg = gAverage(Tp);
Info<< "T solid : " << nl << endl; Info<< "T solid : " << nl << endl;
Info Info
<< " heat transfer rate from solid:" << Q << " heat transfer rate from solid:" << Q
<< " walltemperature " << " walltemperature "
<< " min:" << limits.min() << " min:" << gMin(Tp)
<< " max:" << limits.max() << " max:" << gMax(Tp)
<< " avg:" << avg << nl << " avg:" << gAverage(Tp) << nl
<< endl; << endl;
} }
} }
@ -448,16 +445,10 @@ updateCoeffs()
scalarField qLiq((Tp - Tc)*KdeltaLiq); scalarField qLiq((Tp - Tc)*KdeltaLiq);
scalarField qVap((Tp - Tv.patchInternalField())*KdeltaVap); scalarField qVap((Tp - Tv.patchInternalField())*KdeltaVap);
auto infoT = gMinMax(Tp);
auto avgT = gAverage(Tp);
auto infoLiq = gMinMax(qLiq);
auto infoVap = gMinMax(qVap);
Info<< "T flow : " << nl << endl; Info<< "T flow : " << nl << endl;
Info<< " qLiq: " << infoLiq.min() << " - " << infoLiq.max() << nl Info<< " qLiq: " << gMin(qLiq) << " - " << gMax(qLiq) << endl;
<< " qVap: " << infoVap.min() << " - " << infoVap.max() << nl; Info<< " qVap: " << gMin(qVap) << " - " << gMax(qVap) << endl;
scalar QLiq = gSum(qLiq*patch().magSf()); scalar QLiq = gSum(qLiq*patch().magSf());
scalar QVap = gSum(qVap*patch().magSf()); scalar QVap = gSum(qVap*patch().magSf());
@ -466,9 +457,9 @@ updateCoeffs()
Info<< " Heat transfer to Vap: " << QVap << endl; Info<< " Heat transfer to Vap: " << QVap << endl;
Info<< " walltemperature " Info<< " walltemperature "
<< " min:" << infoT.min() << " min:" << gMin(Tp)
<< " max:" << infoT.max() << " max:" << gMax(Tp)
<< " avg:" << avgT << " avg:" << gAverage(Tp)
<< endl; << endl;
} }
} }

View File

@ -31,7 +31,7 @@
); );
scalar regionCoNum = CoNum =
0.5*gMax 0.5*gMax
( (
sumPhi/fluidRegions[regioni].V().field() sumPhi/fluidRegions[regioni].V().field()
@ -41,9 +41,9 @@
( (
fvc::surfaceSum(mag(phi1 - phi2))().primitiveField() fvc::surfaceSum(mag(phi1 - phi2))().primitiveField()
/ fluidRegions[regioni].V().field() / fluidRegions[regioni].V().field()
)*runTime.deltaTValue(); )*runTime.deltaTValue(),
CoNum = Foam::max(CoNum, Foam::max(regionCoNum, UrCoNum)); CoNum = max(UrCoNum, CoNum);
} }
} }

View File

@ -2,7 +2,7 @@
forAll(fluidRegions, regioni) forAll(fluidRegions, regioni)
{ {
CoNum = Foam::max CoNum = max
( (
compressibleCourantNo compressibleCourantNo
( (
@ -17,7 +17,7 @@
/* /*
forAll(porousFluidRegions, porousi) forAll(porousFluidRegions, porousi)
{ {
CoNum = Foam::max CoNum = max
( (
compressibleCourantNo compressibleCourantNo
( (

View File

@ -47,10 +47,10 @@ if (adjustTimeStep)
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
Foam::min(maxCo/CoNum, maxDi/DiNum)*runTime.deltaTValue(), min(maxCo/CoNum, maxDi/DiNum)*runTime.deltaTValue(),
Foam::min(runTime.deltaTValue(), maxDeltaT) min(runTime.deltaTValue(), maxDeltaT)
) )
); );
Info<< "deltaT = " << runTime.deltaTValue() << endl; Info<< "deltaT = " << runTime.deltaTValue() << endl;

View File

@ -48,14 +48,18 @@ if (adjustTimeStep)
scalar maxDeltaTFluid = maxCo/(CoNum + SMALL); scalar maxDeltaTFluid = maxCo/(CoNum + SMALL);
scalar maxDeltaTSolid = maxDi/(DiNum + SMALL); scalar maxDeltaTSolid = maxDi/(DiNum + SMALL);
const scalar deltaTFluid = scalar deltaTFluid =
Foam::min(Foam::min(maxDeltaTFluid, 1.0 + 0.1*maxDeltaTFluid), 1.2); min
(
min(maxDeltaTFluid, 1.0 + 0.1*maxDeltaTFluid),
1.2
);
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
Foam::min(deltaTFluid, maxDeltaTSolid)*runTime.deltaTValue(), min(deltaTFluid, maxDeltaTSolid)*runTime.deltaTValue(),
maxDeltaT maxDeltaT
) )
); );

View File

@ -22,7 +22,7 @@ forAll(solidRegions, i)
tmp<volScalarField> trho = thermo.rho(); tmp<volScalarField> trho = thermo.rho();
const volScalarField& rho = trho(); const volScalarField& rho = trho();
DiNum = Foam::max DiNum = max
( (
solidRegionDiffNo solidRegionDiffNo
( (

View File

@ -17,7 +17,7 @@ scalar DiNum = -GREAT;
tmp<volScalarField> trho = thermo.rho(); tmp<volScalarField> trho = thermo.rho();
const volScalarField& rho = trho(); const volScalarField& rho = trho();
DiNum = Foam::max DiNum = max
( (
solidRegionDiffNo solidRegionDiffNo
( (

View File

@ -60,10 +60,13 @@ template<class Type>
void zeroCells void zeroCells
( (
GeometricField<Type, fvPatchField, volMesh>& vf, GeometricField<Type, fvPatchField, volMesh>& vf,
const labelUList& cells const labelList& cells
) )
{ {
UIndirectList<Type>(vf.primitiveField(), cells) = Zero; forAll(cells, i)
{
vf[cells[i]] = Zero;
}
} }

View File

@ -103,8 +103,8 @@ dimensionedScalar alphaMax
laminarTransport laminarTransport
); );
const labelUList& inletCells = mesh.boundary()["inlet"].faceCells(); const labelList& inletCells = mesh.boundary()["inlet"].faceCells();
//const labelUList& outletCells = mesh.boundary()["outlet"].faceCells(); //const labelList& outletCells = mesh.boundary()["outlet"].faceCells();
volScalarField alpha volScalarField alpha
( (

View File

@ -55,7 +55,7 @@ if (mesh.changing())
dimensionedScalar rAUf("rAUf", dimTime, 1.0); dimensionedScalar rAUf("rAUf", dimTime, 1.0);
const cellCellStencilObject& overlap = Stencil::New(mesh); const cellCellStencilObject& overlap = Stencil::New(mesh);
const labelUList& cellTypes = overlap.cellTypes(); const labelList& cellTypes = overlap.cellTypes();
const labelIOList& zoneIDs = overlap.zoneID(); const labelIOList& zoneIDs = overlap.zoneID();
while (pimple.correctNonOrthogonal()) while (pimple.correctNonOrthogonal())

View File

@ -36,26 +36,18 @@
// Update the boundary values of the reciprocal time-step // Update the boundary values of the reciprocal time-step
rDeltaT.correctBoundaryConditions(); rDeltaT.correctBoundaryConditions();
{
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Flow time scale min/max = " Info<< "Flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
} << ", " << gMax(1/rDeltaT.primitiveField()) << endl;
if (rDeltaTSmoothingCoeff < 1.0) if (rDeltaTSmoothingCoeff < 1.0)
{ {
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
} }
{
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Smoothed flow time scale min/max = " Info<< "Smoothed flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
} << ", " << gMax(1/rDeltaT.primitiveField()) << endl;
// Limit rate of change of time scale // Limit rate of change of time scale
// - reduce as much as required // - reduce as much as required
@ -70,10 +62,8 @@
rDeltaT0 rDeltaT0
*max(rDeltaT/rDeltaT0, scalar(1) - rDeltaTDampingCoeff); *max(rDeltaT/rDeltaT0, scalar(1) - rDeltaTDampingCoeff);
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Damped flow time scale min/max = " Info<< "Damped flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
<< ", " << gMax(1/rDeltaT.primitiveField()) << endl;
} }
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020,2025 OpenCFD Ltd. Copyright (C) 2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -54,22 +54,11 @@ License
scalar alphaTemp(pimpleDict.getOrDefault("alphaTemp", 0.05)); scalar alphaTemp(pimpleDict.getOrDefault("alphaTemp", 0.05));
// The old reciprocal time scale field, with any damping factor
tmp<volScalarField> rDeltaT0_damped;
// Calculate damped value before applying any other changes
if
(
rDeltaTDampingCoeff < 1
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
)
{
rDeltaT0_damped = (scalar(1) - rDeltaTDampingCoeff)*(rDeltaT);
}
Info<< "Time scales min/max:" << endl; Info<< "Time scales min/max:" << endl;
// Cache old reciprocal time scale field
volScalarField rDeltaT0("rDeltaT0", rDeltaT);
// Flow time scale // Flow time scale
{ {
rDeltaT.ref() = rDeltaT.ref() =
@ -78,14 +67,12 @@ License
/((2*maxCo)*mesh.V()*rho()) /((2*maxCo)*mesh.V()*rho())
); );
// Limit the largest time scale (=> smallest reciprocal time) // Limit the largest time scale
rDeltaT.clamp_min(1/maxDeltaT); rDeltaT.max(1/maxDeltaT);
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Flow = " Info<< " Flow = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField()) << ", "
<< gMax(1/rDeltaT.primitiveField()) << endl;
} }
// Reaction source time scale // Reaction source time scale
@ -106,13 +93,15 @@ License
) )
); );
rDeltaT.primitiveFieldRef().clamp_min(rDeltaTT);
auto limits = gMinMax(rDeltaTT.field());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Temperature = " Info<< " Temperature = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/(rDeltaTT.field() + VSMALL)) << ", "
<< gMax(1/(rDeltaTT.field() + VSMALL)) << endl;
rDeltaT.ref() = max
(
rDeltaT(),
rDeltaTT
);
} }
// Update tho boundary values of the reciprocal time-step // Update tho boundary values of the reciprocal time-step
@ -124,19 +113,25 @@ License
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
} }
// Limit rate of change of time scale (=> smallest reciprocal time) // Limit rate of change of time scale
// - reduce as much as required // - reduce as much as required
// - only increase at a fraction of old time scale // - only increase at a fraction of old time scale
if (rDeltaT0_damped) if
(
rDeltaTDampingCoeff < 1.0
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
)
{ {
rDeltaT.clamp_min(rDeltaT0_damped()); rDeltaT = max
(
rDeltaT,
(scalar(1) - rDeltaTDampingCoeff)*rDeltaT0
);
} }
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Overall = " Info<< " Overall = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
<< ", " << gMax(1/rDeltaT.primitiveField()) << endl;
} }

View File

@ -36,18 +36,13 @@ Description
if (adjustTimeStep) if (adjustTimeStep)
{ {
const scalar maxDeltaTFact = const scalar maxDeltaTFact =
Foam::min min(maxCo/(CoNum + SMALL), maxCo/(surfaceFilm.CourantNumber() + SMALL));
(
maxCo/(CoNum + SMALL),
maxCo/(surfaceFilm.CourantNumber() + SMALL)
);
const scalar deltaTFact = const scalar deltaTFact =
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2); min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
deltaTFact*runTime.deltaTValue(), deltaTFact*runTime.deltaTValue(),
maxDeltaT maxDeltaT

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020,2025 OpenCFD Ltd. Copyright (C) 2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -54,22 +54,11 @@ License
scalar alphaTemp(pimpleDict.getOrDefault("alphaTemp", 0.05)); scalar alphaTemp(pimpleDict.getOrDefault("alphaTemp", 0.05));
// The old reciprocal time scale field, with any damping factor
tmp<volScalarField> rDeltaT0_damped;
// Calculate damped value before applying any other changes
if
(
rDeltaTDampingCoeff < 1
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
)
{
rDeltaT0_damped = (scalar(1) - rDeltaTDampingCoeff)*(rDeltaT);
}
Info<< "Time scales min/max:" << endl; Info<< "Time scales min/max:" << endl;
// Cache old reciprocal time scale field
volScalarField rDeltaT0("rDeltaT0", rDeltaT);
// Flow time scale // Flow time scale
{ {
rDeltaT.ref() = rDeltaT.ref() =
@ -78,14 +67,12 @@ License
/((2*maxCo)*mesh.V()*rho()) /((2*maxCo)*mesh.V()*rho())
); );
// Limit the largest time scale (=> smallest reciprocal time) // Limit the largest time scale
rDeltaT.clamp_min(1/maxDeltaT); rDeltaT.max(1/maxDeltaT);
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Flow = " Info<< " Flow = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField()) << ", "
<< gMax(1/rDeltaT.primitiveField()) << endl;
} }
// Reaction source time scale // Reaction source time scale
@ -105,13 +92,15 @@ License
) )
); );
rDeltaT.primitiveFieldRef().clamp_min(rDeltaTT);
auto limits = gMinMax(rDeltaTT.field());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Temperature = " Info<< " Temperature = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/(rDeltaTT.field() + VSMALL)) << ", "
<< gMax(1/(rDeltaTT.field() + VSMALL)) << endl;
rDeltaT.ref() = max
(
rDeltaT(),
rDeltaTT
);
} }
// Update the boundary values of the reciprocal time-step // Update the boundary values of the reciprocal time-step
@ -123,22 +112,25 @@ License
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
} }
// Limit rate of change of time scale (=> smallest reciprocal time) // Limit rate of change of time scale
// - reduce as much as required // - reduce as much as required
// - only increase at a fraction of old time scale // - only increase at a fraction of old time scale
if (rDeltaT0_damped) if
(
rDeltaTDampingCoeff < 1.0
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
)
{ {
rDeltaT.clamp_min(rDeltaT0_damped()); rDeltaT = max
(
rDeltaT,
(scalar(1) - rDeltaTDampingCoeff)*rDeltaT0
);
} }
// Update the boundary values of the reciprocal time-step
rDeltaT.correctBoundaryConditions();
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< " Overall = " Info<< " Overall = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
<< ", " << gMax(1/rDeltaT.primitiveField()) << endl;
} }

View File

@ -48,7 +48,8 @@ U.correctBoundaryConditions();
fvOptions.correct(U); fvOptions.correct(U);
rho = thermo.rho(); rho = thermo.rho();
rho.clamp_range(rhoMin, rhoMax); rho = max(rho, rhoMin);
rho = min(rho, rhoMax);
rho.relax(); rho.relax();
Info<< "p min/max = " << min(p).value() << ", " << max(p).value() << endl; Info<< "p min/max = " << min(p).value() << ", " << max(p).value() << endl;

View File

@ -49,7 +49,8 @@
fvOptions.correct(U); fvOptions.correct(U);
rho = thermo.rho(); rho = thermo.rho();
rho.clamp_range(rhoMin, rhoMax); rho = max(rho, rhoMin);
rho = min(rho, rhoMax);
rho.relax(); rho.relax();
Info<< "p min/max = " << min(p).value() << ", " << max(p).value() << endl; Info<< "p min/max = " << min(p).value() << ", " << max(p).value() << endl;

View File

@ -1,5 +1,6 @@
rho = thermo.rho(); rho = thermo.rho();
rho.clamp_range(rhoMin, rhoMax); rho = max(rho, rhoMin);
rho = min(rho, rhoMax);
rho.relax(); rho.relax();
volScalarField rAU(1.0/UEqn.A()); volScalarField rAU(1.0/UEqn.A());
@ -93,7 +94,8 @@ p.relax();
// Recalculate density from the relaxed pressure // Recalculate density from the relaxed pressure
rho = thermo.rho(); rho = thermo.rho();
rho.clamp_range(rhoMin, rhoMax); rho = max(rho, rhoMin);
rho = min(rho, rhoMax);
rho.relax(); rho.relax();
Info<< "rho min/max : " << min(rho).value() << " " << max(rho).value() << endl; Info<< "rho min/max : " << min(rho).value() << " " << max(rho).value() << endl;

View File

@ -1,5 +1,6 @@
rho = thermo.rho(); rho = thermo.rho();
rho.clamp_range(rhoMin, rhoMax); rho = max(rho, rhoMin);
rho = min(rho, rhoMax);
rho.relax(); rho.relax();
volScalarField rAU(1.0/UEqn.A()); volScalarField rAU(1.0/UEqn.A());
@ -93,7 +94,8 @@ p.relax();
// Recalculate density from the relaxed pressure // Recalculate density from the relaxed pressure
rho = thermo.rho(); rho = thermo.rho();
rho.clamp_range(rhoMin, rhoMax); rho = max(rho, rhoMin);
rho = min(rho, rhoMax);
rho.relax(); rho.relax();
Info<< "rho min/max : " << min(rho).value() << " " << max(rho).value() << endl; Info<< "rho min/max : " << min(rho).value() << " " << max(rho).value() << endl;

View File

@ -36,14 +36,13 @@ Description
if (adjustTimeStep) if (adjustTimeStep)
{ {
scalar maxDeltaTFact = scalar maxDeltaTFact =
Foam::min(maxCo/(CoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL)); min(maxCo/(CoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL));
const scalar deltaTFact = scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
deltaTFact*runTime.deltaTValue(), deltaTFact*runTime.deltaTValue(),
maxDeltaT maxDeltaT

View File

@ -53,21 +53,6 @@
pimpleDict.getOrDefault<scalar>("maxDeltaT", GREAT) pimpleDict.getOrDefault<scalar>("maxDeltaT", GREAT)
); );
// The old reciprocal time scale field, with any damping factor
tmp<volScalarField> rDeltaT0_damped;
// Calculate damped value before applying any other changes
if
(
rDeltaTDampingCoeff < 1
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
)
{
rDeltaT0_damped = (scalar(1) - rDeltaTDampingCoeff)*(rDeltaT);
}
volScalarField rDeltaT0("rDeltaT0", rDeltaT); volScalarField rDeltaT0("rDeltaT0", rDeltaT);
// Set the reciprocal time-step from the local Courant number // Set the reciprocal time-step from the local Courant number
@ -98,13 +83,10 @@
// Update tho boundary values of the reciprocal time-step // Update tho boundary values of the reciprocal time-step
rDeltaT.correctBoundaryConditions(); rDeltaT.correctBoundaryConditions();
{
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Flow time scale min/max = " Info<< "Flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
} << ", " << gMax(1/rDeltaT.primitiveField()) << endl;
if (rDeltaTSmoothingCoeff < 1.0) if (rDeltaTSmoothingCoeff < 1.0)
{ {
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
@ -128,25 +110,27 @@
fvc::sweep(rDeltaT, alpha1, nAlphaSweepIter, alphaSpreadDiff); fvc::sweep(rDeltaT, alpha1, nAlphaSweepIter, alphaSpreadDiff);
} }
{
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Smoothed flow time scale min/max = " Info<< "Smoothed flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
} << ", " << gMax(1/rDeltaT.primitiveField()) << endl;
// Limit rate of change of time scale (=> smallest reciprocal time) // Limit rate of change of time scale
// - reduce as much as required // - reduce as much as required
// - only increase at a fraction of old time scale // - only increase at a fraction of old time scale
if (rDeltaT0_damped) if
(
rDeltaTDampingCoeff < 1.0
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
)
{ {
rDeltaT.clamp_min(rDeltaT0_damped()); rDeltaT = max
(
auto limits = gMinMax(rDeltaT.primitiveField()); rDeltaT,
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL)); (scalar(1) - rDeltaTDampingCoeff)*rDeltaT0
);
Info<< "Damped flow time scale min/max = " Info<< "Damped flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
<< ", " << gMax(1/rDeltaT.primitiveField()) << endl;
} }
} }

View File

@ -36,14 +36,13 @@ Description
if (adjustTimeStep) if (adjustTimeStep)
{ {
scalar maxDeltaTFact = scalar maxDeltaTFact =
Foam::min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL)); min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL));
const scalar deltaTFact = scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
deltaTFact*runTime.deltaTValue(), deltaTFact*runTime.deltaTValue(),
maxDeltaT maxDeltaT

View File

@ -37,15 +37,11 @@ if (adjustTimeStep)
if (CoNum > SMALL) if (CoNum > SMALL)
{ {
scalar maxDeltaTFact = scalar maxDeltaTFact =
Foam::min min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL));
(
maxCo/(CoNum + SMALL),
maxAcousticCo/(acousticCoNum + SMALL)
);
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
maxDeltaTFact*runTime.deltaTValue(), maxDeltaTFact*runTime.deltaTValue(),
maxDeltaT maxDeltaT

View File

@ -26,12 +26,12 @@ forAll(dgdt, celli)
{ {
if (dgdt[celli] > 0.0) if (dgdt[celli] > 0.0)
{ {
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4); Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4); Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
} }
else if (dgdt[celli] < 0.0) else if (dgdt[celli] < 0.0)
{ {
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4); Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
} }
} }

View File

@ -210,7 +210,7 @@ void VoFPatchTransfer::correct
film().toRegion(patchi, Vp); film().toRegion(patchi, Vp);
const polyPatch& pp = pbm[patchi]; const polyPatch& pp = pbm[patchi];
const labelUList& faceCells = pp.faceCells(); const labelList& faceCells = pp.faceCells();
// Accumulate the total mass removed from patch // Accumulate the total mass removed from patch
scalar dMassPatch = 0; scalar dMassPatch = 0;

View File

@ -26,12 +26,12 @@ forAll(dgdt, celli)
{ {
if (dgdt[celli] > 0.0) if (dgdt[celli] > 0.0)
{ {
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4); Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4); Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
} }
else if (dgdt[celli] < 0.0) else if (dgdt[celli] < 0.0)
{ {
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4); Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
} }
} }

View File

@ -26,12 +26,12 @@ forAll(dgdt, celli)
{ {
if (dgdt[celli] > 0.0) if (dgdt[celli] > 0.0)
{ {
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4); Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4); Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
} }
else if (dgdt[celli] < 0.0) else if (dgdt[celli] < 0.0)
{ {
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4); Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
} }
} }

View File

@ -135,7 +135,7 @@ public:
virtual volScalarField& he() virtual volScalarField& he()
{ {
NotImplemented; NotImplemented;
return volScalarField::null().constCast(); return const_cast<volScalarField&>(volScalarField::null());
} }
//- Enthalpy/Internal energy [J/kg] //- Enthalpy/Internal energy [J/kg]

View File

@ -243,7 +243,7 @@ public:
virtual volScalarField& he() virtual volScalarField& he()
{ {
NotImplemented; NotImplemented;
return volScalarField::null().constCast(); return const_cast<volScalarField&>(volScalarField::null());
} }
//- Enthalpy/Internal energy [J/kg] //- Enthalpy/Internal energy [J/kg]

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -679,7 +679,7 @@ void Foam::radiation::laserDTRM::calculate()
} }
} }
scalar totalQ = gWeightedSum(mesh_.V(), Q_.primitiveField()); scalar totalQ = gSum(Q_.primitiveFieldRef()*mesh_.V());
Info << "Total energy absorbed [W]: " << totalQ << endl; Info << "Total energy absorbed [W]: " << totalQ << endl;
if (mesh_.time().writeTime()) if (mesh_.time().writeTime())

View File

@ -36,13 +36,13 @@ Description
if (adjustTimeStep) if (adjustTimeStep)
{ {
scalar maxDeltaTFact = scalar maxDeltaTFact =
Foam::min min
( (
maxCo/(CoNum + SMALL), maxCo/(CoNum + SMALL),
Foam::min min
( (
maxAlphaCo/(alphaCoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL),
Foam::min min
( (
maxAlphaDdt/(ddtAlphaNum + SMALL), maxAlphaDdt/(ddtAlphaNum + SMALL),
maxDi/(DiNum + SMALL) maxDi/(DiNum + SMALL)
@ -50,18 +50,16 @@ if (adjustTimeStep)
) )
); );
const scalar deltaTFact = scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT runTime.setDeltaT
( (
Foam::min min
( (
deltaTFact*runTime.deltaTValue(), deltaTFact*runTime.deltaTValue(),
maxDeltaT maxDeltaT
) )
); );
Info<< "deltaT = " << runTime.deltaTValue() << endl; Info<< "deltaT = " << runTime.deltaTValue() << endl;
} }

View File

@ -86,7 +86,7 @@ public:
virtual volScalarField& he() virtual volScalarField& he()
{ {
NotImplemented; NotImplemented;
return volScalarField::null().constCast(); return const_cast<volScalarField&>(volScalarField::null());
} }
//- Return access to the internal energy field [J/Kg] //- Return access to the internal energy field [J/Kg]

View File

@ -65,7 +65,7 @@
dimensionedScalar rAUf("rAUf", dimTime/rho.dimensions(), 1.0); dimensionedScalar rAUf("rAUf", dimTime/rho.dimensions(), 1.0);
const cellCellStencilObject& overlap = Stencil::New(mesh); const cellCellStencilObject& overlap = Stencil::New(mesh);
const labelUList& cellTypes = overlap.cellTypes(); const labelList& cellTypes = overlap.cellTypes();
const labelIOList& zoneIDs = overlap.zoneID(); const labelIOList& zoneIDs = overlap.zoneID();
while (pimple.correctNonOrthogonal()) while (pimple.correctNonOrthogonal())

View File

@ -38,9 +38,7 @@
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Flow time scale min/max = " Info<< "Flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
<< ", " << gMax(1/rDeltaT.primitiveField()) << endl;
} }

View File

@ -8,5 +8,5 @@
Info<< "Max Ur Courant Number = " << UrCoNum << endl; Info<< "Max Ur Courant Number = " << UrCoNum << endl;
CoNum = Foam::max(CoNum, UrCoNum); CoNum = max(CoNum, UrCoNum);
} }

View File

@ -31,9 +31,7 @@
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
auto limits = gMinMax(rDeltaT.primitiveField());
limits.reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL));
Info<< "Flow time scale min/max = " Info<< "Flow time scale min/max = "
<< limits.min() << ", " << limits.max() << endl; << gMin(1/rDeltaT.primitiveField())
<< ", " << gMax(1/rDeltaT.primitiveField()) << endl;
} }

View File

@ -8,5 +8,5 @@
Info<< "Max Ur Courant Number = " << UrCoNum << endl; Info<< "Max Ur Courant Number = " << UrCoNum << endl;
CoNum = Foam::max(CoNum, UrCoNum); CoNum = max(CoNum, UrCoNum);
} }

View File

@ -1,6 +1,7 @@
#!/bin/sh #!/bin/sh
cd "${0%/*}" || exit # Run from this directory cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments -no-recursion "$@" set -- -no-recursion "$@" # Parse arguments only
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments
. ${WM_PROJECT_DIR:?}/wmake/scripts/wmakeFunctions # Require wmake functions . ${WM_PROJECT_DIR:?}/wmake/scripts/wmakeFunctions # Require wmake functions
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2025 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,12 +25,9 @@ License
Description Description
Test the sizeof for basic types. Test the sizeof for basic types.
Also tests how the data mapping of OpenFOAM types to UPstream (MPI)
type ids are handled.
Can be compiled and run without any OpenFOAM libraries. Can be compiled and run without any OpenFOAM libraries.
g++ -std=c++17 -oTest-machine-sizes Test-machine-sizes.cpp g++ -std=c++11 -oTest-machine-sizes Test-machine-sizes.cpp
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -40,134 +37,6 @@ Description
#include <iostream> #include <iostream>
#include <limits> #include <limits>
#include <typeinfo> #include <typeinfo>
#include <type_traits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Partial copy from UPstream.H
//- Some MPI data types
//
//- Mapping of some fundamental and aggregate types to MPI data types
enum class dataTypes : int
{
// Fundamental Types [10]:
Basic_begin,
type_byte = Basic_begin,
type_int16,
type_int32,
type_int64,
type_uint16,
type_uint32,
type_uint64,
type_float,
type_double,
type_long_double,
invalid,
Basic_end = invalid
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Partial copy from UPstreamTraits.H
//- UPstream data type corresponding to an intrinsic (MPI) type
template<class T>
struct UPstream_mpi_dataType : std::false_type
{
static constexpr auto datatype_id = dataTypes::invalid;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Specializations to match elements of UPstream::dataTypes
#undef defineUPstreamDataTraits
#define defineUPstreamDataTraits(TypeId, Type) \
template<> struct UPstream_mpi_dataType<Type> : std::true_type \
{ \
static constexpr auto datatype_id = dataTypes::TypeId; \
};
defineUPstreamDataTraits(type_byte, char);
defineUPstreamDataTraits(type_byte, unsigned char);
defineUPstreamDataTraits(type_int16, int16_t);
defineUPstreamDataTraits(type_int32, int32_t);
defineUPstreamDataTraits(type_int64, int64_t);
defineUPstreamDataTraits(type_uint16, uint16_t);
defineUPstreamDataTraits(type_uint32, uint32_t);
defineUPstreamDataTraits(type_uint64, uint64_t);
defineUPstreamDataTraits(type_float, float);
defineUPstreamDataTraits(type_double, double);
defineUPstreamDataTraits(type_long_double, long double);
#undef defineUPstreamDataTraits
//- Explicit handling of data type aliases. This is necessary since
//- different systems map things like 'unsigned long' differently but we
//- restrict ourselves to int32/int64 types
template<class T>
struct UPstream_alias_dataType
:
std::bool_constant
<
// Basic MPI type
UPstream_mpi_dataType<std::remove_cv_t<T>>::value ||
(
// Or some int 32/64 type to re-map
std::is_integral_v<T>
&& (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))
)
>
{
using base = std::conditional_t
<
UPstream_mpi_dataType<std::remove_cv_t<T>>::value,
std::remove_cv_t<T>, // <- using mpi type (no alias)
std::conditional_t // <- using alias
<
(
std::is_integral_v<T>
&& (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))
),
std::conditional_t
<
(sizeof(T) == sizeof(int32_t)),
std::conditional_t<std::is_signed_v<T>, int32_t, uint32_t>,
std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>
>,
char // Fallback is a byte (eg, arbitrary contiguous data)
>
>;
static constexpr auto datatype_id =
UPstream_mpi_dataType<base>::datatype_id;
};
// Handle int8_t/uint8_t as aliases since 'signed char' etc may be
// ambiguous
//- Map \c int8_t to UPstream::dataTypes::type_byte
template<>
struct UPstream_alias_dataType<int8_t> : std::true_type
{
using base = char;
static constexpr auto datatype_id = dataTypes::type_byte;
};
//- Map \c uint8_t to UPstream::dataTypes::type_byte
template<>
struct UPstream_alias_dataType<uint8_t> : std::true_type
{
using base = unsigned char;
static constexpr auto datatype_id = dataTypes::type_byte;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class T> template<class T>
void print(const char* name, bool showLimits = true) void print(const char* name, bool showLimits = true)
@ -178,84 +47,28 @@ void print(const char* name, bool showLimits = true)
if (showLimits) if (showLimits)
{ {
std::cout std::cout
<< " max=<"; << " \"max\"=" << std::numeric_limits<T>::max();
if constexpr (sizeof(T) == 1)
{
std::cout << int(std::numeric_limits<T>::max());
}
else
{
std::cout << std::numeric_limits<T>::max();
}
std::cout << '>';
}
// A declared or deduced MPI type, or aliased
if constexpr (UPstream_mpi_dataType<T>::value)
{
std::cout
<< " is_mpi=("
<< int(UPstream_mpi_dataType<T>::datatype_id) << ')';
}
else
{
std::cout << " is_mpi=(null)";
}
// Any aliases?
if constexpr (UPstream_alias_dataType<T>::value)
{
if constexpr (UPstream_mpi_dataType<T>::value)
{
std::cout << " alias=base";
}
else
{
std::cout
<< " alias=("
<< int(UPstream_alias_dataType<T>::datatype_id) << ')';
}
} }
std::cout<< '\n'; std::cout<< '\n';
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
std::cout<< "c++ = " << __cplusplus << '\n'; std::cout<< "c++ = " << __cplusplus << '\n';
std::cout<< "machine sizes (and some MPI traits)\n---\n\n"; std::cout<< "machine sizes\n---\n\n";
print<int8_t>("int8_t");
print<uint8_t>("uint8_t");
print<int16_t>("int16_t");
print<uint16_t>("uint16_t");
print<int32_t>("int32_t");
print<uint32_t>("uint32_t");
print<int64_t>("int64_t");
print<uint64_t>("uint64_t");
std::cout << '\n';
print<char>("char");
print<signed char>("signed char");
print<unsigned char>("unsigned char");
print<short>("short"); print<short>("short");
print<int>("int"); print<int>("int");
print<unsigned>("unsigned");
print<long>("long"); print<long>("long");
print<unsigned long>("unsigned long"); print<unsigned long>("unsigned long");
print<std::size_t>("std::size_t");
print<long long>("long long"); print<long long>("long long");
std::cout << '\n';
print<std::size_t>("std::size_t");
print<std::streamsize>("std::streamsize");
std::cout << '\n';
print<float>("float"); print<float>("float");
print<double>("double"); print<double>("double");
print<long double>("long double"); print<long double>("long double");

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd. Copyright (C) 2020-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,11 +38,12 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "Tensor.H" #include "Tensor.H"
#include "SymmTensor.H" #include "SymmTensor.H"
#include "SphericalTensor.H" #include "SphericalTensor.H"
#include "DiagTensor.H" #include "DiagTensor.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -56,11 +57,45 @@ unsigned nTest_ = 0;
unsigned nFail_ = 0; unsigned nFail_ = 0;
// Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485.
template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar relTol = 1e-8, //<! are values the same within 8 decimals
const scalar absTol = 0 //<! useful for cmps near zero
)
{
Info<< msg << x << endl;
unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
++nFail;
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance. // Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485 // The function is converted from PEP-485
template<class Type> template<class Type>
void cmp typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -69,36 +104,17 @@ void cmp
const scalar absTol = 0 const scalar absTol = 0
) )
{ {
const auto notEqual = [=](const auto& a, const auto& b) -> bool Info<< msg << x << endl;
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if constexpr (is_vectorspace_v<Type>)
{
for (direction i = 0; i < pTraits<Type>::nComponents; ++i) for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{ {
if (notEqual(x[i], y[i])) if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{ {
++nFail; ++nFail;
} }
} }
}
else
{
if (notEqual(x, y))
{
++nFail;
}
}
Info<< msg << x << endl;
if (nFail) if (nFail)
{ {
@ -352,26 +368,27 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names) inline typename std::enable_if<I == sizeof...(Tp), void>::type
{ run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl; Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name << " ##" << nl; Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl; Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
test_global_opers(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names); run_tests<I + 1, Tp...>(types, typeID);
}
} }
@ -386,8 +403,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"DiagTensor<float>", "DiagTensor<floatScalar>",
"DiagTensor<double>", "DiagTensor<doubleScalar>",
"DiagTensor<complex>" "DiagTensor<complex>"
}); });

View File

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

View File

@ -25,10 +25,10 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application Application
Test-PtrDictionary1 Test-Dictionary
Description Description
Tests for Dictionary (not dictionary) and PtrDictionary Tests for Dictionary (not dictionary)
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -185,7 +185,7 @@ int main(int argc, char *argv[])
} }
std::cout<< "iter type: " std::cout<< "iter type: "
<< typeid(std::begin(scalarDict2)).name() << '\n'; << typeid(stdFoam::begin(scalarDict2)).name() << '\n';
scalarDict.transfer(scalarDict2); scalarDict.transfer(scalarDict2);

View File

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

View File

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

View File

@ -52,8 +52,7 @@ void printInfo
if (showSize) if (showSize)
{ {
Info<< " size=\"" << list.size() Info<< " size=\"" << list.size()
<< "\" capacity=\"" << list.capacity() << "\"" << "\" capacity=\"" << list.capacity() << "\"";
<< "\" min=\"" << SizeMin << "\"" ;
if (list.cdata()) if (list.cdata())
{ {
Info<< " ptr=\"" << name(list.cdata()) << "\""; Info<< " ptr=\"" << name(list.cdata()) << "\"";
@ -80,8 +79,7 @@ void printInfo
if (showSize) if (showSize)
{ {
Info<< " size=\"" << list.size() Info<< " size=\"" << list.size()
<< "\" capacity=\"" << list.capacity() << "\"" << "\" capacity=\"" << list.capacity() << "\"";
<< "\" min=\"" << SizeMin << "\"" ;
if (list.cdata()) if (list.cdata())
{ {
Info<< " ptr=\"" << name(list.cdata()) << "\""; Info<< " ptr=\"" << name(list.cdata()) << "\"";
@ -170,22 +168,6 @@ int main(int argc, char *argv[])
printInfo("", list2); printInfo("", list2);
} }
{
DynamicList<float, 32> list1(std::pair<label,label>(16,0));
list1 = -1;
Info<< "construct with specified size/capacity" << nl;
printInfo("", list1);
}
{
DynamicList<float, 32> list1(std::pair<label,label>(8,16));
list1 = -1;
Info<< "construct with specified size/capacity" << nl;
printInfo("", list1);
}
Info<< "\nEnd\n"; Info<< "\nEnd\n";
return 0; return 0;

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd. Copyright (C) 2019-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -41,6 +41,7 @@ See also
#include "List.H" #include "List.H"
#include "IPstream.H" #include "IPstream.H"
#include "OPstream.H" #include "OPstream.H"
#include <numeric>
using namespace Foam; using namespace Foam;
@ -84,7 +85,8 @@ void compileInfo()
template<class FixedListType> template<class FixedListType>
std::enable_if_t<(FixedListType::max_size() == 2), bool> typename std::enable_if
<(FixedListType::max_size() == 2), bool>::type
is_pair() is_pair()
{ {
return true; return true;
@ -92,7 +94,7 @@ is_pair()
template<class FixedListType> template<class FixedListType>
std::enable_if_t<(FixedListType::max_size() != 2), std::string> typename std::enable_if<(FixedListType::max_size() != 2), std::string>::type
is_pair() is_pair()
{ {
return "not really at all"; return "not really at all";

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021-2025 OpenCFD Ltd. Copyright (C) 2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,11 +42,9 @@ Note
#include "Hash.H" #include "Hash.H"
#ifdef FULLDEBUG #ifdef FULLDEBUG
#define HashTypeInfo(Name) \ #define HashTypeInfo(Args) void info() { std::cerr<< "" Args << "\n"; }
static constexpr const char* name() noexcept { return Name; } \
void info() const { std::cerr<< name() << " hashing\n"; }
#else #else
#define HashTypeInfo(Name) void info() const {} #define HashTypeInfo(Args) void info() {}
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -55,37 +53,21 @@ namespace Foam
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class HashFunc Declaration Class Hash Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class T> template<class T, class SFINAEType=bool>
struct HashFun struct HashFun
{
void info() const
{ {
#ifdef FULLDEBUG #ifdef FULLDEBUG
if constexpr (std::is_base_of_v<std::string, T>) static constexpr const char* name() noexcept { return "default"; }
{
std::cerr<< "std::string hashing\n";
}
else
{
std::cerr<< "default hashing\n";
}
#endif #endif
} HashTypeInfo("plain hash")
unsigned operator()(const T& obj, unsigned seed=0) const unsigned operator()(const T& obj, unsigned seed=0) const
{
if constexpr (std::is_base_of_v<std::string, T>)
{
return Foam::Hasher(obj.data(), obj.size(), seed);
}
else
{ {
return Foam::Hasher(&obj, sizeof(obj), seed); return Foam::Hasher(&obj, sizeof(obj), seed);
} }
}
}; };
@ -94,17 +76,45 @@ struct HashFun
//- Hashing for label //- Hashing for label
template<> struct HashFun<Foam::label> : Hash<label> template<> struct HashFun<Foam::label> : Hash<label>
{ {
HashTypeInfo("label") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "label"; }
#endif
HashTypeInfo("hash label")
}; };
//- Hashing for pointers, interpret pointer as a integer type //- Hashing for pointers, interpret pointer as a integer type
template<> struct HashFun<void*> : Hash<void *> template<> struct HashFun<void*> : Hash<void *>
{ {
HashTypeInfo("pointer") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "pointer"; }
#endif
HashTypeInfo("hash ptr")
}; };
//- Hashing for string types
template<class StringType>
struct HashFun
<
StringType,
typename std::enable_if
<
std::is_base_of<std::string, StringType>::value, bool
>::type
>
{
#ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "string"; }
#endif
HashTypeInfo("hash string")
unsigned operator()(const std::string& obj, unsigned seed=0) const
{
return Foam::Hasher(obj.data(), obj.size(), seed);
}
};
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -123,56 +133,83 @@ namespace Foam
template<> struct HashFun<edge> : Hash<edge> template<> struct HashFun<edge> : Hash<edge>
{ {
HashTypeInfo("edge") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "edge"; }
#endif
HashTypeInfo("hash edge")
}; };
template<> struct HashFun<face> : Hash<face> template<> struct HashFun<face> : Hash<face>
{ {
HashTypeInfo("face") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "face"; }
#endif
HashTypeInfo("hash face")
}; };
template<> struct HashFun<triFace> : Hash<triFace> template<> struct HashFun<triFace> : Hash<triFace>
{ {
HashTypeInfo("triFace") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "triFace"; }
#endif
HashTypeInfo("hash triFace")
}; };
template<class T> template<class T>
struct HashFun<Pair<T>> : Hash<Pair<T>> struct HashFun<Pair<T>> : Hash<Pair<T>>
{ {
HashTypeInfo("Pair") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "Pair"; }
#endif
HashTypeInfo("hash Pair")
}; };
template<class T1, class T2> template<class T1, class T2>
struct HashFun<Tuple2<T1, T2>> : Hash<Tuple2<T1, T2>> struct HashFun<Tuple2<T1, T2>> : Hash<Tuple2<T1, T2>>
{ {
HashTypeInfo("Tuple2") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "Tuple2"; }
#endif
HashTypeInfo("hash Tuple2")
}; };
template<class T> template<class T>
struct HashFun<List<T>> : Hash<List<T>> struct HashFun<List<T>> : Hash<List<T>>
{ {
HashTypeInfo("List") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "List"; }
#endif
HashTypeInfo("hash List")
}; };
template<class T> struct HashFun<UList<T>> : Hash<UList<T>> template<class T> struct HashFun<UList<T>> : Hash<UList<T>>
{ {
HashTypeInfo("UList") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "UList"; }
#endif
HashTypeInfo("hash UList")
}; };
template<class T, int SizeMin> template<class T, int SizeMin>
struct HashFun<DynamicList<T, SizeMin>> : Hash<DynamicList<T, SizeMin>> struct HashFun<DynamicList<T, SizeMin>> : Hash<DynamicList<T, SizeMin>>
{ {
HashTypeInfo("DynamicList") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "DynamicList"; }
#endif
HashTypeInfo("hash DynamicList")
}; };
template<class T, unsigned N> template<class T, unsigned N>
struct HashFun<FixedList<T, N>> : Hash<FixedList<T, N>> struct HashFun<FixedList<T, N>> : Hash<FixedList<T, N>>
{ {
HashTypeInfo("FixedList") #ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "FixedList"; }
#endif
HashTypeInfo("hash FixedList")
}; };

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2025 OpenCFD Ltd. Copyright (C) 2018-2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -81,7 +81,7 @@ void infoHashString
void reportHashList(const UList<string>& list) void reportHashList(const UList<string>& list)
{ {
Info<< "contiguous = " << is_contiguous_v<string> << nl << nl; Info<< "contiguous = " << is_contiguous<string>::value << nl << nl;
for (const string& val : list) for (const string& val : list)
{ {
@ -94,7 +94,7 @@ void reportHashList(const UList<string>& list)
void reportHashList(const UList<label>& list) void reportHashList(const UList<label>& list)
{ {
Info<<"contiguous = " << is_contiguous_v<label> << nl << nl; Info<<"contiguous = " << is_contiguous<label>::value << nl << nl;
for (const label val : list) for (const label val : list)
{ {
@ -113,7 +113,7 @@ void reportHashList(const UList<label>& list)
void reportHashList(const UList<face>& list) void reportHashList(const UList<face>& list)
{ {
Info<<"contiguous = " << is_contiguous_v<label> << nl << nl; Info<<"contiguous = " << is_contiguous<label>::value << nl << nl;
for (const face& f : list) for (const face& f : list)
{ {
@ -154,7 +154,7 @@ void reportHashList(const UList<labelList>& list)
void reportHashList(const UList<wordPair>& list) void reportHashList(const UList<wordPair>& list)
{ {
Info<<"contiguous = " << is_contiguous_v<wordPair> << nl << nl; Info<<"contiguous = " << is_contiguous<wordPair>::value << nl << nl;
for (const wordPair& pr : list) for (const wordPair& pr : list)
{ {
@ -179,7 +179,7 @@ void reportHashList(const UList<wordPair>& list)
void reportHashList(const UList<labelPair>& list) void reportHashList(const UList<labelPair>& list)
{ {
Info<<"contiguous = " << is_contiguous_v<labelPair> << nl << nl; Info<<"contiguous = " << is_contiguous<labelPair>::value << nl << nl;
for (const labelPair& pr : list) for (const labelPair& pr : list)
{ {
@ -200,7 +200,7 @@ void reportHashList(const UList<labelPair>& list)
void reportHashList(const UList<labelPairPair>& list) void reportHashList(const UList<labelPairPair>& list)
{ {
Info<<"contiguous = " << is_contiguous_v<labelPairPair> << nl << nl; Info<<"contiguous = " << is_contiguous<labelPairPair>::value << nl << nl;
for (const labelPairPair& pr : list) for (const labelPairPair& pr : list)
{ {
@ -221,7 +221,7 @@ void reportHashList(const UList<labelPairPair>& list)
void reportHashList(const UList<edge>& list) void reportHashList(const UList<edge>& list)
{ {
Info<<"contiguous = " << is_contiguous_v<edge> << nl << nl; Info<<"contiguous = " << is_contiguous<edge>::value << nl << nl;
for (const edge& e : list) for (const edge& e : list)
{ {
@ -242,7 +242,7 @@ void reportHashList(const UList<edge>& list)
void reportHashList(const UList<triFace>& list) void reportHashList(const UList<triFace>& list)
{ {
Info<<"contiguous = " << is_contiguous_v<triFace> << nl << nl; Info<<"contiguous = " << is_contiguous<triFace>::value << nl << nl;
for (const triFace& f : list) for (const triFace& f : list)
{ {
@ -274,7 +274,9 @@ int main(int argc, char *argv[])
Info<< nl << "No " << is.name() << " file found ..." << nl; Info<< nl << "No " << is.name() << " file found ..." << nl;
} }
for (token tok; tok.read(is); /*nil*/) token tok;
while (is.good() && is.read(tok) && tok.good())
{ {
const word listType(tok.wordToken()); const word listType(tok.wordToken());

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -83,10 +83,12 @@ Ostream& printView(Ostream& os, const char* first, const char* last)
} }
#if __cplusplus >= 201703L
Ostream& printView(Ostream& os, std::string_view s) Ostream& printView(Ostream& os, std::string_view s)
{ {
return printView(os, s.begin(), s.end()); return printView(os, s.begin(), s.end());
} }
#endif
Ostream& printView(Ostream& os, stdFoam::span<char> s) Ostream& printView(Ostream& os, stdFoam::span<char> s)
@ -136,10 +138,17 @@ void printInfo(const List<char>& buf)
void printTokens(Istream& is) void printTokens(Istream& is)
{ {
label count = 0; label count = 0;
for (token tok; tok.read(is); ++count) token t;
while (is.good())
{ {
Info<< "token: " << tok << nl; is >> t;
if (t.good())
{
++count;
Info<<"token: " << t << endl;
} }
}
Info<< count << " tokens" << endl; Info<< count << " tokens" << endl;
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -213,10 +213,11 @@ int main(int argc, char *argv[])
mesh mesh
); );
Info<< "points path: " << io.typeFilePath<pointIOField>() << nl; Info<< "points path: " << io.typeFilePath<labelIOList>() << nl;
Info<< "points path: " << io.typeFilePath<void>() << nl;
io.resetHeader("bad-points"); io.resetHeader("bad-points");
Info<< "bad path: " << io.typeFilePath<labelIOList>() << nl; Info<< "bad path: " << io.typeFilePath<void>() << nl;
} }
IOobject io IOobject io
@ -269,7 +270,7 @@ int main(int argc, char *argv[])
ioOutput.rename(args.executable() + "-labels"); ioOutput.rename(args.executable() + "-labels");
Info<< "write " << ioOutput.objectRelPath() << endl; Info<< "write " << ioOutput.objectRelPath() << endl;
{ {
IOList<label>::writeContents(ioOutput, ints); IOListRef<label>(ioOutput, ints).write();
} }
ioOutput.rename(args.executable() + "-points"); ioOutput.rename(args.executable() + "-points");

View File

@ -45,7 +45,7 @@ using namespace Foam;
template<class Type> template<class Type>
word report() word report()
{ {
if constexpr (is_globalIOobject<Type>::value) if (is_globalIOobject<Type>::value)
{ {
return "global"; return "global";
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -73,13 +73,18 @@ Ostream& toString(Ostream& os, const List<char>& list)
void printTokens(Istream& is) void printTokens(Istream& is)
{ {
Info<< "stream tokens:" << endl;
label count = 0; label count = 0;
for (token tok; tok.read(is); ++count) token t;
while (is.good())
{ {
Info<< " : " << tok << nl; is >> t;
if (t.good())
{
++count;
Info<< "token: " << t << endl;
} }
}
Info<< count << " tokens" << endl; Info<< count << " tokens" << endl;
} }
@ -450,12 +455,6 @@ int main(int argc, char *argv[])
"( const char input \"string\" to tokenize )\n" "( const char input \"string\" to tokenize )\n"
"List<label> 5(0 1 2 3 4);"; "List<label> 5(0 1 2 3 4);";
// printTokens
{
ISpanStream is(charInput);
printTokens(is);
}
string stringInput("( string ; input \"string\" to tokenize )"); string stringInput("( string ; input \"string\" to tokenize )");
List<char> listInput List<char> listInput

View File

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

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -51,10 +51,10 @@ See also
#include "IndirectList.H" #include "IndirectList.H"
#include "SubList.H" #include "SubList.H"
#include "SliceList.H" #include "SliceList.H"
#include "SubField.H"
#include "ListPolicy.H" #include "ListPolicy.H"
#include <list> #include <list>
#include <numeric>
#include <functional> #include <functional>
// see issue #2083 // see issue #2083
@ -75,6 +75,8 @@ public:
namespace Detail
{
namespace ListPolicy namespace ListPolicy
{ {
@ -82,6 +84,7 @@ namespace ListPolicy
template<> struct short_length<short> : std::integral_constant<int,20> {}; template<> struct short_length<short> : std::integral_constant<int,20> {};
} // End namespace ListPolicy } // End namespace ListPolicy
} // End namespace Detail
} // End namespace Foam } // End namespace Foam
@ -115,10 +118,10 @@ Ostream& printListOutputType(const char* what)
{ {
Info<< what Info<< what
<< " (contiguous=" << " (contiguous="
<< is_contiguous_v<T> << " no_linebreak=" << is_contiguous<T>::value << " no_linebreak="
<< ListPolicy::no_linebreak<T>::value << Detail::ListPolicy::no_linebreak<T>::value
<< " short_length=" << " short_length="
<< ListPolicy::short_length<T>::value << ')'; << Detail::ListPolicy::short_length<T>::value << ')';
return Info; return Info;
} }
@ -140,46 +143,8 @@ int main(int argc, char *argv[])
argList::addBoolOption("ListList", "Test list of list functionality"); argList::addBoolOption("ListList", "Test list of list functionality");
argList::addBoolOption("flag"); argList::addBoolOption("flag");
argList::addBoolOption("reserve", "Test ListPolicy for reserve_size");
#include "setRootCase.H" #include "setRootCase.H"
if (args.found("reserve"))
{
using namespace Foam::ListPolicy;
using control = std::pair<label, label>;
for
(
const auto& tup :
{
control{ 10, 5 },
control{ 20, 25 }
}
)
{
const auto [len, capacity] = tup;
Info<< "test " << tup << nl;
auto size = reserve_size<16,2>(len, capacity);
Info<< " => " << size << " (ratio 2)" << nl;
size = reserve_size<16,3,2>(len, capacity);
Info<< " => " << size << " (ratio 3/2)" << nl;
size = reserve_size<16,13,8>(len, capacity);
Info<< " => " << size << " (ratio " << (13.0/8) << ')' << nl;
size = reserve_size<16,25,16>(len, capacity);
Info<< " => " << size << " (ratio " << (25.0/16) << ')' << nl;
}
Info<< nl << "\nEnd" << endl;
return 0;
}
{ {
List<label> ident(15); List<label> ident(15);
Foam::identity(ident, 0); Foam::identity(ident, 0);
@ -204,6 +169,16 @@ int main(int argc, char *argv[])
Info<<" " << *iter; Info<<" " << *iter;
} }
Info<< nl; Info<< nl;
Info<< "data:" << Foam::name(ident.cdata())
<< " size:" << ident.size() << nl;
Info<< "resize_unsafe(10)" << nl;
ident.resize_unsafe(10);
Info<< "data:" << Foam::name(ident.cdata())
<< " size:" << ident.size() << nl;
} }
if (false) if (false)
@ -272,33 +247,6 @@ int main(int argc, char *argv[])
}; };
Info<< "list4: " << list4 << endl; Info<< "list4: " << list4 << endl;
{
List<scalar> list4Mag = ListOps::create<scalar>
(
list4,
[](const auto& a){ return a.mag(); }
);
const auto equalMag = [](const auto& a, const auto& b)
{
return (Foam::mag(a) == Foam::mag(b));
};
Info<< "list4 (mag): " << list4Mag << endl;
bool same = ListOps::equal(list4, list4Mag, equalMag);
Info<< "mag(list4) == list4(mag): " << same << nl;
SubField<scalar>(list4Mag) *= -1;
same = ListOps::equal(list4, list4Mag, equalMag);
Info<< "mag(list4) == list4(mag): " << same << nl;
SubField<scalar>(list4Mag) *= 1.1;
same = ListOps::equal(list4, list4Mag, equalMag);
Info<< "mag(list4) == list4(mag): " << same << nl;
}
List<vector> list5 List<vector> list5
{ {
{5, 3, 1}, {5, 3, 1},

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -35,7 +35,6 @@ Description
#include "FixedList.H" #include "FixedList.H"
#include "labelList.H" #include "labelList.H"
#include "vectorList.H" #include "vectorList.H"
#include "SubList.H"
#include "ListOps.H" #include "ListOps.H"
#include "IFstream.H" #include "IFstream.H"
#include "OFstream.H" #include "OFstream.H"
@ -201,7 +200,6 @@ int main(int argc, char *argv[])
argList::addBoolOption("order"); argList::addBoolOption("order");
argList::addBoolOption("labelList"); argList::addBoolOption("labelList");
argList::addBoolOption("vectorList"); argList::addBoolOption("vectorList");
argList::addBoolOption("ulist");
argList args(argc, argv); argList args(argc, argv);
@ -263,37 +261,6 @@ int main(int argc, char *argv[])
} }
if (args.found("ulist"))
{
using span_type = stdFoam::span<vector>;
using ulist_type = UList<vector>;
ulist_type view1, view2;
span_type span1, span2;
List<vector> list(10, vector::one);
Info<< "List: " << Foam::name(list.data()) << nl;
Info<< "view: " << Foam::name(view1.data()) << nl;
Info<< "span: " << Foam::name(span1.data()) << nl;
view1 = list.slice(4);
span1 = span_type(list.begin(4), list.size()-4);
Info<< "view [4]:" << Foam::name(view1.data()) << nl;
Info<< "span [4]:" << Foam::name(span1.data()) << nl;
view2 = std::move(view1);
span2 = std::move(span1);
Info<< "view old:" << Foam::name(view1.data()) << nl;
Info<< "span old:" << Foam::name(span1.data()) << nl;
Info<< "view [4]:" << Foam::name(view2.data()) << nl;
Info<< "span [4]:" << Foam::name(span2.data()) << nl;
view1 = list.slice(7);
Info<< "view [7]:" << Foam::name(view1.data()) << nl;
}
Info<< nl << "Done" << nl << endl; Info<< nl << "Done" << nl << endl;
return 0; return 0;
} }

View File

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

View File

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

View File

@ -50,6 +50,7 @@ Description
#include "ListPolicy.H" #include "ListPolicy.H"
#include <list> #include <list>
#include <numeric>
#include <functional> #include <functional>
using namespace Foam; using namespace Foam;
@ -85,7 +86,7 @@ bool readBracketList(List<T>& list, Istream& is)
// constexpr label chunkSize = 128; // constexpr label chunkSize = 128;
typedef std::unique_ptr<List<T>> chunkType; typedef std::unique_ptr<List<T>> chunkType;
tok.read(is); is >> tok;
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
if (tok.isPunctuation(token::END_LIST)) if (tok.isPunctuation(token::END_LIST))
@ -149,7 +150,7 @@ bool readBracketList(List<T>& list, Istream& is)
"reading entry" "reading entry"
); );
tok.read(is); is >> tok;
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021-2025 OpenCFD Ltd. Copyright (C) 2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -128,17 +128,18 @@ void test_member_funcs(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names) inline typename std::enable_if<I == sizeof...(Tp), void>::type
{ run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names); run_tests<I + 1, Tp...>(types, typeID);
}
} }

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -83,10 +83,12 @@ Ostream& printView(Ostream& os, const char* first, const char* last)
} }
#if __cplusplus >= 201703L
Ostream& printView(Ostream& os, std::string_view s) Ostream& printView(Ostream& os, std::string_view s)
{ {
return printView(os, s.begin(), s.end()); return printView(os, s.begin(), s.end());
} }
#endif
Ostream& printView(Ostream& os, stdFoam::span<char> s) Ostream& printView(Ostream& os, stdFoam::span<char> s)
@ -127,10 +129,17 @@ void printInfo(const BufType& buf)
void printTokens(Istream& is) void printTokens(Istream& is)
{ {
label count = 0; label count = 0;
for (token tok; tok.read(is); ++count) token t;
while (is.good())
{ {
Info<< "token: " << tok << nl; is >> t;
if (t.good())
{
++count;
Info<<"token: " << t << endl;
} }
}
Info<< count << " tokens" << endl; Info<< count << " tokens" << endl;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -85,10 +85,12 @@ Ostream& printView(Ostream& os, const char* first, const char* last)
} }
#if __cplusplus >= 201703L
Ostream& printView(Ostream& os, std::string_view s) Ostream& printView(Ostream& os, std::string_view s)
{ {
return printView(os, s.begin(), s.end()); return printView(os, s.begin(), s.end());
} }
#endif
Ostream& printView(Ostream& os, stdFoam::span<char> s) Ostream& printView(Ostream& os, stdFoam::span<char> s)
@ -143,10 +145,17 @@ void printInfo(const UList<char>& buf)
void printTokens(Istream& is) void printTokens(Istream& is)
{ {
label count = 0; label count = 0;
for (token tok; tok.read(is); ++count) token t;
while (is.good())
{ {
Info<< "token: " << tok << nl; is >> t;
if (t.good())
{
++count;
Info<<"token: " << t << endl;
} }
}
Info<< count << " tokens" << endl; Info<< count << " tokens" << endl;
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd. Copyright (C) 2020-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,11 +38,12 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "Tensor.H" #include "Tensor.H"
#include "SymmTensor.H" #include "SymmTensor.H"
#include "SphericalTensor.H" #include "SphericalTensor.H"
#include "DiagTensor.H" #include "DiagTensor.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -56,50 +57,65 @@ unsigned nTest_ = 0;
unsigned nFail_ = 0; unsigned nFail_ = 0;
// Compare two containers elementwise, and print output. // Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance. // Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485. // The function is converted from PEP-485.
template<class Type, class Type2 = Type> template<class Type>
void cmp typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
const Type2& y, const Type& y,
const scalar relTol = 1e-8, //<! are values the same within 8 decimals const scalar relTol = 1e-8, //<! are values the same within 8 decimals
const scalar absTol = 0 //<! useful for cmps near zero const scalar absTol = 0 //<! useful for cmps near zero
) )
{ {
const auto notEqual = [=](const auto& a, const auto& b) -> bool Info<< msg << x << endl;
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if constexpr (is_vectorspace_v<Type>) if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{ {
++nFail; ++nFail;
} }
}
}
else
{
if (notEqual(x, y))
{
++nFail;
}
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar relTol = 1e-8,
const scalar absTol = 0
)
{
Info<< msg << x << endl; Info<< msg << x << endl;
unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{
++nFail;
}
}
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -261,26 +277,27 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names) inline typename std::enable_if<I == sizeof...(Tp), void>::type
{ run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl; Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name << " ##" << nl; Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl; Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
test_global_opers(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names); run_tests<I + 1, Tp...>(types, typeID);
}
} }
@ -295,8 +312,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SphericalTensor<float>", "SphericalTensor<floatScalar>",
"SphericalTensor<double>", "SphericalTensor<doubleScalar>",
"SphericalTensor<complex>" "SphericalTensor<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd. Copyright (C) 2020-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,10 +38,11 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "Tensor2D.H" #include "Tensor2D.H"
#include "SymmTensor2D.H" #include "SymmTensor2D.H"
#include "SphericalTensor2D.H" #include "SphericalTensor2D.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -55,11 +56,12 @@ unsigned nTest_ = 0;
unsigned nFail_ = 0; unsigned nFail_ = 0;
// Compare two containers elementwise, and print output. // Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance. // Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485. // The function is converted from PEP-485.
template<class Type> template<class Type>
void cmp typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -68,37 +70,51 @@ void cmp
const scalar absTol = 0 //<! useful for cmps near zero const scalar absTol = 0 //<! useful for cmps near zero
) )
{ {
const auto notEqual = [=](const auto& a, const auto& b) -> bool Info<< msg << x << endl;
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if constexpr (is_vectorspace_v<Type>) if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{ {
++nFail; ++nFail;
} }
}
}
else
{
if (notEqual(x, y))
{
++nFail;
}
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar relTol = 1e-8,
const scalar absTol = 0
)
{
Info<< msg << x << endl; Info<< msg << x << endl;
unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{
++nFail;
}
}
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -244,26 +260,27 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names) inline typename std::enable_if<I == sizeof...(Tp), void>::type
{ run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl; Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name << " ##" << nl; Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl; Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
test_global_opers(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names); run_tests<I + 1, Tp...>(types, typeID);
}
} }
@ -278,8 +295,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SphericalTensor2D<float>", "SphericalTensor2D<floatScalar>",
"SphericalTensor2D<double>", "SphericalTensor2D<doubleScalar>",
"SphericalTensor2D<complex>" "SphericalTensor2D<complex>"
}); });

View File

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

View File

@ -38,6 +38,7 @@ Description
#include "SubField.H" #include "SubField.H"
#include "labelRange.H" #include "labelRange.H"
#include "ListOps.H" #include "ListOps.H"
#include <numeric>
using namespace Foam; using namespace Foam;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd. Copyright (C) 2020-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -40,10 +40,11 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "symmTensor.H" #include "symmTensor.H"
#include "transform.H" #include "transform.H"
#include "Random.H" #include "Random.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -68,12 +69,12 @@ symmTensor makeRandomContainer(Random& rnd)
// Create a symmTensor based on a given value // Create a symmTensor based on a given value
template<class Type> template<class Type>
std::enable_if_t typename std::enable_if
< <
std::is_floating_point_v<Type> || std::is_same_v<complex, Type>, std::is_same<floatScalar, Type>::value ||
std::is_same<doubleScalar, Type>::value,
symmTensor symmTensor
> >::type makeContainer(const Type val)
makeContainer(const Type val)
{ {
symmTensor T(Zero); symmTensor T(Zero);
std::fill(T.begin(), T.end(), val); std::fill(T.begin(), T.end(), val);
@ -81,11 +82,12 @@ makeContainer(const Type val)
} }
// Compare two containers elementwise, and print output. // Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance. // Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485. // The function is converted from PEP-485.
template<class Type> template<class Type>
void cmp typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -94,37 +96,51 @@ void cmp
const scalar relTol = 1e-8 //<! are values the same within 8 decimals const scalar relTol = 1e-8 //<! are values the same within 8 decimals
) )
{ {
const auto notEqual = [=](const auto& a, const auto& b) -> bool Info<< msg << x << "?=" << y << endl;
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if constexpr (is_vectorspace_v<Type>) if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{ {
++nFail; ++nFail;
} }
}
}
else
{
if (notEqual(x, y))
{
++nFail;
}
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar absTol = 0,
const scalar relTol = 1e-8
)
{
Info<< msg << x << "?=" << y << endl; Info<< msg << x << "?=" << y << endl;
unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{
++nFail;
}
}
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -572,26 +588,27 @@ void test_eigen_funcs(const symmTensor& T)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names) inline typename std::enable_if<I == sizeof...(Tp), void>::type
{ run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl; Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name << " ##" << nl; Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl; Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
test_global_opers(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names); run_tests<I + 1, Tp...>(types, typeID);
}
} }
@ -606,8 +623,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SymmTensor<float>", "SymmTensor<floatScalar>",
"SymmTensor<double>", "SymmTensor<doubleScalar>",
"SymmTensor<complex>" "SymmTensor<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2025 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -40,10 +40,11 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "symmTensor2D.H" #include "symmTensor2D.H"
#include "transform.H" #include "transform.H"
#include "Random.H" #include "Random.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -66,11 +67,45 @@ symmTensor2D makeRandomContainer(Random& rnd)
} }
// Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485.
template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar absTol = 0, //<! useful for cmps near zero
const scalar relTol = 1e-8 //<! are values the same within 8 decimals
)
{
Info<< msg << x << "?=" << y << endl;
unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
++nFail;
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance. // Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485 // The function is converted from PEP-485
template<class Type> template<class Type>
void cmp typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -79,36 +114,17 @@ void cmp
const scalar relTol = 1e-8 const scalar relTol = 1e-8
) )
{ {
const auto notEqual = [=](const auto& a, const auto& b) -> bool Info<< msg << x << "?=" << y << endl;
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if constexpr (is_vectorspace_v<Type>)
{
for (direction i = 0; i < pTraits<Type>::nComponents; ++i) for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{ {
if (notEqual(x[i], y[i])) if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{ {
++nFail; ++nFail;
} }
} }
}
else
{
if (notEqual(x, y))
{
++nFail;
}
}
Info<< msg << x << "?=" << y << endl;
if (nFail) if (nFail)
{ {
@ -522,26 +538,27 @@ void test_eigen_funcs(const symmTensor2D& T)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names) inline typename std::enable_if<I == sizeof...(Tp), void>::type
{ run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl; Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name << " ##" << nl; Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl; Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
test_global_opers(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names); run_tests<I + 1, Tp...>(types, typeID);
}
} }
@ -556,8 +573,8 @@ int main(int argc, char *argv[])
const List<word> typeID const List<word> typeID
({ ({
"SymmTensor2D<float>", "SymmTensor2D<floatScalar>",
"SymmTensor2D<double>", "SymmTensor2D<doubleScalar>",
"SymmTensor2D<complex>" "SymmTensor2D<complex>"
}); });

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018 OpenFOAM Foundation Copyright (C) 2018 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd. Copyright (C) 2019-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -41,10 +41,11 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "tensor.H" #include "tensor.H"
#include "transform.H" #include "transform.H"
#include "Random.H" #include "Random.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -67,11 +68,45 @@ tensor makeRandomContainer(Random& rnd)
} }
// Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485.
template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar absTol = 0, //<! useful for cmps near zero
const scalar relTol = 1e-8 //<! are values the same within 8 decimals
)
{
Info<< msg << x << "?=" << y << endl;
unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
++nFail;
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance. // Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485 // The function is converted from PEP-485
template<class Type> template<class Type>
void cmp typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -80,36 +115,17 @@ void cmp
const scalar relTol = 1e-8 const scalar relTol = 1e-8
) )
{ {
const auto notEqual = [=](const auto& a, const auto& b) -> bool Info<< msg << x << "?=" << y << endl;
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if constexpr (is_vectorspace_v<Type>)
{
for (direction i = 0; i < pTraits<Type>::nComponents; ++i) for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{ {
if (notEqual(x[i], y[i])) if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{ {
++nFail; ++nFail;
} }
} }
}
else
{
if (notEqual(x, y))
{
++nFail;
}
}
Info<< msg << x << "?=" << y << endl;
if (nFail) if (nFail)
{ {
@ -971,26 +987,27 @@ void test_eigen_funcs(const tensor& T, const bool prod = true)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names) inline typename std::enable_if<I == sizeof...(Tp), void>::type
{ run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
if constexpr (I < sizeof...(Tp))
{
const auto& name = names;
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl; Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name <<" ##" << nl; Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name <<" ##" << nl; Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
test_global_opers(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names); run_tests<I + 1, Tp...>(types, typeID);
}
} }
@ -1005,8 +1022,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"Tensor<float>", "Tensor<floatScalar>",
"Tensor<double>", "Tensor<doubleScalar>",
"Tensor<complex>" "Tensor<complex>"
}); });

Some files were not shown because too many files have changed in this diff Show More