Compare commits

..

11 Commits

Author SHA1 Message Date
e5c6ccc3d3 CONFIG: bump patch level 2025-08-14 11:04:56 +02:00
af3c9ebb5e BUG: missed removal of pointMesh/boundaryProcAddressing (fixes #3412) 2025-08-14 11:04:25 +02:00
de413eaf9c ENH: pointConstraint: work in binary mode 2025-08-14 11:04:25 +02:00
07945a519f COMP: resolve label 64 compilation ambiguity for Mingw (fixes #3390)
COMP: restrict HashTable maxTableSize to int32 range

- avoids compiler warning about possible overflow (left-shift
  operation) for label 64 compilations and we don't need anything
  larger than int32 HashTable capacity anyhow.

ENH: make nearest power-of-two non-branching (previously brute-force)
2025-08-14 11:04:25 +02:00
0bb0c1db74 BUG: plicRDF: reconstructing distance func for point neighbours (fixes #3279) 2025-05-28 12:13:52 +01:00
535a4fccb4 Merge branch 'fix-3360-wrong-addressing' into 'master'
BUG: wrong cellZone addressing in uniformityCellZone (fixes #3360)

Closes #3360

See merge request Development/openfoam!738
2025-05-13 10:36:26 +00:00
e1b04cb6a7 BUG: wrong cellZone addressing in uniformityCellZone (fixes #3360)
The mean value, variance and volume fields for each zone were accessed
using the wrong indices
2025-05-13 11:29:18 +03:00
b7ce6bf69d CONFIG: inject -no-recursion into the argument list (#3198)
- sourcing a file with '-no-recursion "$@"' does not work with dash.
  Need to modify the argument list directly.
2025-03-19 15:28:57 +01:00
0a53013499 BUG: foamReport mesh quantities are not parallel (fixes #3338) 2025-03-17 11:53:23 +01:00
47f2ff618d COMP: remove obsolete -fsimdmath flag for ARM64 (#3326) 2025-03-17 09:59:42 +01:00
47575aabf2 COMP: compilation with clang (c++17) and older flex files (fixes #3337)
- The register keyword has been removed from c++17 but old flex
  versions (version < 2.6.0) produce code including it, leading to
  compilation errors when using clang (despite disabling the diagnostic).
  gcc compiles but issues warnings.

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2025 OpenCFD Ltd.
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,12 +25,9 @@ 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++17 -oTest-machine-sizes Test-machine-sizes.cpp
g++ -std=c++11 -oTest-machine-sizes Test-machine-sizes.cpp
\*---------------------------------------------------------------------------*/
@ -40,114 +37,6 @@ 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
{
// Builtin Types [8]:
DataTypes_begin, //!< Begin builtin types (internal use)
type_byte = DataTypes_begin, // also for char, unsigned char
type_int32,
type_int64,
type_uint32,
type_uint64,
type_float,
type_double,
type_long_double,
invalid
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Partial copy from UPstreamTraits.H
//- A supported UPstream data type (intrinsic or user-defined)
template<class T>
struct UPstream_base_dataType : std::false_type
{
static constexpr auto datatype_id = dataTypes::invalid;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Specializations of the above,
// each to match the elements of UPstream::dataTypes
#undef defineUPstreamDataTraits
#define defineUPstreamDataTraits(TypeId, Type) \
template<> struct UPstream_base_dataType<Type> : std::true_type \
{ \
static constexpr auto datatype_id = dataTypes::TypeId; \
};
defineUPstreamDataTraits(type_byte, char);
defineUPstreamDataTraits(type_byte, unsigned char);
defineUPstreamDataTraits(type_int32, int32_t);
defineUPstreamDataTraits(type_int64, int64_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
<
// Base type (no alias needed)
UPstream_base_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))
)
>
{
// Is it using the base type? (no alias needed)
static constexpr bool is_base =
UPstream_base_dataType<std::remove_cv_t<T>>::value;
using base = std::conditional_t
<
UPstream_base_dataType<std::remove_cv_t<T>>::value, // is_base
std::remove_cv_t<T>,
std::conditional_t
<
(
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 value (assuming it is contiguous)
>
>;
static constexpr auto datatype_id =
UPstream_base_dataType<base>::datatype_id;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class T>
void print(const char* name, bool showLimits = true)
@ -158,78 +47,28 @@ void print(const char* name, bool showLimits = true)
if (showLimits)
{
std::cout
<< " 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
std::cout
<< " is_mpi=" << UPstream_base_dataType<T>::value
<< " (" << int(UPstream_base_dataType<T>::datatype_id) << ")";
if (UPstream_alias_dataType<T>::value)
{
if (UPstream_alias_dataType<T>::is_base)
{
std::cout<< " is_base";
}
else
{
std::cout<< " is_alias ("
<< int(UPstream_alias_dataType<T>::datatype_id) << ")";
}
}
else
{
std::cout<< " no_alias";
<< " \"max\"=" << std::numeric_limits<T>::max();
}
std::cout<< '\n';
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
std::cout<< "c++ = " << __cplusplus << '\n';
std::cout<< "machine sizes (and some MPI traits)\n---\n\n";
std::cout<< "machine sizes\n---\n\n";
print<int8_t>("int8_t");
print<uint8_t>("uint8_t");
print<int16_t>("int16_t");
print<uint16_t>("uint16_t");
print<int32_t>("int32_t");
print<uint32_t>("uint32_t");
print<int64_t>("int64_t");
print<uint64_t>("uint64_t");
std::cout << '\n';
print<char>("char");
print<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");

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -38,11 +38,12 @@ 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;
@ -56,11 +57,45 @@ 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>
void cmp
typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
(
const word& msg,
const Type& x,
@ -69,37 +104,18 @@ void cmp
const scalar absTol = 0
)
{
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)
);
};
Info<< msg << x << endl;
unsigned nFail = 0;
if constexpr (is_vectorspace_v<Type>)
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
}
else
{
if (notEqual(x, y))
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{
++nFail;
}
}
Info<< msg << x << endl;
if (nFail)
{
Info<< nl
@ -352,26 +368,27 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
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)
{
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(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 global functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
test_global_opers(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
run_tests<I + 1, Tp...>(types, typeID);
}
@ -386,8 +403,8 @@ int main()
const List<word> typeID
({
"DiagTensor<float>",
"DiagTensor<double>",
"DiagTensor<floatScalar>",
"DiagTensor<doubleScalar>",
"DiagTensor<complex>"
});

View File

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

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -85,7 +85,8 @@ void compileInfo()
template<class FixedListType>
std::enable_if_t<(FixedListType::max_size() == 2), bool>
typename std::enable_if
<(FixedListType::max_size() == 2), bool>::type
is_pair()
{
return true;
@ -93,7 +94,7 @@ is_pair()
template<class FixedListType>
std::enable_if_t<(FixedListType::max_size() != 2), std::string>
typename std::enable_if<(FixedListType::max_size() != 2), std::string>::type
is_pair()
{
return "not really at all";

View File

@ -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.
@ -37,11 +37,30 @@ License
using namespace Foam;
void checkCanonicalSize(label size)
{
const auto n = HashTableCore::canonicalSize(size);
std::ostringstream buf;
buf.setf(std::ios_base::hex, std::ios_base::basefield);
buf << n;
Info<< "hash-table size of " << size
<< " = " << n << " (0x" << buf.str().c_str() << ')' << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
for (label size : { -1, 0, 1, 7, 500, 1024, 1025, 10000, (labelMax-1)} )
{
checkCanonicalSize(size);
}
Info<< nl;
HashTable<scalar> table1
{
{"aaa", 1.0},

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2025 OpenCFD Ltd.
Copyright (C) 2018-2021 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_v<string> << nl << nl;
Info<< "contiguous = " << is_contiguous<string>::value << 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_v<label> << nl << nl;
Info<<"contiguous = " << is_contiguous<label>::value << 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_v<label> << nl << nl;
Info<<"contiguous = " << is_contiguous<label>::value << 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_v<wordPair> << nl << nl;
Info<<"contiguous = " << is_contiguous<wordPair>::value << 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_v<labelPair> << nl << nl;
Info<<"contiguous = " << is_contiguous<labelPair>::value << 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_v<labelPairPair> << nl << nl;
Info<<"contiguous = " << is_contiguous<labelPairPair>::value << 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_v<edge> << nl << nl;
Info<<"contiguous = " << is_contiguous<edge>::value << 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_v<triFace> << nl << nl;
Info<<"contiguous = " << is_contiguous<triFace>::value << nl << nl;
for (const triFace& f : list)
{

View File

@ -213,10 +213,11 @@ int main(int argc, char *argv[])
mesh
);
Info<< "points path: " << io.typeFilePath<pointIOField>() << nl;
Info<< "points path: " << io.typeFilePath<labelIOList>() << nl;
Info<< "points path: " << io.typeFilePath<void>() << nl;
io.resetHeader("bad-points");
Info<< "bad path: " << io.typeFilePath<labelIOList>() << nl;
Info<< "bad path: " << io.typeFilePath<void>() << nl;
}
IOobject io

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -118,7 +118,7 @@ Ostream& printListOutputType(const char* what)
{
Info<< what
<< " (contiguous="
<< is_contiguous_v<T> << " no_linebreak="
<< is_contiguous<T>::value << " no_linebreak="
<< Detail::ListPolicy::no_linebreak<T>::value
<< " short_length="
<< Detail::ListPolicy::short_length<T>::value << ')';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2022 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,11 +70,12 @@ tensor2D makeRandomContainer(Random& rnd)
}
// 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
// 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>
void cmp
typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
(
const word& msg,
const Type& x,
@ -83,37 +84,51 @@ void cmp
const scalar relTol = 1e-8 //<! are values the same within 8 decimals
)
{
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)
);
};
Info<< msg << x << "?=" << y << endl;
unsigned nFail = 0;
if constexpr (is_vectorspace_v<Type>)
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
++nFail;
}
else
if (nFail)
{
if (notEqual(x, y))
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]))
{
++nFail;
}
}
Info<< msg << x << "?=" << y << endl;
if (nFail)
{
Info<< nl
@ -780,26 +795,27 @@ void test_eigen_funcs(const tensor2D& T)
// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
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)
{
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(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 global functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl;
test_global_opers(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
run_tests<I + 1, Tp...>(types, typeID);
}
@ -815,8 +831,8 @@ int main(int argc, char *argv[])
const List<word> typeID
({
"Tensor2D<float>",
"Tensor2D<double>",
"Tensor2D<floatScalar>",
"Tensor2D<doubleScalar>",
"Tensor2D<complex>"
});

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -67,9 +67,13 @@ doubleScalar getTol(complex)
}
// Create a random Matrix (real or complex)
// Create a non-complex random Matrix.
template<class MatrixType>
MatrixType makeRandomMatrix
typename std::enable_if
<
!std::is_same<complex, typename MatrixType::cmptType>:: value,
MatrixType
>::type makeRandomMatrix
(
const labelPair& dims,
Random& rndGen
@ -77,22 +81,34 @@ MatrixType makeRandomMatrix
{
MatrixType mat(dims);
if constexpr (std::is_same_v<complex, typename MatrixType::cmptType>)
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)
{
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>(); }
);
x = complex(rndGen.GaussNormal<scalar>(), rndGen.GaussNormal<scalar>());
}
return mat;
@ -163,57 +179,128 @@ List<Type> flt
}
// Compare two values or two containers (elementwise), and print output.
// Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485.
template<class Type1, class Type2 = Type1>
void cmp
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 Type1& x,
const Type2& y,
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
const bool verbose = false
)
{
const auto notEqual = [=](const auto& a, const auto& b) -> bool
if (verbose)
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
Info<< msg << x << "?=" << y << endl;
}
unsigned nFail = 0;
if constexpr
(
std::is_floating_point_v<Type1> || std::is_same_v<complex, Type1>
)
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
if (notEqual(x, y))
++nFail;
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if
<
!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]))
{
++nFail;
}
}
else
{
for (label i = 0; i < x.size(); ++i)
{
if (notEqual(x[i], y[i]))
{
++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 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
@ -234,6 +321,11 @@ void cmp
const bool verbose = false
)
{
if (verbose)
{
Info<< msg << x << "?=" << y << endl;
}
unsigned nFail = 0;
if (x != y)
@ -241,11 +333,6 @@ void cmp
++nFail;
}
if (verbose)
{
Info<< msg << x << "?=" << y << endl;
}
if (nFail)
{
Info<< nl

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,7 +32,6 @@ Description
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "labelPair.H"
#include "Tuple2.H"
#include "label.H"
@ -103,12 +102,8 @@ void printTuple2(const Pair<word>& t)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
int main()
{
argList::noCheckProcessorDirectories();
#include "setRootCase.H"
typedef Tuple2<label, scalar> indexedScalar;
Info<< "Default constructed Tuple: " << indexedScalar() << nl;

View File

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

View File

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

View File

@ -1,267 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "Switch.H"
#include "IOstreams.H"
#include "UPstream.H"
#include <type_traits>
using namespace Foam;
// Just for debugging
const List<std::string> dataType_names
({
"byte",
"int32",
"int64",
"uint32",
"uint64",
"float",
"double",
"long_double",
"float(2)",
"double(2)",
"float(3)",
"double(3)",
"float(6)",
"double(6)",
"float(9)",
"double(9)"
});
//- 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
{};
// Possible future change...
// //- A supported UPstream data type (intrinsic or user-defined)
// template<>
// struct UPstream_base_dataType<complex> : std::true_type
// {
// static constexpr auto datatype_id = []()
// {
// if constexpr (sizeof(complex) == 2*sizeof(float))
// return UPstream::dataTypes::type_2float;
// else
// return UPstream::dataTypes::type_2double;
// }();
// };
template<class T>
void printTypeName(const bool showSize = false)
{
// 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 (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();
Info<< " (" << sizeof(Type) << " bytes)";
}
Info<< ", cmpt:";
printTypeName<typename Foam::pTraits_cmptType<Type>::type>(true);
Info<< nl
<< " is_contiguous:"
<< is_contiguous<Type>::value
<< ", is base:"
<< UPstream_base_dataType<Type>::value
<< ", is cmpt:"
<< UPstream_dataType<Type>::value << nl;
Info<< "is base:"
<< UPstream_base_dataType<Type>::value
<< " (type:" << int(UPstream_base_dataType<Type>::datatype_id)
<< ") is alias:" << UPstream_alias_dataType<Type>::value
<< " (type:" << int(UPstream_alias_dataType<Type>::datatype_id)
<< ")" << nl;
{
int index = int(UPstream_base_dataType<Type>::datatype_id);
Info<< "datatype: " << index;
if (index < dataType_names.size())
{
Info<< ' ' << dataType_names[index];
}
Info<< nl;
}
{
// Use element or component type (or byte-wise) for data type
using base = typename UPstream_dataType<Type>::base;
constexpr auto datatype = UPstream_dataType<Type>::datatype_id;
Info<< "datatype => ";
printTypeName<base>();
Info<< " (" << sizeof(Type)/sizeof(base) << " elems)" << nl
<< "datatype: " << static_cast<int>(datatype) << nl;
}
}
template<class BinaryOp>
void printOpCodeTraits(BinaryOp bop, std::string_view name)
{
Info<< "op: " << name << ' ';
if constexpr (UPstream_opType<BinaryOp>::value)
{
Info<< "supported";
}
else
{
Info<< "unknown";
}
Info<< ": " << int(UPstream_opType<BinaryOp>::opcode_id) << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
printPstreamTraits<bool>();
printPstreamTraits<label>();
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>");
Info<< nl << "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -123,12 +123,15 @@ 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().data() << nl << nl;
<< " " << args.commandLine().c_str() << nl << nl;
Pout<< "rootPath: " << args.rootPath() << nl
<< "globalCase: " << args.globalCaseName() << nl

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2022 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_v<boolVector> << nl
<< " contiguous = " << is_contiguous<boolVector>::value << nl
<< nl;
{

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2025 OpenCFD Ltd.
Copyright (C) 2018-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -72,14 +72,13 @@ void printInfo(const char* const name = nullptr)
Info<< name;
}
Info<< " contiguous=" << Switch(is_contiguous<T>::value)
<< " / " << Switch(is_contiguous_v<T>);
Info<< " contiguous=" << Switch(is_contiguous<T>::value);
if constexpr (is_contiguous_label<T>::value)
if (is_contiguous_label<T>::value)
{
Info<< " label";
}
if constexpr (is_contiguous_scalar<T>::value)
if (is_contiguous_scalar<T>::value)
{
Info<< " scalar";
}
@ -97,11 +96,10 @@ int main(int argc, char *argv[])
argList::noParallel();
argList::noFunctionObjects();
printInfo<label>();
printInfo<label>();
printInfo<double>();
printInfo<FixedList<double, 4>>();
printInfo<const Pair<long>>();
printInfo<Pair<long>>();
printInfo<FixedList<word, 2>>();
printInfo<Pair<word>>();

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021-2025 OpenCFD Ltd.
Copyright (C) 2021-2024 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_v<expressions::exprValue>
<< " contiguous:" << is_contiguous<expressions::exprValue>::value
<< nl << nl;
{

View File

@ -3,5 +3,4 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools
-lfiniteVolume

View File

@ -3,5 +3,4 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools
-lfiniteVolume

View File

@ -48,7 +48,7 @@ word toString(const fileOperation::procRangeType& group)
{
return word::null;
}
return Foam::name(group.min()) + "-" + Foam::name(group.max());
return Foam::name(group.first()) + "-" + Foam::name(group.last());
}

View File

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

View File

@ -1,4 +0,0 @@
include $(GENERAL_RULES)/mpi-rules
EXE_INC = $(PFLAGS) $(PINC)
EXE_LIBS = $(PLIBS)

View File

@ -1,578 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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_bytes(),
allOffsets.size_bytes(),
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();
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;
}
// ************************************************************************* //

View File

@ -31,12 +31,13 @@ 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;

View File

@ -3,5 +3,4 @@ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools
-lfiniteVolume

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,9 +36,10 @@ Description
\*---------------------------------------------------------------------------*/
#include "complex.H"
#include "DiagonalMatrix.H"
#include "RectangularMatrix.H"
#include "scalar.H"
#include "complex.H"
#include "TestTools.H"
using namespace Foam;
@ -172,23 +173,24 @@ void test_global_funcs(Type)
// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
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)
{
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(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 global functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
run_tests<I + 1, Tp...>(types, typeID);
}
@ -203,8 +205,8 @@ int main()
const List<word> typeID
({
"DiagonalMatrix<float>",
"DiagonalMatrix<double>",
"DiagonalMatrix<floatScalar>",
"DiagonalMatrix<doubleScalar>",
"DiagonalMatrix<complex>"
});

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2022 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,26 +335,27 @@ void test_eigenvectors(Type)
// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
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)
{
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test eigenvalues: "<< typeID[I] <<" ##" << nl;
test_eigenvalues(std::get<I>(types));
Info<< nl << " ## Test eigenvalues: " << name << " ##" << nl;
test_eigenvalues(std::get<I>(types));
Info<< nl << " ## Test eigenvectors: "<< typeID[I] <<" ##" << nl;
test_eigenvectors(std::get<I>(types));
Info<< nl << " ## Test eigenvectors: " << name << " ##" << nl;
test_eigenvectors(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
run_tests<I + 1, Tp...>(types, typeID);
}
@ -371,8 +372,8 @@ int main()
const List<word> typeID
({
"SquareMatrix<float>",
"SquareMatrix<double>"
"SquareMatrix<floatScalar>",
"SquareMatrix<doubleScalar>"
});
run_tests(types, typeID);
@ -538,6 +539,3 @@ int main()
Info<< nl << " #### Passed all " << nTest_ <<" tests ####\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2022 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,20 +533,21 @@ void test_decomposition(MatrixType)
// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
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)
{
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test decomposition: "<< typeID[I] <<" ##" << nl;
test_decomposition(std::get<I>(types));
Info<< nl << " ## Test decomposition: " << name << " ##" << nl;
test_decomposition(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
run_tests<I + 1, Tp...>(types, typeID);
}
@ -569,9 +570,9 @@ int main()
const List<word> typeID
({
"RectangularMatrix<double>",
"RectangularMatrix<doubleScalar>",
"RectangularMatrix<complex>",
"SquareMatrix<double>",
"SquareMatrix<doubleScalar>",
"SquareMatrix<complex>"
});

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,9 +42,10 @@ Note
\*---------------------------------------------------------------------------*/
#include "complex.H"
#include "RectangularMatrix.H"
#include "SquareMatrix.H"
#include "scalar.H"
#include "complex.H"
#include "IOmanip.H"
#include "TestTools.H"
@ -808,34 +809,36 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
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)
{
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl;
test_member_opers(std::get<I>(types));
Info<< nl << " ## Test member opers: " << name << " ##" << nl;
test_member_opers(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl;
test_global_opers(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl;
test_friend_funcs(std::get<I>(types));
Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
run_tests<I + 1, Tp...>(types, typeID);
}
// * * * * * * * * * * * * * * * Main Program * * * * * * * * * * * * * * * //
int main()
@ -849,8 +852,8 @@ int main()
const List<word> typeID
({
"RectangularMatrix<float>",
"RectangularMatrix<double>",
"RectangularMatrix<floatScalar>",
"RectangularMatrix<doubleScalar>",
"RectangularMatrix<complex>"
});

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,10 +42,11 @@ 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"
@ -931,32 +932,33 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
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)
{
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl;
test_member_opers(std::get<I>(types));
Info<< nl << " ## Test member opers: " << name << " ##" << nl;
test_member_opers(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl;
test_global_opers(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl;
test_friend_funcs(std::get<I>(types));
Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
run_tests<I + 1, Tp...>(types, typeID);
}
@ -973,8 +975,8 @@ int main()
const List<word> typeID
({
"SquareMatrix<float>",
"SquareMatrix<double>",
"SquareMatrix<floatScalar>",
"SquareMatrix<doubleScalar>",
"SquareMatrix<complex>"
});

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,11 +42,12 @@ 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"
@ -137,32 +138,33 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp>
void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
inline typename std::enable_if<I == sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
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)
{
if constexpr (I < sizeof...(Tp))
{
const auto& name = names[I];
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_constructors(std::get<I>(types));
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl;
test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl;
test_member_opers(std::get<I>(types));
Info<< nl << " ## Test member opers: " << name << " ##" << nl;
test_member_opers(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl;
test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl;
test_global_opers(std::get<I>(types));
Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl;
test_friend_funcs(std::get<I>(types));
Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
run_tests<I + 1, Tp...>(types, typeID);
}
@ -179,8 +181,8 @@ int main()
const List<word> typeID
({
"SymmetricSquareMatrix<float>",
"SymmetricSquareMatrix<double>",
"SymmetricSquareMatrix<floatScalar>",
"SymmetricSquareMatrix<doubleScalar>",
"SymmetricSquareMatrix<complex>"
});

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -170,19 +170,8 @@ int main(int argc, char *argv[])
values1 *= (Pstream::myProcNo()+1);
{
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;
}
Pout<<"min-max of " << flatOutput(values1) << " = "
<< minMax(values1) << endl;
// Construct from values
MinMax<scalar> minmax1(values1);
@ -193,7 +182,10 @@ 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;

View File

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

View File

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

View File

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

View File

@ -1,165 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
);
// 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;
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2023-2025 OpenCFD Ltd.
Copyright (C) 2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,11 +32,9 @@ 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 "sphericalTensor.H"
#include "symmTensor.H"
#include "complex.H"
#include "uLabel.H"
#include "Switch.H"
@ -52,37 +50,26 @@ template<class T, class = void>
struct has_typeName : std::false_type {};
//- Test if Type has typeName member
template<class T>
struct has_typeName
<
T,
std::void_t<decltype(pTraits<std::remove_cv_t<T>>::typeName)>
>
struct has_typeName<T, stdFoam::void_t<decltype(pTraits<T>::typeName)>>
:
std::true_type
{};
template<class T>
void printTypeName()
typename std::enable_if<has_typeName<T>::value, void>::type
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 (has_typeName<T>::value)
{
Info<< pTraits<std::remove_cv_t<T>>::typeName;
}
else
{
Info<< typeid(T).name();
}
Info<< pTraits<T>::typeName;
}
template<class T>
typename std::enable_if<!has_typeName<T>::value, void>::type
printTypeName()
{
Info<< typeid(T).name();
}
@ -93,24 +80,23 @@ template<class T>
struct has_zero_one
<
T,
std::void_t
<
decltype(pTraits<std::remove_cv_t<T>>::zero),
decltype(pTraits<std::remove_cv_t<T>>::one)
>
stdFoam::void_t<decltype(pTraits<T>::zero), decltype(pTraits<T>::one)>
> : std::true_type {};
template<class T>
void printMinMaxRange()
typename std::enable_if<has_zero_one<T>::value, void>::type
printMinMaxRange()
{
if constexpr (has_zero_one<T>::value)
{
Info<< " zero=" << pTraits<std::remove_cv_t<T>>::zero
<< " one=" << pTraits<std::remove_cv_t<T>>::one;
}
Info<< " zero=" << pTraits<T>::zero
<< " one=" << pTraits<T>::one;
}
template<class T>
typename std::enable_if<!has_zero_one<T>::value, void>::type
printMinMaxRange()
{}
template<class T>
void printTraits()
@ -118,12 +104,11 @@ void printTraits()
printTypeName<T>();
printMinMaxRange<T>();
Info<< " integral=" << std::is_integral_v<T>
<< " floating=" << std::is_floating_point_v<T>
Info<< " integral=" << std::is_integral<T>::value
<< " floating=" << std::is_floating_point<T>::value
<< " rank=" << pTraits_rank<T>::value
<< " nComponents=" << pTraits_nComponents<T>::value
<< " vector-space=" << Switch::name(is_vectorspace_v<T>)
<< " rotate=" << Switch::name(is_rotational_vectorspace_v<T>)
<< " vector-space=" << Switch::name(is_vectorspace<T>::value)
<< " 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()
@ -152,11 +137,9 @@ int main()
printTraits<bool>();
printTraits<label>();
printTraits<scalar>();
printTraits<const complex>(); // Uses specialized pTraits_...
printTraits<complex>(); // Uses specialized pTraits_...
printTraits<floatVector>();
printTraits<doubleVector>();
printTraits<sphericalTensor>();
printTraits<symmTensor>();
printTraits<tensor>();
printTraits<boolVector>(); // Uses specialized pTraits_...
printTraits<word>();

View File

@ -1,3 +0,0 @@
Test-parallel-barrier1.cxx
EXE = $(FOAM_USER_APPBIN)/Test-parallel-barrier1

View File

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

View File

@ -1,125 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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;
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2025 OpenCFD Ltd.
Copyright (C) 2022 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_v<T> << endl;
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << 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_v<T> << endl;
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl;
Pout<< "pre-broadcast: " << flatOutput(values) << endl;
Pstream::broadcast(values);
Pout<< "post-broadcast: " << flatOutput(values) << endl;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2025 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,17 +44,55 @@ Description
using namespace Foam;
//- Number of elements corresponding to max byte transfer.
// Normal upper limit is INT_MAX since MPI sizes are limited to <int>.
template<class Type>
inline std::size_t maxTransferCount
(
const std::size_t max_bytes = std::size_t(0)
) noexcept
{
return
(
(max_bytes == 0) // ie, unlimited
? (std::size_t(0)) //
: (max_bytes > std::size_t(INT_MAX)) // MPI limit is <int>
? (std::size_t(INT_MAX) / sizeof(Type)) //
: (max_bytes > sizeof(Type)) // require an integral number
? (max_bytes / sizeof(Type)) //
: (std::size_t(1)) // min of one element
);
}
//- Upper limit on number of transfer bytes.
// Max bytes is normally INT_MAX since MPI sizes are limited to <int>.
// Negative values indicate a subtraction from INT_MAX.
inline std::size_t PstreamDetail_maxTransferBytes
(
const int64_t max_bytes
) noexcept
{
return
(
(max_bytes < 0) // (numBytes fewer than INT_MAX)
? std::size_t(INT_MAX + max_bytes)
: std::size_t(max_bytes)
);
}
template<class Container, class Type>
void broadcast_chunks
(
Container& sendData,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
const label comm = UPstream::worldComm
const int64_t maxComms_bytes = UPstream::maxCommsSize
)
{
// OR static_assert(is_contiguous_v<Type>, "Contiguous data only!")
if constexpr (!is_contiguous_v<Type>)
// OR static_assert(is_contiguous<T>::value, "Contiguous data only!")
if (!is_contiguous<Type>::value)
{
FatalErrorInFunction
<< "Contiguous data only." << sizeof(Type)
@ -81,9 +119,9 @@ void broadcast_chunks
// Is zero for non-chunked exchanges.
const std::size_t chunkSize
(
PstreamDetail::maxTransferCount<Type>
PstreamDetail_maxTransferCount<Type>
(
PstreamDetail::maxTransferBytes(maxComms_bytes)
PstreamDetail_maxTransferBytes(maxComms_bytes)
)
);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2025 OpenCFD Ltd.
Copyright (C) 2022-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -67,6 +67,10 @@ int main(int argc, char *argv[])
{
argList::noBanner();
argList::noCheckProcessorDirectories();
argList::addVerboseOption("Set UPstream::debug level");
// Check -verbose before initialisation
UPstream::debug = argList::verbose(argc, argv);
#include "setRootCase.H"

View File

@ -158,7 +158,7 @@ int main(int argc, char *argv[])
for (label count = 0; count < repeat; ++count)
{
label comm = UPstream::newCommunicator(UPstream::worldComm, top);
label comm = UPstream::allocateCommunicator(UPstream::worldComm, top);
scalar localValue = 111*UPstream::myProcNo(UPstream::worldComm);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2025 OpenCFD Ltd.
Copyright (C) 2022-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -66,16 +66,20 @@ int main(int argc, char *argv[])
{
argList::noBanner();
argList::noCheckProcessorDirectories();
argList::addVerboseOption("Set UPstream::debug level");
argList::addBoolOption("info", "information");
argList::addBoolOption("print-tree", "Report tree(s) as graph");
argList::addBoolOption("no-test", "Disable general tests");
argList::addBoolOption("comm-split", "Test simple comm split");
argList::addBoolOption("mpi-host-comm", "Test DIY host-comm split");
argList::addBoolOption("host-comm", "Test Pstream host-comm");
argList::addBoolOption("host-broadcast", "Test host-base broadcasts");
// Check -verbose before initialisation
UPstream::debug = argList::verbose(argc, argv);
#include "setRootCase.H"
const bool optPrintTree = args.found("print-tree");
bool generalTest = !args.found("no-test");
Info<< nl
<< "parallel:" << UPstream::parRun()
@ -85,23 +89,10 @@ int main(int argc, char *argv[])
if (UPstream::parRun() && optPrintTree)
{
Info<< "comms: "
<< UPstream::whichCommunication(UPstream::worldComm) << nl;
Info<< "comms: " << UPstream::whichCommunication() << endl;
UPstream::printCommTree(UPstream::commWorld());
}
if (UPstream::parRun())
{
Pout<< "world ranks: 0.."
<< UPstream::nProcs(UPstream::commWorld())-1 << nl;
Pout<< "inter-node ranks: " << UPstream::numNodes() << ' '
<< flatOutput(UPstream::procID(UPstream::commInterNode())) << nl;
Pout<< "local-node ranks: "
<< flatOutput(UPstream::procID(UPstream::commLocalNode())) << nl;
}
if (args.found("info"))
{
Info<< nl;
@ -117,29 +108,334 @@ int main(int argc, char *argv[])
Pout<< endl;
}
bool generalTest = true;
if (UPstream::parRun() && args.found("comm-split"))
{
generalTest = false;
int world_nprocs = 0;
int world_rank = -1;
MPI_Comm_size(MPI_COMM_WORLD, &world_nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int host_nprocs = 0;
int host_rank = -1;
MPI_Comm commIntraHost;
MPI_Comm_split_type
(
MPI_COMM_WORLD,
MPI_COMM_TYPE_SHARED, // OMPI_COMM_TYPE_NODE
0, MPI_INFO_NULL, &commIntraHost
);
MPI_Comm_size(commIntraHost, &host_nprocs);
MPI_Comm_rank(commIntraHost, &host_rank);
int leader_nprocs = 0;
int leader_rank = -1;
MPI_Comm commInterHost;
if (false)
{
// Easy enough to use MPI_Comm_split, but slightly annoying
// that it returns MPI_COMM_NULL for unused ranks...
MPI_Comm commInterHost;
MPI_Comm_split
(
MPI_COMM_WORLD,
(host_rank == 0) ? 0 : MPI_UNDEFINED,
0, &commInterHost
);
if (commInterHost != MPI_COMM_NULL)
{
MPI_Comm_size(commInterHost, &leader_nprocs);
MPI_Comm_rank(commInterHost, &leader_rank);
}
}
else
{
boolList isHostLeader(world_nprocs, false);
isHostLeader[world_rank] = (host_rank == 0);
MPI_Allgather
(
// recv is also send
MPI_IN_PLACE, 1, MPI_C_BOOL,
isHostLeader.data(), 1, MPI_C_BOOL,
MPI_COMM_WORLD
);
Pout<< "leaders: " << isHostLeader << endl;
DynamicList<int> subRanks(isHostLeader.size());
forAll(isHostLeader, proci)
{
if (isHostLeader[proci])
{
subRanks.push_back(proci);
}
}
// Starting from parent
MPI_Group parent_group;
MPI_Comm_group(MPI_COMM_WORLD, &parent_group);
MPI_Group active_group;
MPI_Group_incl
(
parent_group,
subRanks.size(),
subRanks.cdata(),
&active_group
);
// Create new communicator for this group
MPI_Comm_create_group
(
MPI_COMM_WORLD,
active_group,
UPstream::msgType(),
&commInterHost
);
// Groups not needed after this...
MPI_Group_free(&parent_group);
MPI_Group_free(&active_group);
MPI_Comm_size(commInterHost, &leader_nprocs);
MPI_Comm_rank(commInterHost, &leader_rank);
}
Pout<< nl << "[MPI_Comm_split_type]" << nl
<< "Host rank " << host_rank << " / " << host_nprocs
<< " on " << hostName()
<< " inter-rank: " << leader_rank << " / " << leader_nprocs
<< " host leader:" << (leader_rank == 0)
<< " sub-rank:" << (leader_rank > 0)
<< nl;
if (commInterHost != MPI_COMM_NULL)
{
MPI_Comm_free(&commInterHost);
}
if (commIntraHost != MPI_COMM_NULL)
{
MPI_Comm_free(&commIntraHost);
}
}
if (UPstream::parRun() && args.found("mpi-host-comm"))
{
generalTest = false;
// Host communicator, based on the current world communicator
// Use hostname
// Lowest rank per hostname is the IO rank
label numprocs = UPstream::nProcs(UPstream::commGlobal());
// Option 1: using hostnames
// - pro: trivial coding
// - con: unequal lengths, more allocations and 'hops'
stringList hosts(numprocs);
hosts[Pstream::myProcNo(UPstream::commGlobal())] = hostName();
Pstream::gatherList(hosts, UPstream::msgType(), UPstream::commGlobal());
// Option 2: using SHA1 of hostnames
// - con: uglier coding (but only needed locally!)
// - pro: fixed digest length enables direct MPI calls
// can avoid Pstream::gatherList() during setup...
List<SHA1Digest> digests;
if (UPstream::master(UPstream::commGlobal()))
{
digests.resize(numprocs);
}
{
const SHA1Digest myDigest(SHA1(hostName()).digest());
UPstream::mpiGather
(
myDigest.cdata_bytes(), // Send
digests.data_bytes(), // Recv
SHA1Digest::max_size(), // Num send/recv per rank
UPstream::commGlobal()
);
}
labelList hostIDs(numprocs);
DynamicList<label> subRanks(numprocs);
Info<< "digests: " << digests << nl;
// Compact numbering
if (UPstream::master(UPstream::commGlobal()))
{
DynamicList<word> hostNames(numprocs);
forAll(hosts, proci)
{
const word& host = hosts[proci];
hostIDs[proci] = hostNames.find(host);
if (hostIDs[proci] < 0)
{
// First appearance of host (encode as leader)
hostIDs[proci] = -(hostNames.size() + 1);
hostNames.push_back(host);
}
}
hostIDs = -1;
DynamicList<SHA1Digest> uniqDigests(numprocs);
forAll(digests, proci)
{
const SHA1Digest& dig = digests[proci];
hostIDs[proci] = uniqDigests.find(dig);
if (hostIDs[proci] < 0)
{
// First appearance of host (encode as leader)
hostIDs[proci] = -(uniqDigests.size() + 1);
uniqDigests.push_back(dig);
}
}
}
Info<< "hosts = " << hosts << endl;
Info<< "hostIDs = " << hostIDs << endl;
UPstream::broadcast
(
hostIDs.data_bytes(),
hostIDs.size_bytes(),
UPstream::commGlobal(),
UPstream::masterNo()
);
// Ranks for world to inter-host communicator
// - very straightforward
#if 0
subRanks.clear();
forAll(hostIDs, proci)
{
// Is host leader?
if (hostIDs[proci] < 0)
{
subRanks.push_back(proci);
// Flip back to generic host id
hostIDs[proci] = -(hostIDs[proci] + 1);
}
}
// From world to hostMaster
const label commInterHost =
UPstream::allocateCommunicator(UPstream::commGlobal(), subRanks);
#endif
const label myWorldProci = UPstream::myProcNo(UPstream::commGlobal());
label myHostId = hostIDs[myWorldProci];
if (myHostId < 0) myHostId = -(myHostId + 1); // Flip to generic id
// Ranks for within a host
subRanks.clear();
forAll(hostIDs, proci)
{
label id = hostIDs[proci];
if (id < 0) id = -(id + 1); // Flip to generic id
if (id == myHostId)
{
subRanks.push_back(proci);
}
}
// The intra-host ranks
const label commIntraHost =
UPstream::allocateCommunicator(UPstream::commGlobal(), subRanks);
// Test what if we have intra-host comm and we want host-master
List<bool> isHostMaster(numprocs, false);
if (UPstream::master(commIntraHost))
{
isHostMaster[myWorldProci] = true;
}
UPstream::mpiAllGather
(
isHostMaster.data_bytes(),
sizeof(bool),
UPstream::commGlobal()
);
// Ranks for world to hostMaster
// - very straightforward
subRanks.clear();
forAll(isHostMaster, proci)
{
if (isHostMaster[proci])
{
subRanks.push_back(proci);
}
}
// From world to hostMaster
const label commInterHost =
UPstream::allocateCommunicator(UPstream::commGlobal(), subRanks);
Pout<< nl << "[manual split]" << nl
<< nl << "Host rank " << UPstream::myProcNo(commIntraHost)
<< " / " << UPstream::nProcs(commIntraHost)
<< " on " << hostName()
<< ", inter-rank: " << UPstream::myProcNo(commInterHost)
<< " / " << UPstream::nProcs(commInterHost)
<< " host leader:" << UPstream::master(commInterHost)
<< " sub-rank:" << UPstream::is_subrank(commInterHost)
<< nl;
UPstream::freeCommunicator(commInterHost);
UPstream::freeCommunicator(commIntraHost);
}
if (UPstream::parRun() && args.found("host-comm"))
{
generalTest = false;
Info<< nl << "[pstream host-comm]" << nl << endl;
const label commInterNode = UPstream::commInterNode();
const label commLocalNode = UPstream::commLocalNode();
const label commInterHost = UPstream::commInterHost();
const label commIntraHost = UPstream::commIntraHost();
Pout<< "Host rank " << UPstream::myProcNo(commLocalNode)
<< " / " << UPstream::nProcs(commLocalNode)
Pout<< "Host rank " << UPstream::myProcNo(commIntraHost)
<< " / " << UPstream::nProcs(commIntraHost)
<< " on " << hostName()
<< ", inter-rank: " << UPstream::myProcNo(commInterNode)
<< " / " << UPstream::nProcs(commInterNode)
<< ", host leader:" << UPstream::master(commInterNode)
<< " sub-rank:" << UPstream::is_subrank(commInterNode)
<< ", inter-rank: " << UPstream::myProcNo(commInterHost)
<< " / " << UPstream::nProcs(commInterHost)
<< ", host leader:" << UPstream::master(commInterHost)
<< " sub-rank:" << UPstream::is_subrank(commInterHost)
<< endl;
{
Info<< "host-master: "
<< UPstream::whichCommunication(commInterNode) << endl;
<< UPstream::whichCommunication(commInterHost) << endl;
UPstream::printCommTree(commInterNode);
UPstream::printCommTree(commLocalNode);
UPstream::printCommTree(commInterHost);
UPstream::printCommTree(commIntraHost);
}
}
@ -148,32 +444,32 @@ int main(int argc, char *argv[])
generalTest = false;
Info<< nl << "[pstream host-broadcast]" << nl << endl;
const label commInterNode = UPstream::commInterNode();
const label commLocalNode = UPstream::commLocalNode();
const label commInterHost = UPstream::commInterHost();
const label commIntraHost = UPstream::commIntraHost();
Pout<< "world rank: " << UPstream::myProcNo(UPstream::commWorld())
<< " host-leader rank: "
<< UPstream::myProcNo(UPstream::commInterNode())
<< UPstream::myProcNo(UPstream::commInterHost())
<< " intra-host rank: "
<< UPstream::myProcNo(UPstream::commLocalNode())
<< UPstream::myProcNo(UPstream::commIntraHost())
<< endl;
label value1(0), value2(0), value3(0);
label hostIndex = UPstream::myProcNo(commInterNode);
label hostIndex = UPstream::myProcNo(commInterHost);
if (UPstream::master(commInterNode))
if (UPstream::master(commInterHost))
{
value1 = 100;
value2 = 200;
}
if (UPstream::master(commLocalNode))
if (UPstream::master(commIntraHost))
{
value3 = 300;
}
Pstream::broadcast(value1, commInterNode);
Pstream::broadcast(value2, commLocalNode);
Pstream::broadcast(hostIndex, commLocalNode);
Pstream::broadcast(value1, commInterHost);
Pstream::broadcast(value2, commIntraHost);
Pstream::broadcast(hostIndex, commIntraHost);
Pout<< "host: " << hostIndex
<< " broadcast 1: "
@ -182,7 +478,7 @@ int main(int argc, char *argv[])
<< value3 << endl;
// re-broadcast
Pstream::broadcast(value1, commLocalNode);
Pstream::broadcast(value1, commIntraHost);
Pout<< "host: " << hostIndex
<< " broadcast 2: "
<< value1 << endl;
@ -191,42 +487,42 @@ int main(int argc, char *argv[])
label reduced1 = value1;
label reduced2 = value1;
Foam::reduce
reduce
(
reduced1,
sumOp<label>(),
UPstream::msgType(),
commLocalNode
commIntraHost
);
Foam::reduce
reduce
(
reduced2,
sumOp<label>(),
UPstream::msgType(),
commInterNode
commInterHost
);
Pout<< "value1: (host) " << reduced1
<< " (leader) " << reduced2 << endl;
// Pout<< "ranks: " << UPstream::nProcs(commInterNode) << endl;
// Pout<< "ranks: " << UPstream::nProcs(commInterHost) << endl;
wordList strings;
if (UPstream::is_rank(commInterNode))
if (UPstream::is_rank(commInterHost))
{
strings.resize(UPstream::nProcs(commInterNode));
strings[UPstream::myProcNo(commInterNode)] = name(pid());
strings.resize(UPstream::nProcs(commInterHost));
strings[UPstream::myProcNo(commInterHost)] = name(pid());
}
// Some basic gather/scatter
Pstream::allGatherList(strings, UPstream::msgType(), commInterNode);
Pstream::allGatherList(strings, UPstream::msgType(), commInterHost);
Pout<< "pids " << flatOutput(strings) << endl;
Foam::reverse(strings);
Pstream::broadcast(strings, commLocalNode);
Pstream::broadcast(strings, commIntraHost);
Pout<< "PIDS " << flatOutput(strings) << endl;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -125,16 +125,13 @@ int main(int argc, char *argv[])
argList::addVerboseOption("Set UPstream::debug level");
// Check -verbose before initialisation
if (!UPstream::debug)
{
UPstream::debug = argList::verbose(argc, argv);
}
UPstream::debug = argList::verbose(argc, argv);
startMPI();
#include "setRootCase.H"
Pout<< message().data();
Pout<< message().c_str();
stopMPI();

View File

@ -7,7 +7,6 @@ EXE_INC = \
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools \
-ldynamicFvMesh \
-lsampling \
-loverset

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2025 OpenCFD Ltd.
Copyright (C) 2022-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,15 +44,19 @@ using namespace Foam;
int main(int argc, char *argv[])
{
argList::noFunctionObjects();
argList::addVerboseOption("Set UPstream::debug level");
argList::addBoolOption("comm-graph", "Test simple graph communicator");
argList::addNote
(
"Create graph of OpenFOAM mesh connections"
);
// Check -verbose before initialisation
UPstream::debug = argList::verbose(argc, argv);
#include "setRootCase.H"
if (!UPstream::parRun())
if (!Pstream::parRun())
{
FatalErrorInFunction
<< "Only meaningful in parallel"

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -36,13 +36,13 @@ template<class T>
void constructInfo()
{
Info<< " move-constructible:"
<< std::is_move_constructible_v<T>
<< std::is_move_constructible<T>::value
<< " move-assignable:"
<< std::is_move_assignable_v<T>
<< std::is_move_assignable<T>::value
<< " nothrow:"
<< std::is_nothrow_move_assignable_v<T>
<< std::is_nothrow_move_assignable<T>::value
<< " trivially:"
<< std::is_trivially_move_assignable_v<T>
<< std::is_trivially_move_assignable<T>::value
<< nl;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2025 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -322,12 +322,12 @@ int main(int argc, char *argv[])
Info<< "_GLIBCXX_RELEASE = " << (_GLIBCXX_RELEASE) << nl;
#endif
if constexpr (std::is_same_v<regExp, regExpCxx>)
if (std::is_same<regExp, regExpCxx>::value)
{
Info<< "Foam::regExp uses C++11 regex" << nl;
}
#ifndef _WIN32
if constexpr (std::is_same_v<regExp, regExpPosix>)
if (std::is_same<regExp, regExpPosix>::value)
{
Info<< "Foam::regExp uses POSIX regex" << nl;
}

View File

@ -53,27 +53,6 @@ namespace Foam
{}
};
// Test compilation with static_assert workaround
// (workaround before CWG2518)
template<class T>
inline unsigned sizeof_float()
{
if constexpr (std::is_floating_point_v<T>)
{
return sizeof(T);
}
else
{
// static_assert(false, "only use for floats");
static_assert
(
stdFoam::dependent_false_v<T>,
"only use for floats"
);
return 0u;
}
}
}

View File

@ -2,4 +2,4 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/mesh/blockMesh/lnInclude
EXE_LIBS = -lblockMesh -lmeshTools
EXE_LIBS = -lblockMesh

View File

@ -3,5 +3,4 @@ EXE_INC = \
-I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = \
-lfileFormats \
-lsurfMesh

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2024 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -45,13 +45,13 @@ void printInfo(const tmp<T>& item, const bool verbose = false)
}
Info<< " move-constructible:"
<< std::is_move_constructible_v<tmp<T>>
<< std::is_move_constructible<tmp<T>>::value
<< " move-assignable:"
<< std::is_move_assignable_v<tmp<T>>
<< std::is_move_assignable<tmp<T>>::value
<< " nothrow:"
<< std::is_nothrow_move_assignable_v<tmp<T>>
<< std::is_nothrow_move_assignable<tmp<T>>::value
<< " trivially:"
<< std::is_trivially_move_assignable_v<tmp<T>>
<< std::is_trivially_move_assignable<tmp<T>>::value
<< nl;
if (verbose && item)

View File

@ -51,7 +51,7 @@ void printConnection(Ostream& os, const label proci, const labelUList& below)
// The number of receives - as per gatherList (v2112)
void printRecvCount_gatherList
(
const UPstream::commsStructList& comms,
const UList<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm
)
{
@ -91,7 +91,7 @@ void printRecvCount_gatherList
// The number of sends - as per scatterList (v2112)
void printSendCount_scatterList
(
const UPstream::commsStructList& comms,
const UList<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm
)
{
@ -131,7 +131,7 @@ void printSendCount_scatterList
// Transmission widths (contiguous data)
void printWidths
(
const UPstream::commsStructList& comms,
const UList<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm
)
{

View File

@ -31,9 +31,8 @@ void test(const vector& a, const vector& b, const scalar tolerance)
int main()
{
vector a(vector::uniform(1));
vector b;
b.fill(2);
vector a(1.0, 1.0, 1.0);
vector b(2.0, 2.0, 2.0);
test(a, b, 0.0);
test(a, b, VSMALL);
@ -68,9 +67,5 @@ int main()
test(a, b, 1e-3);
test(a, b, 1e-1);
Info<< "\nEnd\n" << nl;
return 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -231,7 +231,7 @@ int main(int argc, char *argv[])
Info<< nl
<< "solverPerformanceDict: "
<< mesh.data().solverPerformanceDict() << endl;
<< mesh.solverPerformanceDict() << endl;
if (args.found("zip"))

View File

@ -62,6 +62,9 @@ Description
// Flex may use register, which is deprecated and incompatible with C++17
#pragma clang diagnostic ignored "-Wdeprecated-register"
// A 'nothing' define to effectively remove from code as well (issue #3337)
#undef register
#define register
using namespace Foam;

View File

@ -8,6 +8,5 @@ EXE_INC = \
EXE_LIBS = \
-lfiniteVolume \
-lgenericPatchFields \
-lfileFormats \
-lmeshTools \
-lconversion -lccm

View File

@ -7,6 +7,4 @@ EXE_INC = \
EXE_LIBS = \
-lfiniteVolume \
-lgenericPatchFields \
-lfileFormats \
-lmeshTools \
-lconversion -lccm

View File

@ -56,6 +56,9 @@ Description
// Flex may use register, which is deprecated and incompatible with C++17
#pragma clang diagnostic ignored "-Wdeprecated-register"
// A 'nothing' define to effectively remove from code as well (issue #3337)
#undef register
#define register
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -63,6 +63,9 @@ Description
// Flex may use register, which is deprecated and incompatible with C++17
#pragma clang diagnostic ignored "-Wdeprecated-register"
// A 'nothing' define to effectively remove from code as well (issue #3337)
#undef register
#define register
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -51,6 +51,9 @@ Description
// Flex may use register, which is deprecated and incompatible with C++17
#pragma clang diagnostic ignored "-Wdeprecated-register"
// A 'nothing' define to effectively remove from code as well (issue #3337)
#undef register
#define register
using namespace Foam;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2025 OpenCFD Ltd.
Copyright (C) 2015-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -1520,10 +1520,6 @@ int main(int argc, char *argv[])
const bool adaptMesh(dict.get<bool>("adaptMesh"));
const bool addSidePatches(dict.getOrDefault<bool>("addSidePatches", true));
if (hasZones)
{
Info<< "Extruding zones " << zoneNames
@ -1568,15 +1564,6 @@ int main(int argc, char *argv[])
}
if (addSidePatches && zoneNames.size() > 1)
{
Info<< "Extruding edges on more than one faceZone into boundary faces"
<< endl;
}
else
{
Info<< "Extruding internal edges into internal faces" << endl;
}
//// Read objects in time directory
@ -1931,12 +1918,7 @@ int main(int argc, char *argv[])
edgeMaxZoneID
);
if (!addSidePatches)
{
// Disabling inter-zone multiple boundary faces by setting 'left' and
// 'right' zone to be the same
edgeMaxZoneID = edgeMinZoneID;
}
DynamicList<polyPatch*> regionPatches(patches.size());
@ -2208,7 +2190,7 @@ int main(int argc, char *argv[])
label zone0 = zoneID[eFaces[0]];
label zone1 = zoneID[eFaces[1]];
if (addSidePatches && (zone0 != zone1)) // || (cos(angle) > blabla))
if (zone0 != zone1) // || (cos(angle) > blabla))
{
label minZone = min(zone0,zone1);
label maxZone = max(zone0,zone1);

View File

@ -123,7 +123,7 @@ void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
{
// Number of global patches and min-max range of total patches
Info<< mesh.boundaryMesh().nNonProcessor() << ' '
<< returnReduce(labelMinMax(nPatches), sumOp<labelMinMax>{}) << nl;
<< returnReduce(labelMinMax(nPatches), minMaxOp<label>()) << nl;
}
else
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2025 OpenCFD Ltd.
Copyright (C) 2016-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -232,7 +232,7 @@ vtk::outputOptions getOutputOptions(const argList& args)
if (!args.found("ascii"))
{
if constexpr (sizeof(float) != 4 || sizeof(label) != 4)
if (sizeof(float) != 4 || sizeof(label) != 4)
{
opts.ascii(true);

View File

@ -124,8 +124,8 @@ void Foam::PDRutils::one_d_overlap
}
// Ensure search is within the (point) bounds
xmin = grid.clamp(xmin);
xmax = grid.clamp(xmax);
xmin = grid.clip(xmin);
xmax = grid.clip(xmax);
// The begin/end of the obstacle
*cmin = grid.findCell(xmin);

View File

@ -7,7 +7,7 @@
# \\/ M anipulation |
#------------------------------------------------------------------------------
# Copyright (C) 2011-2015 OpenFOAM Foundation
# Copyright (C) 2017-2025 OpenCFD Ltd.
# Copyright (C) 2017-2023 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -23,7 +23,9 @@
#------------------------------------------------------------------------------
. "${WM_PROJECT_DIR:?}"/bin/tools/RunFunctions # Run functions
printHelp() {
usage() {
exec 1>&2
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat<<USAGE
Usage: ${0##*/} [OPTION] -np <N> <executable> <args>
@ -42,13 +44,12 @@ options:
-yes Start without additional prompting
-local Same as -spawn=1
-remote Same as -spawn=2
-clean Remove log and startup files
-clean Remove old processor*.{log,sh} files, mpirun.schema etc
-decompose-dict=<file> Specific decomposeParDict name
-help Print the usage
Invoke mpirun with separate per-processor log files or with separate XTerms.
Also detects some OpenFOAM options:
-decomposeParDict <file> Use specified file for decomposePar dictionary
Invoke mpirun with separate per-processor log files or running in
separate XTerms.
Common shortcuts. Sets default spawn to -local, add -yes.
-normal = -method=0
@ -57,6 +58,9 @@ Common shortcuts. Sets default spawn to -local, add -yes.
-valgrind = -method=5l (valgrind + log)
-xvalgrind = -method=5 (valgrind + xterm)
Also detects some OpenFOAM options:
-decomposeParDict <file> Use specified file for decomposePar dictionary
USAGE
exit 0 # A clean exit
}
@ -202,7 +206,7 @@ do
# Processing application arguments
case "$1" in
(-help* | --help*) printHelp ;;
(-help* | --help*) usage ;;
('') ;; ## Ignore junk
(-np)
@ -234,16 +238,13 @@ done
# Cleanup only
if [ -n "$optClean" ]
then
exec 1>&2
echo "Cleanup old mpirunDebug files..."
rm -f gdbCommands mpirun.schema vgcore.*
echo "Cleanup old mpirunDebug files..." 1>&2
rm -f gdbCommands mpirun.schema
rm -f processor*.log processor*.sh
rm -rf mpirun.log mpirun.files
echo " gdbCommands mpirun.schema vgcore.*"
echo " processor*.{log,sh}"
echo " mpirun.{files,log}/"
echo "Done"
exit 0 # A clean exit
echo " gdbCommands mpirun.schema" 1>&2
echo " processor*.log processor*.sh" 1>&2
echo "Done" 1>&2
exit 0
fi
@ -344,22 +345,16 @@ esac
echo "**sourceFoam: $sourceFoam" 1>&2
mkdir -p ./mpirun.files
mkdir -p ./mpirun.log
schema_file="$PWD/mpirun.files/mpirun.schema"
rm -f "$schema_file"
touch "$schema_file"
rm -f "$PWD"/mpirun.schema
touch "$PWD"/mpirun.schema
proc=0
xpos=0
ypos=0
for ((proc=0; proc<$nProcs; proc++))
do
procCmdFile="$PWD/mpirun.files/processor${proc}.sh"
procLog="./mpirun.log/processor${proc}.log"
procCmdFile="$PWD/processor${proc}.sh"
procLog="processor${proc}.log"
xterm="xterm -font fixed -title processor${proc} -geometry 120x15+$xpos+$ypos"
unset node
@ -377,8 +372,8 @@ COMMANDS
# Add to the mpirun.schema
case "$method" in
(*xterm*) echo "${node}${xterm} -e ${procCmdFile}" >> "$schema_file" ;;
(*) echo "${node}${procCmdFile}" >> "$schema_file" ;;
(*xterm*) echo "${node}${xterm} -e ${procCmdFile}" >> "$PWD"/mpirun.schema ;;
(*) echo "${node}${procCmdFile}" >> "$PWD"/mpirun.schema ;;
esac
case "$method" in
@ -424,33 +419,17 @@ COMMANDS
fi
done
if [ "$nProcs" -lt 10 ]
then
for ((proc = 0; proc < $nProcs; proc++))
do
procLog="mpirun.log/processor${proc}.log"
echo " tail -f $procLog" 1>&2
done
else
for ((proc = 0; proc < 4; proc++))
do
procLog="mpirun.log/processor${proc}.log"
echo " tail -f $procLog" 1>&2
done
echo " ..." 1>&2
for ((proc = $nProcs-2; proc < $nProcs; proc++))
do
procLog="mpirun.log/processor${proc}.log"
echo " tail -f $procLog" 1>&2
done
fi
for ((proc=0; proc<$nProcs; proc++))
do
procLog="processor${proc}.log"
echo " tail -f $procLog" 1>&2
done
unset cmd
case "$WM_MPLIB" in
*OPENMPI*)
cmd="mpirun --oversubscribe -app "$schema_file" </dev/null"
cmd="mpirun --oversubscribe -app $PWD/mpirun.schema </dev/null"
;;
MPICH)
cmd="mpiexec"
@ -458,16 +437,16 @@ MPICH)
do
read procCmd
procXtermCmdFile="$PWD/mpirun.files/xterm-processor${proc}.sh"
echo "#!/bin/sh" > "$procXtermCmdFile"
echo "$procCmd" >> "$procXtermCmdFile"
chmod +x "$procXtermCmdFile"
if [ "$proc" -ne 0 ]
procXtermCmdFile="$PWD/processor${proc}Xterm.sh"
echo "#!/bin/sh" > $procXtermCmdFile
echo "$procCmd" >> $procXtermCmdFile
chmod +x $procXtermCmdFile
if [ $proc -ne 0 ]
then
cmd="${cmd} :"
fi
cmd="${cmd} -n 1 ${procXtermCmdFile}"
done < "$schema_file"
done < "$PWD"/mpirun.schema
;;
*)
die "Unsupported WM_MPLIB setting : $WM_MPLIB"
@ -475,7 +454,7 @@ MPICH)
esac
echo 1>&2
echo "Constructed $schema_file file:" 1>&2
echo "Constructed $PWD/mpirun.schema file:" 1>&2
echo 1>&2
echo " $cmd" 1>&2
echo 1>&2

View File

@ -6,7 +6,7 @@
# \\ / A nd | www.openfoam.com
# \\/ M anipulation |
#------------------------------------------------------------------------------
# Copyright (C) 2016-2025 OpenCFD Ltd.
# Copyright (C) 2016 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -22,25 +22,22 @@
# Confirm that all available EXE targets have actually been created:
#
# foamGrepExeTargets > targets-available
# foamGrepExeTargets -bin > targets-created
# foamGrepExeTargets -appbin > targets-created
# diff -uw targets-available targets-created
#
#------------------------------------------------------------------------------
# Locations
FOAM_GIT_DIR="$WM_PROJECT_DIR/.git"
printHelp() {
usage() {
exec 1>&2
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat<<USAGE
usage: ${0##*/}
-bin List contents of \$FOAM_APPBIN (no git required)
-no-git Disable use of git for obtaining information
-help Print the usage
-appbin list contents of \$FOAM_APPBIN (no git required)
-help
List exe targets (contains EXE). Uses git when possible
List available EXE= targets. Requires git.
USAGE
exit 0 # clean exit
exit 1
}
# Report error and exit
@ -58,63 +55,54 @@ die()
#------------------------------------------------------------------------------
unset projectdir
for i in "./.git" "$WM_PROJECT_DIR/.git"
do
if [ -d "$i" ]
then
projectdir="${i%/*}"
break
fi
done
# Parse options
while [ "$#" -gt 0 ]
do
case "$1" in
-h | -help* | --help*)
printHelp
-h | -help*)
usage
;;
-bin)
if [ -n "$FOAM_APPBIN" ] && cd "$FOAM_APPBIN"
then
/bin/ls -1
exit 0
else
-appbin)
test -n "$FOAM_APPBIN" && cd "$FOAM_APPBIN" || \
die "FOAM_APPBIN is not valid"
fi
;;
-no-git)
unset FOAM_GIT_DIR
/bin/ls -1
exit 0
;;
*)
die "unknown option/argument: '$1'"
;;
esac
shift
done
# Check environment variables
[ -d "$WM_PROJECT_DIR" ] || \
die "Bad or unset environment variable: \$WM_PROJECT_DIR"
# Default is grep (via git)
[ -d "$projectdir" ] || \
die "Cannot locate OpenFOAM project, or it does not have a git directory"
cd "$WM_PROJECT_DIR" || die "No project directory: $WM_PROJECT_DIR"
# Run from top-level directory - otherwise the grep is quite difficult
# A version with 'find' is likewise possible, but not as fast.
# Check 'src' too, in case somehow something is there as well.
for dir in applications/solvers applications/utilities src
do
if [ -d "$dir" ]
then
echo "Checking: $dir" 1>&2
else
echo "No directory: $dir" 1>&2
continue
fi
if [ -d "$FOAM_GIT_DIR" ]
then
git grep --cached -H -P '^\s*EXE\s*=' "$dir" 2>/dev/null
else
# Filesystem find (not quite as fast)
for i in $(find "$dir" -name files)
do
grep -H -P '^\s*EXE\s*=' "$i" 2>/dev/null
done
fi
done | sed -ne 's@/Make/files:.*$@@p' | sed -e 's@.*/@@' | sort | uniq
(
cd "$projectdir" && \
git grep --cached -P '^\s*EXE\s*=' \
applications/solvers \
applications/utilities \
src
) | sed -e 's@.*/@@' | sort | uniq
# -----------------------------------------------------------------------------

View File

@ -1,125 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / 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, distributed under GPL-3.0-or-later.
#
# Script
# foamGrepLibTargets
#
# Description
# List library targets (contain "LIB_LIBS =")
#
#------------------------------------------------------------------------------
# Locations
FOAM_GIT_DIR="$WM_PROJECT_DIR/.git"
printHelp() {
cat<<USAGE
usage: ${0##*/}
-no-git Disable use of git for obtaining information
-app Search applications/solvers/ applications/utilities/
-src Search src/
-no-git Disable use of git for obtaining information
-help Print the usage
List library targets (contains LIB_LIBS). Uses git when possible
USAGE
exit 0 # clean exit
}
# Report error and exit
die()
{
exec 1>&2
echo
echo "Error encountered:"
while [ "$#" -ge 1 ]; do echo " $1"; shift; done
echo
echo "See '${0##*/} -help' for usage"
echo
exit 1
}
#------------------------------------------------------------------------------
unset locations
# Parse options
while [ "$#" -gt 0 ]
do
case "$1" in
-h | -help* | --help*)
printHelp
;;
-app)
locations="$locations applications/solvers applications/utilities"
;;
-src)
locations="$locations src"
;;
-no-git)
unset FOAM_GIT_DIR
;;
*)
die "unknown option/argument: '$1'"
;;
esac
shift
done
# Check environment variables
[ -d "$WM_PROJECT_DIR" ] || \
die "Bad or unset environment variable: \$WM_PROJECT_DIR"
# Fallback to all locations
if [ -z "$locations" ]
then
locations="applications/solvers applications/utilities src"
fi
set -- $locations
if [ "$#" -eq 0 ]
then
die "No search locations"
fi
# Run from top-level directory - otherwise the grep is quite difficult
cd "$WM_PROJECT_DIR" || die "No project directory: $WM_PROJECT_DIR"
for dir in "$@"
do
if [ -d "$dir" ]
then
echo "Checking: $dir" 1>&2
else
echo "No directory: $dir" 1>&2
continue
fi
if [ -d "$FOAM_GIT_DIR" ]
then
git grep --cached -H -P '^\s*LIB_LIBS\s*=' "$dir" 2>/dev/null
else
# Filesystem find (not quite as fast)
for i in $(find "$dir" -name options)
do
grep -H -P '^\s*LIB_LIBS\s*=' "$i" 2>/dev/null
done
fi
done | sed -ne 's@/Make/options:.*$@@p' | sort | uniq
# -----------------------------------------------------------------------------

View File

@ -137,11 +137,15 @@ cd $WM_THIRD_PARTY_DIR
Subequent compilation with Allwmake will now run largely without any
problems, except that the components linking against CGAL
(foamyMesh and surfaceBooleanFeatures) will also try to link against
a nonexistent mpfr library. As a workaround, the link-dependency will
be removed in wmake/rules/General/cgal by specifying the `CGAL_FLAVOUR`
when compiling:
a nonexistent mpfr library. As a workaround, the link-dependency can
be removed in wmake/rules/General/CGAL :
```
no-cgal | cgal-header | cgal-header-no-mpfr | cgal-no-mpfr | cgal-mpfr
CGAL_LIBS = \
-L$(BOOST_ARCH_PATH)/lib \
-L$(BOOST_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
-L$(CGAL_ARCH_PATH)/lib \
-L$(CGAL_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
-lCGAL
```
A robuster solution is still being sought.

View File

@ -96,7 +96,6 @@ export WM_COMPILE_OPTION=Opt
# +strict : more deprecation warnings (may generate *many* warnings)
# ccache=... : ccache command (unquoted, single/double or <> quoted)
# version=... : compiler suffix (eg, version=11 -> gcc-11)
# lnInclude-extra : add '-extra' option for wmakeLnInclude
#export WM_COMPILE_CONTROL="+strict"
# [WM_MPLIB] - MPI implementation:

View File

@ -28,16 +28,6 @@ faceZones (f0 f1);
//faceSets (f0 f1);
//faceSetsShadow (f0Shadow f1Shadow);
// Optional : if edge on multiple sets/zones :
// - addSidePatches false : extrude as an internal face (same as a zone-internal
// edge)
// - addSidePatches true : extrude each zone separately so creating multiple
// (default) boundary faces. These faces go into a cyclic type
// patch with corresponding transform.
addSidePatches false;
// Adapt the original mesh to have mapped patches at where the
// faceZones are?
// If true:

View File

@ -22,15 +22,12 @@ set c0;
// x,y,z axis. Specify in globalCoeffs section below.
// - patchLocal : coordinate system different for every cell. Specify in
// patchLocalCoeffs section below.
// - user : coordinate system provided. Usually cylindrical or spherical.
// Specify in userCoeffs section below.
// - fieldBased : uses the list of field names from the directions list for
// selecting the directions to cut. Meant to be used with geometricCut, but
// can also be used with useHexTopology.
coordinateSystem global;
//coordinateSystem patchLocal;
//coordinateSystem fieldBased;
//coordinateSystem user;
// .. and its coefficients. x,y in this case. (normal direction is calculated
// as tan1^tan2)
@ -46,15 +43,6 @@ patchLocalCoeffs
tan1 (1 0 0);
}
userCoeffs
{
type cylindrical;
origin (0 0 0);
e1 (1 0 0); // tan1 direction
e3 (0 1 0); // normal direction
}
// List of directions to refine, if global or patchLocal
directions
(

View File

@ -135,18 +135,6 @@ OptimisationSwitches
// Default communication type (nonBlocking | scheduled | buffered)
commsType nonBlocking;
// Use host/node topology-aware routines
// 0: disabled
// 1: split by hostname [default]
// 2: split by shared
// >=4: (debug/manual) split with given number per node
nodeComms 1;
// Minimum number of nodes before topology-aware routines are enabled
// <= 2 : always
// >= 3 : when there are more than N nodes
nodeComms.min 0;
// Transfer double as float for processor boundaries. Mostly defunct.
floatTransfer 0;
@ -240,12 +228,6 @@ OptimisationSwitches
// from all the individual wall patches. Set to 0/false to revert to
// <v2412 behaviour
//useCombinedWallPatch 0;
//- Use local communicator for AMI communication. Default for v2506.
//localAMIComm = 0; // old behaviour : all ranks included
//localAMIComm = 1; // (default) only ranks that have patch faces
//localAMIComm = 2; // like 1 but always include rank 0 so messages
// still come from processor0
}

View File

@ -96,7 +96,6 @@ setenv WM_COMPILE_OPTION Opt
# +strict : more deprecation warnings (may generate *many* warnings)
# ccache=... : ccache command (unquoted, single/double or <> quoted)
# version=... : compiler suffix (eg, version=11 -> gcc-11)
# lnInclude-extra : add '-extra' option for wmakeLnInclude
#setenv WM_COMPILE_CONTROL "+strict"
# [WM_MPLIB] - MPI implementation:

View File

@ -0,0 +1,10 @@
// Compatibility include. For v2112 and earlier
#ifndef FoamCompat_Swap_H
#define FoamCompat_Swap_H
#include "stdFoam.H"
#endif
// ************************************************************************* //

View File

@ -0,0 +1,11 @@
// ************************************************************************* //
// Compatibility include
#ifndef FoamCompat_endian_H
#define FoamCompat_endian_H
#include "foamEndian.H"
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2025 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -188,12 +188,12 @@ Foam::PackedList<Width>::unpack() const
{
static_assert
(
std::is_integral_v<IntType>,
std::is_integral<IntType>::value,
"Integral required for output."
);
static_assert
(
Width < std::numeric_limits<IntType>::digits,
std::numeric_limits<IntType>::digits >= Width,
"Width of IntType is too small to hold result"
);
@ -244,12 +244,12 @@ Foam::PackedList<Width>::unpack(const labelRange& range) const
{
static_assert
(
std::is_integral_v<IntType>,
std::is_integral<IntType>::value,
"Integral required for unpack output."
);
static_assert
(
Width < std::numeric_limits<IntType>::digits,
std::numeric_limits<IntType>::digits >= Width,
"Width of IntType is too small to hold unpack output."
);
@ -278,12 +278,12 @@ Foam::PackedList<Width>::unpack(const labelUList& locations) const
{
static_assert
(
std::is_integral_v<IntType>,
std::is_integral<IntType>::value,
"Integral required for unpack output."
);
static_assert
(
Width < std::numeric_limits<IntType>::digits,
std::numeric_limits<IntType>::digits >= Width,
"Width of IntType is too small to hold unpack output."
);

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