Compare commits
113 Commits
feature-su
...
issue-3348
| Author | SHA1 | Date | |
|---|---|---|---|
| bd41a2abdb | |||
| a2df607998 | |||
| e121db6e86 | |||
| e720f823d3 | |||
| bdac68ebc7 | |||
| edf9621ebe | |||
| a9863d9a3f | |||
| bdb890d4e2 | |||
| 707db0b65b | |||
| 8716795d86 | |||
| 8bbfe6eb44 | |||
| aaa9af9ee8 | |||
| 4de0b84c2f | |||
| db871856c0 | |||
| a01f3ed8b7 | |||
| c4b261c615 | |||
| 7b0ab0dbb3 | |||
| b9b0d1b3aa | |||
| 034a0524af | |||
| eaa65913f4 | |||
| 6dd8804acb | |||
| a77aaa7582 | |||
| 5cc36dc5b7 | |||
| d4a959a93f | |||
| 09e04003c4 | |||
| dcbd546d51 | |||
| d64c6371f1 | |||
| 2d246cd5d1 | |||
| 51bb06764a | |||
| 795bce4519 | |||
| db0709f957 | |||
| 38e08fc092 | |||
| 36ae93d017 | |||
| ab7cfdcf49 | |||
| f13be4f62c | |||
| ae638c2b9c | |||
| 9cd0aa8816 | |||
| 939ca03495 | |||
| 28818c73f9 | |||
| 20b2f46315 | |||
| 5d9f8e9a9d | |||
| 3bf1399098 | |||
| 20b6aeb4dd | |||
| c7fc9d4ddc | |||
| f0b844eb47 | |||
| 151f4df546 | |||
| 7ac83f22c7 | |||
| 8c395357f3 | |||
| d4b5280742 | |||
| be30598e3d | |||
| d64682a7af | |||
| cf9fa16788 | |||
| 9437e8d068 | |||
| dd09aa1289 | |||
| 56c52fd69e | |||
| 34c933c1ce | |||
| f276016896 | |||
| e3703c7626 | |||
| dccdb263e8 | |||
| bf60a124ab | |||
| c448ea2a11 | |||
| d41c644a49 | |||
| d2dfd115be | |||
| 8f3d29c1b7 | |||
| e67fffac3f | |||
| 2783e78ae2 | |||
| e041af9481 | |||
| e8e90a8de3 | |||
| 0aecb25024 | |||
| 14b2302b38 | |||
| d655c2d343 | |||
| 533d3b58f8 | |||
| 0c282bda65 | |||
| 4720b61313 | |||
| a66be057c2 | |||
| eae448c7aa | |||
| 81fa7d08ee | |||
| 0ce5053c75 | |||
| eb4345ed44 | |||
| 15ac0bc30b | |||
| 21f36b18e5 | |||
| 3852f7c5b7 | |||
| a3e1376117 | |||
| 512ec01328 | |||
| 3e8b0a2c73 | |||
| 831a55f1ba | |||
| 579f8ef7c6 | |||
| 0ba4f36c60 | |||
| 0adc745b50 | |||
| 3b40dd8c29 | |||
| 6f2fadb48f | |||
| 559ed6c464 | |||
| 0cb812f6ac | |||
| 4ae8ce3f0c | |||
| 9f0d1c7121 | |||
| e1d40646cc | |||
| 9013c9941d | |||
| 0cc5273d0a | |||
| 8f83ed786c | |||
| cf2b305b4f | |||
| b9f05bdc01 | |||
| 0b831572f3 | |||
| 6dc57a1a8b | |||
| a18c15a4cf | |||
| 39e1eb9dc6 | |||
| c77b0e14a1 | |||
| 77cdf22eac | |||
| 2e1552dd30 | |||
| d072ad0e3f | |||
| 0a99702f9e | |||
| b86ba60d35 | |||
| 392aa56f23 | |||
| 6520d8e061 |
@ -1,2 +1,2 @@
|
||||
api=2412
|
||||
api=2501
|
||||
patch=0
|
||||
|
||||
@ -36,11 +36,12 @@ Description
|
||||
if (adjustTimeStep)
|
||||
{
|
||||
scalar maxDeltaTFact = maxCo/(CoNum + StCoNum + SMALL);
|
||||
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
scalar deltaTFact =
|
||||
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
deltaTFact*runTime.deltaTValue(),
|
||||
maxDeltaT
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
if (adjustTimeStep)
|
||||
{
|
||||
runTime.setDeltaT(min(dtChem, maxDeltaT));
|
||||
runTime.setDeltaT(Foam::min(dtChem, maxDeltaT));
|
||||
Info<< "deltaT = " << runTime.deltaTValue() << endl;
|
||||
}
|
||||
|
||||
@ -54,9 +54,18 @@ if (adjustTimeStep)
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
dt0*min(min(TFactorFluid, min(TFactorFilm, TFactorSolid)), 1.2),
|
||||
dt0
|
||||
* Foam::min
|
||||
(
|
||||
Foam::min
|
||||
(
|
||||
TFactorFluid,
|
||||
Foam::min(TFactorFilm, TFactorSolid)
|
||||
),
|
||||
1.2
|
||||
),
|
||||
maxDeltaT
|
||||
)
|
||||
);
|
||||
|
||||
@ -75,8 +75,10 @@
|
||||
)
|
||||
{
|
||||
rDeltaT =
|
||||
(
|
||||
rDeltaT0
|
||||
*max(rDeltaT/rDeltaT0, scalar(1) - rDeltaTDampingCoeff);
|
||||
* Foam::max(rDeltaT/rDeltaT0, scalar(1) - rDeltaTDampingCoeff)
|
||||
);
|
||||
|
||||
Info<< "Damped flow time scale min/max = "
|
||||
<< gMin(1/rDeltaT.primitiveField())
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
scalar CoNum = -GREAT;
|
||||
forAll(fluidRegions, regionI)
|
||||
{
|
||||
CoNum = max
|
||||
CoNum = Foam::max
|
||||
(
|
||||
compressibleCourantNo
|
||||
(
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
);
|
||||
|
||||
|
||||
CoNum =
|
||||
scalar maxPhiCoNum =
|
||||
0.5*gMax
|
||||
(
|
||||
sumPhi/fluidRegions[regioni].V().field()
|
||||
@ -41,9 +41,9 @@
|
||||
(
|
||||
fvc::surfaceSum(mag(phi1 - phi2))().primitiveField()
|
||||
/ fluidRegions[regioni].V().field()
|
||||
)*runTime.deltaTValue(),
|
||||
)*runTime.deltaTValue();
|
||||
|
||||
CoNum = max(UrCoNum, CoNum);
|
||||
CoNum = Foam::max(CoNum, Foam::max(maxPhiCoNum, UrCoNum));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
forAll(fluidRegions, regioni)
|
||||
{
|
||||
CoNum = max
|
||||
CoNum = Foam::max
|
||||
(
|
||||
compressibleCourantNo
|
||||
(
|
||||
@ -17,7 +17,7 @@
|
||||
/*
|
||||
forAll(porousFluidRegions, porousi)
|
||||
{
|
||||
CoNum = max
|
||||
CoNum = Foam::max
|
||||
(
|
||||
compressibleCourantNo
|
||||
(
|
||||
|
||||
@ -47,10 +47,10 @@ if (adjustTimeStep)
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
min(maxCo/CoNum, maxDi/DiNum)*runTime.deltaTValue(),
|
||||
min(runTime.deltaTValue(), maxDeltaT)
|
||||
Foam::min(maxCo/CoNum, maxDi/DiNum)*runTime.deltaTValue(),
|
||||
Foam::min(runTime.deltaTValue(), maxDeltaT)
|
||||
)
|
||||
);
|
||||
Info<< "deltaT = " << runTime.deltaTValue() << endl;
|
||||
|
||||
@ -49,17 +49,17 @@ if (adjustTimeStep)
|
||||
scalar maxDeltaTSolid = maxDi/(DiNum + SMALL);
|
||||
|
||||
scalar deltaTFluid =
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
min(maxDeltaTFluid, 1.0 + 0.1*maxDeltaTFluid),
|
||||
Foam::min(maxDeltaTFluid, 1.0 + 0.1*maxDeltaTFluid),
|
||||
1.2
|
||||
);
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
min(deltaTFluid, maxDeltaTSolid)*runTime.deltaTValue(),
|
||||
Foam::min(deltaTFluid, maxDeltaTSolid)*runTime.deltaTValue(),
|
||||
maxDeltaT
|
||||
)
|
||||
);
|
||||
|
||||
@ -22,7 +22,7 @@ forAll(solidRegions, i)
|
||||
tmp<volScalarField> trho = thermo.rho();
|
||||
const volScalarField& rho = trho();
|
||||
|
||||
DiNum = max
|
||||
DiNum = Foam::max
|
||||
(
|
||||
solidRegionDiffNo
|
||||
(
|
||||
|
||||
@ -17,7 +17,7 @@ scalar DiNum = -GREAT;
|
||||
tmp<volScalarField> trho = thermo.rho();
|
||||
const volScalarField& rho = trho();
|
||||
|
||||
DiNum = max
|
||||
DiNum = Foam::max
|
||||
(
|
||||
solidRegionDiffNo
|
||||
(
|
||||
|
||||
@ -36,13 +36,16 @@ Description
|
||||
if (adjustTimeStep)
|
||||
{
|
||||
const scalar maxDeltaTFact =
|
||||
min(maxCo/(CoNum + SMALL), maxCo/(surfaceFilm.CourantNumber() + SMALL));
|
||||
Foam::min
|
||||
(
|
||||
maxCo/(CoNum + SMALL), maxCo/(surfaceFilm.CourantNumber() + SMALL)
|
||||
);
|
||||
const 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
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
deltaTFact*runTime.deltaTValue(),
|
||||
maxDeltaT
|
||||
|
||||
@ -36,13 +36,14 @@ Description
|
||||
if (adjustTimeStep)
|
||||
{
|
||||
scalar maxDeltaTFact =
|
||||
min(maxCo/(CoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL));
|
||||
Foam::min(maxCo/(CoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL));
|
||||
|
||||
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
scalar deltaTFact =
|
||||
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
deltaTFact*runTime.deltaTValue(),
|
||||
maxDeltaT
|
||||
|
||||
@ -36,13 +36,14 @@ Description
|
||||
if (adjustTimeStep)
|
||||
{
|
||||
scalar maxDeltaTFact =
|
||||
min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL));
|
||||
Foam::min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL));
|
||||
|
||||
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
scalar deltaTFact =
|
||||
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
deltaTFact*runTime.deltaTValue(),
|
||||
maxDeltaT
|
||||
|
||||
@ -37,11 +37,15 @@ if (adjustTimeStep)
|
||||
if (CoNum > SMALL)
|
||||
{
|
||||
scalar maxDeltaTFact =
|
||||
min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL));
|
||||
Foam::min
|
||||
(
|
||||
maxCo/(CoNum + SMALL),
|
||||
maxAcousticCo/(acousticCoNum + SMALL)
|
||||
);
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
maxDeltaTFact*runTime.deltaTValue(),
|
||||
maxDeltaT
|
||||
|
||||
@ -26,12 +26,12 @@ forAll(dgdt, celli)
|
||||
{
|
||||
if (dgdt[celli] > 0.0)
|
||||
{
|
||||
Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
|
||||
Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
|
||||
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
|
||||
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
|
||||
}
|
||||
else if (dgdt[celli] < 0.0)
|
||||
{
|
||||
Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
|
||||
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,12 +26,12 @@ forAll(dgdt, celli)
|
||||
{
|
||||
if (dgdt[celli] > 0.0)
|
||||
{
|
||||
Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
|
||||
Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
|
||||
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
|
||||
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
|
||||
}
|
||||
else if (dgdt[celli] < 0.0)
|
||||
{
|
||||
Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
|
||||
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,12 +26,12 @@ forAll(dgdt, celli)
|
||||
{
|
||||
if (dgdt[celli] > 0.0)
|
||||
{
|
||||
Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
|
||||
Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
|
||||
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
|
||||
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
|
||||
}
|
||||
else if (dgdt[celli] < 0.0)
|
||||
{
|
||||
Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
|
||||
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -679,7 +679,7 @@ void Foam::radiation::laserDTRM::calculate()
|
||||
}
|
||||
}
|
||||
|
||||
scalar totalQ = gSum(Q_.primitiveFieldRef()*mesh_.V());
|
||||
scalar totalQ = gWeightedSum(mesh_.V(), Q_.primitiveField());
|
||||
Info << "Total energy absorbed [W]: " << totalQ << endl;
|
||||
|
||||
if (mesh_.time().writeTime())
|
||||
|
||||
@ -36,13 +36,13 @@ Description
|
||||
if (adjustTimeStep)
|
||||
{
|
||||
scalar maxDeltaTFact =
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
maxCo/(CoNum + SMALL),
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
maxAlphaCo/(alphaCoNum + SMALL),
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
maxAlphaDdt/(ddtAlphaNum + SMALL),
|
||||
maxDi/(DiNum + SMALL)
|
||||
@ -50,11 +50,12 @@ if (adjustTimeStep)
|
||||
)
|
||||
);
|
||||
|
||||
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
scalar deltaTFact =
|
||||
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
Foam::min
|
||||
(
|
||||
deltaTFact*runTime.deltaTValue(),
|
||||
maxDeltaT
|
||||
|
||||
@ -8,5 +8,5 @@
|
||||
|
||||
Info<< "Max Ur Courant Number = " << UrCoNum << endl;
|
||||
|
||||
CoNum = max(CoNum, UrCoNum);
|
||||
CoNum = Foam::max(CoNum, UrCoNum);
|
||||
}
|
||||
|
||||
@ -8,5 +8,5 @@
|
||||
|
||||
Info<< "Max Ur Courant Number = " << UrCoNum << endl;
|
||||
|
||||
CoNum = max(CoNum, UrCoNum);
|
||||
CoNum = Foam::max(CoNum, UrCoNum);
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,9 +25,12 @@ License
|
||||
|
||||
Description
|
||||
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.
|
||||
|
||||
g++ -std=c++11 -oTest-machine-sizes Test-machine-sizes.cpp
|
||||
g++ -std=c++17 -oTest-machine-sizes Test-machine-sizes.cpp
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -37,6 +40,134 @@ Description
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#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>
|
||||
void print(const char* name, bool showLimits = true)
|
||||
@ -47,28 +178,84 @@ void print(const char* name, bool showLimits = true)
|
||||
if (showLimits)
|
||||
{
|
||||
std::cout
|
||||
<< " \"max\"=" << std::numeric_limits<T>::max();
|
||||
<< " 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';
|
||||
}
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::cout<< "c++ = " << __cplusplus << '\n';
|
||||
std::cout<< "machine sizes\n---\n\n";
|
||||
std::cout<< "machine sizes (and some MPI traits)\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<int>("int");
|
||||
print<unsigned>("unsigned");
|
||||
print<long>("long");
|
||||
print<unsigned long>("unsigned long");
|
||||
print<std::size_t>("std::size_t");
|
||||
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<double>("double");
|
||||
print<long double>("long double");
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -38,12 +38,11 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "Tensor.H"
|
||||
#include "SymmTensor.H"
|
||||
#include "SphericalTensor.H"
|
||||
#include "DiagTensor.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -57,45 +56,11 @@ unsigned nTest_ = 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.
|
||||
// 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
|
||||
void cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
@ -104,18 +69,37 @@ cmp
|
||||
const scalar absTol = 0
|
||||
)
|
||||
{
|
||||
Info<< msg << x << endl;
|
||||
const auto notEqual = [=](const auto& a, const auto& b) -> bool
|
||||
{
|
||||
return
|
||||
(
|
||||
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
|
||||
< Foam::mag(a - b)
|
||||
);
|
||||
};
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
if constexpr (is_vectorspace_v<Type>)
|
||||
{
|
||||
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
{
|
||||
if (notEqual(x[i], y[i]))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (notEqual(x, y))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< msg << x << endl;
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
@ -368,27 +352,26 @@ void test_global_opers(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -403,8 +386,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"DiagTensor<floatScalar>",
|
||||
"DiagTensor<doubleScalar>",
|
||||
"DiagTensor<float>",
|
||||
"DiagTensor<double>",
|
||||
"DiagTensor<complex>"
|
||||
});
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
Test-Dictionary.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-Dictionary
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -85,8 +85,7 @@ void compileInfo()
|
||||
|
||||
|
||||
template<class FixedListType>
|
||||
typename std::enable_if
|
||||
<(FixedListType::max_size() == 2), bool>::type
|
||||
std::enable_if_t<(FixedListType::max_size() == 2), bool>
|
||||
is_pair()
|
||||
{
|
||||
return true;
|
||||
@ -94,7 +93,7 @@ is_pair()
|
||||
|
||||
|
||||
template<class FixedListType>
|
||||
typename std::enable_if<(FixedListType::max_size() != 2), std::string>::type
|
||||
std::enable_if_t<(FixedListType::max_size() != 2), std::string>
|
||||
is_pair()
|
||||
{
|
||||
return "not really at all";
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-HashTable1.C
|
||||
Test-HashTable1.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-HashTable1
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -42,9 +42,11 @@ Note
|
||||
#include "Hash.H"
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
#define HashTypeInfo(Args) void info() { std::cerr<< "" Args << "\n"; }
|
||||
#define HashTypeInfo(Name) \
|
||||
static constexpr const char* name() noexcept { return Name; } \
|
||||
void info() const { std::cerr<< name() << " hashing\n"; }
|
||||
#else
|
||||
#define HashTypeInfo(Args) void info() {}
|
||||
#define HashTypeInfo(Name) void info() const {}
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -53,20 +55,36 @@ namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Hash Declaration
|
||||
Class HashFunc Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class T, class SFINAEType=bool>
|
||||
template<class T>
|
||||
struct HashFun
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "default"; }
|
||||
#endif
|
||||
HashTypeInfo("plain hash")
|
||||
void info() const
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
if constexpr (std::is_base_of_v<std::string, T>)
|
||||
{
|
||||
std::cerr<< "std::string hashing\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr<< "default hashing\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned operator()(const T& obj, unsigned seed=0) const
|
||||
{
|
||||
return Foam::Hasher(&obj, sizeof(obj), seed);
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -76,45 +94,17 @@ struct HashFun
|
||||
//- Hashing for label
|
||||
template<> struct HashFun<Foam::label> : Hash<label>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "label"; }
|
||||
#endif
|
||||
HashTypeInfo("hash label")
|
||||
HashTypeInfo("label")
|
||||
};
|
||||
|
||||
|
||||
//- Hashing for pointers, interpret pointer as a integer type
|
||||
template<> struct HashFun<void*> : Hash<void *>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "pointer"; }
|
||||
#endif
|
||||
HashTypeInfo("hash ptr")
|
||||
HashTypeInfo("pointer")
|
||||
};
|
||||
|
||||
|
||||
//- 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
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -133,83 +123,56 @@ namespace Foam
|
||||
|
||||
template<> struct HashFun<edge> : Hash<edge>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "edge"; }
|
||||
#endif
|
||||
HashTypeInfo("hash edge")
|
||||
HashTypeInfo("edge")
|
||||
};
|
||||
|
||||
|
||||
template<> struct HashFun<face> : Hash<face>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "face"; }
|
||||
#endif
|
||||
HashTypeInfo("hash face")
|
||||
HashTypeInfo("face")
|
||||
};
|
||||
|
||||
|
||||
template<> struct HashFun<triFace> : Hash<triFace>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "triFace"; }
|
||||
#endif
|
||||
HashTypeInfo("hash triFace")
|
||||
HashTypeInfo("triFace")
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
struct HashFun<Pair<T>> : Hash<Pair<T>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "Pair"; }
|
||||
#endif
|
||||
HashTypeInfo("hash Pair")
|
||||
HashTypeInfo("Pair")
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct HashFun<Tuple2<T1, T2>> : Hash<Tuple2<T1, T2>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "Tuple2"; }
|
||||
#endif
|
||||
HashTypeInfo("hash Tuple2")
|
||||
HashTypeInfo("Tuple2")
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
struct HashFun<List<T>> : Hash<List<T>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "List"; }
|
||||
#endif
|
||||
HashTypeInfo("hash List")
|
||||
HashTypeInfo("List")
|
||||
};
|
||||
|
||||
template<class T> struct HashFun<UList<T>> : Hash<UList<T>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "UList"; }
|
||||
#endif
|
||||
HashTypeInfo("hash UList")
|
||||
HashTypeInfo("UList")
|
||||
};
|
||||
|
||||
template<class T, int SizeMin>
|
||||
struct HashFun<DynamicList<T, SizeMin>> : Hash<DynamicList<T, SizeMin>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "DynamicList"; }
|
||||
#endif
|
||||
HashTypeInfo("hash DynamicList")
|
||||
HashTypeInfo("DynamicList")
|
||||
};
|
||||
|
||||
template<class T, unsigned N>
|
||||
struct HashFun<FixedList<T, N>> : Hash<FixedList<T, N>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "FixedList"; }
|
||||
#endif
|
||||
HashTypeInfo("hash FixedList")
|
||||
HashTypeInfo("FixedList")
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -81,7 +81,7 @@ void infoHashString
|
||||
|
||||
void reportHashList(const UList<string>& list)
|
||||
{
|
||||
Info<< "contiguous = " << is_contiguous<string>::value << nl << nl;
|
||||
Info<< "contiguous = " << is_contiguous_v<string> << nl << nl;
|
||||
|
||||
for (const string& val : list)
|
||||
{
|
||||
@ -94,7 +94,7 @@ void reportHashList(const UList<string>& list)
|
||||
|
||||
void reportHashList(const UList<label>& list)
|
||||
{
|
||||
Info<<"contiguous = " << is_contiguous<label>::value << nl << nl;
|
||||
Info<<"contiguous = " << is_contiguous_v<label> << nl << nl;
|
||||
|
||||
for (const label val : list)
|
||||
{
|
||||
@ -113,7 +113,7 @@ void reportHashList(const UList<label>& list)
|
||||
|
||||
void reportHashList(const UList<face>& list)
|
||||
{
|
||||
Info<<"contiguous = " << is_contiguous<label>::value << nl << nl;
|
||||
Info<<"contiguous = " << is_contiguous_v<label> << nl << nl;
|
||||
|
||||
for (const face& f : list)
|
||||
{
|
||||
@ -154,7 +154,7 @@ void reportHashList(const UList<labelList>& list)
|
||||
|
||||
void reportHashList(const UList<wordPair>& list)
|
||||
{
|
||||
Info<<"contiguous = " << is_contiguous<wordPair>::value << nl << nl;
|
||||
Info<<"contiguous = " << is_contiguous_v<wordPair> << nl << nl;
|
||||
|
||||
for (const wordPair& pr : list)
|
||||
{
|
||||
@ -179,7 +179,7 @@ void reportHashList(const UList<wordPair>& list)
|
||||
|
||||
void reportHashList(const UList<labelPair>& list)
|
||||
{
|
||||
Info<<"contiguous = " << is_contiguous<labelPair>::value << nl << nl;
|
||||
Info<<"contiguous = " << is_contiguous_v<labelPair> << nl << nl;
|
||||
|
||||
for (const labelPair& pr : list)
|
||||
{
|
||||
@ -200,7 +200,7 @@ void reportHashList(const UList<labelPair>& list)
|
||||
|
||||
void reportHashList(const UList<labelPairPair>& list)
|
||||
{
|
||||
Info<<"contiguous = " << is_contiguous<labelPairPair>::value << nl << nl;
|
||||
Info<<"contiguous = " << is_contiguous_v<labelPairPair> << nl << nl;
|
||||
|
||||
for (const labelPairPair& pr : list)
|
||||
{
|
||||
@ -221,7 +221,7 @@ void reportHashList(const UList<labelPairPair>& list)
|
||||
|
||||
void reportHashList(const UList<edge>& list)
|
||||
{
|
||||
Info<<"contiguous = " << is_contiguous<edge>::value << nl << nl;
|
||||
Info<<"contiguous = " << is_contiguous_v<edge> << nl << nl;
|
||||
|
||||
for (const edge& e : list)
|
||||
{
|
||||
@ -242,7 +242,7 @@ void reportHashList(const UList<edge>& list)
|
||||
|
||||
void reportHashList(const UList<triFace>& list)
|
||||
{
|
||||
Info<<"contiguous = " << is_contiguous<triFace>::value << nl << nl;
|
||||
Info<<"contiguous = " << is_contiguous_v<triFace> << nl << nl;
|
||||
|
||||
for (const triFace& f : list)
|
||||
{
|
||||
|
||||
@ -213,11 +213,10 @@ int main(int argc, char *argv[])
|
||||
mesh
|
||||
);
|
||||
|
||||
Info<< "points path: " << io.typeFilePath<labelIOList>() << nl;
|
||||
Info<< "points path: " << io.typeFilePath<void>() << nl;
|
||||
Info<< "points path: " << io.typeFilePath<pointIOField>() << nl;
|
||||
|
||||
io.resetHeader("bad-points");
|
||||
Info<< "bad path: " << io.typeFilePath<void>() << nl;
|
||||
Info<< "bad path: " << io.typeFilePath<labelIOList>() << nl;
|
||||
}
|
||||
|
||||
IOobject io
|
||||
|
||||
@ -45,7 +45,7 @@ using namespace Foam;
|
||||
template<class Type>
|
||||
word report()
|
||||
{
|
||||
if (is_globalIOobject<Type>::value)
|
||||
if constexpr (is_globalIOobject<Type>::value)
|
||||
{
|
||||
return "global";
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -74,15 +74,11 @@ Ostream& toString(Ostream& os, const List<char>& list)
|
||||
void printTokens(Istream& is)
|
||||
{
|
||||
label count = 0;
|
||||
token t;
|
||||
while (is.good())
|
||||
|
||||
Info<< "stream tokens:" << endl;
|
||||
for (token tok; tok.read(is); ++count)
|
||||
{
|
||||
is >> t;
|
||||
if (t.good())
|
||||
{
|
||||
++count;
|
||||
Info<< "token: " << t << endl;
|
||||
}
|
||||
Info<< " : " << tok << endl;
|
||||
}
|
||||
|
||||
Info<< count << " tokens" << endl;
|
||||
@ -455,6 +451,12 @@ int main(int argc, char *argv[])
|
||||
"( const char input \"string\" to tokenize )\n"
|
||||
"List<label> 5(0 1 2 3 4);";
|
||||
|
||||
// printTokens
|
||||
{
|
||||
ISpanStream is(charInput);
|
||||
printTokens(is);
|
||||
}
|
||||
|
||||
string stringInput("( string ; input \"string\" to tokenize )");
|
||||
|
||||
List<char> listInput
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-IjkField.C
|
||||
Test-IjkField.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-IjkField
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -118,7 +118,7 @@ Ostream& printListOutputType(const char* what)
|
||||
{
|
||||
Info<< what
|
||||
<< " (contiguous="
|
||||
<< is_contiguous<T>::value << " no_linebreak="
|
||||
<< is_contiguous_v<T> << " no_linebreak="
|
||||
<< Detail::ListPolicy::no_linebreak<T>::value
|
||||
<< " short_length="
|
||||
<< Detail::ListPolicy::short_length<T>::value << ')';
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-List2.C
|
||||
Test-List2.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-List2
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -35,6 +35,7 @@ Description
|
||||
#include "FixedList.H"
|
||||
#include "labelList.H"
|
||||
#include "vectorList.H"
|
||||
#include "SubList.H"
|
||||
#include "ListOps.H"
|
||||
#include "IFstream.H"
|
||||
#include "OFstream.H"
|
||||
@ -200,6 +201,7 @@ int main(int argc, char *argv[])
|
||||
argList::addBoolOption("order");
|
||||
argList::addBoolOption("labelList");
|
||||
argList::addBoolOption("vectorList");
|
||||
argList::addBoolOption("ulist");
|
||||
|
||||
argList args(argc, argv);
|
||||
|
||||
@ -261,6 +263,37 @@ 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;
|
||||
return 0;
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -128,18 +128,17 @@ void test_member_funcs(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
3
applications/test/PtrDictionary1/Make/files
Normal file
3
applications/test/PtrDictionary1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-PtrDictionary1.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-PtrDictionary1
|
||||
@ -25,10 +25,10 @@ License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
Test-Dictionary
|
||||
Test-PtrDictionary1
|
||||
|
||||
Description
|
||||
Tests for Dictionary (not dictionary)
|
||||
Tests for Dictionary (not dictionary) and PtrDictionary
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -185,7 +185,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
std::cout<< "iter type: "
|
||||
<< typeid(stdFoam::begin(scalarDict2)).name() << '\n';
|
||||
<< typeid(std::begin(scalarDict2)).name() << '\n';
|
||||
|
||||
scalarDict.transfer(scalarDict2);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -38,12 +38,11 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "Tensor.H"
|
||||
#include "SymmTensor.H"
|
||||
#include "SphericalTensor.H"
|
||||
#include "DiagTensor.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -57,65 +56,50 @@ unsigned nTest_ = 0;
|
||||
unsigned nFail_ = 0;
|
||||
|
||||
|
||||
// Compare two floating point types, and print output.
|
||||
// Compare two containers elementwise, 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
|
||||
template<class Type, class Type2 = Type>
|
||||
void cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
const Type& y,
|
||||
const Type2& 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;
|
||||
const auto notEqual = [=](const auto& a, const auto& b) -> bool
|
||||
{
|
||||
return
|
||||
(
|
||||
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
|
||||
< Foam::mag(a - b)
|
||||
);
|
||||
};
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
|
||||
if constexpr (is_vectorspace_v<Type>)
|
||||
{
|
||||
++nFail;
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
{
|
||||
if (notEqual(x[i], y[i]))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nFail)
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
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]))
|
||||
if (notEqual(x, y))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< msg << x << endl;
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
@ -277,27 +261,26 @@ void test_global_opers(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -312,8 +295,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"SphericalTensor<floatScalar>",
|
||||
"SphericalTensor<doubleScalar>",
|
||||
"SphericalTensor<float>",
|
||||
"SphericalTensor<double>",
|
||||
"SphericalTensor<complex>"
|
||||
});
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -38,11 +38,10 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "Tensor2D.H"
|
||||
#include "SymmTensor2D.H"
|
||||
#include "SphericalTensor2D.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -56,12 +55,11 @@ unsigned nTest_ = 0;
|
||||
unsigned nFail_ = 0;
|
||||
|
||||
|
||||
// Compare two floating point types, and print output.
|
||||
// Compare two containers elementwise, 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
|
||||
void cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
@ -70,51 +68,37 @@ cmp
|
||||
const scalar absTol = 0 //<! useful for cmps near zero
|
||||
)
|
||||
{
|
||||
Info<< msg << x << endl;
|
||||
const auto notEqual = [=](const auto& a, const auto& b) -> bool
|
||||
{
|
||||
return
|
||||
(
|
||||
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
|
||||
< Foam::mag(a - b)
|
||||
);
|
||||
};
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
|
||||
if constexpr (is_vectorspace_v<Type>)
|
||||
{
|
||||
++nFail;
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
{
|
||||
if (notEqual(x[i], y[i]))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nFail)
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
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]))
|
||||
if (notEqual(x, y))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< msg << x << endl;
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
@ -260,27 +244,26 @@ void test_global_opers(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -295,8 +278,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"SphericalTensor2D<floatScalar>",
|
||||
"SphericalTensor2D<doubleScalar>",
|
||||
"SphericalTensor2D<float>",
|
||||
"SphericalTensor2D<double>",
|
||||
"SphericalTensor2D<complex>"
|
||||
});
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -40,11 +40,10 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "symmTensor.H"
|
||||
#include "transform.H"
|
||||
#include "Random.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -69,12 +68,12 @@ symmTensor makeRandomContainer(Random& rnd)
|
||||
|
||||
// Create a symmTensor based on a given value
|
||||
template<class Type>
|
||||
typename std::enable_if
|
||||
std::enable_if_t
|
||||
<
|
||||
std::is_same<floatScalar, Type>::value ||
|
||||
std::is_same<doubleScalar, Type>::value,
|
||||
std::is_floating_point_v<Type> || std::is_same_v<complex, Type>,
|
||||
symmTensor
|
||||
>::type makeContainer(const Type val)
|
||||
>
|
||||
makeContainer(const Type val)
|
||||
{
|
||||
symmTensor T(Zero);
|
||||
std::fill(T.begin(), T.end(), val);
|
||||
@ -82,12 +81,11 @@ typename std::enable_if
|
||||
}
|
||||
|
||||
|
||||
// Compare two floating point types, and print output.
|
||||
// Compare two containers elementwise, 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
|
||||
void cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
@ -96,51 +94,37 @@ cmp
|
||||
const scalar relTol = 1e-8 //<! are values the same within 8 decimals
|
||||
)
|
||||
{
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
const auto notEqual = [=](const auto& a, const auto& b) -> bool
|
||||
{
|
||||
return
|
||||
(
|
||||
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
|
||||
< Foam::mag(a - b)
|
||||
);
|
||||
};
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
|
||||
if constexpr (is_vectorspace_v<Type>)
|
||||
{
|
||||
++nFail;
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
{
|
||||
if (notEqual(x[i], y[i]))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nFail)
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
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]))
|
||||
if (notEqual(x, y))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
@ -588,27 +572,26 @@ void test_eigen_funcs(const symmTensor& T)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -623,8 +606,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"SymmTensor<floatScalar>",
|
||||
"SymmTensor<doubleScalar>",
|
||||
"SymmTensor<float>",
|
||||
"SymmTensor<double>",
|
||||
"SymmTensor<complex>"
|
||||
});
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -40,11 +40,10 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "symmTensor2D.H"
|
||||
#include "transform.H"
|
||||
#include "Random.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -67,45 +66,11 @@ 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.
|
||||
// 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
|
||||
void cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
@ -114,18 +79,37 @@ cmp
|
||||
const scalar relTol = 1e-8
|
||||
)
|
||||
{
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
const auto notEqual = [=](const auto& a, const auto& b) -> bool
|
||||
{
|
||||
return
|
||||
(
|
||||
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
|
||||
< Foam::mag(a - b)
|
||||
);
|
||||
};
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
if constexpr (is_vectorspace_v<Type>)
|
||||
{
|
||||
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
{
|
||||
if (notEqual(x[i], y[i]))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (notEqual(x, y))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
@ -538,27 +522,26 @@ void test_eigen_funcs(const symmTensor2D& T)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -573,8 +556,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"SymmTensor2D<floatScalar>",
|
||||
"SymmTensor2D<doubleScalar>",
|
||||
"SymmTensor2D<float>",
|
||||
"SymmTensor2D<double>",
|
||||
"SymmTensor2D<complex>"
|
||||
});
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,11 +41,10 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "tensor.H"
|
||||
#include "transform.H"
|
||||
#include "Random.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -68,45 +67,11 @@ 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.
|
||||
// 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
|
||||
void cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
@ -115,18 +80,37 @@ cmp
|
||||
const scalar relTol = 1e-8
|
||||
)
|
||||
{
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
const auto notEqual = [=](const auto& a, const auto& b) -> bool
|
||||
{
|
||||
return
|
||||
(
|
||||
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
|
||||
< Foam::mag(a - b)
|
||||
);
|
||||
};
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
if constexpr (is_vectorspace_v<Type>)
|
||||
{
|
||||
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
{
|
||||
if (notEqual(x[i], y[i]))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (notEqual(x, y))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
@ -987,27 +971,26 @@ void test_eigen_funcs(const tensor& T, const bool prod = true)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names;
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name <<" ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test global operators: " << name <<" ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1022,8 +1005,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"Tensor<floatScalar>",
|
||||
"Tensor<doubleScalar>",
|
||||
"Tensor<float>",
|
||||
"Tensor<double>",
|
||||
"Tensor<complex>"
|
||||
});
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2014 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,13 +41,13 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
#include "vector2DField.H"
|
||||
#include "tensor2D.H"
|
||||
#include "symmTensor2D.H"
|
||||
#include "transform.H"
|
||||
#include "Random.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -70,12 +70,11 @@ tensor2D 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.
|
||||
// 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
|
||||
void cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
@ -84,51 +83,37 @@ cmp
|
||||
const scalar relTol = 1e-8 //<! are values the same within 8 decimals
|
||||
)
|
||||
{
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
const auto notEqual = [=](const auto& a, const auto& b) -> bool
|
||||
{
|
||||
return
|
||||
(
|
||||
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
|
||||
< Foam::mag(a - b)
|
||||
);
|
||||
};
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
|
||||
if constexpr (is_vectorspace_v<Type>)
|
||||
{
|
||||
++nFail;
|
||||
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
|
||||
{
|
||||
if (notEqual(x[i], y[i]))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nFail)
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
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]))
|
||||
if (notEqual(x, y))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
@ -795,27 +780,26 @@ void test_eigen_funcs(const tensor2D& T)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -831,8 +815,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"Tensor2D<floatScalar>",
|
||||
"Tensor2D<doubleScalar>",
|
||||
"Tensor2D<float>",
|
||||
"Tensor2D<double>",
|
||||
"Tensor2D<complex>"
|
||||
});
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -67,13 +67,9 @@ doubleScalar getTol(complex)
|
||||
}
|
||||
|
||||
|
||||
// Create a non-complex random Matrix.
|
||||
// Create a random Matrix (real or complex)
|
||||
template<class MatrixType>
|
||||
typename std::enable_if
|
||||
<
|
||||
!std::is_same<complex, typename MatrixType::cmptType>:: value,
|
||||
MatrixType
|
||||
>::type makeRandomMatrix
|
||||
MatrixType makeRandomMatrix
|
||||
(
|
||||
const labelPair& dims,
|
||||
Random& rndGen
|
||||
@ -81,34 +77,22 @@ typename std::enable_if
|
||||
{
|
||||
MatrixType mat(dims);
|
||||
|
||||
std::generate
|
||||
(
|
||||
mat.begin(),
|
||||
mat.end(),
|
||||
[&]{return rndGen.GaussNormal<scalar>();}
|
||||
);
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
// Create a complex random Matrix.
|
||||
template<class MatrixType>
|
||||
typename std::enable_if
|
||||
<
|
||||
std::is_same<complex, typename MatrixType::cmptType>:: value,
|
||||
MatrixType
|
||||
>::type makeRandomMatrix
|
||||
(
|
||||
const labelPair& dims,
|
||||
Random& rndGen
|
||||
)
|
||||
{
|
||||
MatrixType mat(dims);
|
||||
|
||||
for (auto& x : mat)
|
||||
if constexpr (std::is_same_v<complex, typename MatrixType::cmptType>)
|
||||
{
|
||||
x = complex(rndGen.GaussNormal<scalar>(), rndGen.GaussNormal<scalar>());
|
||||
for (auto& x : mat)
|
||||
{
|
||||
x.real(rndGen.GaussNormal<scalar>());
|
||||
x.imag(rndGen.GaussNormal<scalar>());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::generate
|
||||
(
|
||||
mat.begin(),
|
||||
mat.end(),
|
||||
[&]{ return rndGen.GaussNormal<scalar>(); }
|
||||
);
|
||||
}
|
||||
|
||||
return mat;
|
||||
@ -179,128 +163,57 @@ List<Type> flt
|
||||
}
|
||||
|
||||
|
||||
// Compare two floating point types, and print output.
|
||||
// Compare two values or two containers (elementwise), 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
|
||||
<
|
||||
std::is_same<floatScalar, Type>::value ||
|
||||
std::is_same<doubleScalar, Type>::value ||
|
||||
std::is_same<complex, Type>::value,
|
||||
void
|
||||
>::type cmp
|
||||
template<class Type1, class Type2 = Type1>
|
||||
void cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
const Type& y,
|
||||
const Type1& x,
|
||||
const Type2& y,
|
||||
const scalar absTol = 0, //<! useful for cmps near zero
|
||||
const scalar relTol = 1e-8, //<! are values the same within 8 decimals
|
||||
const bool verbose = false
|
||||
)
|
||||
{
|
||||
if (verbose)
|
||||
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;
|
||||
|
||||
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
|
||||
if constexpr
|
||||
(
|
||||
std::is_floating_point_v<Type1> || std::is_same_v<complex, Type1>
|
||||
)
|
||||
{
|
||||
++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
|
||||
<
|
||||
!std::is_same<floatScalar, Type>::value &&
|
||||
!std::is_same<doubleScalar, Type>::value &&
|
||||
!std::is_same<complex, Type>::value,
|
||||
void
|
||||
>::type cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type& x,
|
||||
const Type& y,
|
||||
const scalar absTol = 0,
|
||||
const scalar relTol = 1e-8,
|
||||
const bool verbose = false
|
||||
)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
}
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
for (label i = 0; i < x.size(); ++i)
|
||||
{
|
||||
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
|
||||
if (notEqual(x, y))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
if (nFail)
|
||||
else
|
||||
{
|
||||
Info<< nl
|
||||
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
|
||||
++nFail_;
|
||||
for (label i = 0; i < x.size(); ++i)
|
||||
{
|
||||
if (notEqual(x[i], y[i]))
|
||||
{
|
||||
++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 Type1, class Type2>
|
||||
typename std::enable_if
|
||||
<
|
||||
!std::is_same<floatScalar, Type1>::value &&
|
||||
!std::is_same<doubleScalar, Type1>::value &&
|
||||
!std::is_same<complex, Type1>::value,
|
||||
void
|
||||
>::type cmp
|
||||
(
|
||||
const word& msg,
|
||||
const Type1& x,
|
||||
const Type2& y,
|
||||
const scalar absTol = 0,
|
||||
const scalar relTol = 1e-8,
|
||||
const bool verbose = false
|
||||
)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
}
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
for (label i = 0; i < x.size(); ++i)
|
||||
{
|
||||
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
|
||||
{
|
||||
++nFail;
|
||||
}
|
||||
}
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
@ -321,11 +234,6 @@ void cmp
|
||||
const bool verbose = false
|
||||
)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
}
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
if (x != y)
|
||||
@ -333,6 +241,11 @@ void cmp
|
||||
++nFail;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< msg << x << "?=" << y << endl;
|
||||
}
|
||||
|
||||
if (nFail)
|
||||
{
|
||||
Info<< nl
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-Tuple2.C
|
||||
Test-Tuple2.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-Tuple2
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -32,6 +32,7 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "labelPair.H"
|
||||
#include "Tuple2.H"
|
||||
#include "label.H"
|
||||
@ -102,8 +103,12 @@ void printTuple2(const Pair<word>& t)
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main()
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noCheckProcessorDirectories();
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
typedef Tuple2<label, scalar> indexedScalar;
|
||||
|
||||
Info<< "Default constructed Tuple: " << indexedScalar() << nl;
|
||||
3
applications/test/UPstreamTraits/Make/files
Normal file
3
applications/test/UPstreamTraits/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-UPstreamTraits.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-UPstreamTraits
|
||||
2
applications/test/UPstreamTraits/Make/options
Normal file
2
applications/test/UPstreamTraits/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
466
applications/test/UPstreamTraits/Test-UPstreamTraits.cxx
Normal file
466
applications/test/UPstreamTraits/Test-UPstreamTraits.cxx
Normal file
@ -0,0 +1,466 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Description
|
||||
Simple compilation tests and access for UPstream types
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "pTraits.H"
|
||||
#include "contiguous.H"
|
||||
#include "FixedList.H"
|
||||
#include "boolVector.H" // A FixedList pretending to be a vector
|
||||
#include "barycentric.H"
|
||||
#include "complex.H"
|
||||
#include "vector.H"
|
||||
#include "tensor.H"
|
||||
#include "uLabel.H"
|
||||
#include "MinMax.H"
|
||||
#include "Switch.H"
|
||||
#include "IOstreams.H"
|
||||
#include "UPstream.H"
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Add in some extras from functional
|
||||
|
||||
//- Map std::plus to \c UPstream::opCodes::op_sum
|
||||
template<>
|
||||
struct UPstream_opType<std::plus<void>> : std::true_type
|
||||
{
|
||||
static constexpr auto opcode_id = UPstream::opCodes::op_sum;
|
||||
};
|
||||
|
||||
|
||||
//- Map 'signed char' to UPstream::dataTypes::type_byte
|
||||
// Caution with: may be identical to int8_t mapping!!
|
||||
#if 0
|
||||
template<>
|
||||
struct UPstream_alias_dataType<signed char> : std::true_type
|
||||
{
|
||||
using base = char;
|
||||
static constexpr auto datatype_id = UPstream::dataTypes::type_byte;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
//- Test for pTraits typeName member : default is false
|
||||
template<class T, class = void>
|
||||
struct check_has_typeName : std::false_type {};
|
||||
|
||||
//- Test for pTraits zero
|
||||
template<class T>
|
||||
struct check_has_typeName
|
||||
<
|
||||
T,
|
||||
std::void_t<decltype(pTraits<std::remove_cv_t<T>>::typeName)>
|
||||
>
|
||||
:
|
||||
std::true_type
|
||||
{};
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Just for debugging
|
||||
static const Foam::List<std::string> dataType_names
|
||||
({
|
||||
"byte",
|
||||
"int16",
|
||||
"int32",
|
||||
"int64",
|
||||
"uint16",
|
||||
"uint32",
|
||||
"uint64",
|
||||
"float",
|
||||
"double",
|
||||
"long_double",
|
||||
|
||||
"float[3]",
|
||||
"double[3]",
|
||||
"float[6]",
|
||||
"double[6]",
|
||||
"float[9]",
|
||||
"double[9]"
|
||||
});
|
||||
|
||||
// Just for debugging
|
||||
static const Foam::List<std::string> opType_names
|
||||
({
|
||||
"op_min",
|
||||
"op_max",
|
||||
"op_sum",
|
||||
"op_prod",
|
||||
"op_bool_and",
|
||||
"op_bool_or",
|
||||
"op_bool_xor",
|
||||
"op_bit_and",
|
||||
"op_bit_or",
|
||||
"op_bit_xor",
|
||||
"op_replace",
|
||||
"op_no_op"
|
||||
});
|
||||
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
void printDataTypeId(UPstream::dataTypes datatype_id)
|
||||
{
|
||||
if (datatype_id != UPstream::dataTypes::invalid)
|
||||
{
|
||||
const int index = int(datatype_id);
|
||||
if (index < dataType_names.size())
|
||||
{
|
||||
Info<< dataType_names[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< '(' << index << ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printOpCodeId(UPstream::opCodes opcode_id)
|
||||
{
|
||||
if (opcode_id != UPstream::opCodes::invalid)
|
||||
{
|
||||
const int index = int(opcode_id);
|
||||
if (index < opType_names.size())
|
||||
{
|
||||
Info<< ':' << opType_names[index].c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< '(' << index << ')';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "(null)";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, bool showSize = false>
|
||||
void printTypeName()
|
||||
{
|
||||
// Both float and double have pTraits typeName = "scalar"!
|
||||
if constexpr (std::is_same_v<float, std::remove_cv_t<T>>)
|
||||
{
|
||||
Info<< "<float>";
|
||||
}
|
||||
else if constexpr (std::is_same_v<double, std::remove_cv_t<T>>)
|
||||
{
|
||||
Info<< "<double>";
|
||||
}
|
||||
else if constexpr (check_has_typeName<T>::value)
|
||||
{
|
||||
Info<< pTraits<std::remove_cv_t<T>>::typeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< typeid(T).name();
|
||||
}
|
||||
if constexpr (showSize)
|
||||
{
|
||||
Info<< " (" << sizeof(T) << " bytes)";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type, bool UseTypeName = true>
|
||||
void printPstreamTraits(const std::string_view name = std::string_view())
|
||||
{
|
||||
Info<< "========" << nl;
|
||||
Info<< "type: ";
|
||||
if (!name.empty())
|
||||
{
|
||||
Info<< name << ' ';
|
||||
}
|
||||
|
||||
if constexpr (UseTypeName)
|
||||
{
|
||||
printTypeName<Type, true>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< typeid(Type).name() << " (" << sizeof(Type) << " bytes)";
|
||||
}
|
||||
|
||||
{
|
||||
using cmpt = typename Foam::pTraits_cmptType<Type>::type;
|
||||
|
||||
if constexpr (!std::is_same_v<Type, cmpt>)
|
||||
{
|
||||
Info<< ", cmpt:";
|
||||
|
||||
if constexpr (UseTypeName)
|
||||
{
|
||||
printTypeName<cmpt, true>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< typeid(cmpt).name() << " (" << sizeof(cmpt) << " bytes)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Info<< nl
|
||||
<< " is_contiguous:"
|
||||
<< is_contiguous<Type>::value;
|
||||
|
||||
if constexpr (UPstream_mpi_dataType<Type>::value)
|
||||
{
|
||||
Info<< ", is_mpi=("
|
||||
<< int(UPstream_mpi_dataType<Type>::datatype_id) << ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << ", is_mpi=(null)";
|
||||
}
|
||||
if constexpr (UPstream_user_dataType<Type>::value)
|
||||
{
|
||||
Info<< ", is_user=("
|
||||
<< int(UPstream_user_dataType<Type>::datatype_id) << ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << ", is_user=(null)";
|
||||
}
|
||||
if constexpr (UPstream_any_dataType<Type>::value)
|
||||
{
|
||||
Info<< ", is_any=("
|
||||
<< int(UPstream_any_dataType<Type>::datatype_id) << ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << ", is_any=(null)";
|
||||
}
|
||||
|
||||
// Any aliases?
|
||||
if constexpr
|
||||
(
|
||||
UPstream_alias_dataType<Type>::value
|
||||
&& !UPstream_mpi_dataType<Type>::value
|
||||
)
|
||||
{
|
||||
Info<< ", alias=("
|
||||
<< int(UPstream_alias_dataType<Type>::datatype_id) << ')';
|
||||
}
|
||||
|
||||
Info<< " base-type:" << int(UPstream_basic_dataType<Type>::datatype_id)
|
||||
<< " data-type:" << int(UPstream_dataType<Type>::datatype_id)
|
||||
<< nl;
|
||||
|
||||
if constexpr (UPstream_basic_dataType<Type>::value)
|
||||
{
|
||||
Info<< " base-type=";
|
||||
printDataTypeId(UPstream_basic_dataType<Type>::datatype_id);
|
||||
}
|
||||
else if constexpr (UPstream_dataType<Type>::value)
|
||||
{
|
||||
Info<< " data-type=";
|
||||
printDataTypeId(UPstream_dataType<Type>::datatype_id);
|
||||
}
|
||||
|
||||
{
|
||||
// Use element or component type (or byte-wise) for data type
|
||||
using base = typename UPstream_dataType<Type>::base;
|
||||
|
||||
Info<< " : ";
|
||||
if constexpr (UseTypeName)
|
||||
{
|
||||
printTypeName<base, true>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< typeid(base).name() << " (" << sizeof(base) << " bytes)";
|
||||
}
|
||||
|
||||
Info<< " cmpt-type=";
|
||||
printDataTypeId(UPstream_dataType<Type>::datatype_id);
|
||||
Info<< " count=" << UPstream_dataType<Type>::size(1);
|
||||
Info<< nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class BinaryOp>
|
||||
void printOpCodeTraits(BinaryOp bop, std::string_view name)
|
||||
{
|
||||
Info<< "op: " << name << ' ';
|
||||
|
||||
printOpCodeId(UPstream_opType<BinaryOp>::opcode_id);
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
|
||||
template<class DataType, class BinaryOp>
|
||||
void printOpCodeTraits(BinaryOp bop, std::string_view name)
|
||||
{
|
||||
Info<< "op: " << name << ' ';
|
||||
|
||||
printOpCodeId(UPstream_opType<BinaryOp>::opcode_id);
|
||||
|
||||
if constexpr (!std::is_void_v<DataType>)
|
||||
{
|
||||
if constexpr (UPstream_basic_dataType<DataType>::value)
|
||||
{
|
||||
Info<< " [supported type]";
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< " [disabled]";
|
||||
}
|
||||
}
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
|
||||
template<class DataType, class BinaryOp>
|
||||
void print_data_opType(BinaryOp bop, std::string_view name)
|
||||
{
|
||||
Info<< "op: " << name << ' ';
|
||||
|
||||
printOpCodeId(UPstream_data_opType<BinaryOp, DataType>::opcode_id);
|
||||
|
||||
const bool ok = UPstream_data_opType<BinaryOp, DataType>::value;
|
||||
|
||||
Info<< " okay=" << ok << nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main()
|
||||
{
|
||||
printPstreamTraits<bool>();
|
||||
printPstreamTraits<label>();
|
||||
|
||||
printPstreamTraits<char, false>("<char>");
|
||||
printPstreamTraits<signed char, false>("<signed char>");
|
||||
printPstreamTraits<unsigned char, false>("<unsigned char>");
|
||||
|
||||
printPstreamTraits<int8_t, false>("<int8_t>");
|
||||
printPstreamTraits<uint8_t, false>("<uint8_t>");
|
||||
|
||||
printPstreamTraits<int16_t, false>("<int16_t>");
|
||||
printPstreamTraits<uint16_t, false>("<uint16_t>");
|
||||
|
||||
printPstreamTraits<int>("<int>");
|
||||
printPstreamTraits<long>("<long>");
|
||||
printPstreamTraits<unsigned>("<unsigned>");
|
||||
printPstreamTraits<unsigned int>("<unsigned int>");
|
||||
printPstreamTraits<unsigned long>("<long long>");
|
||||
|
||||
printPstreamTraits<const float>();
|
||||
printPstreamTraits<floatVector>();
|
||||
|
||||
printPstreamTraits<scalar>();
|
||||
printPstreamTraits<double>();
|
||||
printPstreamTraits<doubleVector>();
|
||||
|
||||
// Avoid typeName for barycentric. It is declared, but not defined
|
||||
printPstreamTraits<barycentric, false>("barycentric");
|
||||
|
||||
printPstreamTraits<complex>(); // Uses specialized pTraits_...
|
||||
|
||||
printPstreamTraits<boolVector>(); // Uses specialized pTraits_...
|
||||
printPstreamTraits<floatVector>();
|
||||
printPstreamTraits<doubleVector>();
|
||||
printPstreamTraits<tensor>();
|
||||
printPstreamTraits<word>();
|
||||
printPstreamTraits<std::string>();
|
||||
|
||||
// This will not identify properly at the moment...
|
||||
printPstreamTraits<FixedList<doubleVector, 4>>();
|
||||
printPstreamTraits<labelPair>();
|
||||
|
||||
Info<< nl
|
||||
<< "========" << nl
|
||||
<< "Mapping of binary reduction ops" << nl;
|
||||
|
||||
printOpCodeTraits(minOp<scalar>{}, "min");
|
||||
printOpCodeTraits(maxOp<vector>{}, "max");
|
||||
printOpCodeTraits(sumOp<vector>{}, "sum");
|
||||
printOpCodeTraits(plusOp<vector>{}, "plus");
|
||||
printOpCodeTraits(multiplyOp<scalar>{}, "multiply");
|
||||
printOpCodeTraits(divideOp<vector>{}, "divide");
|
||||
printOpCodeTraits(minMagSqrOp<vector>{}, "minMagSqr");
|
||||
|
||||
printOpCodeTraits(bitAndOp<vector>{}, "bitAnd<vector>");
|
||||
printOpCodeTraits(bitOrOp<vector>{}, "bitOr<vector>");
|
||||
|
||||
printOpCodeTraits(bitOrOp<float>{}, "bitOr<float>");
|
||||
printOpCodeTraits(bitAndOp<unsigned>{}, "bitAnd<unsigned>");
|
||||
printOpCodeTraits(bitOrOp<unsigned>{}, "bitOr<unsigned>");
|
||||
|
||||
printOpCodeTraits<vector>(sumOp<vector>{}, "sum");
|
||||
printOpCodeTraits(sumOp<scalarMinMax>{}, "sum");
|
||||
|
||||
printOpCodeTraits(std::plus<>{}, "sum");
|
||||
printOpCodeTraits<bool>(std::plus<>{}, "sum");
|
||||
printOpCodeTraits<vector>(std::plus<>{}, "sum");
|
||||
|
||||
|
||||
// Expect success
|
||||
Info<< nl << "expect success" << nl;
|
||||
print_data_opType<vector>(maxOp<scalar>(), "maxOp(scalar)");
|
||||
print_data_opType<unsigned>(bitOrOp<unsigned>(), "bitOrOp(unsigned)");
|
||||
print_data_opType<uint8_t>(bitOrOp<uint8_t>(), "bitOrOp(uint8_t)");
|
||||
print_data_opType<uint16_t>(bitOrOp<uint16_t>(), "bitOrOp(uint16_t)");
|
||||
|
||||
// Even allow signed integrals
|
||||
print_data_opType<int>(bitOrOp<int>(), "bitOrOp(int)");
|
||||
print_data_opType<int8_t>(bitOrOp<int8_t>(), "bitOrOp(int8_t)");
|
||||
|
||||
// Failure - supported op, unsupported data type.
|
||||
Info<< nl << "expect failure" << nl;
|
||||
print_data_opType<bool>(maxOp<scalar>(), "maxOp(scalar, bool)");
|
||||
print_data_opType<bool>(bitOrOp<unsigned>(), "bitOrOp(unsigned, bool)");
|
||||
|
||||
// False positives. Failure - supported op, unsupported data type.
|
||||
Info<< nl << "false positives" << nl;
|
||||
print_data_opType<void>(maxOp<bool>(), "maxOp(bool, void)");
|
||||
print_data_opType<float>(bitOrOp<unsigned>(), "bitOrOp(unsigned, float)");
|
||||
|
||||
Info<< nl << "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -123,15 +123,12 @@ int main(int argc, char *argv[])
|
||||
argList::addDryRunOption("Just for testing");
|
||||
argList::addVerboseOption("Increase verbosity");
|
||||
|
||||
// Check -verbose before initialisation
|
||||
UPstream::debug = argList::verbose(argc, argv);
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
Pout<< "command-line ("
|
||||
<< args.options().size() << " options, "
|
||||
<< args.args().size() << " args)" << nl
|
||||
<< " " << args.commandLine().c_str() << nl << nl;
|
||||
<< " " << args.commandLine().data() << nl << nl;
|
||||
|
||||
Pout<< "rootPath: " << args.rootPath() << nl
|
||||
<< "globalCase: " << args.globalCaseName() << nl
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -54,7 +54,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
Info<< "boolVector" << nl
|
||||
<< " size = " << boolVector::size() << nl
|
||||
<< " contiguous = " << is_contiguous<boolVector>::value << nl
|
||||
<< " contiguous = " << is_contiguous_v<boolVector> << nl
|
||||
<< nl;
|
||||
|
||||
{
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -72,13 +72,14 @@ void printInfo(const char* const name = nullptr)
|
||||
Info<< name;
|
||||
}
|
||||
|
||||
Info<< " contiguous=" << Switch(is_contiguous<T>::value);
|
||||
Info<< " contiguous=" << Switch(is_contiguous<T>::value)
|
||||
<< " / " << Switch(is_contiguous_v<T>);
|
||||
|
||||
if (is_contiguous_label<T>::value)
|
||||
if constexpr (is_contiguous_label<T>::value)
|
||||
{
|
||||
Info<< " label";
|
||||
}
|
||||
if (is_contiguous_scalar<T>::value)
|
||||
if constexpr (is_contiguous_scalar<T>::value)
|
||||
{
|
||||
Info<< " scalar";
|
||||
}
|
||||
@ -96,10 +97,11 @@ int main(int argc, char *argv[])
|
||||
argList::noParallel();
|
||||
argList::noFunctionObjects();
|
||||
|
||||
printInfo<label>();
|
||||
printInfo<label>();
|
||||
printInfo<double>();
|
||||
printInfo<FixedList<double, 4>>();
|
||||
printInfo<Pair<long>>();
|
||||
printInfo<const Pair<long>>();
|
||||
|
||||
printInfo<FixedList<word, 2>>();
|
||||
printInfo<Pair<word>>();
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021-2024 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
@ -122,7 +122,7 @@ int main(int argc, char *argv[])
|
||||
// Regular broadcast doesn't work
|
||||
Info<< "exprValue"
|
||||
<< " sizeof:" << sizeof(expressions::exprValue)
|
||||
<< " contiguous:" << is_contiguous<expressions::exprValue>::value
|
||||
<< " contiguous:" << is_contiguous_v<expressions::exprValue>
|
||||
<< nl << nl;
|
||||
|
||||
{
|
||||
|
||||
@ -3,4 +3,5 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume
|
||||
-lfiniteVolume \
|
||||
-lmeshTools
|
||||
|
||||
@ -3,4 +3,5 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume
|
||||
-lfiniteVolume \
|
||||
-lmeshTools
|
||||
|
||||
@ -48,7 +48,7 @@ word toString(const fileOperation::procRangeType& group)
|
||||
{
|
||||
return word::null;
|
||||
}
|
||||
return Foam::name(group.first()) + "-" + Foam::name(group.last());
|
||||
return Foam::name(group.min()) + "-" + Foam::name(group.max());
|
||||
}
|
||||
|
||||
|
||||
|
||||
3
applications/test/gather-scatter1/Make/files
Normal file
3
applications/test/gather-scatter1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-gather-scatter1.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-gather-scatter1
|
||||
2
applications/test/gather-scatter1/Make/options
Normal file
2
applications/test/gather-scatter1/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
282
applications/test/gather-scatter1/Test-gather-scatter1.cxx
Normal file
282
applications/test/gather-scatter1/Test-gather-scatter1.cxx
Normal file
@ -0,0 +1,282 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
Test-gather-scatter1
|
||||
|
||||
Description
|
||||
Simple tests for gather/scatter
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "List.H"
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "Pstream.H"
|
||||
#include "IOstreams.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
|
||||
//- Ostensibly the inverse of gatherList, but actually works like
|
||||
//- a broadcast that skips overwriting the local rank!
|
||||
template<class T>
|
||||
void real_scatterList
|
||||
(
|
||||
//! [in,out]
|
||||
UList<T>& values,
|
||||
[[maybe_unused]] const int tag = UPstream::msgType(),
|
||||
const int communicator = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
if (!UPstream::is_parallel(communicator))
|
||||
{
|
||||
// Nothing to do
|
||||
return;
|
||||
}
|
||||
else if constexpr (is_contiguous_v<T>)
|
||||
{
|
||||
// This part is a real in-place scatter:
|
||||
|
||||
// In-place scatter for contiguous types - one element per rank
|
||||
// - on master:
|
||||
// * send pointer is the full list
|
||||
// * recv pointer is first destination
|
||||
// - on rank:
|
||||
// * send pointer is irrelevant
|
||||
// * recv pointer is destination in the list
|
||||
//
|
||||
// So can simply use identical pointers for send/recv
|
||||
|
||||
auto* ptr = values.data() + UPstream::myProcNo(communicator);
|
||||
UPstream::mpiScatter(ptr, ptr, 1, communicator);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Communication order
|
||||
const auto& commOrder = UPstream::whichCommunication(communicator);
|
||||
|
||||
Pstream::scatterList_algorithm(commOrder, values, tag, communicator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- gatherList_algorithm, but with specific communication style
|
||||
template<class T>
|
||||
void gatherList_algo
|
||||
(
|
||||
const bool linear,
|
||||
//! [in,out]
|
||||
UList<T>& values,
|
||||
[[maybe_unused]] const int tag = UPstream::msgType(),
|
||||
const int communicator = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
if (UPstream::is_parallel(communicator))
|
||||
{
|
||||
Pstream::gatherList_algorithm
|
||||
(
|
||||
UPstream::whichCommunication(communicator, linear),
|
||||
values,
|
||||
tag,
|
||||
communicator
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- scatterList_algorithm, but with specific communication style
|
||||
template<class T>
|
||||
void scatterList_algo
|
||||
(
|
||||
const bool linear,
|
||||
//! [in,out]
|
||||
UList<T>& values,
|
||||
[[maybe_unused]] const int tag = UPstream::msgType(),
|
||||
const int communicator = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
if (UPstream::is_parallel(communicator))
|
||||
{
|
||||
Pstream::scatterList_algorithm
|
||||
(
|
||||
UPstream::whichCommunication(communicator, linear),
|
||||
values,
|
||||
tag,
|
||||
communicator
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Perform tests
|
||||
template<class ListType, class ResetCode>
|
||||
void doTest(ResetCode reset)
|
||||
{
|
||||
ListType values;
|
||||
|
||||
reset(values);
|
||||
|
||||
Pout<< nl << "before:" << flatOutput(values) << endl;
|
||||
Pstream::broadcastList(values);
|
||||
Pout<< "broadcast:" << flatOutput(values) << endl;
|
||||
|
||||
reset(values);
|
||||
|
||||
Pout<< nl << "before:" << flatOutput(values) << endl;
|
||||
Pstream::scatterList(values);
|
||||
Pout<< "scatter:" << flatOutput(values) << endl;
|
||||
|
||||
reset(values);
|
||||
|
||||
Pout<< "before:" << flatOutput(values) << endl;
|
||||
real_scatterList(values);
|
||||
Pout<< "inplace:" << flatOutput(values) << endl;
|
||||
|
||||
using control = std::pair<int, int>;
|
||||
|
||||
const char* algoType[2] = { "tree", "linear" };
|
||||
|
||||
for
|
||||
(
|
||||
auto [gather, scatter] :
|
||||
{
|
||||
control{0, 0},
|
||||
control{1, 1},
|
||||
control{0, 1},
|
||||
control{1, 0}
|
||||
}
|
||||
)
|
||||
{
|
||||
reset(values);
|
||||
|
||||
Pout<< nl << "before:" << flatOutput(values) << endl;
|
||||
|
||||
gatherList_algo(gather, values);
|
||||
Pout<< "gather[" << algoType[gather] << "]:"
|
||||
<< flatOutput(values) << endl;
|
||||
|
||||
scatterList_algo(scatter, values);
|
||||
Pout<< "scatter[" << algoType[scatter] << "]:"
|
||||
<< flatOutput(values) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addVerboseOption("increase UPstream::debug level");
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
const int optVerbose = args.verbose();
|
||||
|
||||
if (optVerbose)
|
||||
{
|
||||
UPstream::debug = optVerbose;
|
||||
}
|
||||
|
||||
Pout<< nl << "Test contiguous" << endl;
|
||||
{
|
||||
doTest<labelList>
|
||||
(
|
||||
[](auto& values){
|
||||
if (UPstream::master())
|
||||
{
|
||||
values = identity(UPstream::nProcs());
|
||||
}
|
||||
else
|
||||
{
|
||||
values.resize(UPstream::nProcs());
|
||||
values = -1;
|
||||
values[UPstream::myProcNo()] = 10 * UPstream::myProcNo();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Pout<< nl << "Test non-contiguous" << endl;
|
||||
{
|
||||
doTest<wordList>
|
||||
(
|
||||
[](auto& values) {
|
||||
values.resize(UPstream::nProcs());
|
||||
if (UPstream::master())
|
||||
{
|
||||
forAll(values, i)
|
||||
{
|
||||
values[i] = "proc" + Foam::name(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
values = "none";
|
||||
values[UPstream::myProcNo()] =
|
||||
"_" + Foam::name(UPstream::myProcNo());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Test dummy broadcast as well
|
||||
Pout<< nl << "Test broadcastList" << endl;
|
||||
{
|
||||
wordList list;
|
||||
|
||||
Pout<< nl << "before: " << flatOutput(list) << endl;
|
||||
|
||||
Pstream::broadcastList(list);
|
||||
Pout<< "-> " << flatOutput(list) << endl;
|
||||
}
|
||||
|
||||
// Test in-place reduce
|
||||
Pout<< nl << "Test in-place reduce" << endl;
|
||||
{
|
||||
FixedList<label, 6> list;
|
||||
list = UPstream::myProcNo();
|
||||
|
||||
Pout<< nl << "before: " << flatOutput(list) << endl;
|
||||
|
||||
UPstream::mpiReduce
|
||||
(
|
||||
list.data(),
|
||||
list.size(),
|
||||
UPstream::opCodes::op_sum,
|
||||
UPstream::worldComm
|
||||
);
|
||||
|
||||
Pout<< "-> " << flatOutput(list) << endl;
|
||||
}
|
||||
|
||||
Info<< nl << "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
3
applications/test/globalIndex3/Make/files
Normal file
3
applications/test/globalIndex3/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-globalIndex3.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-globalIndex3
|
||||
4
applications/test/globalIndex3/Make/options
Normal file
4
applications/test/globalIndex3/Make/options
Normal file
@ -0,0 +1,4 @@
|
||||
include $(GENERAL_RULES)/mpi-rules
|
||||
|
||||
EXE_INC = $(PFLAGS) $(PINC)
|
||||
EXE_LIBS = $(PLIBS)
|
||||
578
applications/test/globalIndex3/Test-globalIndex3.cxx
Normal file
578
applications/test/globalIndex3/Test-globalIndex3.cxx
Normal file
@ -0,0 +1,578 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
Test-globalIndex3
|
||||
|
||||
Description
|
||||
Tests for globalIndex with node-wise splitting
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "globalIndex.H"
|
||||
#include "globalMeshData.H"
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "IndirectList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "Random.H"
|
||||
#include "openfoam_mpi.H"
|
||||
|
||||
// pre-scan for "-split-size NUM"
|
||||
int option_splitsize(int argc, char *argv[])
|
||||
{
|
||||
int ivalue = -1;
|
||||
for (int argi = 1; argi < argc-1; ++argi)
|
||||
{
|
||||
if (strcmp(argv[argi], "-split-size") == 0)
|
||||
{
|
||||
++argi;
|
||||
ivalue = atoi(argv[argi]);
|
||||
}
|
||||
}
|
||||
|
||||
return ivalue;
|
||||
}
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
template<class T>
|
||||
void printList(Ostream& os, const UList<T>& list)
|
||||
{
|
||||
os << list.size() << " " << flatOutput(list) << nl;
|
||||
}
|
||||
|
||||
void printGlobalIndex(Ostream& os, const globalIndex& gi)
|
||||
{
|
||||
printList(os, gi.offsets());
|
||||
}
|
||||
|
||||
|
||||
template<class ProcIDsContainer, class Type>
|
||||
void globalIndexGather
|
||||
(
|
||||
const labelUList& off, // needed on master only
|
||||
const label comm,
|
||||
const ProcIDsContainer& procIDs,
|
||||
const UList<Type>& fld,
|
||||
UList<Type>& allFld, // must be adequately sized on master
|
||||
const int tag,
|
||||
UPstream::commsTypes commsType,
|
||||
bool useWindow = false
|
||||
)
|
||||
{
|
||||
// low-level: no parRun guard
|
||||
const int masterProci = procIDs.size() ? procIDs[0] : 0;
|
||||
|
||||
// Protection for disjoint calls
|
||||
if (FOAM_UNLIKELY(!UPstream::is_rank(comm)))
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Calling with process not on the communicator"
|
||||
<< Foam::abort(FatalError);
|
||||
}
|
||||
|
||||
// Require contiguous data for non-blocking
|
||||
if constexpr (!is_contiguous_v<Type>)
|
||||
{
|
||||
if (commsType == UPstream::commsTypes::nonBlocking)
|
||||
{
|
||||
commsType = UPstream::commsTypes::scheduled;
|
||||
}
|
||||
}
|
||||
|
||||
const label startOfRequests = UPstream::nRequests();
|
||||
|
||||
|
||||
// Very hard-coded at the moment
|
||||
int returnCode = MPI_SUCCESS;
|
||||
const int nCmpts = pTraits<Type>::nComponents;
|
||||
|
||||
MPI_Win win;
|
||||
MPI_Datatype dataType = MPI_DOUBLE;
|
||||
if (useWindow)
|
||||
{
|
||||
using cmptType = typename pTraits<Type>::cmptType;
|
||||
|
||||
if (std::is_same<float, cmptType>::value)
|
||||
{
|
||||
dataType = MPI_FLOAT;
|
||||
}
|
||||
else if (std::is_same<double, cmptType>::value)
|
||||
{
|
||||
dataType = MPI_DOUBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not supported
|
||||
useWindow = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (useWindow)
|
||||
{
|
||||
MPI_Comm mpiComm =
|
||||
PstreamUtils::Cast::to_mpi(UPstream::Communicator::lookup(comm));
|
||||
|
||||
char commName[MPI_MAX_OBJECT_NAME];
|
||||
int nameLen = 0;
|
||||
|
||||
if
|
||||
(
|
||||
MPI_COMM_NULL != mpiComm
|
||||
&& MPI_SUCCESS == MPI_Comm_get_name(mpiComm, commName, &nameLen)
|
||||
&& (nameLen > 0)
|
||||
)
|
||||
{
|
||||
Pout<< "window on " << commName << nl;
|
||||
}
|
||||
|
||||
if (UPstream::myProcNo(comm) == masterProci || fld.empty())
|
||||
{
|
||||
// Collective
|
||||
returnCode = MPI_Win_create
|
||||
(
|
||||
nullptr,
|
||||
0,
|
||||
1, // disp_units
|
||||
MPI_INFO_NULL,
|
||||
mpiComm,
|
||||
&win
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Collective
|
||||
returnCode = MPI_Win_create
|
||||
(
|
||||
const_cast<char *>(fld.cdata_bytes()),
|
||||
fld.size_bytes(),
|
||||
sizeof(Type), // disp_units
|
||||
MPI_INFO_NULL,
|
||||
mpiComm,
|
||||
&win
|
||||
);
|
||||
}
|
||||
|
||||
if (MPI_SUCCESS != returnCode || MPI_WIN_NULL == win)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "MPI_Win_create() failed"
|
||||
<< Foam::abort(FatalError);
|
||||
// return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (UPstream::myProcNo(comm) == masterProci)
|
||||
{
|
||||
const label total = off.back(); // == totalSize()
|
||||
|
||||
if (allFld.size() < total)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "[out] UList size=" << allFld.size()
|
||||
<< " too small to receive " << total << nl
|
||||
<< Foam::abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// Assign my local data - respect offset information
|
||||
// so that we can request 0 entries to be copied.
|
||||
// Also handle the case where we have a slice of the full
|
||||
// list.
|
||||
{
|
||||
SubList<Type> dst(allFld, off[1]-off[0], off[0]);
|
||||
SubList<Type> src(fld, off[1]-off[0]);
|
||||
|
||||
if (!dst.empty() && (dst.data() != src.data()))
|
||||
{
|
||||
dst = src;
|
||||
}
|
||||
}
|
||||
|
||||
if (useWindow)
|
||||
{
|
||||
MPI_Win_lock_all(MPI_MODE_NOCHECK, win);
|
||||
}
|
||||
|
||||
for (label i = 1; i < procIDs.size(); ++i)
|
||||
{
|
||||
SubList<Type> slot(allFld, off[i+1]-off[i], off[i]);
|
||||
|
||||
if (slot.empty())
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
else if (useWindow)
|
||||
{
|
||||
returnCode = MPI_Get
|
||||
(
|
||||
// origin
|
||||
slot.data(),
|
||||
slot.size()*(nCmpts),
|
||||
dataType,
|
||||
|
||||
// target
|
||||
procIDs[i],
|
||||
0, // displacement
|
||||
slot.size()*(nCmpts),
|
||||
dataType,
|
||||
win
|
||||
);
|
||||
|
||||
if (MPI_SUCCESS != returnCode)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "MPI_Get failed"
|
||||
<< Foam::abort(FatalError);
|
||||
// return nullptr;
|
||||
}
|
||||
}
|
||||
else if constexpr (is_contiguous_v<Type>)
|
||||
{
|
||||
UIPstream::read
|
||||
(
|
||||
commsType,
|
||||
procIDs[i],
|
||||
slot,
|
||||
tag,
|
||||
comm
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream::recv(slot, procIDs[i], tag, comm);
|
||||
}
|
||||
}
|
||||
|
||||
if (useWindow)
|
||||
{
|
||||
MPI_Win_unlock_all(win);
|
||||
}
|
||||
}
|
||||
else if (!useWindow)
|
||||
{
|
||||
if (fld.empty())
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
else if constexpr (is_contiguous_v<Type>)
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
commsType,
|
||||
masterProci,
|
||||
fld,
|
||||
tag,
|
||||
comm
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream::send(fld, commsType, masterProci, tag, comm);
|
||||
}
|
||||
}
|
||||
|
||||
if (useWindow)
|
||||
{
|
||||
// Collective
|
||||
MPI_Win_free(&win);
|
||||
}
|
||||
|
||||
if (commsType == UPstream::commsTypes::nonBlocking)
|
||||
{
|
||||
// Wait for outstanding requests
|
||||
UPstream::waitRequests(startOfRequests);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Report inter-node/intra-node offsets
|
||||
static void reportOffsets(const globalIndex& gi)
|
||||
{
|
||||
labelList interNodeOffsets;
|
||||
labelList localNodeOffsets;
|
||||
labelRange nodeRange;
|
||||
|
||||
const label numProc = UPstream::nProcs(UPstream::commConstWorld());
|
||||
|
||||
gi.splitNodeOffsets
|
||||
(
|
||||
interNodeOffsets,
|
||||
localNodeOffsets,
|
||||
UPstream::worldComm
|
||||
);
|
||||
|
||||
const auto interNodeComm = UPstream::commInterNode();
|
||||
|
||||
// Only communicate to the node leaders
|
||||
labelList allOffsets;
|
||||
if (UPstream::is_rank(interNodeComm))
|
||||
{
|
||||
// Send top-level offsets to the node leaders
|
||||
if (UPstream::master(interNodeComm))
|
||||
{
|
||||
allOffsets = gi.offsets();
|
||||
}
|
||||
else // ie, UPstream::is_subrank(interNodeComm)
|
||||
{
|
||||
allOffsets.resize_nocopy(numProc+1);
|
||||
}
|
||||
|
||||
UPstream::broadcast
|
||||
(
|
||||
allOffsets.data(),
|
||||
allOffsets.size(),
|
||||
interNodeComm
|
||||
);
|
||||
}
|
||||
|
||||
// Ranges (node leaders only)
|
||||
if (UPstream::is_rank(interNodeComm))
|
||||
{
|
||||
const auto& procIds = UPstream::procID(interNodeComm);
|
||||
const int ranki = UPstream::myProcNo(interNodeComm);
|
||||
|
||||
// For reporting
|
||||
nodeRange.reset
|
||||
(
|
||||
procIds[ranki],
|
||||
(
|
||||
(ranki+1 < procIds.size() ? procIds[ranki+1] : numProc)
|
||||
- procIds[ranki]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Pout<< "node-range: " << nodeRange << nl;
|
||||
Pout<< "all-offset: "; printList(Pout, allOffsets);
|
||||
Pout<< "inter-offset: "; printList(Pout, interNodeOffsets);
|
||||
Pout<< "intra-offset: "; printList(Pout, localNodeOffsets);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void globalIndexGather
|
||||
(
|
||||
const globalIndex& gi,
|
||||
const UList<Type>& sendData,
|
||||
List<Type>& allData,
|
||||
const int tag,
|
||||
const UPstream::commsTypes commsType,
|
||||
const label comm = UPstream::worldComm,
|
||||
bool useWindow = false
|
||||
)
|
||||
{
|
||||
if (!UPstream::parRun())
|
||||
{
|
||||
// Serial: direct copy
|
||||
allData = sendData;
|
||||
return;
|
||||
}
|
||||
|
||||
if (UPstream::master(comm))
|
||||
{
|
||||
allData.resize_nocopy(gi.offsets().back()); // == totalSize()
|
||||
}
|
||||
else
|
||||
{
|
||||
allData.clear(); // zero-size on non-master
|
||||
}
|
||||
|
||||
|
||||
const auto& offsets = gi.offsets(); // needed on master only
|
||||
|
||||
Info<< "Using node-comms: " << UPstream::usingNodeComms(comm) << nl;
|
||||
|
||||
const auto interNodeComm = UPstream::commInterNode();
|
||||
const auto localNodeComm = UPstream::commLocalNode();
|
||||
|
||||
if (UPstream::usingNodeComms(comm))
|
||||
{
|
||||
// Stage 0 : The inter-node/intra-node offsets
|
||||
labelList interNodeOffsets;
|
||||
labelList localNodeOffsets;
|
||||
|
||||
gi.splitNodeOffsets(interNodeOffsets, localNodeOffsets, comm);
|
||||
|
||||
// The first node re-uses the output (allData) when collecting
|
||||
// content. All other nodes require temporary node-local storage.
|
||||
|
||||
List<Type> tmpNodeData;
|
||||
if (UPstream::is_subrank(interNodeComm))
|
||||
{
|
||||
tmpNodeData.resize(localNodeOffsets.back());
|
||||
}
|
||||
|
||||
List<Type>& nodeData =
|
||||
(
|
||||
UPstream::master(interNodeComm) ? allData : tmpNodeData
|
||||
);
|
||||
|
||||
|
||||
// Stage 1 : Gather data within the node
|
||||
{
|
||||
globalIndexGather
|
||||
(
|
||||
localNodeOffsets, // (master only)
|
||||
localNodeComm,
|
||||
UPstream::allProcs(localNodeComm),
|
||||
sendData,
|
||||
nodeData,
|
||||
tag,
|
||||
commsType,
|
||||
useWindow
|
||||
);
|
||||
}
|
||||
|
||||
// Stage 2 : Gather data between nodes
|
||||
if (UPstream::is_rank(interNodeComm))
|
||||
{
|
||||
globalIndexGather
|
||||
(
|
||||
interNodeOffsets, // (master only)
|
||||
interNodeComm,
|
||||
UPstream::allProcs(interNodeComm),
|
||||
nodeData,
|
||||
allData,
|
||||
tag,
|
||||
commsType,
|
||||
useWindow
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
globalIndexGather
|
||||
(
|
||||
offsets, // needed on master only
|
||||
comm,
|
||||
UPstream::allProcs(comm), // All communicator ranks
|
||||
sendData,
|
||||
allData,
|
||||
tag,
|
||||
commsType,
|
||||
useWindow
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addVerboseOption("Set UPstream::debug level");
|
||||
argList::addOption("split-size", "NUM", "split with ncores/node");
|
||||
argList::addBoolOption("builtin", "only use builtin globalIndex::gather");
|
||||
argList::addBoolOption("window", "get data via window");
|
||||
|
||||
// Check -verbose before initialisation
|
||||
UPstream::debug = argList::verbose(argc, argv);
|
||||
|
||||
// Check -split-size before initialisation
|
||||
{
|
||||
int splitSize = option_splitsize(argc, argv);
|
||||
|
||||
if (splitSize >= 0)
|
||||
{
|
||||
UPstream::nodeCommsControl_ = splitSize;
|
||||
}
|
||||
}
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
const bool useLocalComms = UPstream::usingNodeComms(UPstream::worldComm);
|
||||
bool useWindow = args.found("window");
|
||||
bool useBuiltin = args.found("builtin");
|
||||
|
||||
Info<< nl
|
||||
<< "Getting local-comms: " << Switch::name(useLocalComms) << nl
|
||||
<< "Getting data with window: " << Switch::name(useWindow) << nl
|
||||
<< nl;
|
||||
|
||||
if (useWindow && useBuiltin)
|
||||
{
|
||||
Info<< "Selected '-window' and '-builtin' : ignoring -builtin'"
|
||||
<< nl;
|
||||
useBuiltin = false;
|
||||
}
|
||||
|
||||
Random rng(31 + 2*UPstream::myProcNo());
|
||||
|
||||
const label localSize = (5*rng.position<label>(1, 15));
|
||||
|
||||
globalIndex globIndex
|
||||
(
|
||||
globalIndex::gatherOnly{},
|
||||
localSize,
|
||||
UPstream::commWorld()
|
||||
);
|
||||
|
||||
Info<< "global-index: ";
|
||||
printGlobalIndex(Info, globIndex);
|
||||
reportOffsets(globIndex);
|
||||
|
||||
Field<scalar> allData;
|
||||
Field<scalar> localFld(localSize, scalar(UPstream::myProcNo()));
|
||||
|
||||
if (useBuiltin)
|
||||
{
|
||||
globIndex.gather
|
||||
(
|
||||
localFld,
|
||||
allData,
|
||||
UPstream::msgType(),
|
||||
UPstream::commsTypes::nonBlocking,
|
||||
UPstream::commWorld()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
globalIndexGather
|
||||
(
|
||||
globIndex,
|
||||
localFld,
|
||||
allData,
|
||||
UPstream::msgType(),
|
||||
UPstream::commsTypes::nonBlocking,
|
||||
UPstream::commWorld(),
|
||||
useWindow
|
||||
);
|
||||
}
|
||||
|
||||
Pout<< "local: " << flatOutput(localFld) << nl;
|
||||
Info<< "field: " << flatOutput(allData) << nl;
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -31,13 +31,12 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "tensor.H"
|
||||
#include "symmTensor.H"
|
||||
#include "transform.H"
|
||||
#include "unitConversion.H"
|
||||
#include "Random.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
#include "sigFpe.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -3,4 +3,5 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume
|
||||
-lfiniteVolume \
|
||||
-lmeshTools
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-DiagonalMatrix.C
|
||||
Test-DiagonalMatrix.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-DiagonalMatrix
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -36,10 +36,9 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "DiagonalMatrix.H"
|
||||
#include "RectangularMatrix.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
#include "TestTools.H"
|
||||
|
||||
using namespace Foam;
|
||||
@ -173,24 +172,23 @@ void test_global_funcs(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -205,8 +203,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"DiagonalMatrix<floatScalar>",
|
||||
"DiagonalMatrix<doubleScalar>",
|
||||
"DiagonalMatrix<float>",
|
||||
"DiagonalMatrix<double>",
|
||||
"DiagonalMatrix<complex>"
|
||||
});
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-EigenMatrix.C
|
||||
Test-EigenMatrix.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-EigenMatrix
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is derivative work of OpenFOAM.
|
||||
@ -36,10 +36,10 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "scalarMatrices.H"
|
||||
#include "RectangularMatrix.H"
|
||||
#include "SquareMatrix.H"
|
||||
#include "complex.H"
|
||||
#include "IOmanip.H"
|
||||
#include "EigenMatrix.H"
|
||||
#include "TestTools.H"
|
||||
@ -335,27 +335,26 @@ void test_eigenvectors(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test eigenvalues: "<< typeID[I] <<" ##" << nl;
|
||||
test_eigenvalues(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test eigenvectors: "<< typeID[I] <<" ##" << nl;
|
||||
test_eigenvectors(std::get<I>(types));
|
||||
Info<< nl << " ## Test eigenvalues: " << name << " ##" << nl;
|
||||
test_eigenvalues(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test eigenvectors: " << name << " ##" << nl;
|
||||
test_eigenvectors(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -372,8 +371,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"SquareMatrix<floatScalar>",
|
||||
"SquareMatrix<doubleScalar>"
|
||||
"SquareMatrix<float>",
|
||||
"SquareMatrix<double>"
|
||||
});
|
||||
|
||||
run_tests(types, typeID);
|
||||
@ -539,3 +538,6 @@ int main()
|
||||
Info<< nl << " #### Passed all " << nTest_ <<" tests ####\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,3 +1,3 @@
|
||||
Test-Matrix.C
|
||||
Test-Matrix.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-Matrix
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-QRMatrix.C
|
||||
Test-QRMatrix.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-QRMatrix
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -32,9 +32,9 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "MatrixTools.H"
|
||||
#include "QRMatrix.H"
|
||||
#include "complex.H"
|
||||
#include "IOmanip.H"
|
||||
#include "TestTools.H"
|
||||
|
||||
@ -533,21 +533,20 @@ void test_decomposition(MatrixType)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test decomposition: "<< typeID[I] <<" ##" << nl;
|
||||
test_decomposition(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test decomposition: " << name << " ##" << nl;
|
||||
test_decomposition(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -570,9 +569,9 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"RectangularMatrix<doubleScalar>",
|
||||
"RectangularMatrix<double>",
|
||||
"RectangularMatrix<complex>",
|
||||
"SquareMatrix<doubleScalar>",
|
||||
"SquareMatrix<double>",
|
||||
"SquareMatrix<complex>"
|
||||
});
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-RectangularMatrix.C
|
||||
Test-RectangularMatrix.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-RectangularMatrix
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -42,10 +42,9 @@ Note
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "RectangularMatrix.H"
|
||||
#include "SquareMatrix.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
#include "IOmanip.H"
|
||||
#include "TestTools.H"
|
||||
|
||||
@ -809,36 +808,34 @@ void test_global_opers(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member opers: " << name << " ##" << nl;
|
||||
test_member_opers(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl;
|
||||
test_friend_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
|
||||
test_friend_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Main Program * * * * * * * * * * * * * * * //
|
||||
|
||||
int main()
|
||||
@ -852,8 +849,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"RectangularMatrix<floatScalar>",
|
||||
"RectangularMatrix<doubleScalar>",
|
||||
"RectangularMatrix<float>",
|
||||
"RectangularMatrix<double>",
|
||||
"RectangularMatrix<complex>"
|
||||
});
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-SquareMatrix.C
|
||||
Test-SquareMatrix.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-SquareMatrix
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -42,11 +42,10 @@ Note
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "scalarMatrices.H"
|
||||
#include "RectangularMatrix.H"
|
||||
#include "SquareMatrix.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
#include "IOmanip.H"
|
||||
#include "TestTools.H"
|
||||
|
||||
@ -932,33 +931,32 @@ void test_global_opers(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member opers: " << name << " ##" << nl;
|
||||
test_member_opers(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl;
|
||||
test_friend_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
|
||||
test_friend_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -975,8 +973,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"SquareMatrix<floatScalar>",
|
||||
"SquareMatrix<doubleScalar>",
|
||||
"SquareMatrix<float>",
|
||||
"SquareMatrix<double>",
|
||||
"SquareMatrix<complex>"
|
||||
});
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-SymmetricSquareMatrix.C
|
||||
Test-SymmetricSquareMatrix.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-SymmetricSquareMatrix
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -42,12 +42,11 @@ Note
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "complex.H"
|
||||
#include "scalarMatrices.H"
|
||||
#include "RectangularMatrix.H"
|
||||
#include "SquareMatrix.H"
|
||||
#include "SymmetricSquareMatrix.H"
|
||||
#include "scalar.H"
|
||||
#include "complex.H"
|
||||
#include "IOmanip.H"
|
||||
#include "Random.H"
|
||||
#include "TestTools.H"
|
||||
@ -138,33 +137,32 @@ void test_global_opers(Type)
|
||||
|
||||
// Do compile-time recursion over the given types
|
||||
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){}
|
||||
|
||||
|
||||
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)
|
||||
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
|
||||
{
|
||||
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
if constexpr (I < sizeof...(Tp))
|
||||
{
|
||||
const auto& name = names[I];
|
||||
|
||||
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
|
||||
test_constructors(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl;
|
||||
test_member_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
|
||||
test_member_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test member opers: " << name << " ##" << nl;
|
||||
test_member_opers(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
|
||||
test_global_funcs(std::get<I>(types));
|
||||
|
||||
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl;
|
||||
test_friend_funcs(std::get<I>(types));
|
||||
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
|
||||
test_global_opers(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, typeID);
|
||||
Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
|
||||
test_friend_funcs(std::get<I>(types));
|
||||
|
||||
run_tests<I + 1, Tp...>(types, names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -181,8 +179,8 @@ int main()
|
||||
|
||||
const List<word> typeID
|
||||
({
|
||||
"SymmetricSquareMatrix<floatScalar>",
|
||||
"SymmetricSquareMatrix<doubleScalar>",
|
||||
"SymmetricSquareMatrix<float>",
|
||||
"SymmetricSquareMatrix<double>",
|
||||
"SymmetricSquareMatrix<complex>"
|
||||
});
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-minMax1.C
|
||||
Test-minMax1.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-minMax1
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -170,8 +170,19 @@ int main(int argc, char *argv[])
|
||||
|
||||
values1 *= (Pstream::myProcNo()+1);
|
||||
|
||||
Pout<<"min-max of " << flatOutput(values1) << " = "
|
||||
<< minMax(values1) << endl;
|
||||
{
|
||||
auto limits = minMax(values1);
|
||||
|
||||
Pout<<"min-max of " << flatOutput(values1) << " = "
|
||||
<< limits << endl;
|
||||
|
||||
// add in some more values
|
||||
limits.add(-100, 10, 1000, 500, 800);
|
||||
|
||||
limits.add(-120, 1200);
|
||||
|
||||
Pout<<"with more values: " << limits << endl;
|
||||
}
|
||||
|
||||
// Construct from values
|
||||
MinMax<scalar> minmax1(values1);
|
||||
@ -182,10 +193,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
minmax1 += values1;
|
||||
Pout<<"range: " << minmax1 << endl;
|
||||
|
||||
|
||||
Info<< "Reduced: "<< returnReduce(minmax1, plusOp<scalarMinMax>()) << nl;
|
||||
Info<< "Reduced: "<< returnReduce(minmax1, minMaxOp<scalar>()) << nl;
|
||||
|
||||
// Info<< "gMinMax: "<< gMinMax(values1v) << nl;
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-minMax2.C
|
||||
Test-minMax2.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-minMax2
|
||||
|
||||
3
applications/test/nodeTopology/Make/files
Normal file
3
applications/test/nodeTopology/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-nodeTopology.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-nodeTopology
|
||||
2
applications/test/nodeTopology/Make/options
Normal file
2
applications/test/nodeTopology/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
172
applications/test/nodeTopology/Test-nodeTopology.cxx
Normal file
172
applications/test/nodeTopology/Test-nodeTopology.cxx
Normal file
@ -0,0 +1,172 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
Test-nodeTopology
|
||||
|
||||
Description
|
||||
Simple reporting of node topology
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "IOstreams.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noBanner();
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addOption
|
||||
(
|
||||
"numProcs",
|
||||
"int",
|
||||
"Num of ranks to simulate (default: 16)"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"cores",
|
||||
"int",
|
||||
"Num of cores to simulate (default: 4)"
|
||||
);
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
label nProcs = UPstream::nProcs(UPstream::worldComm);
|
||||
|
||||
DynamicList<int> fake_interNode_offsets;
|
||||
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
if (args.found("numProcs"))
|
||||
{
|
||||
InfoErr<< "ignoring -numProcs option in parallel" << nl;
|
||||
}
|
||||
if (args.found("cores"))
|
||||
{
|
||||
InfoErr<< "ignoring -cores option in parallel" << nl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// serial
|
||||
nProcs = args.getOrDefault<label>("numProcs", 16);
|
||||
label nCores = args.getOrDefault<label>("cores", 4);
|
||||
|
||||
auto& interNode_offsets = fake_interNode_offsets;
|
||||
|
||||
if (nCores > 1 && nCores < nProcs)
|
||||
{
|
||||
// Build the inter-node offsets
|
||||
interNode_offsets.reserve((nProcs/nCores) + 4);
|
||||
interNode_offsets.push_back(0);
|
||||
|
||||
for
|
||||
(
|
||||
int count = interNode_offsets.back() + nCores;
|
||||
count < nProcs;
|
||||
count += nCores
|
||||
)
|
||||
{
|
||||
interNode_offsets.push_back(count);
|
||||
}
|
||||
|
||||
interNode_offsets.push_back(nProcs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some fallback
|
||||
interNode_offsets.reserve(2);
|
||||
interNode_offsets.push_back(0);
|
||||
interNode_offsets.push_back(nProcs);
|
||||
}
|
||||
}
|
||||
|
||||
const List<int>& interNodeOffsets =
|
||||
(
|
||||
UPstream::parRun()
|
||||
? UPstream::interNode_offsets()
|
||||
: fake_interNode_offsets
|
||||
);
|
||||
|
||||
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
const auto& procs = UPstream::localNode_parentProcs();
|
||||
Perr<< "local processors: [" << procs.min()
|
||||
<< ".." << procs.max() << ']' << endl;
|
||||
}
|
||||
|
||||
// Generate the graph
|
||||
if (UPstream::master(UPstream::worldComm))
|
||||
{
|
||||
auto& os = Info.stream();
|
||||
|
||||
os << "// node topology graph:" << nl;
|
||||
os.beginBlock("graph");
|
||||
|
||||
// Prefer left-to-right layout for large graphs
|
||||
os << indent << "rankdir=LR" << nl;
|
||||
|
||||
const label numNodes = interNodeOffsets.size()-1;
|
||||
|
||||
// First level are the inter-node connections
|
||||
{
|
||||
os << indent << 0 << " -- " << token::LBRACE;
|
||||
|
||||
for (label nodei = 1; nodei < numNodes; ++nodei)
|
||||
{
|
||||
os << ' ' << interNodeOffsets[nodei];
|
||||
}
|
||||
|
||||
os << token::SPACE << token::RBRACE
|
||||
<< " // inter-node: " << flatOutput(interNodeOffsets)
|
||||
<< nl;
|
||||
}
|
||||
|
||||
// Next level are the local-node connections
|
||||
for (label nodei = 0; nodei < numNodes; ++nodei)
|
||||
{
|
||||
const auto firstProc = interNodeOffsets[nodei];
|
||||
const auto lastProc = interNodeOffsets[nodei+1];
|
||||
|
||||
os << indent << firstProc << " -- " << token::DQUOTE
|
||||
<< (firstProc+1) << ".." << (lastProc-1)
|
||||
<< token::DQUOTE << nl;
|
||||
}
|
||||
|
||||
os.endBlock();
|
||||
os << "// end graph" << nl;
|
||||
}
|
||||
|
||||
InfoErr << "\nDone" << nl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
3
applications/test/one-sided1/Make/files
Normal file
3
applications/test/one-sided1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-one-sided1.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-one-sided1
|
||||
2
applications/test/one-sided1/Make/options
Normal file
2
applications/test/one-sided1/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
354
applications/test/one-sided1/Test-one-sided1.cxx
Normal file
354
applications/test/one-sided1/Test-one-sided1.cxx
Normal file
@ -0,0 +1,354 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
Test-one-sided1
|
||||
|
||||
Description
|
||||
Simple test of one-sided communication
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "IPstream.H"
|
||||
#include "OPstream.H"
|
||||
#include "SubField.H"
|
||||
#include "vector.H"
|
||||
#include "IOstreams.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
template<class T>
|
||||
Ostream& printSpanInfo(Ostream& os, const UList<T>& span)
|
||||
{
|
||||
os << "addr=" << Foam::name(span.cdata())
|
||||
<< " size= " << span.size();
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addVerboseOption();
|
||||
argList::addBoolOption("no-shared", "disable shared memory tests");
|
||||
argList::addBoolOption("no-sleep", "disable sleep for async test");
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
const bool with_shared = !args.found("no-shared");
|
||||
const bool with_sleep = !args.found("no-sleep");
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< nl
|
||||
<< "nProcs = " << UPstream::nProcs()
|
||||
<< " with " << UPstream::nComms() << " predefined comm(s)" << nl;
|
||||
|
||||
if (!UPstream::parRun())
|
||||
{
|
||||
Info<< "###############" << nl
|
||||
<< "Not running in parallel. Stopping now" << nl
|
||||
<< "###############" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const auto myProci = UPstream::myProcNo();
|
||||
const auto numProc = UPstream::nProcs();
|
||||
|
||||
// Make some windows
|
||||
Field<label> buffer(10 + myProci);
|
||||
buffer = myProci;
|
||||
|
||||
Pout<< "input: " << flatOutput(buffer) << endl;
|
||||
|
||||
UPstream::Window win;
|
||||
win.create(buffer, UPstream::worldComm);
|
||||
|
||||
// Pass 1
|
||||
// - grab things from sub-ranks
|
||||
if (UPstream::master())
|
||||
{
|
||||
win.lock_all(true);
|
||||
|
||||
win.get
|
||||
(
|
||||
buffer.slice(4, 2),
|
||||
1, // target_rank
|
||||
2 // target_disp
|
||||
);
|
||||
|
||||
win.unlock_all();
|
||||
}
|
||||
|
||||
Pout<< "output: " << flatOutput(buffer) << endl;
|
||||
|
||||
// Pass 2:
|
||||
// accumulate into master
|
||||
if (UPstream::is_subrank())
|
||||
{
|
||||
win.lock(0);
|
||||
|
||||
win.put
|
||||
(
|
||||
UPstream::opCodes::op_sum,
|
||||
buffer.slice(2, 4),
|
||||
UPstream::masterNo(),
|
||||
2 // target_disp
|
||||
);
|
||||
|
||||
win.unlock(0);
|
||||
}
|
||||
|
||||
Pout<< "updated: " << flatOutput(buffer) << endl;
|
||||
|
||||
// Pass 3:
|
||||
// Update some values - something very asynchronous
|
||||
if (UPstream::is_subrank())
|
||||
{
|
||||
if (with_sleep)
|
||||
{
|
||||
if (UPstream::myProcNo() % 3)
|
||||
{
|
||||
Foam::sleep(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
Foam::sleep(1);
|
||||
}
|
||||
}
|
||||
buffer *= 10;
|
||||
forAll(buffer, i)
|
||||
{
|
||||
buffer[i] *= 1 + (i % 3);
|
||||
}
|
||||
}
|
||||
|
||||
// Needs a process sync, otherwise master fetches old values
|
||||
UPstream::barrier(UPstream::worldComm);
|
||||
|
||||
label lastValue(-1);
|
||||
|
||||
if (UPstream::master())
|
||||
{
|
||||
win.lock_all(true);
|
||||
|
||||
for (const auto proci : UPstream::subProcs())
|
||||
{
|
||||
win.fetch_and_op
|
||||
(
|
||||
UPstream::opCodes::op_sum,
|
||||
buffer[0],
|
||||
lastValue,
|
||||
proci,
|
||||
2 // target_disp
|
||||
);
|
||||
}
|
||||
|
||||
// Force changes to occur
|
||||
win.flush_all();
|
||||
win.unlock_all();
|
||||
}
|
||||
|
||||
|
||||
Pout<< "last-value : " << lastValue << nl
|
||||
<< "final : " << flatOutput(buffer) << endl;
|
||||
|
||||
labelList allUpdates;
|
||||
|
||||
if (UPstream::master())
|
||||
{
|
||||
allUpdates.resize(UPstream::nProcs(), -10);
|
||||
|
||||
win.lock_all(true);
|
||||
|
||||
for (const auto proci : UPstream::subProcs())
|
||||
{
|
||||
win.get_value
|
||||
(
|
||||
allUpdates[proci],
|
||||
proci,
|
||||
2 // target_disp
|
||||
);
|
||||
}
|
||||
|
||||
win.flush_all();
|
||||
win.unlock_all();
|
||||
}
|
||||
|
||||
Info<< "gets: " << flatOutput(allUpdates) << endl;
|
||||
|
||||
|
||||
// This should fail (runtime)
|
||||
#if 0
|
||||
if (UPstream::master())
|
||||
{
|
||||
labelPair value1(-1, -1);
|
||||
|
||||
win.lock_all(true);
|
||||
|
||||
for (const auto proci : UPstream::subProcs())
|
||||
{
|
||||
win.fetch_and_op
|
||||
(
|
||||
UPstream::opCodes::op_sum,
|
||||
value1,
|
||||
lastValue,
|
||||
proci,
|
||||
8 // target_disp
|
||||
);
|
||||
}
|
||||
|
||||
win.unlock_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Last thing before closing out
|
||||
// replace values. Not very efficient...
|
||||
|
||||
// Persistent data to move onto target:
|
||||
const label newValue(333);
|
||||
const label multiplier(-3);
|
||||
|
||||
if (UPstream::master())
|
||||
{
|
||||
win.lock_all(true);
|
||||
|
||||
for (const auto proci : UPstream::subProcs())
|
||||
{
|
||||
win.fetch_and_op
|
||||
(
|
||||
UPstream::opCodes::op_replace,
|
||||
newValue,
|
||||
lastValue,
|
||||
proci, // target_rank
|
||||
3 // target_disp
|
||||
);
|
||||
|
||||
win.put_value
|
||||
(
|
||||
UPstream::opCodes::op_prod,
|
||||
multiplier,
|
||||
proci, // target_rank
|
||||
5 // target_disp
|
||||
);
|
||||
}
|
||||
win.unlock_all();
|
||||
}
|
||||
|
||||
win.close(); // process collective
|
||||
|
||||
Pout<< "modified: " << flatOutput(buffer) << endl;
|
||||
|
||||
if (with_shared)
|
||||
{
|
||||
// Make some shared window
|
||||
UList<label> newBuffer;
|
||||
|
||||
{
|
||||
label localLen(0);
|
||||
|
||||
if
|
||||
(
|
||||
(myProci == 3)
|
||||
|| (myProci == numProc-2)
|
||||
)
|
||||
{
|
||||
localLen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
localLen = (10 + UPstream::myProcNo());
|
||||
}
|
||||
|
||||
// Just to prove that we can shallow copy the view...
|
||||
newBuffer =
|
||||
win.allocate_shared<label>(localLen, UPstream::worldComm);
|
||||
}
|
||||
|
||||
newBuffer = UPstream::myProcNo();
|
||||
|
||||
Pout<< "Shared: " << flatOutput(newBuffer) << endl;
|
||||
|
||||
{
|
||||
UList<label> local = win.view<label>();
|
||||
Pout<< "local win: ";
|
||||
printSpanInfo(Pout, local) << endl;
|
||||
}
|
||||
|
||||
Pout<< "Query rank1" << endl;
|
||||
|
||||
{
|
||||
// UPtrList<UList<label>> totalList(UPstream::nProcs());
|
||||
//
|
||||
// totalList.set(0, &newBuffer);
|
||||
|
||||
const label* ptr0 = nullptr;
|
||||
|
||||
{
|
||||
UList<label> buf = win.view_shared<label>(0);
|
||||
ptr0 = buf.cdata();
|
||||
|
||||
Pout<< "addr 0 = " << Foam::name(ptr0)
|
||||
<< " diff = " << label(0)
|
||||
<< " + " << buf.size() << endl;
|
||||
}
|
||||
|
||||
// UList<label> other = win.global_view<label>();
|
||||
|
||||
for (const auto proci : UPstream::subProcs())
|
||||
{
|
||||
UList<label> other = win.view_shared<label>(proci);
|
||||
|
||||
const label* ptr = other.cdata();
|
||||
|
||||
Pout<< "addr " << proci << " = "
|
||||
<< Foam::name(ptr)
|
||||
<< " diff = " << label(ptr - ptr0)
|
||||
<< " + " << other.size() << endl;
|
||||
// totalList.set(proci, &other);
|
||||
}
|
||||
}
|
||||
|
||||
win.close();
|
||||
}
|
||||
|
||||
// Since close() is ignored on null window,
|
||||
// can call it an arbitrary number of times
|
||||
win.close();
|
||||
win.close();
|
||||
win.close();
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,2 +1,3 @@
|
||||
Test-pTraits.C
|
||||
Test-pTraits.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-pTraits
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2023 OpenCFD Ltd.
|
||||
Copyright (C) 2023-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -32,9 +32,11 @@ Description
|
||||
#include "pTraits.H"
|
||||
#include "contiguous.H"
|
||||
#include "boolVector.H" // A FixedList pretending to be a vector
|
||||
#include "complex.H"
|
||||
#include "vector.H"
|
||||
#include "tensor.H"
|
||||
#include "complex.H"
|
||||
#include "sphericalTensor.H"
|
||||
#include "symmTensor.H"
|
||||
#include "uLabel.H"
|
||||
#include "Switch.H"
|
||||
|
||||
@ -50,26 +52,37 @@ template<class T, class = void>
|
||||
struct has_typeName : std::false_type {};
|
||||
|
||||
//- Test if Type has typeName member
|
||||
|
||||
template<class T>
|
||||
struct has_typeName<T, stdFoam::void_t<decltype(pTraits<T>::typeName)>>
|
||||
struct has_typeName
|
||||
<
|
||||
T,
|
||||
std::void_t<decltype(pTraits<std::remove_cv_t<T>>::typeName)>
|
||||
>
|
||||
:
|
||||
std::true_type
|
||||
{};
|
||||
|
||||
|
||||
template<class T>
|
||||
typename std::enable_if<has_typeName<T>::value, void>::type
|
||||
printTypeName()
|
||||
void printTypeName()
|
||||
{
|
||||
Info<< pTraits<T>::typeName;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
typename std::enable_if<!has_typeName<T>::value, void>::type
|
||||
printTypeName()
|
||||
{
|
||||
Info<< typeid(T).name();
|
||||
// Both float and double have pTraits typeName = "scalar"!
|
||||
if constexpr (std::is_same_v<float, std::remove_cv_t<T>>)
|
||||
{
|
||||
Info<< "<float>";
|
||||
}
|
||||
else if constexpr (std::is_same_v<double, std::remove_cv_t<T>>)
|
||||
{
|
||||
Info<< "<double>";
|
||||
}
|
||||
else if constexpr (has_typeName<T>::value)
|
||||
{
|
||||
Info<< pTraits<std::remove_cv_t<T>>::typeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< typeid(T).name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -80,23 +93,24 @@ template<class T>
|
||||
struct has_zero_one
|
||||
<
|
||||
T,
|
||||
stdFoam::void_t<decltype(pTraits<T>::zero), decltype(pTraits<T>::one)>
|
||||
std::void_t
|
||||
<
|
||||
decltype(pTraits<std::remove_cv_t<T>>::zero),
|
||||
decltype(pTraits<std::remove_cv_t<T>>::one)
|
||||
>
|
||||
> : std::true_type {};
|
||||
|
||||
|
||||
template<class T>
|
||||
typename std::enable_if<has_zero_one<T>::value, void>::type
|
||||
printMinMaxRange()
|
||||
void printMinMaxRange()
|
||||
{
|
||||
Info<< " zero=" << pTraits<T>::zero
|
||||
<< " one=" << pTraits<T>::one;
|
||||
if constexpr (has_zero_one<T>::value)
|
||||
{
|
||||
Info<< " zero=" << pTraits<std::remove_cv_t<T>>::zero
|
||||
<< " one=" << pTraits<std::remove_cv_t<T>>::one;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
typename std::enable_if<!has_zero_one<T>::value, void>::type
|
||||
printMinMaxRange()
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
void printTraits()
|
||||
@ -104,11 +118,12 @@ void printTraits()
|
||||
printTypeName<T>();
|
||||
printMinMaxRange<T>();
|
||||
|
||||
Info<< " integral=" << std::is_integral<T>::value
|
||||
<< " floating=" << std::is_floating_point<T>::value
|
||||
Info<< " integral=" << std::is_integral_v<T>
|
||||
<< " floating=" << std::is_floating_point_v<T>
|
||||
<< " rank=" << pTraits_rank<T>::value
|
||||
<< " nComponents=" << pTraits_nComponents<T>::value
|
||||
<< " vector-space=" << Switch::name(is_vectorspace<T>::value)
|
||||
<< " vector-space=" << Switch::name(is_vectorspace_v<T>)
|
||||
<< " rotate=" << Switch::name(is_rotational_vectorspace_v<T>)
|
||||
<< " is_label=" << Switch::name(is_contiguous_label<T>::value)
|
||||
<< " is_scalar=" << Switch::name(is_contiguous_scalar<T>::value)
|
||||
<< " cmptType=" << typeid(typename pTraits_cmptType<T>::type).name()
|
||||
@ -137,9 +152,11 @@ int main()
|
||||
printTraits<bool>();
|
||||
printTraits<label>();
|
||||
printTraits<scalar>();
|
||||
printTraits<complex>(); // Uses specialized pTraits_...
|
||||
printTraits<const complex>(); // Uses specialized pTraits_...
|
||||
printTraits<floatVector>();
|
||||
printTraits<doubleVector>();
|
||||
printTraits<sphericalTensor>();
|
||||
printTraits<symmTensor>();
|
||||
printTraits<tensor>();
|
||||
printTraits<boolVector>(); // Uses specialized pTraits_...
|
||||
printTraits<word>();
|
||||
3
applications/test/parallel-barrier1/Make/files
Normal file
3
applications/test/parallel-barrier1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-parallel-barrier1.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-parallel-barrier1
|
||||
2
applications/test/parallel-barrier1/Make/options
Normal file
2
applications/test/parallel-barrier1/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
125
applications/test/parallel-barrier1/Test-parallel-barrier1.cxx
Normal file
125
applications/test/parallel-barrier1/Test-parallel-barrier1.cxx
Normal file
@ -0,0 +1,125 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
Test-parallel-barrier1
|
||||
|
||||
Description
|
||||
Simple test of local barriers communication
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "clockTime.H"
|
||||
#include "IPstream.H"
|
||||
#include "OPstream.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addVerboseOption();
|
||||
argList::addOption("delay", "sec", "Seconds to sleep (default 2)");
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
if (!UPstream::parRun())
|
||||
{
|
||||
Info<< "###############" << nl
|
||||
<< "Not running in parallel. Stopping now" << nl
|
||||
<< "###############" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const auto delay = args.getOrDefault<label>("delay", 2);
|
||||
|
||||
Info<< nl
|
||||
<< "Testing local barrier, sleep=" << delay << endl;
|
||||
|
||||
|
||||
const auto myProci = UPstream::myProcNo(UPstream::worldComm);
|
||||
const auto numProc = UPstream::nProcs(UPstream::worldComm);
|
||||
|
||||
constexpr int uniqTag = 1516;
|
||||
|
||||
clockTime timing;
|
||||
|
||||
if (UPstream::master(UPstream::worldComm))
|
||||
{
|
||||
// Wait for the last rank
|
||||
UPstream::wait_done(numProc-1, UPstream::worldComm);
|
||||
|
||||
// Wait for any other rank
|
||||
if (numProc > 2)
|
||||
{
|
||||
int from = UPstream::wait_done(-1, UPstream::worldComm, uniqTag);
|
||||
Pout<< "done signal from: " << from << endl;
|
||||
}
|
||||
}
|
||||
else if (myProci == numProc-1)
|
||||
{
|
||||
Foam::sleep(delay);
|
||||
UPstream::send_done(UPstream::masterNo(), UPstream::worldComm);
|
||||
}
|
||||
|
||||
// Cascade sequencing (and delays)
|
||||
if (numProc > 7)
|
||||
{
|
||||
if (myProci == 2)
|
||||
{
|
||||
Foam::sleep(2*delay);
|
||||
UPstream::send_done(4, UPstream::worldComm);
|
||||
}
|
||||
else if (myProci == 4)
|
||||
{
|
||||
UPstream::wait_done(2, UPstream::worldComm);
|
||||
Foam::sleep(2*delay);
|
||||
UPstream::send_done(5, UPstream::worldComm);
|
||||
}
|
||||
else if (myProci == 5)
|
||||
{
|
||||
UPstream::wait_done(4, UPstream::worldComm);
|
||||
}
|
||||
}
|
||||
|
||||
// Some arbitrary signaling rank
|
||||
if ((numProc > 2) && (myProci == numProc/2))
|
||||
{
|
||||
Pout<< "send done signal " << myProci << " -> 0" << endl;
|
||||
UPstream::send_done(UPstream::masterNo(), UPstream::worldComm, uniqTag);
|
||||
}
|
||||
|
||||
Pout<< "done: " << timing.elapsedTime() << " s" << endl;
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
Copyright (C) 2022-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -46,7 +46,7 @@ using namespace Foam;
|
||||
template<class T>
|
||||
void printPre(const T& value)
|
||||
{
|
||||
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl;
|
||||
Info<< nl << "is_contiguous:" << is_contiguous_v<T> << endl;
|
||||
Pout<< "pre-broadcast: " << value << endl;
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ void testBroadcast(T& value)
|
||||
template<class T>
|
||||
void testBroadcast(List<T>& values)
|
||||
{
|
||||
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl;
|
||||
Info<< nl << "is_contiguous:" << is_contiguous_v<T> << endl;
|
||||
Pout<< "pre-broadcast: " << flatOutput(values) << endl;
|
||||
Pstream::broadcast(values);
|
||||
Pout<< "post-broadcast: " << flatOutput(values) << endl;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user