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:
Mark Olesen 2021-04-12 17:05:11 +02:00 committed by Andrew Heather
parent b060378dca
commit 95cd8ee75c
75 changed files with 1429 additions and 955 deletions

View File

@ -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();

View File

@ -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!=

View File

@ -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;

View File

@ -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;

View File

@ -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",

View File

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

View 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
// ************************************************************************* //

View File

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

View 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;
}
// ************************************************************************* //

View File

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

View File

@ -0,0 +1,3 @@
EXE_INC = ${c++LESSWARN}
/* EXE_LIBS = */

View File

@ -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;

View File

@ -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 },

View File

@ -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;

View File

@ -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)
{

View File

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

View File

@ -0,0 +1,3 @@
EXE_INC = ${c++LESSWARN}
/* EXE_LIBS = */

View 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;
}
// ************************************************************************* //

View File

@ -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
{

View File

@ -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);
}
}
}

View File

@ -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)
{

View File

@ -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_;

View File

@ -180,7 +180,8 @@ $(ops)/flipOp.C
primitives/predicates/scalar/scalarPredicates.C
primitives/hashes/Hasher/Hasher.C
hash = primitives/hashes/Hash
$(hash)/Hasher.C
sha1 = primitives/hashes/SHA1
$(sha1)/SHA1.C

View File

@ -518,6 +518,24 @@ public:
);
// Hashing
//- Hashing functor for PackedList
// Seeded with logical size for disambiguation of padding
struct hasher
{
unsigned operator()(const PackedList<Width>& obj) const
{
return Foam::Hasher
(
obj.cdata(),
obj.size_bytes(),
unsigned(obj.size())
);
}
};
// Housekeeping
//- Deprecated(2020-11) use fill()
@ -533,6 +551,13 @@ public:
};
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- Hashing for PackedList data
template<unsigned Width>
struct Hash<PackedList<Width>> : PackedList<Width>::hasher {};
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
//- Write List to Ostream, as per UList::writeList() with default length.

View File

@ -594,6 +594,12 @@ public:
};
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- Hashing for bitSet data
template<> struct Hash<bitSet> : bitSet::hasher {};
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
//- Write bitset to Ostream with 40 items per line.

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -62,10 +62,10 @@ namespace HashSetOps
{
//- Combine HashSet operation. Equivalent to 'a |= b'
template<class Key=word, class Hash=string::hash>
template<class Key=word, class HashType=Foam::Hash<Key>>
struct plusEqOp
{
typedef HashSet<Key, Hash> value_type;
typedef HashSet<Key, HashType> value_type;
void operator()(value_type& a, const value_type& b) const
{
@ -131,10 +131,10 @@ namespace HashTableOps
{
//- Combine HashTable operation. Equivalent to 'a += b'
template<class T, class Key=word, class Hash=string::hash>
template<class T, class Key=word, class HashType=Foam::Hash<Key>>
struct plusEqOp
{
typedef HashTable<T, Key, Hash> value_type;
typedef HashTable<T, Key, HashType> value_type;
void operator()(value_type& a, const value_type& b) const
{

View File

@ -62,7 +62,7 @@ Istream& operator>>(Istream& is, HashPtrTable<T, Key, Hash>& tbl);
Class HashPtrTable Declaration
\*---------------------------------------------------------------------------*/
template<class T, class Key=word, class Hash=string::hash>
template<class T, class Key=word, class Hash=Foam::Hash<Key>>
class HashPtrTable
:
public HashTable<T*, Key, Hash>

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -80,7 +80,7 @@ template<class T> class MinMax;
Class HashSet Declaration
\*---------------------------------------------------------------------------*/
template<class Key=word, class Hash=string::hash>
template<class Key=word, class Hash=Foam::Hash<Key>>
class HashSet
:
public HashTable<zero::null, Key, Hash>

View File

@ -115,7 +115,7 @@ Ostream& operator<<(Ostream&, const HashTable<T, Key, Hash>&);
Class HashTable Declaration
\*---------------------------------------------------------------------------*/
template<class T, class Key=word, class Hash=string::hash>
template<class T, class Key=word, class Hash=Foam::Hash<Key>>
class HashTable
:
public HashTableCore

View File

@ -372,6 +372,11 @@ inline void Swap(DynamicList<T, SizeMinA>& a, DynamicList<T, SizeMinB>& b)
}
//- Hashing for List data
template<class T, int SizeMin>
struct Hash<DynamicList<T, SizeMin>> : List<T>::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -46,8 +46,8 @@ SourceFiles
#include "zero.H"
#include "contiguous.H"
#include "autoPtr.H"
#include "Hash.H"
#include "Swap.H"
#include "HashFwd.H"
#include "SLListFwd.H"
#include "ListPolicy.H"
@ -455,11 +455,8 @@ public:
// Hashing
//- Hashing function class for FixedList
// Normally use the global Hash specialization, but can also use
// this one for inheritance in sub-classes
template<class HashT=Foam::Hash<T>>
struct Hash
//- Hashing functor for FixedList.
struct hasher
{
inline unsigned operator()
(
@ -469,18 +466,28 @@ public:
{
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), N*sizeof(T), seed);
return Foam::Hasher(obj.cdata(), obj.size_bytes(), seed);
}
Foam::Hash<T> op;
for (const T& val : obj)
{
seed = HashT()(val, seed);
seed = op(val, seed);
}
return seed;
}
};
//- Deprecated(2021-04) hashing functor. Use hasher()
// \deprecated(2021-04) - use hasher() functor
template<class Unused=bool>
struct Hash : FixedList<T, N>::hasher
{
FOAM_DEPRECATED_FOR(2021-04, "hasher()") Hash() {}
};
};
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- FixedList is contiguous if the type is contiguous
@ -495,6 +502,10 @@ struct is_contiguous_label<FixedList<T, N>> : is_contiguous_label<T> {};
template<class T, unsigned N>
struct is_contiguous_scalar<FixedList<T, N>> : is_contiguous_scalar<T> {};
//- Hashing for FixedList data
template<class T, unsigned N>
struct Hash<FixedList<T, N>> : FixedList<T, N>::hasher {};
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
@ -507,31 +518,6 @@ inline void Swap(FixedList<T, N>& a, FixedList<T, N>& b)
}
//- Hashing for FixedList data, which uses Hasher for contiguous data and
//- element-wise incrementally hashing otherwise.
template<class T, unsigned N>
struct Hash<FixedList<T, N>>
{
inline unsigned operator()
(
const FixedList<T, N>& obj,
unsigned seed=0
) const
{
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), N*sizeof(T), seed);
}
for (const T& val : obj)
{
seed = Hash<T>()(val, seed);
}
return seed;
}
};
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
//- Write List to Ostream, as per FixedList::writeList() with default length.

View File

@ -364,6 +364,10 @@ public:
template<>
Istream& List<char>::readList(Istream& is);
//- Hashing for List data
template<class T>
struct Hash<List<T>> : List<T>::hasher {};
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
@ -372,27 +376,6 @@ Istream& List<char>::readList(Istream& is);
labelList identity(const label len, label start=0);
//- Hashing for List data, which uses Hasher for contiguous data and
//- element-wise incrementally hashing otherwise.
template<class T>
struct Hash<List<T>>
{
inline unsigned operator()(const UList<T>& obj, unsigned seed=0) const
{
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), obj.size()*sizeof(T), seed);
}
for (const T& val : obj)
{
seed = Hash<T>()(val, seed);
}
return seed;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -53,8 +53,8 @@ SourceFiles
#include "contiguous.H"
#include "nullObject.H"
#include "stdFoam.H"
#include "Hash.H"
#include "Swap.H"
#include "HashFwd.H"
#include "ListPolicy.H"
#include <initializer_list>
@ -522,13 +522,10 @@ public:
}
// Other
// Hashing
//- Hashing function class for UList.
// Can use this one (instead of the global Hash<>) for inheritance
// in sub-classes
template<class HashT=Foam::Hash<T>>
struct Hash
//- Hashing functor for UList
struct hasher
{
inline unsigned operator()
(
@ -538,16 +535,25 @@ public:
{
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), obj.size_bytes(), seed);
return Foam::Hasher(obj.cdata(), obj.size_bytes(), seed);
}
Foam::Hash<T> op;
for (const T& val : obj)
{
seed = HashT()(val, seed);
seed = op(val, seed);
}
return seed;
}
};
//- Deprecated(2021-04) hashing functor. Use hasher()
// \deprecated(2021-04) - use hasher() functor
template<class Unused=bool>
struct Hash : UList<T>::hasher
{
FOAM_DEPRECATED_FOR(2021-04, "hasher()") Hash() {}
};
};
@ -617,28 +623,13 @@ inline void Swap(UList<T>& a, UList<T>& b)
}
//- Hashing for UList data, which uses Hasher for contiguous data and
//- element-wise incrementally hashing otherwise.
template<class T>
struct Hash<UList<T>>
{
inline unsigned operator()(const UList<T>& obj, unsigned seed=0) const
{
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), obj.size_bytes(), seed);
}
for (const T& val : obj)
{
seed = Hash<T>()(val, seed);
}
return seed;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for List data
template<class T>
struct Hash<UList<T>> : UList<T>::hasher {};
//- Object access operator or list access operator.
//- \sa ListListOps::combine()
template<class T>

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,7 +52,7 @@ Description
typedef autoPtr<baseType> (*argNames##ConstructorPtr)argList; \
\
/* Construct from argList function table type */ \
typedef HashTable<argNames##ConstructorPtr, word, string::hash> \
typedef HashTable<argNames##ConstructorPtr, word> \
argNames##ConstructorTable; \
\
/* Construct from argList function pointer table pointer */ \
@ -152,7 +152,7 @@ Description
typedef autoPtr<baseType> (*argNames##ConstructorPtr)argList; \
\
/* Construct from argList function table type */ \
typedef HashTable<argNames##ConstructorPtr, word, string::hash> \
typedef HashTable<argNames##ConstructorPtr, word> \
argNames##ConstructorTable; \
\
/* Construct from argList function pointer table pointer */ \

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,8 +46,7 @@ Description
typedef returnType (*memberFunction##argNames##MemberFunctionPtr)argList; \
\
/* Construct from argList function table type */ \
typedef HashTable \
<memberFunction##argNames##MemberFunctionPtr, word, string::hash> \
typedef HashTable<memberFunction##argNames##MemberFunctionPtr, word> \
memberFunction##argNames##MemberFunctionTable; \
\
/* Construct from argList function pointer table pointer */ \

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -285,32 +285,37 @@ public:
// Hashing
//- The (commutative) hash-value for edge
inline unsigned hashval(unsigned seed=0) const
//- The (commutative) hash value for edge, hashes lower value first
inline unsigned hash_code(unsigned seed=0) const
{
if (first() < second())
Foam::Hash<label> op;
if (second() < first())
{
seed = Foam::Hash<label>()(first(), seed);
seed = Foam::Hash<label>()(second(), seed);
return op(first(), op(second(), seed));
}
else
{
seed = Foam::Hash<label>()(second(), seed);
seed = Foam::Hash<label>()(first(), seed);
return op(second(), op(first(), seed));
}
return seed;
}
//- Hashing function class for edge (commutative)
//- Hashing functor for edge (commutative)
// Also useful for inheritance in sub-classes
template<class HashT=Foam::Hash<label>>
struct Hash
struct hasher
{
inline unsigned operator()(const edge& obj, unsigned seed=0) const
unsigned operator()(const edge& obj, unsigned seed=0) const
{
return obj.hashval(seed);
return obj.hash_code(seed);
}
};
//- Deprecated(2021-04) hashing functor. Use hasher()
// \deprecated(2021-04) - use hasher() functor
template<class Unused=bool>
struct Hash : edge::hasher
{
FOAM_DEPRECATED_FOR(2021-04, "hasher()") Hash() {}
};
};
@ -322,6 +327,9 @@ template<> struct is_contiguous<edge> : std::true_type {};
//- Contiguous label data for edge (a pair of labels)
template<> struct is_contiguous_label<edge> : std::true_type {};
//- Hashing for edge uses commutative (incremental) hash
template<> struct Hash<edge> : edge::hasher {};
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
@ -332,17 +340,6 @@ inline edge reverse(const edge& e)
}
//- Hash specialization for edge, using a commutative (incremental) hash.
template<>
struct Hash<edge>
{
inline unsigned operator()(const edge& e, unsigned seed=0) const
{
return e.hashval(seed);
}
};
// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * //
//- Compare edges for equal content, ignoring orientation

View File

@ -30,7 +30,6 @@ License
#include "triFace.H"
#include "triPointRef.H"
#include "mathematicalConstants.H"
#include "Swap.H"
#include "ConstCirculator.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -304,24 +303,18 @@ int Foam::face::compare(const face& a, const face& b)
// will be circular in the same order (but not necessarily in the
// same direction or from the same starting point).
// Trivial reject: faces are different size
label sizeA = a.size();
label sizeB = b.size();
const label sizeA = a.size();
const label sizeB = b.size();
// Trivial reject: faces are different size
if (sizeA != sizeB || sizeA == 0)
{
return 0;
}
else if (sizeA == 1)
{
if (a[0] == b[0])
{
return 1;
}
else
{
return 0;
}
// Trivial: face with a single vertex
return (a[0] == b[0] ? 1 : 0);
}
ConstCirculator<face> aCirc(a);
@ -410,7 +403,7 @@ bool Foam::face::sameVertices(const face& a, const face& b)
{
return false;
}
// Check faces with a single vertex
// Trivial: face with a single vertex
else if (sizeA == 1)
{
return (a[0] == b[0]);
@ -440,6 +433,57 @@ bool Foam::face::sameVertices(const face& a, const face& b)
}
unsigned Foam::face::symmhash_code(const UList<label>& f, unsigned seed)
{
Foam::Hash<label> op;
label len = f.size();
if (!len)
{
// Trivial: zero-sized
return 0;
}
else if (len == 1)
{
// Trivial: single vertex
return op(f[0], seed);
}
// Find location of the min vertex
label pivot = 0;
for (label i = 1; i < len; ++i)
{
if (f[pivot] > f[i])
{
pivot = i;
}
}
// Use next lowest value for deciding direction to circulate
if (f.fcValue(pivot) < f.rcValue(pivot))
{
// Forward circulate
while (len--)
{
seed = op(f[pivot], seed);
pivot = f.fcIndex(pivot);
}
}
else
{
// Reverse circulate
while (len--)
{
seed = op(f[pivot], seed);
pivot = f.rcIndex(pivot);
}
}
return seed;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::face::collapse()

View File

@ -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.
@ -421,20 +421,55 @@ public:
//- Return true if the faces have the same vertices
static bool sameVertices(const face& a, const face& b);
// Hashing
//- The symmetric hash value for face.
// Starts with lowest vertex value and walks in the direction
// of the next lowest value.
static unsigned symmhash_code(const UList<label>& f, unsigned seed=0);
//- The hash value for face.
// Currently hashes as sequential contiguous data,
// but could/should be commutative
inline unsigned hash_code(unsigned seed=0) const
{
return Foam::Hasher(this->cdata(), this->size_bytes(), seed);
}
//- The symmetric hash value for face.
// Starts with lowest vertex value and walks in the direction
// of the next lowest value.
inline unsigned symmhash_code(unsigned seed=0) const
{
return face::symmhash_code(*this, seed);
}
//- Hashing functor for face
struct hasher
{
unsigned operator()(const face& obj, unsigned seed=0) const
{
return obj.hash_code(seed);
}
};
//- Symmetric hashing functor for face
struct symmHasher
{
unsigned operator()(const face& obj, unsigned seed=0) const
{
return face::symmhash_code(obj, seed);
}
};
};
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
//- Hash specialization for face
template<>
struct Hash<face>
{
inline unsigned operator()(const face& obj, unsigned seed=0) const
{
return Hasher(obj.cdata(), obj.size()*sizeof(label), seed);
}
};
//- Hash face as contiguous (non-commutative) list data
template<> struct Hash<face> : face::hasher {};
//- Specialization to offset faces, used in ListListOps::combineOffset

View File

@ -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.
@ -270,33 +270,35 @@ public:
// Hashing
//- The (commutative) hash-value for triFace
inline unsigned hashval(unsigned seed=0) const
//- The (commutative) hash value for triFace
inline unsigned hash_code(unsigned seed=0) const
{
// Fortunately we don't need this very often
const uLabel t0((*this)[0]);
const uLabel t1((*this)[1]);
const uLabel t2((*this)[2]);
const uLabel val = (t0*t1*t2 + t0+t1+t2);
const uLabel val(t0*t1*t2 + t0+t1+t2);
return Foam::Hash<uLabel>()(val, seed);
}
//- Hashing function class for triFace (commutative)
// Also useful for inheritance in sub-classes
template<class HashT=Foam::Hash<label>>
struct Hash
//- Hashing functor for triFace (commutative)
struct hasher
{
inline unsigned operator()
(
const triFace& obj,
unsigned seed=0
) const
unsigned operator()(const triFace& obj, unsigned seed=0) const
{
return obj.hashval(seed);
return obj.hash_code(seed);
}
};
//- Deprecated(2021-04) hashing functor. Use hasher()
// \deprecated(2021-04) - use hasher() functor
template<class Unused=bool>
struct Hash : triFace::hasher
{
FOAM_DEPRECATED_FOR(2021-04, "hasher()") Hash() {}
};
};
@ -308,16 +310,8 @@ template<> struct is_contiguous<triFace> : std::true_type {};
//- Contiguous label data for triFace
template<> struct is_contiguous_label<triFace> : std::true_type {};
//- Hash specialization for triFace as a commutative hash value.
template<>
struct Hash<triFace>
{
inline unsigned operator()(const triFace& obj, unsigned seed=0) const
{
return obj.hashval(seed);
}
};
//- Hashing for triFace uses commutative (incremental) hash
template<> struct Hash<triFace> : triFace::hasher {};
//- Specialization to offset faces, used in ListListOps::combineOffset

View File

@ -203,11 +203,11 @@ int Foam::processorCyclicPolyPatch::tag() const
if (owner())
{
tag_ = string::hash()(cycPatch.name()) % 32768u;
tag_ = string::hasher()(cycPatch.name()) % 32768u;
}
else
{
tag_ = string::hash()(cycPatch.neighbPatch().name()) % 32768u;
tag_ = string::hasher()(cycPatch.neighbPatch().name()) % 32768u;
}
if (tag_ == Pstream::msgType() || tag_ == -1)

View File

@ -147,28 +147,21 @@ public:
// Hashing
//- Symmetrical hashing for Pair data.
// The lower value is hashed first.
template<class HashT=Foam::Hash<T>>
struct SymmHash
//- Symmetric hashing functor for Pair, hashes lower value first
// Regular hasher inherited from FixedList
struct symmHasher
{
inline unsigned operator()
(
const Pair<T>& obj,
unsigned seed=0
) const
unsigned operator()(const Pair<T>& obj, unsigned seed=0) const
{
if (obj.first() < obj.second())
Foam::Hash<T> op;
if (obj.second() < obj.first())
{
seed = HashT()(obj.first(), seed);
seed = HashT()(obj.second(), seed);
return op(obj.first(), op(obj.second(), seed));
}
else
{
seed = HashT()(obj.second(), seed);
seed = HashT()(obj.first(), seed);
return op(obj.second(), op(obj.first(), seed));
}
return seed;
}
};
};
@ -188,29 +181,13 @@ struct is_contiguous_label<Pair<T>> : is_contiguous_label<T> {};
template<class T>
struct is_contiguous_scalar<Pair<T>> : is_contiguous_scalar<T> {};
//- Hashing for Pair of data
template<class T>
struct Hash<Pair<T>> : Pair<T>::hasher {};
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
//- Hashing for Pair data, which uses Hasher for contiguous data and
//- element-wise incrementally hashing otherwise.
template<class T>
struct Hash<Pair<T>>
{
inline unsigned operator()(const Pair<T>& obj, unsigned seed=0) const
{
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), obj.size_bytes(), seed);
}
seed = Hash<T>()(obj.first(), seed);
seed = Hash<T>()(obj.second(), seed);
return seed;
}
};
//- Return reverse of a Pair
template<class T>
Pair<T> reverse(const Pair<T>& p)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,19 +52,19 @@ Description
#ifndef labelPairHashes_H
#define labelPairHashes_H
#include "HashSet.H"
#include "labelPair.H"
#include "HashSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class T>
using LabelPairMap = HashTable<T, labelPair, labelPair::Hash<>>;
using LabelPairMap = HashTable<T, labelPair, Foam::Hash<labelPair>>;
typedef HashSet<labelPair, labelPair::Hash<>> labelPairHashSet;
typedef HashSet<labelPair, Foam::Hash<labelPair>> labelPairHashSet;
typedef HashTable<label, labelPair, labelPair::Hash<>> labelPairLookup;
typedef HashTable<label, labelPair, Foam::Hash<labelPair>> labelPairLookup;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,67 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation
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/>.
Alias
Foam::WordPairMap
A HashTable to objects of type \<T\> with a wordPair key.
Typedef
Foam::wordPairHashSet
Description
A HashSet for a wordPair.
Typedef
Foam::wordPairHashTable
Description
HashTable of wordPair
\*---------------------------------------------------------------------------*/
#ifndef wordPairHashes_H
#define wordPairHashes_H
#include "wordPair.H"
#include "HashSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class T>
using WordPairMap = HashTable<T, wordPair, Foam::Hash<wordPair>>;
typedef HashSet<wordPair, Foam::Hash<wordPair>> wordPairHashSet;
typedef HashTable<word, wordPair, Foam::Hash<wordPair>> wordPairHashTable;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -141,6 +141,29 @@ public:
};
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- Hashing for Tuple2 data
template<class T1, class T2>
struct Hash<Tuple2<T1, T2>>
{
unsigned operator()(const Tuple2<T1, T2>& obj, unsigned seed=0) const
{
return Hash<T2>()(obj.second(), Hash<T1>()(obj.first(), seed));
}
};
//- Hashing for std::pair data
template<class T1, class T2>
struct Hash<std::pair<T1, T2>>
{
unsigned operator()(const std::pair<T1, T2>& obj, unsigned seed=0) const
{
return Hash<T2>()(obj.second, Hash<T1>()(obj.first, seed));
}
};
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
//- Return reverse of a Tuple2

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2012 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,20 +29,22 @@ Class
Description
Hash function class.
The default definition is for primitives, non-primitives used to hash
entries on hash tables likely need a specialized version of this class.
The default definition is for primitives.
Non-primitives used to hash entries on hash tables will likely need
a specialized version.
Note
The second template parameter (bool) is used for SFINAE overloading,
\*---------------------------------------------------------------------------*/
#ifndef Hash_H
#define Hash_H
#include "label.H"
#include "uLabel.H"
#include "Hasher.H"
#include "fileName.H"
#include "keyType.H"
#include "wordRe.H"
#include <cstdint>
#include <string>
#include <type_traits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -53,107 +55,82 @@ namespace Foam
Class Hash Declaration
\*---------------------------------------------------------------------------*/
template<class T>
template<class T, class SFINAEType=bool>
struct Hash
{
inline unsigned operator()(const T& obj, unsigned seed=0) const
unsigned operator()(const T& obj, unsigned seed=0) const
{
return Hasher(&obj, sizeof(obj), seed);
return Foam::Hasher(&obj, sizeof(T), seed);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hash specialization for label
template<>
struct Hash<Foam::label>
{
//- Incrementally hash a label.
// This will necessarily return a different value than the
// non-incremental version.
inline unsigned operator()(const label obj, unsigned seed) const
{
return Hasher(&obj, sizeof(label), seed);
// Specialization for trivial (integer) types
#undef FOAM_INTHASHER
#define FOAM_INTHASHER(IntType) \
/*! \brief Hashing specialization for IntType */ \
/*! Unseeded (single value) uses natural order, otherwise incremental */ \
template<> struct Hash<IntType> \
{ \
unsigned operator()(const IntType val) const \
{ \
return static_cast<unsigned>(val); \
} \
unsigned operator()(const IntType val, unsigned seed) const \
{ \
return Foam::Hasher(&val, sizeof(IntType), seed); \
} \
}
//- Return the unsigned representation of a label.
// This helps if people have relied on the hash value corresponding to
// the natural order.
inline unsigned operator()(const label obj) const
FOAM_INTHASHER(bool);
FOAM_INTHASHER(char);
FOAM_INTHASHER(int32_t);
FOAM_INTHASHER(int64_t);
FOAM_INTHASHER(uint32_t);
#undef FOAM_INTHASHER
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing specialization for nullptr. Always 0
template<>
struct Hash<std::nullptr_t>
{
unsigned operator()(std::nullptr_t, unsigned seed=0) const noexcept
{
return obj;
return seed;
}
};
//- Hash specialization for string
template<>
struct Hash<Foam::string>
{
inline unsigned operator()(const string& obj, unsigned seed=0) const
{
return string::hash()(obj, seed);
}
};
//- Hash specialization for word
template<>
struct Hash<Foam::word>
{
inline unsigned operator()(const word& obj, unsigned seed=0) const
{
return string::hash()(obj, seed);
}
};
//- Hash specialization for fileName
template<>
struct Hash<Foam::fileName>
{
inline unsigned operator()(const fileName& obj, unsigned seed=0) const
{
return string::hash()(obj, seed);
}
};
//- Hash specialization for wordRe
template<>
struct Hash<Foam::wordRe>
{
inline unsigned operator()(const wordRe& obj, unsigned seed=0) const
{
return string::hash()(obj, seed);
}
};
//- Hash specialization for keyType
template<>
struct Hash<Foam::keyType>
{
inline unsigned operator()(const keyType& obj, unsigned seed=0) const
{
return string::hash()(obj, seed);
}
};
//- Hash specialization for pointers, interpret pointer as a integer type.
//- Hashing specialization for pointers, interpret pointer as a integer type
template<>
struct Hash<void*>
{
inline unsigned operator()(const void* const& obj, unsigned seed) const
unsigned operator()(const void* const ptr, unsigned seed=0) const
{
return Hash<intptr_t>()(intptr_t(obj), seed);
const uintptr_t addr = uintptr_t(ptr);
return Foam::Hasher(&addr, sizeof(addr), seed);
}
};
inline unsigned operator()(const void* const& obj) const
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing partial specialization for derived string types
template<class StringType>
struct Hash
<
StringType,
typename std::enable_if
<std::is_base_of<std::string, StringType>::value, bool>::type
>
{
unsigned operator()(const std::string& str, unsigned seed=0) const
{
return Hash<intptr_t>()(intptr_t(obj));
return Foam::Hasher(str.data(), str.length(), seed);
}
};

View File

@ -1,47 +1,14 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 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
Forward definition for Hash function class and the definition for
the Hasher function.
Compatibility include.
Previous support for forward declarations is no longer needed.
\*---------------------------------------------------------------------------*/
#ifndef HashFwd_H
#define HashFwd_H
#include "Hasher.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class T> struct Hash;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "Hash.H"
#endif

View File

@ -159,6 +159,114 @@ Description
}
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
// ----------------------------------------------------------------------------
// This works on all machines. To be useful, it requires
// -- that the key be an array of uint32_t's, and
// -- that the length be the number of uint32_t's in the key
//
// The function hashword() is identical to hashlittle() on little-endian
// machines, and identical to hashbig() on big-endian machines,
// except that the length has to be measured in uint32_ts rather than in
// bytes. hashlittle() is more complicated than hashword() only because
// hashlittle() has to dance around fitting the key bytes into registers.
// ----------------------------------------------------------------------------
unsigned Foam::HasherInt
(
const uint32_t *k,
size_t length,
unsigned seed
)
{
uint32_t a, b, c;
// Set up the internal state
a = b = c = 0xdeadbeef + (static_cast<uint32_t>(length) << 2) + seed;
// handle most of the key
while (length > 3)
{
a += k[0];
b += k[1];
c += k[2];
bitMixer(a,b,c);
length -= 3;
k += 3;
}
// handle the last 3 uint32_t's
switch (length) // all case statements fall through
{
case 3 : c += k[2]; [[fallthrough]];
case 2 : b += k[1]; [[fallthrough]];
case 1 : a += k[0];
bitMixerFinal(a,b,c);
[[fallthrough]];
case 0 : // case 0: nothing left to add
break;
}
return c;
}
// ----------------------------------------------------------------------------
// hashword2() -- same as hashword(), but take two seeds and return two
// 32-bit values. pc and pb must both be non-null, and *pc and *pb must
// both be initialized with seeds. If you pass in (*pb)==0, the output
// (*pc) will be the same as the return value from hashword().
// ----------------------------------------------------------------------------
// Currently unused
#if 0
unsigned Foam::HasherDual
(
const uint32_t *k,
size_t length,
unsigned& hash1, // IN: seed OUT: primary hash value
unsigned& hash2 // IN: more seed OUT: secondary hash value
)
{
uint32_t a, b, c;
// Set up the internal state
a = b = c = 0xdeadbeef + (static_cast<uint32_t>(length) << 2) + hash1;
c += hash2;
// handle most of the key
while (length > 3)
{
a += k[0];
b += k[1];
c += k[2];
bitMixer(a,b,c);
length -= 3;
k += 3;
}
// handle the last 3 uint32_t's
switch (length) // all case statements fall through
{
case 3 : c += k[2]; [[fallthrough]];
case 2 : b += k[1]; [[fallthrough]];
case 1 : a += k[0];
bitMixerFinal(a,b,c);
[[fallthrough]];
case 0 : // case 0: nothing left to add
break;
}
// report the result
hash1 = c;
hash2 = b;
// return primary hash value
return c;
}
#endif
// * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * * //
// ----------------------------------------------------------------------------
@ -304,6 +412,7 @@ static unsigned jenkins_hashlittle
}
else
{
// need to read the key one byte at a time
const uint8_t *k = reinterpret_cast<const uint8_t*>(key);
// all but the last block: affect some 32 bits of (a,b,c)
@ -468,7 +577,6 @@ static unsigned jenkins_hashbig
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
unsigned Foam::Hasher
(
const void *key,
@ -486,106 +594,4 @@ unsigned Foam::Hasher
}
// ----------------------------------------------------------------------------
// This works on all machines. To be useful, it requires
// -- that the key be an array of uint32_t's, and
// -- that the length be the number of uint32_t's in the key
//
// The function hashword() is identical to hashlittle() on little-endian
// machines, and identical to hashbig() on big-endian machines,
// except that the length has to be measured in uint32_ts rather than in
// bytes. hashlittle() is more complicated than hashword() only because
// hashlittle() has to dance around fitting the key bytes into registers.
// ----------------------------------------------------------------------------
unsigned Foam::HasherInt
(
const uint32_t *k,
size_t length,
unsigned seed
)
{
uint32_t a, b, c;
// Set up the internal state
a = b = c = 0xdeadbeef + (static_cast<uint32_t>(length) << 2) + seed;
// handle most of the key
while (length > 3)
{
a += k[0];
b += k[1];
c += k[2];
bitMixer(a,b,c);
length -= 3;
k += 3;
}
// handle the last 3 uint32_t's
switch (length) // all case statements fall through
{
case 3 : c += k[2]; [[fallthrough]];
case 2 : b += k[1]; [[fallthrough]];
case 1 : a += k[0];
bitMixerFinal(a,b,c);
[[fallthrough]];
case 0 : // case 0: nothing left to add
break;
}
return c;
}
// ----------------------------------------------------------------------------
// hashword2() -- same as hashword(), but take two seeds and return two
// 32-bit values. pc and pb must both be non-null, and *pc and *pb must
// both be initialized with seeds. If you pass in (*pb)==0, the output
// (*pc) will be the same as the return value from hashword().
// ----------------------------------------------------------------------------
unsigned Foam::HasherDual
(
const uint32_t *k,
size_t length,
unsigned& hash1, // IN: seed OUT: primary hash value
unsigned& hash2 // IN: more seed OUT: secondary hash value
)
{
uint32_t a, b, c;
// Set up the internal state
a = b = c = 0xdeadbeef + (static_cast<uint32_t>(length) << 2) + hash1;
c += hash2;
// handle most of the key
while (length > 3)
{
a += k[0];
b += k[1];
c += k[2];
bitMixer(a,b,c);
length -= 3;
k += 3;
}
// handle the last 3 uint32_t's
switch (length) // all case statements fall through
{
case 3 : c += k[2]; [[fallthrough]];
case 2 : b += k[1]; [[fallthrough]];
case 1 : a += k[0];
bitMixerFinal(a,b,c);
[[fallthrough]];
case 0 : // case 0: nothing left to add
break;
}
// report the result
hash1 = c;
hash2 = b;
// return primary hash value
return c;
}
// ************************************************************************* //

View File

@ -27,7 +27,7 @@ InNamespace
Foam
Description
Misc. hashing functions, mostly from Bob Jenkins.
Miscellaneous hashing functions, mostly from Bob Jenkins.
The Jenkins hashing function(s) is similar in speed to Paul Hsieh's
SuperFast hash, but is public domain, supports incremental hashing
@ -61,16 +61,6 @@ namespace Foam
// \param[in] seed - the previous hash, or an arbitrary value
unsigned Hasher(const void* data, size_t len, unsigned seed = 0);
//- Hashing of bit-wise internal content of given data object.
// For primitives and simple collections of primitives this is reasonable,
// but ill-advised for more complex data structures.
template<class T>
inline unsigned HasherT(const T& obj, unsigned seed = 0)
{
return Hasher(&obj, sizeof(obj), seed);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -38,7 +38,7 @@ See also
#define HasherInt_H
#include "Hasher.H"
#include "int.H"
#include <cstdint>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -52,9 +52,9 @@ SourceFiles
#include "char.H"
#include "Hasher.H"
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstring>
#include <string>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -139,6 +139,21 @@ protected:
public:
// Public Classes
//- Hashing functor for string and derived string classes
struct hasher
{
unsigned operator()(const std::string& str, unsigned seed=0) const
{
return Foam::Hasher(str.data(), str.length(), seed);
}
};
//- Hashing functor for string and derived string classes
struct hash : string::hasher {};
// Static Data Members
//- The type name "string"
@ -151,17 +166,6 @@ public:
static const string null;
//- Hashing function for string and derived string classes
struct hash
{
inline unsigned operator()
(
const std::string& str,
unsigned seed = 0
) const;
};
// Constructors
//- Default construct

View File

@ -239,14 +239,4 @@ inline bool Foam::string::operator()(const std::string& text) const
}
inline unsigned Foam::string::hash::operator()
(
const std::string& str,
unsigned seed
) const
{
return Hasher(str.data(), str.size(), seed);
}
// ************************************************************************* //

View File

@ -719,7 +719,7 @@ std::string::size_type Foam::stringOps::count(const char* s, const char c)
Foam::string Foam::stringOps::expand
(
const std::string& s,
const HashTable<string, word, string::hash>& mapping,
const HashTable<string>& mapping,
const char sigil
)
{
@ -732,7 +732,7 @@ Foam::string Foam::stringOps::expand
void Foam::stringOps::inplaceExpand
(
std::string& s,
const HashTable<string, word, string::hash>& mapping,
const HashTable<string>& mapping,
const char sigil
)
{

View File

@ -93,7 +93,7 @@ namespace stringOps
string expand
(
const std::string& s,
const HashTable<string, word, string::hash>& mapping,
const HashTable<string>& mapping,
const char sigil = '$'
);
@ -135,7 +135,7 @@ namespace stringOps
void inplaceExpand
(
std::string& s,
const HashTable<string, word, string::hash>& mapping,
const HashTable<string>& mapping,
const char sigil = '$'
);

View File

@ -1196,7 +1196,7 @@ void Foam::fvMeshDistribute::findCouples
// Insert all into big map. Find matches
HashTable<labelPair, labelPair, labelPair::Hash<>> map(2*sum(nProcFaces));
LabelPairMap<labelPair> map(2*sum(nProcFaces));
nProcFaces = 0;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -55,7 +55,7 @@ SourceFiles
#include "pointFieldsFwd.H"
#include "Tuple2.H"
#include "pointIndexHit.H"
#include "wordPairHashTable.H"
#include "wordPairHashes.H"
#include "surfaceZonesInfo.H"
#include "volumeType.H"
#include "DynamicField.H"

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -5155,7 +5155,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
{
// 1. Detect inter-region face and allocate names
HashTable<word, labelPair, labelPair::Hash<>> zoneIDsToFaceZone;
LabelPairMap<word> zoneIDsToFaceZone;
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
{
@ -5208,10 +5208,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
<< endl;
// From cellZone indices to faceZone index
HashTable<label, labelPair, labelPair::Hash<>> fZoneLookup
(
zonesToFaceZone.size()
);
LabelPairMap<label> fZoneLookup(zonesToFaceZone.size());
const cellZoneMesh& cellZones = mesh_.cellZones();

View File

@ -1,57 +1,13 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Typedef
Foam::wordPairHashTable
Description
HashTable of Pair<word>
Typedef
Foam::wordPairHashTable
Description
HashTable of Pair<word>
Compatibility include.
\*---------------------------------------------------------------------------*/
#ifndef wordPairHashTable_H
#define wordPairHashTable_H
#include "Pair.H"
#include "HashTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef HashTable<word, Pair<word>, FixedList<word, 2>::Hash<>>
wordPairHashTable;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "wordPairHashes.H"
#endif

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,7 +37,7 @@ SourceFiles
#ifndef snappyRefineDriver_H
#define snappyRefineDriver_H
#include "wordPairHashTable.H"
#include "wordPairHashes.H"
#include "labelList.H"
#include "scalarField.H"
#include "Tuple2.H"
@ -51,7 +51,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class refinementParameters;
class snapParameters;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -68,50 +68,25 @@ class multiphaseSystem
public IOdictionary,
public transportModel
{
public:
//- Name pair for the interface
class interfacePair
:
public Pair<word>
{
public:
class symmHash
:
public Hash<interfacePair>
{
public:
// Ordered hashing (alias)
using hash = Pair<word>::hasher;
symmHash()
{}
label operator()(const interfacePair& key) const
{
return word::hash()(key.first()) + word::hash()(key.second());
}
};
class hash
:
public Hash<interfacePair>
{
public:
hash()
{}
label operator()(const interfacePair& key) const
{
return word::hash()(key.first(), word::hash()(key.second()));
}
};
// Unordered hashing (alias)
using symmHash = Pair<word>::symmHasher;
// Constructors
interfacePair()
{}
interfacePair() = default;
interfacePair(const word& alpha1Name, const word& alpha2Name)
:
@ -132,11 +107,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!=

View File

@ -5,7 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2014-2015 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -41,35 +42,6 @@ Foam::phasePairKey::phasePairKey
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
bool Foam::phasePairKey::ordered() const
{
return ordered_;
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
Foam::label Foam::phasePairKey::hash::operator()
(
const phasePairKey& key
) const
{
if (key.ordered_)
{
return
word::hash()
(
key.first(),
word::hash()(key.second())
);
}
return word::hash()(key.first()) + word::hash()(key.second());
}
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
bool Foam::operator==
@ -78,12 +50,11 @@ bool Foam::operator==
const phasePairKey& b
)
{
const auto cmp = Pair<word>::compare(a,b);
const int cmp = Pair<word>::compare(a, b);
return
(
(a.ordered_ == b.ordered_)
&& (a.ordered_ ? (cmp == 1) : cmp)
(a.ordered() == b.ordered())
&& (a.ordered() ? (cmp == 1) : cmp)
);
}
@ -102,30 +73,29 @@ bool Foam::operator!=
Foam::Istream& Foam::operator>>(Istream& is, phasePairKey& key)
{
const FixedList<word, 3> temp(is);
const FixedList<word, 3> toks(is);
key.first() = temp[0];
key.first() = toks[0];
key.second() = toks[2];
const word& order = toks[1];
if (temp[1] == "and")
{
key.ordered_ = false;
}
else if (temp[1] == "to")
if (order == "to")
{
key.ordered_ = true;
}
else if (order == "and")
{
key.ordered_ = false;
}
else
{
FatalErrorInFunction
<< "Phase pair type is not recognised. "
<< temp
<< "Use (phaseDispersed to phaseContinuous) for an ordered pair, "
<< "or (phase1 and phase2) for an unordered pair."
<< "Phase pair type is not recognised. " << toks
<< "Use (phaseDispersed to phaseContinuous) for an ordered pair,"
" or (phase1 and phase2) for an unordered pair.\n"
<< exit(FatalError);
}
key.second() = temp[2];
return is;
}
@ -137,7 +107,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const phasePairKey& key)
os << token::BEGIN_LIST
<< key.first()
<< token::SPACE
<< (key.ordered_ ? "to" : "and")
<< (key.ordered() ? "to" : "and")
<< token::SPACE
<< key.second()
<< token::END_LIST;

View File

@ -5,7 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2014-2016 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,8 +28,15 @@ Class
Foam::phasePairKey
Description
An ordered or unorder pair of phase names.
Typically specified as follows.
\verbatim
(phase1 and phase2) // unordered
(phase1 to phase2) // ordered
\endverbatim
SourceFiles
phasePairKey.C
\*---------------------------------------------------------------------------*/
@ -42,7 +50,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class phasePairKey;
bool operator==(const phasePairKey& a, const phasePairKey& b);
@ -59,7 +67,7 @@ class phasePairKey
:
public Pair<word>
{
// Private data
// Private Data
//- Flag to indicate whether ordering is important
bool ordered_;
@ -67,20 +75,12 @@ class phasePairKey
public:
//- Ordered or unordered hashing of word pair
struct hash
{
//- Generate a hash from a phase pair key
label operator()(const phasePairKey& key) const;
};
// Constructors
//- Construct null
phasePairKey() {} // = default
//- Default construct
phasePairKey() = default;
//- Construct from names and optional ordering flag
//- Construct from names and (optional) ordering flag
phasePairKey
(
const word& name1,
@ -93,10 +93,13 @@ public:
virtual ~phasePairKey() = default;
// Access
// Member Functions
//- Return the ordered flag
bool ordered() const;
bool ordered() const noexcept
{
return ordered_;
}
// Friend Operators
@ -112,9 +115,37 @@ public:
//- Write to Ostream
friend Ostream& operator<<(Ostream& os, const phasePairKey& key);
// Hashing
//- Hashing functor for phasePairKey
struct hasher
{
unsigned operator()(const phasePairKey& key) const
{
if (key.ordered())
{
return Pair<word>::hasher()(key);
}
else
{
return Pair<word>::symmHasher()(key);
}
}
};
//- Alternative name for functor
using hash = phasePairKey::hasher;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for phasePairKey
template<> struct Hash<phasePairKey> : phasePairKey::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -56,7 +56,7 @@ class hyperbolic
// Private data
//- Minimum fraction of phases which can be considered continuous
HashTable<dimensionedScalar, word, word::hash> minContinuousAlpha_;
HashTable<dimensionedScalar> minContinuousAlpha_;
//- Width of the transition
const dimensionedScalar transitionAlphaScale_;

View File

@ -56,12 +56,10 @@ class linear
// Private data
//- Minimum fraction of phases which can be considered fully continuous
HashTable<dimensionedScalar, word, word::hash>
minFullyContinuousAlpha_;
HashTable<dimensionedScalar> minFullyContinuousAlpha_;
//- Minimum fraction of phases which can be considered partly continuous
HashTable<dimensionedScalar, word, word::hash>
minPartlyContinuousAlpha_;
HashTable<dimensionedScalar> minPartlyContinuousAlpha_;
public:

View File

@ -5,7 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2018 OpenFOAM Foundation
Copyright (C) 2014-2015 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,14 +30,6 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::phasePairKey::hash::hash()
{}
Foam::phasePairKey::phasePairKey()
{}
Foam::phasePairKey::phasePairKey
(
const word& name1,
@ -49,45 +42,6 @@ Foam::phasePairKey::phasePairKey
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::phasePairKey::~phasePairKey()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
bool Foam::phasePairKey::ordered() const
{
return ordered_;
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
Foam::label Foam::phasePairKey::hash::operator()
(
const phasePairKey& key
) const
{
if (key.ordered_)
{
return
word::hash()
(
key.first(),
word::hash()(key.second())
);
}
else
{
return
word::hash()(key.first())
+ word::hash()(key.second());
}
}
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
bool Foam::operator==
@ -96,14 +50,12 @@ bool Foam::operator==
const phasePairKey& b
)
{
const label c = Pair<word>::compare(a, b);
const int cmp = Pair<word>::compare(a, b);
return
(a.ordered_ == b.ordered_)
&& (
(a.ordered_ && (c == 1))
|| (!a.ordered_ && (c != 0))
);
(
(a.ordered() == b.ordered())
&& (a.ordered() ? (cmp == 1) : cmp)
);
}
@ -121,30 +73,29 @@ bool Foam::operator!=
Foam::Istream& Foam::operator>>(Istream& is, phasePairKey& key)
{
const FixedList<word, 3> temp(is);
const FixedList<word, 3> toks(is);
key.first() = temp[0];
key.first() = toks[0];
key.second() = toks[2];
const word& order = toks[1];
if (temp[1] == "and")
{
key.ordered_ = false;
}
else if (temp[1] == "in")
if (order == "in")
{
key.ordered_ = true;
}
else if (order == "and")
{
key.ordered_ = false;
}
else
{
FatalErrorInFunction
<< "Phase pair type is not recognised. "
<< temp
<< "Use (phaseDispersed in phaseContinuous) for an ordered"
<< "pair, or (phase1 and pase2) for an unordered pair."
<< "Phase pair type is not recognised. " << toks
<< "Use (phaseDispersed in phaseContinuous) for an ordered pair,"
" or (phase1 and phase2) for an unordered pair.\n"
<< exit(FatalError);
}
key.second() = temp[2];
return is;
}
@ -156,7 +107,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const phasePairKey& key)
os << token::BEGIN_LIST
<< key.first()
<< token::SPACE
<< (key.ordered_ ? "in" : "and")
<< (key.ordered() ? "in" : "and")
<< token::SPACE
<< key.second()
<< token::END_LIST;

View File

@ -5,7 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2018 OpenFOAM Foundation
Copyright (C) 2014-2016 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,8 +28,15 @@ Class
Foam::phasePairKey
Description
An ordered or unorder pair of phase names.
Typically specified as follows.
\verbatim
(phase1 and phase2) // unordered
(phase1 in phase2) // ordered
\endverbatim
SourceFiles
phasePairKey.C
\*---------------------------------------------------------------------------*/
@ -42,16 +50,14 @@ SourceFiles
namespace Foam
{
// Forward declaration of friend functions and operators
// Forward Declarations
class phasePairKey;
bool operator==(const phasePairKey&, const phasePairKey&);
bool operator!=(const phasePairKey&, const phasePairKey&);
Istream& operator>>(Istream&, phasePairKey&);
Ostream& operator<<(Ostream&, const phasePairKey&);
bool operator==(const phasePairKey& a, const phasePairKey& b);
bool operator!=(const phasePairKey& a, const phasePairKey& b);
Istream& operator>>(Istream& is, phasePairKey& key);
Ostream& operator<<(Ostream& os, const phasePairKey& key);
/*---------------------------------------------------------------------------*\
Class phasePairKey Declaration
@ -61,30 +67,7 @@ class phasePairKey
:
public Pair<word>
{
public:
class hash
:
public Hash<phasePairKey>
{
public:
// Constructors
// Construct null
hash();
// Member operators
// Generate a hash from a phase pair key
label operator()(const phasePairKey& key) const;
};
private:
// Private data
// Private Data
//- Flag to indicate whether ordering is important
bool ordered_;
@ -94,10 +77,10 @@ public:
// Constructors
//- Construct null
phasePairKey();
//- Default construct
phasePairKey() = default;
//- Construct from names and the ordering flag
//- Construct from names and (optional) ordering flag
phasePairKey
(
const word& name1,
@ -106,32 +89,63 @@ public:
);
// Destructor
virtual ~phasePairKey();
//- Destructor
virtual ~phasePairKey() = default;
// Access
// Member Functions
//- Return the ordered flag
bool ordered() const;
bool ordered() const noexcept
{
return ordered_;
}
// Friend Operators
//- Test if keys are equal
//- Test for equality
friend bool operator==(const phasePairKey& a, const phasePairKey& b);
//- Test if keys are unequal
//- Test for inequality
friend bool operator!=(const phasePairKey& a, const phasePairKey& b);
//- Read from stdin
//- Read from Istream
friend Istream& operator>>(Istream& is, phasePairKey& key);
//- Write to stdout
//- Write to Ostream
friend Ostream& operator<<(Ostream& os, const phasePairKey& key);
// Hashing
//- Hashing functor for phasePairKey
struct hasher
{
unsigned operator()(const phasePairKey& key) const
{
if (key.ordered())
{
return Pair<word>::hasher()(key);
}
else
{
return Pair<word>::symmHasher()(key);
}
}
};
//- Alternative name for functor
using hash = phasePairKey::hasher;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for phasePairKey
template<> struct Hash<phasePairKey> : phasePairKey::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -99,8 +99,7 @@ protected:
dictTable;
typedef
HashTable<autoPtr<blendingMethod>, word, word::hash>
blendingMethodTable;
HashTable<autoPtr<blendingMethod>> blendingMethodTable;
typedef
HashTable

View File

@ -56,7 +56,7 @@ class hyperbolic
// Private data
//- Maximum fraction of phases which can be considered dispersed
HashTable<dimensionedScalar, word, word::hash> maxDispersedAlpha_;
HashTable<dimensionedScalar> maxDispersedAlpha_;
//- Width of the transition
const dimensionedScalar transitionAlphaScale_;

View File

@ -56,12 +56,10 @@ class linear
// Private data
//- Maximum fraction of phases which can be considered fully dispersed
HashTable<dimensionedScalar, word, word::hash>
maxFullyDispersedAlpha_;
HashTable<dimensionedScalar> maxFullyDispersedAlpha_;
//- Maximum fraction of phases which can be considered partly dispersed
HashTable<dimensionedScalar, word, word::hash>
maxPartlyDispersedAlpha_;
HashTable<dimensionedScalar> maxPartlyDispersedAlpha_;
public:

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2015 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,15 +30,6 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::phasePairKey::hash::hash()
{}
Foam::phasePairKey::phasePairKey()
{}
Foam::phasePairKey::phasePairKey
(
const word& name1,
@ -50,37 +42,6 @@ Foam::phasePairKey::phasePairKey
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::phasePairKey::~phasePairKey()
{}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
Foam::label Foam::phasePairKey::hash::operator()
(
const phasePairKey& key
) const
{
if (key.ordered_)
{
return
word::hash()
(
key.first(),
word::hash()(key.second())
);
}
else
{
return
word::hash()(key.first())
+ word::hash()(key.second());
}
}
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
bool Foam::operator==
@ -89,14 +50,12 @@ bool Foam::operator==
const phasePairKey& b
)
{
const auto c = Pair<word>::compare(a,b);
const int cmp = Pair<word>::compare(a, b);
return
(a.ordered_ == b.ordered_)
&& (
(a.ordered_ && (c == 1))
|| (!a.ordered_ && (c != 0))
);
(
(a.ordered() == b.ordered())
&& (a.ordered() ? (cmp == 1) : cmp)
);
}
@ -114,30 +73,29 @@ bool Foam::operator!=
Foam::Istream& Foam::operator>>(Istream& is, phasePairKey& key)
{
const FixedList<word, 3> temp(is);
const FixedList<word, 3> toks(is);
key.first() = temp[0];
key.first() = toks[0];
key.second() = toks[2];
const word& order = toks[1];
if (temp[1] == "and")
{
key.ordered_ = false;
}
else if (temp[1] == "in")
if (order == "in")
{
key.ordered_ = true;
}
else if (order == "and")
{
key.ordered_ = false;
}
else
{
FatalErrorInFunction
<< "Phase pair type is not recognised. "
<< temp
<< "Use (phaseDispersed in phaseContinuous) for an ordered"
<< "pair, or (phase1 and pase2) for an unordered pair."
FatalErrorInFunction
<< "Phase pair type is not recognised. " << toks
<< "Use (phaseDispersed in phaseContinuous) for an ordered pair,"
" or (phase1 and phase2) for an unordered pair.\n"
<< exit(FatalError);
}
key.second() = temp[2];
return is;
}
@ -149,7 +107,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const phasePairKey& key)
os << token::BEGIN_LIST
<< key.first()
<< token::SPACE
<< (key.ordered_ ? "in" : "and")
<< (key.ordered() ? "in" : "and")
<< token::SPACE
<< key.second()
<< token::END_LIST;

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2016 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,8 +28,15 @@ Class
Foam::phasePairKey
Description
An ordered or unorder pair of phase names.
Typically specified as follows.
\verbatim
(phase1 and phase2) // unordered
(phase1 in phase2) // ordered
\endverbatim
SourceFiles
phasePairKey.C
\*---------------------------------------------------------------------------*/
@ -42,7 +50,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class phasePairKey;
bool operator==(const phasePairKey& a, const phasePairKey& b);
@ -59,59 +67,39 @@ class phasePairKey
:
public Pair<word>
{
public:
class hash
:
public Hash<phasePairKey>
{
public:
// Constructors
// Construct null
hash();
// Member operators
// Generate a hash from a phase pair key
label operator()(const phasePairKey& key) const;
};
private:
// Private data
// Private Data
//- Flag to indicate whether ordering is important
bool ordered_;
public:
public:
// Constructors
//- Construct null
phasePairKey();
//- Default construct
phasePairKey() = default;
//- Construct from names and the ordering flag
//- Construct from names and (optional) ordering flag
phasePairKey
(
const word& name1,
const word& name2,
const bool ordered
const bool ordered = false
);
//- Destructor
virtual ~phasePairKey();
virtual ~phasePairKey() = default;
// Access
// Member Functions
//- Return the ordered flag
bool ordered() const;
bool ordered() const noexcept
{
return ordered_;
}
// Friend Operators
@ -127,9 +115,37 @@ public:
//- Write to Ostream
friend Ostream& operator<<(Ostream& os, const phasePairKey& key);
// Hashing
//- Hashing functor for phasePairKey
struct hasher
{
unsigned operator()(const phasePairKey& key) const
{
if (key.ordered())
{
return Pair<word>::hasher()(key);
}
else
{
return Pair<word>::symmHasher()(key);
}
}
};
//- Alternative name for functor
using hash = phasePairKey::hasher;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Hashing for phasePairKey
template<> struct Hash<phasePairKey> : phasePairKey::hasher {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -96,7 +96,7 @@ class twoPhaseSystem
autoPtr<orderedPhasePair> pair2In1_;
//- Blending methods
HashTable<autoPtr<blendingMethod>, word, word::hash> blendingMethods_;
HashTable<autoPtr<blendingMethod>> blendingMethods_;
//- Drag model
autoPtr<BlendedInterfacialModel<dragModel>> drag_;

View File

@ -611,7 +611,7 @@ void Foam::meshToMesh::distributeAndMergeCells
// Count any coupled faces
typedef FixedList<label, 3> label3;
typedef HashTable<label, label3, label3::Hash<>> procCoupleInfo;
typedef HashTable<label, label3> procCoupleInfo;
procCoupleInfo procFaceToGlobalCell;
forAll(allNbrProcIDs, proci)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -78,7 +78,7 @@ void Foam::cuttingSurfaceBase::walkCellCuts
Map<label> endPoints;
// Hash of faces (face points) that are exactly on a cell face
HashSet<labelList, labelList::Hash<>> onCellFace;
HashSet<labelList> onCellFace;
// Failure handling