mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve hashing overloads of string-types and HashTable/HashSet
- additional dummy template parameter to assist with supporting
derived classes. Currently just used for string types, but can be
extended.
- provide hash specialization for various integer types.
Removes the need for any forwarding.
- change default hasher for HashSet/HashTable from 'string::hash'
to `Hash<Key>`. This avoids questionable hashing calls and/or
avoids compiler resolution problems.
For example,
HashSet<label>::hasher and labelHashSet::hasher now both properly
map to Hash<label> whereas previously HashSet<label> would have
persistently mapped to string::hash, which was incorrect.
- standardize internal hashing functors.
Functor name is 'hasher', as per STL set/map and the OpenFOAM
HashSet/HashTable definitions.
Older code had a local templated name, which added unnecessary
clutter and the template parameter was always defaulted.
For example,
Old: `FixedList<label, 3>::Hash<>()`
New: `FixedList<label, 3>::hasher()`
Unchanged: `labelHashSet::hasher()`
Existing `Hash<>` functor namings are still supported,
but deprecated.
- define hasher and Hash specialization for bitSet and PackedList
- add symmetric hasher for 'face'.
Starts with lowest vertex value and walks in the direction
of the next lowest value. This ensures that the hash code is
independent of face orientation and face rotation.
NB:
- some of keys for multiphase handling (eg, phasePairKey)
still use yet another function naming: `hash` and `symmHash`.
This will be targeted for alignment in the future.
This commit is contained in:
committed by
Andrew Heather
parent
b060378dca
commit
95cd8ee75c
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -59,24 +59,23 @@ class multiphaseMixtureThermo
|
||||
{
|
||||
public:
|
||||
|
||||
//- Symmetric pair of interface names
|
||||
class interfacePair
|
||||
:
|
||||
public Pair<word>
|
||||
{
|
||||
public:
|
||||
|
||||
struct hash
|
||||
{
|
||||
label operator()(const interfacePair& key) const
|
||||
{
|
||||
return word::hash()(key.first()) + word::hash()(key.second());
|
||||
}
|
||||
};
|
||||
// Always use symmetric hashing
|
||||
using hasher = Pair<word>::symmHasher;
|
||||
|
||||
// Always use symmetric hashing (alias)
|
||||
using hash = Pair<word>::symmHasher;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
interfacePair() {} // = default
|
||||
interfacePair() = default;
|
||||
|
||||
interfacePair(const word& alpha1Name, const word& alpha2Name)
|
||||
:
|
||||
@ -97,11 +96,7 @@ public:
|
||||
const interfacePair& b
|
||||
)
|
||||
{
|
||||
return
|
||||
(
|
||||
((a.first() == b.first()) && (a.second() == b.second()))
|
||||
|| ((a.first() == b.second()) && (a.second() == b.first()))
|
||||
);
|
||||
return (0 != Pair<word>::compare(a, b));
|
||||
}
|
||||
|
||||
friend bool operator!=
|
||||
@ -117,7 +112,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
// Private Data
|
||||
|
||||
//- Dictionary of phases
|
||||
PtrDictionary<phaseModel> phases_;
|
||||
@ -140,7 +135,7 @@ private:
|
||||
const dimensionedScalar deltaN_;
|
||||
|
||||
|
||||
// Private member functions
|
||||
// Private Member Functions
|
||||
|
||||
void calcAlphas();
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -67,24 +68,23 @@ class multiphaseMixture
|
||||
{
|
||||
public:
|
||||
|
||||
//- Symmetric pair of interface names
|
||||
class interfacePair
|
||||
:
|
||||
public Pair<word>
|
||||
{
|
||||
public:
|
||||
|
||||
struct hash
|
||||
{
|
||||
label operator()(const interfacePair& key) const
|
||||
{
|
||||
return word::hash()(key.first()) + word::hash()(key.second());
|
||||
}
|
||||
};
|
||||
// Always use symmetric hashing
|
||||
using hasher = Pair<word>::symmHasher;
|
||||
|
||||
// Always use symmetric hashing (alias)
|
||||
using hash = Pair<word>::symmHasher;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
interfacePair() {} // = default
|
||||
interfacePair() = default;
|
||||
|
||||
interfacePair(const word& alpha1Name, const word& alpha2Name)
|
||||
:
|
||||
@ -105,11 +105,7 @@ public:
|
||||
const interfacePair& b
|
||||
)
|
||||
{
|
||||
return
|
||||
(
|
||||
((a.first() == b.first()) && (a.second() == b.second()))
|
||||
|| ((a.first() == b.second()) && (a.second() == b.first()))
|
||||
);
|
||||
return (0 != Pair<word>::compare(a, b));
|
||||
}
|
||||
|
||||
friend bool operator!=
|
||||
|
||||
@ -186,14 +186,14 @@ int main(int argc, char *argv[])
|
||||
FixedList<label, 4> list1{2, 3, 4, 5};
|
||||
|
||||
Info<< "list1:" << list1
|
||||
<< " hash:" << FixedList<label, 4>::Hash<>()(list1) << nl
|
||||
<< " hash:" << FixedList<label, 4>::hasher()(list1) << nl
|
||||
<< " hash:" << Hash<FixedList<label, 4>>()(list1) << nl;
|
||||
|
||||
label a[4] = {0, 1, 2, 3};
|
||||
FixedList<label, 4> list2(a);
|
||||
|
||||
Info<< "list2:" << list2
|
||||
<< " hash:" << FixedList<label, 4>::Hash<>()(list2) << nl
|
||||
<< " hash:" << FixedList<label, 4>::hasher()(list2) << nl
|
||||
<< " hash:" << Hash<FixedList<label, 4>>()(list2) << nl;
|
||||
|
||||
|
||||
|
||||
@ -127,13 +127,13 @@ int main()
|
||||
myTable.insert("sqrt2", autoPtr<double>::New(1.414214));
|
||||
myTable.insert("euler", autoPtr<double>::New(0.577216));
|
||||
|
||||
HashTable<std::unique_ptr<double>, word, string::hash> myTable1;
|
||||
HashTable<std::unique_ptr<double>> myTable1;
|
||||
|
||||
myTable1.set("abc", std::unique_ptr<double>(new double(42.1)));
|
||||
myTable1.set("pi", std::unique_ptr<double>(new double(3.14159)));
|
||||
myTable1.set("natlog", std::unique_ptr<double>(new double(2.718282)));
|
||||
|
||||
HashTable<autoPtr<double>, word, string::hash> myTable2;
|
||||
HashTable<autoPtr<double>> myTable2;
|
||||
|
||||
myTable2.set("abc", autoPtr<double>(new double(42.1)));
|
||||
myTable2.set("pi", autoPtr<double>(new double(3.14159)));
|
||||
@ -148,7 +148,7 @@ int main()
|
||||
|
||||
{
|
||||
auto iter2 = myTable2.find("pi");
|
||||
Info<< nl "Got pi=";
|
||||
Info<< nl << "Got pi=";
|
||||
if (iter2.good())
|
||||
{
|
||||
Info<< **iter2 << nl;
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2018 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -80,6 +80,11 @@ void printMinMax(const HashSet<Key, Hash>& set)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Info<< "labelHashSet hasher: "
|
||||
<< typeid(labelHashSet::hasher).name() << nl
|
||||
<< "HashSet<label> hasher: "
|
||||
<< typeid(HashSet<label>::hasher).name() << nl << nl;
|
||||
|
||||
hashedWordList words
|
||||
{
|
||||
"abc",
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
Test-Hashing.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-Hashing
|
||||
224
applications/test/Hashing1/HashFunction.H
Normal file
224
applications/test/Hashing1/HashFunction.H
Normal file
@ -0,0 +1,224 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::HashFunction
|
||||
|
||||
Description
|
||||
Hash function class.
|
||||
|
||||
Verify that template overloads are properly resolved
|
||||
|
||||
Note
|
||||
The second template parameter (bool) is used for SFINAE overloading,
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef HashFunction_H
|
||||
#define HashFunction_H
|
||||
|
||||
#include "Hash.H"
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
#define HashTypeInfo(Args) void info() { std::cerr<< "" Args << "\n"; }
|
||||
#else
|
||||
#define HashTypeInfo(Args) void info() {}
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Hash Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class T, class SFINAEType=bool>
|
||||
struct HashFun
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "default"; }
|
||||
#endif
|
||||
HashTypeInfo("plain hash")
|
||||
|
||||
unsigned operator()(const T& obj, unsigned seed=0) const
|
||||
{
|
||||
return Foam::Hasher(&obj, sizeof(obj), seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Hashing for label
|
||||
template<> struct HashFun<Foam::label> : Hash<label>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "label"; }
|
||||
#endif
|
||||
HashTypeInfo("hash label")
|
||||
};
|
||||
|
||||
|
||||
//- Hashing for pointers, interpret pointer as a integer type
|
||||
template<> struct HashFun<void*> : Hash<void *>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "pointer"; }
|
||||
#endif
|
||||
HashTypeInfo("hash ptr")
|
||||
};
|
||||
|
||||
|
||||
//- Hashing for string types
|
||||
template<class StringType>
|
||||
struct HashFun
|
||||
<
|
||||
StringType,
|
||||
typename std::enable_if
|
||||
<
|
||||
std::is_base_of<std::string, StringType>::value, bool
|
||||
>::type
|
||||
>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "string"; }
|
||||
#endif
|
||||
HashTypeInfo("hash string")
|
||||
|
||||
unsigned operator()(const std::string& obj, unsigned seed=0) const
|
||||
{
|
||||
return Foam::Hasher(obj.data(), obj.size(), seed);
|
||||
}
|
||||
};
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Various
|
||||
#include "edge.H"
|
||||
#include "face.H"
|
||||
#include "triFace.H"
|
||||
#include "Pair.H"
|
||||
#include "Tuple2.H"
|
||||
#include "DynamicList.H"
|
||||
#include "FixedList.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
template<> struct HashFun<edge> : Hash<edge>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "edge"; }
|
||||
#endif
|
||||
HashTypeInfo("hash edge")
|
||||
};
|
||||
|
||||
|
||||
template<> struct HashFun<face> : Hash<face>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "face"; }
|
||||
#endif
|
||||
HashTypeInfo("hash face")
|
||||
};
|
||||
|
||||
|
||||
template<> struct HashFun<triFace> : Hash<triFace>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "triFace"; }
|
||||
#endif
|
||||
HashTypeInfo("hash triFace")
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
struct HashFun<Pair<T>> : Hash<Pair<T>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "Pair"; }
|
||||
#endif
|
||||
HashTypeInfo("hash Pair")
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct HashFun<Tuple2<T1, T2>> : Hash<Tuple2<T1, T2>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "Tuple2"; }
|
||||
#endif
|
||||
HashTypeInfo("hash 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")
|
||||
};
|
||||
|
||||
template<class T> struct HashFun<UList<T>> : Hash<UList<T>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "UList"; }
|
||||
#endif
|
||||
HashTypeInfo("hash UList")
|
||||
};
|
||||
|
||||
template<class T, int SizeMin>
|
||||
struct HashFun<DynamicList<T, SizeMin>> : Hash<DynamicList<T, SizeMin>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "DynamicList"; }
|
||||
#endif
|
||||
HashTypeInfo("hash DynamicList")
|
||||
};
|
||||
|
||||
template<class T, unsigned N>
|
||||
struct HashFun<FixedList<T, N>> : Hash<FixedList<T, N>>
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
static constexpr const char* name() noexcept { return "FixedList"; }
|
||||
#endif
|
||||
HashTypeInfo("hash FixedList")
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
3
applications/test/Hashing1/Make/files
Normal file
3
applications/test/Hashing1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-Hashing1.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-Hashing1
|
||||
163
applications/test/Hashing1/Test-Hashing1.C
Normal file
163
applications/test/Hashing1/Test-Hashing1.C
Normal file
@ -0,0 +1,163 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 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-Hashing1
|
||||
|
||||
Description
|
||||
Test/verify overloads of Hash function
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "IOstreams.H"
|
||||
#include "IOobject.H"
|
||||
#include "IFstream.H"
|
||||
|
||||
#include "stringList.H"
|
||||
#include "labelList.H"
|
||||
#include "labelPair.H"
|
||||
#include "wordPair.H"
|
||||
#include "edgeList.H"
|
||||
#include "faceList.H"
|
||||
#include "triFaceList.H"
|
||||
|
||||
#define FULLDEBUG
|
||||
#include "HashFunction.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
template<class T>
|
||||
unsigned rawHasher(const T& obj)
|
||||
{
|
||||
return Foam::Hasher(&obj, sizeof(T), 0u);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
typedef unsigned Type;
|
||||
Type value = 100;
|
||||
|
||||
Info<< "hash " << typeid(value).name() << " of " << value << nl;
|
||||
Info<< " Hasher: " << rawHasher(value) << nl;
|
||||
Info<< " Hash<>: " << Hash<Type>()(value) << nl;
|
||||
}
|
||||
{
|
||||
typedef int32_t Type;
|
||||
Type value = 100;
|
||||
|
||||
Info<< "hash " << typeid(value).name() << " of " << value << nl;
|
||||
Info<< " Hasher: " << rawHasher(value) << nl;
|
||||
Info<< " Hash<>: " << Hash<Type>()(value) << nl;
|
||||
}
|
||||
{
|
||||
typedef int64_t Type;
|
||||
Type value = 100;
|
||||
|
||||
Info<< "hash " << typeid(value).name() << " of " << value << nl;
|
||||
Info<< " Hasher: " << rawHasher(value) << nl;
|
||||
Info<< " Hash<>: " << Hash<Type>()(value) << nl;
|
||||
}
|
||||
|
||||
HashFun<std::string>().info();
|
||||
HashFun<string>().info();
|
||||
HashFun<Foam::word>().info();
|
||||
HashFun<Foam::keyType>().info();
|
||||
|
||||
HashFun<int>().info();
|
||||
HashFun<label>().info();
|
||||
HashFun<float>().info();
|
||||
HashFun<double>().info();
|
||||
|
||||
{
|
||||
float value = 15.f;
|
||||
|
||||
Info<< "hash of " << Foam::name(&value)
|
||||
<< " = " << HashFun<void*>()(&value) << nl;
|
||||
}
|
||||
|
||||
HashFun<labelList>().info();
|
||||
HashFun<wordUList>().info();
|
||||
HashFun<edge>().info();
|
||||
|
||||
HashFun<Pair<label>>().info();
|
||||
HashFun<labelPair>().info();
|
||||
HashFun<labelPairPair>().info();
|
||||
|
||||
HashFun<Tuple2<label, word>>().info();
|
||||
|
||||
{
|
||||
typedef Tuple2<label, word> Type;
|
||||
Type obj(10, "test");
|
||||
Info<< obj << " hash=" << Hash<Type>()(obj) << nl;
|
||||
}
|
||||
|
||||
{
|
||||
typedef Tuple2<label, label> Type;
|
||||
Type obj(10, 12);
|
||||
Info<< obj << " hash=" << Hash<Type>()(obj) << nl;
|
||||
}
|
||||
|
||||
{
|
||||
typedef Pair<label> Type;
|
||||
Type obj(10, 12);
|
||||
Info<< obj << " hash=" << Hash<Type>()(obj) << nl;
|
||||
}
|
||||
|
||||
{
|
||||
typedef std::pair<label, label> Type;
|
||||
Type obj(10, 12);
|
||||
Info<< obj << " hash=" << Hash<Type>()(obj) << nl;
|
||||
|
||||
HashSet<Type> hs;
|
||||
hs.insert(obj);
|
||||
hs.erase(obj);
|
||||
}
|
||||
|
||||
{
|
||||
Pair<label>::hasher op;
|
||||
Info<< "hasher: " << op(Pair<label>(10, 12)) << nl;
|
||||
}
|
||||
|
||||
// Not supported
|
||||
#if 0
|
||||
{
|
||||
Tuple2<label, label>::hasher op;
|
||||
Info<< "hasher: " << op(Tuple2<label>(10, 12)) << nl;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Info<< "\nEnd\n" << nl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
3
applications/test/Hashing2/Make/files
Normal file
3
applications/test/Hashing2/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-Hashing2.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-Hashing2
|
||||
3
applications/test/Hashing2/Make/options
Normal file
3
applications/test/Hashing2/Make/options
Normal file
@ -0,0 +1,3 @@
|
||||
EXE_INC = ${c++LESSWARN}
|
||||
|
||||
/* EXE_LIBS = */
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,7 +25,7 @@ License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
testHashing
|
||||
Test-Hashing2
|
||||
|
||||
Description
|
||||
|
||||
@ -44,6 +44,7 @@ Description
|
||||
#include "triFaceList.H"
|
||||
|
||||
#include "Hash.H"
|
||||
#include "HashSet.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -84,7 +85,7 @@ void reportHashList(const UList<string>& list)
|
||||
|
||||
for (const string& val : list)
|
||||
{
|
||||
unsigned hash1 = string::hash()(val);
|
||||
unsigned hash1 = string::hasher()(val);
|
||||
|
||||
Info<< hex << hash1 << ": " << val << nl;
|
||||
}
|
||||
@ -117,11 +118,11 @@ void reportHashList(const UList<face>& list)
|
||||
for (const face& f : list)
|
||||
{
|
||||
// Direct value
|
||||
unsigned hash1 = face::Hash<>()(f);
|
||||
unsigned hash1 = face::hasher()(f);
|
||||
|
||||
unsigned hash2 = Hash<face>()(f);
|
||||
|
||||
Info<< hex << "face::Hash<> " << hash1
|
||||
Info<< hex << "face hash " << hash1
|
||||
<< " Hash<face> " << hash2
|
||||
<< ": " << dec << flatOutput(f) << nl;
|
||||
}
|
||||
@ -132,14 +133,10 @@ void reportHashList(const UList<labelList>& list)
|
||||
{
|
||||
for (const labelList& val : list)
|
||||
{
|
||||
unsigned hash1 = Hasher
|
||||
(
|
||||
val.cdata(),
|
||||
val.size() * sizeof(label)
|
||||
);
|
||||
unsigned hash1 = Foam::Hasher(val.cdata(), val.size_bytes());
|
||||
|
||||
unsigned hash2 = Hash<labelList>()(val);
|
||||
unsigned hash2b = labelList::Hash<>()(val);
|
||||
unsigned hash2b = labelList::hasher()(val);
|
||||
|
||||
Info<< hex << hash1 << " or " << hash2
|
||||
<< "(" << hash2b << ") "
|
||||
@ -147,7 +144,7 @@ void reportHashList(const UList<labelList>& list)
|
||||
}
|
||||
|
||||
unsigned hash2 = Hash<labelListList>()(list);
|
||||
unsigned hash2bad = HasherT(list);
|
||||
unsigned hash2bad = Foam::Hasher(&list, sizeof(list));
|
||||
|
||||
Info<< hex << hash2 << " : " << dec << flatOutput(list) << nl
|
||||
<< hex << hash2bad << " as direct hash would be wrong"
|
||||
@ -164,10 +161,10 @@ void reportHashList(const UList<wordPair>& list)
|
||||
unsigned hash1 = Hash<wordPair>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = wordPair::Hash<>()(pr);
|
||||
unsigned hash2 = wordPair::hasher()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2sym = wordPair::SymmHash<>()(pr);
|
||||
unsigned hash2sym = wordPair::symmHasher()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash3 = Hash<FixedList<word,2>>()(pr);
|
||||
@ -189,7 +186,7 @@ void reportHashList(const UList<labelPair>& list)
|
||||
unsigned hash1 = Hash<labelPair>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = labelPair::Hash<>()(pr);
|
||||
unsigned hash2 = labelPair::hasher()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash3 = Hash<labelPair>()(pr);
|
||||
@ -210,7 +207,7 @@ void reportHashList(const UList<labelPairPair>& list)
|
||||
unsigned hash1 = Hash<labelPairPair>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = labelPairPair::Hash<>()(pr);
|
||||
unsigned hash2 = labelPairPair::hasher()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash3 = Hash<labelPairPair>()(pr);
|
||||
@ -231,7 +228,7 @@ void reportHashList(const UList<edge>& list)
|
||||
unsigned hash1 = Hash<edge>()(e);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = labelPair::Hash<>()(e);
|
||||
unsigned hash2 = labelPair::hasher()(e);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash3 = Hash<labelPair>()(e);
|
||||
@ -251,7 +248,7 @@ void reportHashList(const UList<triFace>& list)
|
||||
{
|
||||
// direct value
|
||||
unsigned hash1 = Hash<triFace>()(f);
|
||||
unsigned hash2 = FixedList<label, 3>::Hash<>()(f);
|
||||
unsigned hash2 = FixedList<label, 3>::hasher()(f);
|
||||
|
||||
Info<< hex << hash1 << " (as FixedList: " << hash2
|
||||
<< "): " << dec << f << nl;
|
||||
@ -3,8 +3,8 @@
|
||||
#include "Hasher.H"
|
||||
#include "int.H"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
|
||||
#ifndef CLOCKS_PER_SEC
|
||||
#ifdef CLK_TCK
|
||||
@ -1048,7 +1048,7 @@ int32_t i;
|
||||
|
||||
struct tagtest {
|
||||
double res;
|
||||
char * name;
|
||||
const char * name;
|
||||
hashFn hash;
|
||||
} tests[] = {
|
||||
// { 0.0, "CRC32\t\t", GetCRC32 },
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -658,11 +658,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<<"hash of " << flatOutput(list1)
|
||||
<< " = " << Hash<labelList>()(list1) << " or "
|
||||
<< labelList::Hash<>()(list1) << nl;
|
||||
<< labelList::hasher()(list1) << nl;
|
||||
|
||||
Info<<"hash of " << flatOutput(list2) << " = "
|
||||
<< Hash<labelList>()(list2) << " or "
|
||||
<< labelList::Hash<>()(list2) << nl;
|
||||
<< labelList::hasher()(list2) << nl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -57,7 +57,7 @@ Ostream& operator<<
|
||||
);
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
template<class T, class Key, class Hash=Foam::Hash<Key>>
|
||||
class HashSorter
|
||||
{
|
||||
const HashTable<T, Key, Hash>& table;
|
||||
@ -219,8 +219,8 @@ int main(int argc, char *argv[])
|
||||
Info<< nl << "Test inplaceMapValue" << nl << nl;
|
||||
|
||||
HashTable<label> input;
|
||||
typedef HashSorter<label, label, Hash<label>> Mapper;
|
||||
typedef HashSorter<label, word, string::hash> Sorter;
|
||||
typedef HashSorter<label, label> Mapper;
|
||||
typedef HashSorter<label, word> Sorter;
|
||||
|
||||
for (label i=0; i < 10; ++i)
|
||||
{
|
||||
|
||||
3
applications/test/faceHashing/Make/files
Normal file
3
applications/test/faceHashing/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-faceHashing.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-faceHashing
|
||||
3
applications/test/faceHashing/Make/options
Normal file
3
applications/test/faceHashing/Make/options
Normal file
@ -0,0 +1,3 @@
|
||||
EXE_INC = ${c++LESSWARN}
|
||||
|
||||
/* EXE_LIBS = */
|
||||
153
applications/test/faceHashing/Test-faceHashing.C
Normal file
153
applications/test/faceHashing/Test-faceHashing.C
Normal file
@ -0,0 +1,153 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 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-faceHashing
|
||||
|
||||
Description
|
||||
Basic tests of face/triFace hashing
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "IOstreams.H"
|
||||
#include "IOobject.H"
|
||||
#include "IFstream.H"
|
||||
|
||||
#include "faceList.H"
|
||||
#include "triFaceList.H"
|
||||
#include "HashSet.H"
|
||||
#include "HashTable.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
template<class HashSetType, class FaceListType>
|
||||
void checkHashSet(const HashSetType& hs, const FaceListType& faces)
|
||||
{
|
||||
Info<< hs << nl;
|
||||
for (const auto& f : faces)
|
||||
{
|
||||
Info<< " " << f << " found=" << hs.found(f) << nl;
|
||||
}
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
|
||||
void checkHashes(const faceList& faces)
|
||||
{
|
||||
face::hasher op1;
|
||||
face::symmHasher op2;
|
||||
|
||||
Info<< "face hasher/symmHasher: " << faces.size() << " faces" << nl;
|
||||
for (const face& f : faces)
|
||||
{
|
||||
Info<< " " << f << " symmhash=" << op2(f)
|
||||
<< " hash=" << op1(f) << nl;
|
||||
}
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
|
||||
void checkHashes(const triFaceList& faces)
|
||||
{
|
||||
triFace::hasher op1;
|
||||
|
||||
Info<< "triFace hasher: " << faces.size() << " faces" << nl;
|
||||
for (const triFace& f : faces)
|
||||
{
|
||||
Info<< " " << f << " hash=" << op1(f) << nl;
|
||||
}
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
faceList faces
|
||||
({
|
||||
face{0, 1, 2, 3}, // regular
|
||||
face{0, 3, 2, 1}, // flip
|
||||
face{2, 3, 0, 1}, // rotate
|
||||
face{2, 1, 0, 3}, // rotate (flip)
|
||||
face{2, 0, 1, 3}, // permute
|
||||
face{2, 1, 0, 3}, // permute
|
||||
});
|
||||
|
||||
checkHashes(faces);
|
||||
|
||||
HashSet<face, face::hasher> hs1;
|
||||
HashSet<face, face::symmHasher> hs2;
|
||||
hs1.insert(faces);
|
||||
hs2.insert(faces);
|
||||
|
||||
Info<< "hashset (hasher)" << nl;
|
||||
checkHashSet(hs1, faces);
|
||||
Info<< nl;
|
||||
|
||||
hs1.erase(faces[0]);
|
||||
Info<< "remove " << faces[0] << nl;
|
||||
Info<< "hashset (hasher)" << nl;
|
||||
checkHashSet(hs1, faces);
|
||||
Info<< nl;
|
||||
|
||||
Info<< "hashset (symmHasher)" << nl;
|
||||
checkHashSet(hs2, faces);
|
||||
Info<< nl;
|
||||
|
||||
hs2.erase(faces[0]);
|
||||
Info<< "remove " << faces[0] << nl;
|
||||
Info<< "hashset (symmHasher)" << nl;
|
||||
checkHashSet(hs2, faces);
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
{
|
||||
triFaceList faces
|
||||
({
|
||||
triFace{0, 1, 2}, // regular
|
||||
triFace{0, 2, 1}, // flip
|
||||
triFace{2, 0, 1}, // rotate
|
||||
});
|
||||
|
||||
checkHashes(faces);
|
||||
|
||||
HashSet<triFace> hs1;
|
||||
hs1.insert(faces);
|
||||
|
||||
Info<< "hashset (symmHasher)" << nl;
|
||||
checkHashSet(hs1, faces);
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << nl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -167,7 +167,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
|
||||
Info<< "string:" << test << nl << "hash:"
|
||||
<< unsigned(string::hash()(test)) << endl;
|
||||
<< unsigned(string::hasher()(test)) << endl;
|
||||
|
||||
Info<<"trimLeft: " << stringOps::trimLeft(test) << endl;
|
||||
Info<<"trimRight: " << stringOps::trimRight(test) << endl;
|
||||
@ -333,11 +333,11 @@ int main(int argc, char *argv[])
|
||||
cout<< "output string with " << s2.length() << " characters\n";
|
||||
cout<< "ostream<< >" << s2 << "<\n";
|
||||
Info<< "Ostream<< >" << s2 << "<\n";
|
||||
Info<< "hash:" << hex << string::hash()(s2) << dec << endl;
|
||||
Info<< "hash:" << hex << string::hasher()(s2) << dec << endl;
|
||||
|
||||
cout<< "\ntest Foam::name()\n";
|
||||
|
||||
Info<< "hash: = " << word::printf("0x%012X", string::hash()(s2)) << endl;
|
||||
Info<< "hash: = " << word::printf("0x%012X", string::hasher()(s2)) << endl;
|
||||
|
||||
// Test formatting on int
|
||||
{
|
||||
|
||||
@ -850,35 +850,39 @@ int main(int argc, char *argv[])
|
||||
Map<label> faceToCell[2];
|
||||
|
||||
{
|
||||
HashTable<label, face, face::Hash<>> faceToFaceID(boundaryFaces.size());
|
||||
forAll(boundaryFaces, facei)
|
||||
// Can use face::symmHasher or use sorted indices instead
|
||||
// - choose the latter in case UNV has anything odd
|
||||
HashTable<label, face> faceToFaceID(2*boundaryFaces.size());
|
||||
|
||||
forAll(boundaryFaces, bfacei)
|
||||
{
|
||||
SortableList<label> sortedVerts(boundaryFaces[facei]);
|
||||
faceToFaceID.insert(face(sortedVerts), facei);
|
||||
face sortedVerts(boundaryFaces[bfacei]);
|
||||
Foam::sort(sortedVerts);
|
||||
faceToFaceID.insert(sortedVerts, bfacei);
|
||||
}
|
||||
|
||||
forAll(cellVerts, celli)
|
||||
{
|
||||
faceList faces = cellVerts[celli].faces();
|
||||
forAll(faces, i)
|
||||
const cellShape& shape = cellVerts[celli];
|
||||
|
||||
for (const face& f : shape.faces())
|
||||
{
|
||||
SortableList<label> sortedVerts(faces[i]);
|
||||
const auto fnd = faceToFaceID.find(face(sortedVerts));
|
||||
|
||||
if (fnd.found())
|
||||
face sortedVerts(f);
|
||||
Foam::sort(sortedVerts);
|
||||
const label bfacei = faceToFaceID.lookup(sortedVerts, -1);
|
||||
if (bfacei != -1)
|
||||
{
|
||||
label facei = *fnd;
|
||||
int stat = face::compare(faces[i], boundaryFaces[facei]);
|
||||
const int cmp = face::compare(f, boundaryFaces[bfacei]);
|
||||
|
||||
if (stat == 1)
|
||||
if (cmp == 1)
|
||||
{
|
||||
// Same orientation. Cell is owner.
|
||||
own[facei] = celli;
|
||||
own[bfacei] = celli;
|
||||
}
|
||||
else if (stat == -1)
|
||||
else if (cmp == -1)
|
||||
{
|
||||
// Opposite orientation. Cell is neighbour.
|
||||
nei[facei] = celli;
|
||||
nei[bfacei] = celli;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -958,15 +962,13 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
const cellShape& shape = cellVerts[celli];
|
||||
|
||||
const faceList shapeFaces(shape.faces());
|
||||
|
||||
forAll(shapeFaces, i)
|
||||
for (const face& f : shape.faces())
|
||||
{
|
||||
label patchi = findPatch(dofGroups, shapeFaces[i]);
|
||||
label patchi = findPatch(dofGroups, f);
|
||||
|
||||
if (patchi != -1)
|
||||
{
|
||||
dynPatchFaces[patchi].append(shapeFaces[i]);
|
||||
dynPatchFaces[patchi].append(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ int main(int argc, char *argv[])
|
||||
label maxPatch = 0;
|
||||
|
||||
// Boundary faces as three vertices
|
||||
HashTable<label, triFace, triFace::Hash<>> vertsToBoundary(nFaces);
|
||||
HashTable<label, triFace> vertsToBoundary(nFaces);
|
||||
|
||||
forAll(boundaryFaces, facei)
|
||||
{
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -55,15 +56,15 @@ namespace Foam
|
||||
template<class Triangulation>
|
||||
class pointPairs
|
||||
:
|
||||
public HashSet<labelPairPair, labelPairPair::Hash<>>
|
||||
public HashSet<labelPairPair>
|
||||
{
|
||||
// Private typedefs
|
||||
// Private Typedefs
|
||||
|
||||
typedef HashSet<labelPairPair, labelPairPair::Hash<>> StorageContainer;
|
||||
typedef HashSet<labelPairPair> StorageContainer;
|
||||
typedef typename Triangulation::Vertex_handle Vertex_handle;
|
||||
|
||||
|
||||
// Private data
|
||||
// Private Data
|
||||
|
||||
const Triangulation& triangulation_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user