Commit 55e5a777 authored by shunbo's avatar shunbo
Browse files

initial commit

parents
// -*- C++ -*-
// Some table values
(
(0 0)
(20 1)
);
// ************************************************************************* //
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2112 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application none;
deltaT 1;
writeControl timeStep;
writeInterval 10;
// ************************************************************************* //
Test-GAMGAgglomeration.C
EXE = $(FOAM_USER_APPBIN)/Test-GAMGAgglomeration
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 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/>.
Application
Test-GAMGAgglomeration
Description
Test application for GAMG agglomeration. Hardcoded to expect GAMG on p.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "GAMGAgglomeration.H"
#include "OFstream.H"
#include "meshTools.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::addBoolOption
(
"writeObj",
"write obj files of agglomeration"
);
argList::addBoolOption
(
"normalise",
"normalise agglomeration (0..1)"
);
#include "setRootCase.H"
#include "createTime.H"
bool writeObj = args.found("writeObj");
bool normalise = args.found("normalise");
#include "createMesh.H"
const fvSolution& sol = static_cast<const fvSolution&>(mesh);
const dictionary& pDict = sol.subDict("solvers").subDict("p");
const GAMGAgglomeration& agglom = GAMGAgglomeration::New
(
mesh,
pDict
);
labelList cellToCoarse(identity(mesh.nCells()));
labelListList coarseToCell(invertOneToMany(mesh.nCells(), cellToCoarse));
++runTime;
// Write initial agglomeration
{
volScalarField scalarAgglomeration
(
IOobject
(
"agglomeration",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar(dimless, Zero)
);
scalarField& fld = scalarAgglomeration.primitiveFieldRef();
forAll(fld, celli)
{
fld[celli] = cellToCoarse[celli];
}
fld /= max(fld);
scalarAgglomeration.correctBoundaryConditions();
scalarAgglomeration.write();
Info<< "Writing initial cell distribution to "
<< runTime.timeName() << endl;
}
for (label level = 0; level < agglom.size(); level++)
{
++runTime;
Info<< "Time = " << runTime.timeName() << nl << endl;
const labelList& addr = agglom.restrictAddressing(level);
label coarseSize = max(addr)+1;
Info<< "Level : " << level << endl
<< returnReduce(addr.size(), sumOp<label>()) << endl
<< " current size : "
<< returnReduce(addr.size(), sumOp<label>()) << endl
<< " agglomerated size : "
<< returnReduce(coarseSize, sumOp<label>()) << endl;
labelList newAddr;
label newCoarseSize = 0;
bool ok = GAMGAgglomeration::checkRestriction
(
newAddr,
newCoarseSize,
agglom.meshLevel(level).lduAddr(),
addr,
coarseSize
);
if (!ok)
{
WarningInFunction
<< "At level " << level
<< " there are " << coarseSize
<< " agglomerated cells but " << newCoarseSize
<< " disconnected regions" << endl
<< " This means that some agglomerations (coarse cells)"
<< " consist of multiple disconnected regions."
<< endl;
}
forAll(addr, fineI)
{
const labelList& cellLabels = coarseToCell[fineI];
forAll(cellLabels, i)
{
cellToCoarse[cellLabels[i]] = addr[fineI];
}
}
coarseToCell = invertOneToMany(coarseSize, cellToCoarse);
// Write agglomeration
{
volScalarField scalarAgglomeration
(
IOobject
(
"agglomeration",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar(dimless, Zero)
);
scalarField& fld = scalarAgglomeration.primitiveFieldRef();
forAll(fld, celli)
{
fld[celli] = cellToCoarse[celli];
}
if (normalise)
{
fld /= max(fld);
}
scalarAgglomeration.correctBoundaryConditions();
scalarAgglomeration.write();
}
if (writeObj)
{
OFstream str(runTime.path()/runTime.timeName()/"aggomeration.obj");
label vertI = 0;
// Write all mesh cc
forAll(mesh.cellCentres(), celli)
{
meshTools::writeOBJ(str, mesh.cellCentres()[celli]);
vertI++;
}
// Determine coarse cc
forAll(coarseToCell, coarseI)
{
const labelList& cellLabels = coarseToCell[coarseI];
point coarseCc = average
(
pointField(mesh.cellCentres(), cellLabels)
);
meshTools::writeOBJ(str, coarseCc);
vertI++;
forAll(cellLabels, i)
{
label celli = cellLabels[i];
str << "l " << celli+1 << ' ' << vertI << nl;
}
}
}
Info<< endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //
Test-HashPtrTable.C
EXE = $(FOAM_USER_APPBIN)/Test-HashPtrTable
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-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/>.
Description
\*---------------------------------------------------------------------------*/
#include <memory>
#include <iostream>
#include "autoPtr.H"
#include "HashPtrTable.H"
using namespace Foam;
class Scalar
{
scalar data_;
public:
Scalar()
:
data_(0)
{}
Scalar(scalar val)
:
data_(val)
{}
~Scalar()
{
Info<<"delete Scalar: " << data_ << endl;
}
const scalar& value() const
{
return data_;
}
scalar& value()
{
return data_;
}
friend Ostream& operator<<(Ostream& os, const Scalar& val)
{
os << val.data_;
return os;
}
};
template<class T>
void printTable(const HashPtrTable<T>& table)
{
Info<< table.size() << nl << "(" << nl;
forAllConstIters(table, iter)
{
const T* ptr = iter.val();
Info<< iter.key() << " = ";
if (ptr)
{
Info<< *ptr << " (" << name(ptr) << ")";
}
else
{
Info<< "nullptr";
}
Info<< nl;
}
Info<< ")" << endl;
// Iterate across values, with for-range
Info<< "values (";
for (const auto& ptr : table)
{
Info<< ' ';
if (ptr)
{
Info<< *ptr;
}
else
{
Info<< "nullptr";
}
}
Info<< " )" << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
HashPtrTable<double> myTable;
myTable.set("abc", new double(42.1));
myTable.set("def", nullptr);
myTable.set("pi", new double(3.14159));
myTable.set("natlog", new double(2.718282));
myTable.insert("sqrt2", autoPtr<double>::New(1.414214));
myTable.insert("euler", autoPtr<double>::New(0.577216));
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>> myTable2;
myTable2.set("abc", autoPtr<double>(new double(42.1)));
myTable2.set("pi", autoPtr<double>(new double(3.14159)));
myTable2.set("natlog", autoPtr<double>(new double(2.718282)));
myTable2.insert("sqrt2", autoPtr<double>::New(1.414214));
Info<< "Initial table" << nl;
printTable(myTable);
Info<< "print" << nl;
Info<< myTable2 << nl;
{
auto iter2 = myTable2.find("pi");
Info<< nl << "Got pi=";
if (iter2.good())
{
Info<< **iter2 << nl;
}
else
{
Info<< "not-found" << nl;
}
}
HashPtrTable<double> copy(myTable);
// Info<< copy << endl;
printTable(copy);
Info<< copy << endl;
Info<<"\nerase some existing and non-existing entries" << nl;
auto iter = myTable.find("pi");
myTable.erase(iter);
iter = myTable.find("unknownKey");
myTable.erase(iter);
myTable.erase("abc");
myTable.erase("unknownKey");
myTable.release("euler");
Info<< "After erasure" << nl;
printTable(myTable);
HashPtrTable<double> moved(std::move(copy));
Info<< nl << "test movable" << nl;
Info<<"input:" << nl;
printTable(copy);
Info<<"output:" << nl;
printTable(moved);
HashPtrTable<double> other;
Info<<"move assign" << nl;
other = std::move(moved);
printTable(other);
Info<<"old" << nl;
printTable(moved);
Info<< "Verifying deletion characteristics" << nl;
{
HashPtrTable<Scalar> tbl;
tbl.set("abc", new Scalar(42.1));
tbl.set("def", nullptr);
tbl.set("pi", new Scalar(3.14159));
tbl.set("natlog", new Scalar(2.718282));
tbl.insert("sqrt2", autoPtr<Scalar>::New(1.414214));
Info<< "Table: " << tbl << nl;
Info<< nl << "Check exists, non-null" << nl;
for (const word& k : { "abc", "foo", "pi" })
{
Info<< " " << k << ' ';
const auto* inspect = tbl.get(k);
if (inspect)
{
Info<< *inspect << nl;
}
else
{
Info<< "(null)" << nl;
}
}
Info<< nl << "... overwrite again" << nl;
tbl.set("abc", new Scalar(42.1));
tbl.set("def", nullptr);
tbl.set("pi", new Scalar(3.14159));
tbl.set("natlog", new Scalar(2.718282));
tbl.emplace("other", 15.6);
Info<< "Table: " << tbl << nl;
Info << nl << "Test emplace and emplace_set" << nl;
tbl.emplace("abc", 100);
tbl.emplace_set("def", 100);
tbl.emplace_set("other", 100);
Info<< "Table: " << tbl << nl;
}
return 0;
}
// ************************************************************************* //
Test-hashSet.C
EXE = $(FOAM_USER_APPBIN)/Test-hashSet
/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
/* EXE_LIBS = -lfiniteVolume */
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-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/>.
Description
\*---------------------------------------------------------------------------*/
#include "hashedWordList.H"
#include "nil.H"
#include "HashOps.H"
#include "HashSet.H"
#include "Map.H"
#include "MinMax.H"
#include "labelPairHashes.H"
#include "FlatOutput.H"
#include <algorithm>
using namespace Foam;
template<class Iter>
void printIf(const Iter& iter)
{
if (iter)
{
Info<< *iter;
}
else
{
Info<<"(null)";
}
}
template<class Key, class Hash>
void printMinMax(const HashSet<Key, Hash>& set)
{
const auto first = set.cbegin();
const auto last = set.cend();
const auto min = std::min_element(first, last);
const auto max = std::max_element(first, last);
Info<< "set: " << flatOutput(set) << nl;
Info<< " min=";
printIf(min);
Info<< nl;
Info<< " max=";
printIf(max);
Info<< nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
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",
"def",
"ghi"
};
words = { "def", "ghi", "xy", "all", "end", "all" };
wordHashSet setA
{
"xx",
"yy",
"zz"
};
setA = { "kjhk", "kjhk2", "abced" };
HashTable<label> tableA
{
{ "value1", 1 },
{ "value2", 2 },
{ "value3", 3 }
};
HashTable<nil> tableB;
tableB.insert("value4", nil());
tableB.insert("value5", nil());
tableB.insert("value6", nil());
Info<< "tableA keys: "; tableA.writeKeys(Info) << endl;
Info<< "tableB content: " << tableB << endl;
auto keyIterPair = tableA.keys();
for (const auto& i : keyIterPair)
{
Info<<" keys: " << i << endl;
}
Map<label> mapA
{
{ 1, 1 },
{ 2, 2 },
{ 3, 3 }
};
mapA.set(4, 4);
Info<< "hashedWordList: " << words << nl
<< "with lookup: " << words.lookup() << endl;
words.sort();
Info<< "hashedWordList: " << words << nl
<< "with lookup: " << words.lookup() << endl;
words.uniq();
Info<< "hashedWordList: " << words << nl
<< "with lookup: " << words.lookup() << endl;
{
List<word> input = { "def", "ghi", "xy", "all", "end", "all", "def" };
hashedWordList words1(input, true);
Info<< "input word list: " << input << nl
<< "without dup: " << words1 << endl;
Info<< "from wordHashSet: " << hashedWordList(setA) << endl;
Info<< "from HashTable: " << hashedWordList(tableA) << endl;
Info<< "from HashTable: " << hashedWordList(tableB) << endl;
// even this works
Info<< "from hashSet: "
<< hashedWordList
(
wordHashSet(setA)
| wordHashSet(tableA) | wordHashSet(tableB)
) << endl;
}
Info<< "wordHashSet: " << setA << endl;
Info<< "Table-HashSet: " << tableA << endl;
Info<< "Map<label>: " << mapA << endl;
Info<< "create from HashSet: ";
Info<< wordHashSet(setA) << endl;
Info<< "create from HashTable<T>: ";
Info<< wordHashSet(tableA) << endl;
Info<< "create from HashTable<nil>: ";
Info<< wordHashSet(tableB) << endl;
Info<< "create from Map<label>: ";
Info<< labelHashSet(mapA) << endl;
{
auto allToc =
(wordHashSet(setA) | wordHashSet(tableA) | wordHashSet(tableB));
Info<<"combined toc: " << flatOutput(allToc) << nl;
printMinMax(allToc);
}
labelHashSet setB
{
1, 11, 42
};
Info<<"Set with min/max:" << minMax(setB)
<< " min:" << min(setB) << " max:" << max(setB) << nl;
setB = FixedList<label, 4>({1, 2, 3, 4});
setB = {1, 2, 4};
setB = List<label>({1, 2, 4});
Info<< "setB : " << setB << endl;
labelPair pair(12, 15);
setB.set(pair);
Info<< "setB : " << setB << endl;
setB.unset(pair);
labelHashSet setC(1);
setC.insert(2008);
setC.insert(1984);
Info<< "setC : " << setC << endl;
labelHashSet setD(1);
setD.insert({11, 100, 49, 36, 2008});
Info<< "setD : " << flatOutput(setD) << endl;
Info<< "setB == setC: " << (setB == setC) << endl;
Info<< "setC != setD: " << (setC != setD) << endl;
// test operations
setB += setC;
Info<< "setB += setC : " << setB << endl;
setB &= setD;
Info<< "setB &= setD : " << setB << endl;
Info<< "setB : " << setB << endl;
Info<< "setC : " << setC << endl;
Info<< "setD : " << setD << endl;
Info<< "setB ^ setC ^ setD : " << (setB ^ setC ^ setD) << endl;
// test operator[]
Info<< "setD : " << setD << endl;
if (setD[0])
{
Info<< "setD has 0" << endl;
}
else
{
Info<< "setD has no 0" << endl;
}
if (setD[11])
{
Info<< "setD has 11" << endl;
}
else
{
Info<< "setD has no 11" << endl;
}
Info<< "setB : " << flatOutput(setB) << endl;
Info<< "setD : " << flatOutput(setD) << endl;
setD -= setB;
Info<< "setD -= setB : " << flatOutput(setD) << endl;
// This should not work (yet?)
// setD[12] = true;
List<label> someLst(10);
forAll(someLst, elemI)
{
someLst[elemI] = elemI*elemI;
}
label added = setD.set(someLst);
Info<< "added " << added << " from " << someLst.size() << endl;
Info<< "setD : " << flatOutput(setD) << endl;
Info<< "setD for-range()" << nl;
for (auto i : setD)
{
Info << i << endl;
}
printMinMax(setD);
Info<< nl;
printMinMax(labelHashSet());
Info<< nl;
Info<< nl << "Test swapping, moving etc." << nl;
setA.insert({ "some", "more", "entries" });
Info<< "input" << nl;
Info<< "setA: " << setA << nl;
wordHashSet setA1(std::move(setA));
Info<< "move construct" << nl;
Info<< "setA: " << setA << nl
<< "setA1: " << setA1 << nl;
wordHashSet setB1;
Info<< "move assign" << nl;
setB1 = std::move(setA1);
Info<< "setA1: " << setA1 << nl
<< "setB1: " << setB1 << nl;
setB1.swap(setA1);
Info<< "setA1: " << setA1 << nl
<< "setB1: " << setB1 << nl;
return 0;
}
// ************************************************************************* //
Test-HashTable1.C
EXE = $(FOAM_USER_APPBIN)/Test-HashTable1
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-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/>.
\*---------------------------------------------------------------------------*/
#include "HashTable.H"
#include "List.H"
#include "DynamicList.H"
#include "FlatOutput.H"
#include "IOstreams.H"
#include "StringStream.H"
#include "ListOps.H"
#include "flipOp.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
HashTable<scalar> table1
{
{"aaa", 1.0},
{"aba", 2.0},
{"aca", 3.0},
{"ada", 4.0},
{"aeq", 5.0},
{"aaw", 6.0},
{"abs", 7.0},
{"acr", 8.0},
{"adx", 9.0},
{"aec", 10.0}
};
// Info<< "\ntable1: " << table1<< endl;
// Erase by key
table1.erase("aaw");
// Erase by iterator
HashTable<scalar>::iterator iter = table1.find("abs");
table1.erase(iter);
Info<< "\ntable1 toc: " << table1.toc() << endl;
Info<< "\ntable1 sortedToc: " << table1.sortedToc() << endl;
table1.printInfo(Info)
<< "table1 [" << table1.size() << "] " << endl;
forAllConstIters(table1, iter)
{
Info<< iter.key() << " => " << iter() << nl;
}
table1.set("acr", 108);
table1.set("adx", 109);
table1.set("aec", 100);
table1("aaw") -= 1000;
table1("aeq") += 1000;
Info<< "\noverwrote some values table1: " << table1 << endl;
Info<< "\ntest find:" << endl;
Info<< table1.find("aaa")() << nl
<< table1.find("aba")() << nl
<< table1.find("aca")() << nl
<< table1.find("ada")() << nl
<< table1.find("aeq")() << nl
<< table1.find("acr")() << nl
<< table1.find("adx")() << nl
<< table1.find("aec")() << nl
<< table1["aaa"] << nl;
{
OStringStream os;
os << table1;
HashTable<scalar> readTable(IStringStream(os.str())(), 100);
Info<< "Istream constructor:" << readTable << endl;
}
HashTable<scalar> table2(table1); // Copy
HashTable<scalar> table3(std::move(table1)); // Move
Info<< nl
<< "copy table1 -> table2" << nl
<< "move table1 -> table3" << nl;
Info<< "\ntable1" << table1 << nl
<< "\ntable2" << table2 << nl
<< "\ntable3" << table3 << nl;
Info<< "\nerase table2 by iterator" << nl;
forAllIters(table2, iter)
{
Info<< "erasing " << iter.key() << " => " << iter.val() << " ... ";
table2.erase(iter);
Info<< "erased" << endl;
}
Info<< "\ntable1" << table1 << nl
<< "\ntable2" << table2 << nl
<< "\ntable3" << table3 << nl;
table3.resize(1);
Info<< "\nresize(1) table3" << nl;
table3.printInfo(Info)
<< table3 << nl;
table3.resize(10000);
Info<< "\nresize(10000) table3" << nl;
table3.printInfo(Info)
<< table3 << nl;
HashTable<scalar> table4;
table4 = table3;
Info<< "\ncopy table3 -> table4 " << table4 << nl;
Info<< "\nclear table4 ... ";
table4.clear();
Info<< "[" << table4.size() << "] " << table4 << nl;
table1 = table3;
Info<< "\ncopy table3 -> table1 (previously transferred)" << table1 << nl;
Info<< "test table1 == table3 : " << (table1 == table3) << nl;
table1.erase(table1.begin());
Info<< "removed an element - test table1 != table3 : "
<< (table1 != table3) << nl;
// Insert a few things into table2
table2.set("ada", 14.0);
table2.set("aeq", 15.0);
table2.set("aaw", 16.0);
table2.set("abs", 17.0);
table2.set("adx", 20.0);
Info<< "\ntable1" << table1 << nl
<< "\ntable2" << table2 << nl;
label nErased = table1.erase(table2);
Info<< "\nerase table2 keys from table1 (removed "
<< nErased << " elements)" << nl
<< "\ntable1" << table1 << nl
<< "\ntable2" << table2 << nl;
Info<< "\ntable3" << table2
<< "\nclearStorage table2 ... ";
table2.clearStorage();
Info<< table2 << nl;
table1 =
{
{"abc", 3.0},
{"def", 6.0},
{"acr", 8.0},
{"aec", 10.0}
};
Info<< "\ntable1" << table1 << nl;
Info<< "\nrange-for(table1) - returns values" << nl;
for (const auto& it : table1)
{
Info<< "val:" << it << nl;
}
Info<< "\nrange-for(table1.keys()) - returns keys" << nl;
for (const auto& k : table1.keys())
{
Info<< "key:" << k << nl;
}
// These do not yet work. Issues resolving the distance.
//
// List<scalar> table1vals(table1.begin(), table1.end());
{
Info<<"distance/size: "
<< std::distance(table1.begin(), table1.end())
<< "/" << table1.size()
<< " and "
<< std::distance(table1.keys().begin(), table1.keys().end())
<< "/" << table1.keys().size()
<< nl;
List<word> sortKeys
(
ListOps::create<word>
(
table1.keys().begin(),
table1.keys().end(),
noOp{}
)
);
sort(sortKeys);
Info<<"sortKeys: " << flatOutput(sortKeys) << nl;
}
Info<< "\nFrom table1: " << flatOutput(table1.sortedToc()) << nl
<< "retain keys: " << flatOutput(table3.sortedToc()) << nl;
table1.retain(table3);
Info<< "-> " << flatOutput(table1.sortedToc()) << nl;
Info<< "Lookup non-existent" << nl;
Info<< table1.lookup("missing-const", 1.2345e+6)
<< " // const-access" << nl;
Info<< table1("missing-inadvertent", 3.14159)
<< " // (inadvertent?) non-const access" << nl;
Info<< table1("missing-autovivify")
<< " // Known auto-vivification (non-const access)" << nl;
Info<<"\ntable1: " << table1 << endl;
// Start again
HashTable<scalar> table1start
{
{"aaa", 1.0},
{"aba", 2.0},
{"a_ca", 3.0},
{"ada", 4.0},
{"aeq_", 5.0},
{"aaw", 6.0},
{"abs", 7.0},
{"a_cr", 8.0},
{"adx", 9.0},
{"ae_c", 10.0}
};
table1 = table1start;
Info<< "\ntable has keys: "
<< flatOutput(table1.sortedToc()) << nl;
wordRe matcher(".*_.*", wordRe::REGEX);
table1.filterKeys
(
[&matcher](const word& k){ return matcher.match(k); }
);
Info<< "retain things matching " << matcher << " => "
<< flatOutput(table1.sortedToc()) << nl;
table1 = table1start;
table1.filterKeys
(
[&matcher](const word& k){ return matcher.match(k); },
true
);
Info<< "prune things matching " << matcher << " => "
<< flatOutput(table1.sortedToc()) << nl;
// Same, without a lambda
table1 = table1start;
table1.filterKeys(matcher, true);
Info<< "prune things matching " << matcher << " => "
<< flatOutput(table1.sortedToc()) << nl;
// Same idea, but inverted logic inside the lambda
table1 = table1start;
table1.filterKeys
(
[&matcher](const word& k){ return !matcher.match(k); },
true
);
Info<< "prune things matching " << matcher << " => "
<< flatOutput(table1.sortedToc()) << nl;
table1 = table1start;
Info<< "\ntable:" << table1 << nl;
table1.filterValues
(
[](const scalar& v){ return (v >= 5); }
);
Info<< "\ntable with values >= 5:" << table1 << nl;
table1 = table1start;
Info<< "\ntable:" << table1 << nl;
table1.filterEntries
(
[&matcher](const word& k, const scalar& v)
{
return matcher(k) && (v >= 5);
}
);
Info<< "\ntable with values >= 5 and matching " << matcher
<< table1 << nl;
table1 = table1start;
Info<< "\ntable:" << table1 << nl;
Info<< "has "
<< table1.countValues([](const scalar& v) { return v >= 7; })
<< " values >= 7 with these keys: "
<< table1.tocValues([](const scalar& v) { return v >= 7; })
<< nl;
// Start again with new value
table2.set("ada", 14.0);
table2.set("aeq", 15.0);
table2.set("aaw", 16.0);
Info<< nl << "input values" << nl;
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"global Swap function" << nl;
Swap(table1, table2);
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"swap method" << nl;
table1.swap(table2);
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"transfer" << nl;
table1.transfer(table2);
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"move assign" << nl;
table2 = std::move(table1);
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"move construct" << nl;
HashTable<scalar> table1b(std::move(table2));
Info<<"table1 = " << table1b << nl <<"table2 = " << table2 << nl;
table1b.set("more", 14.0);
table1b.set("less", 15.0);
table1b.set("other", 16.0);
Info<<"Test a += b " << nl;
Info<<"a = " << flatOutput(table1b.sortedToc()) << nl
<<"b = " << flatOutput(table3.sortedToc()) << nl;
Info<<"=> " << (table1b += table3) << nl;
Info<< "\nDone\n";
return 0;
}
// ************************************************************************* //
Test-HashTable2.C
EXE = $(FOAM_USER_APPBIN)/Test-HashTable2
/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
/* EXE_LIBS = -lfiniteVolume */
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2020 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
Miscellaneous tests for HashTable
\*---------------------------------------------------------------------------*/
#include "HashTable.H"
#include "HashPtrTable.H"
#include "Map.H"
#include "FlatOutput.H"
using namespace Foam;
// Simple wrapper for testing purposes
class Label
{
label data_;
public:
Label()
:
data_(0)
{}
Label(label val)
:
data_(val)
{}
~Label()
{
Info<<"delete label: " << data_ << endl;
}
// Some arbitrary non-const method (for testing)
label increment()
{
return ++data_;
}
// Some arbitrary method (for testing)
std::string info() const
{
return "boxed label=" + std::to_string(data_);
}
friend Ostream& operator<<(Ostream& os, const Label& val)
{
os << val.data_;
return os;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
HashTable<label, Foam::string> table1
{
{"kjhk", 10},
{"kjhk2", 12}
};
Info<< "table1: " << table1 << nl
<< "toc: " << flatOutput(table1.toc()) << nl;
HashTable<label, label, Hash<label>> table2
{
{3, 10},
{5, 12},
{7, 16}
};
Info<< "table2: " << table2 << nl
<< "toc: " << flatOutput(table2.toc()) << nl;
Map<label> table3(1);
table3.transfer(table2);
Info<< "table2: " << table2 << nl
<< "toc: " << flatOutput(table2.toc()) << nl;
Info<< "table3: " << table3 << nl
<< "toc: " << flatOutput(table3.toc()) << nl;
Map<label> table4(std::move(table3));
Info<< "table3: " << table3 << nl
<< "toc: " << flatOutput(table3.toc()) << nl;
Info<< "table4: " << table4 << nl
<< "toc: " << flatOutput(table4.toc()) << nl;
{
HashTable<Label, Foam::string> table1(0);
table1.insert("abc", 5);
table1.insert("def", 10);
table1.insert("ghi", 15);
table1.insert("jkl", 20);
Info<< nl << "Table toc: " << flatOutput(table1.toc()) << nl;
for (const word k : { "abc" })
{
const auto iter = table1.cfind(k);
if (iter.good())
{
Info<< "have " << k << nl
<< " info: " << (*iter).info() << nl
// Good: does not compile
// << " info: " << iter->info() << nl
;
}
auto iter2 = table1.find(k);
if (iter2.good())
{
Info<< "have " << k << nl
<< " incr: " << (*iter2).increment() << nl
// Good: does not compile
// << " incr: " << iter2->increment() << nl
;
}
}
}
{
HashPtrTable<Label> ptable1(0);
ptable1.insert("abc", autoPtr<Label>::New(5));
ptable1.insert("def", autoPtr<Label>::New(10));
ptable1.insert("ghi", autoPtr<Label>::New(15));
ptable1.insert("jkl", autoPtr<Label>::New(20));
Info<< nl << "PtrTable toc: " << flatOutput(ptable1.toc()) << nl;
for (const word k : { "abc" })
{
const auto iter = ptable1.cfind(k);
// Note: increment() changes contents of pointers,
// not the pointers themselves.
if (iter.good())
{
Info<< "have " << k << nl
<< " addr: " << name(*iter) << nl
<< " info: " << (*iter)->info() << nl
<< " incr: " << (*iter)->increment() << nl
;
}
auto iter2 = ptable1.find(k);
if (iter2.good())
{
Info<< "have " << k << nl
<< " incr: " << (*iter2)->increment() << nl
;
}
}
// Attempt the same again
HashTable<Label*> tableView1;
HashTable<const Label*> tableView2;
forAllConstIters(ptable1, iter)
{
tableView1.insert(iter.key(), iter.val());
tableView2.insert(iter.key(), iter.val());
}
Info<< nl << "Table<pointer> toc: "
<< flatOutput(tableView1.toc()) << nl;
for (const word k : { "abc" })
{
const auto iter1 = tableView1.cfind(k);
// Note that increment changes contents of the pointers
// not the table
if (iter1.good())
{
Info<< "have " << k << nl
<< " addr: " << name(*iter1) << nl
<< " info: " << (*iter1)->info() << nl
<< " incr: " << (*iter1)->increment() << nl
;
}
auto iter2 = tableView2.cfind(k);
if (iter2.good())
{
Info<< "have " << k << nl
<< " addr: " << name(*iter2) << nl
<< " info: " << (*iter2)->info() << nl
// Good: does not compile
// << " incr: " << iter2->increment() << nl
;
}
auto iter3 = tableView2.find(k);
if (iter3.good())
{
Info<< "have " << k << nl
<< " addr: " << name(*iter3) << nl
<< " info: " << (*iter3)->info() << nl
// Good: does not compile
// << " incr: " << iter3->increment() << nl
;
}
}
Info<< nl << "Ending scope" << nl;
}
{
Info<< nl << "Table<labelList> copy/move/emplace insertion" << nl;
HashTable<labelList> ltable1(0);
ltable1.insert("abc", identity(2));
ltable1.insert("def", identity(3));
ltable1.insert("ghi", identity(4));
ltable1.emplace("jkl", label(10), -35);
ltable1.emplace("mno");
ltable1.emplace("def", label(2), -2); // no overwrite
ltable1.emplace_set("ghi", label(2), -2); // overwrite
labelList list1(identity(4, -4));
Info<< "move insert " << list1 << nl;
ltable1.insert("pqr", std::move(list1));
Info<< "after insert " << list1 << nl;
Info<< nl << "HashTable<labelList>: "
<< ltable1 << nl;
// Use '->' dereferencing
const auto iter = ltable1.cfind("ghi");
if (iter)
{
Info<< "got with " << (*iter).size() << nl;
}
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //
Test-HashTable3.C
EXE = $(FOAM_USER_APPBIN)/Test-HashTable3
/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
/* EXE_LIBS = -lfiniteVolume */
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 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/>.
Description
Test speeds for some HashTable operations
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "HashTable.H"
#include "HashPtrTable.H"
#include "Map.H"
#include "cpuTime.H"
using namespace Foam;
template<class T>
Ostream& printInfo(Ostream& os, const HashTable<T, T, Hash<T>>& ht)
{
os << " (size " << ht.size() << " capacity " << ht.capacity() << ") ";
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
const label nLoops = 300;
const label nBase = 100000;
const label nSize = nLoops * nBase;
cpuTime timer;
// ie, a
// Map<label> map(2 * nSize);
// HashTable<label, label, Hash<label>> map(2 * nSize);
HashTable<label, label, Hash<label>> map(2 * nSize);
Info<< "Constructed map of size: " << nSize;
printInfo(Info, map);
Info<< timer.cpuTimeIncrement() << " s\n\n";
for (label i = 0; i < nSize; i++)
{
map.insert(i, i);
}
Info<< "Inserted " << nSize << " elements";
printInfo(Info, map);
Info<< timer.cpuTimeIncrement() << " s\n\n";
label elemI = 0;
for (label iLoop = 0; iLoop < nLoops; iLoop++)
{
for (label i = 0; i < nBase; i++)
{
map.erase(elemI++);
}
// map.shrink();
Info<< "loop " << iLoop << " - Erased " << nBase << " elements";
printInfo(Info, map);
Info << nl;
}
Info<< timer.cpuTimeIncrement() << " s\n";
return 0;
}
// ************************************************************************* //
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment