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