Commit e4d15d87 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

Merge branch 'HashTable-method-enhancements' into 'develop'

Hash table method enhancements

See merge request !112
parents c1cbfe7a 15d0a918
......@@ -234,6 +234,97 @@ int main()
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;
Info<< "\nDone\n";
return 0;
......
Test-IOobjectList.C
EXE = $(FOAM_USER_APPBIN)/Test-IOobjectList
EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = -lfiniteVolume
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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
Basic tests of IOobjectList
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "volFields.H"
#include "timeSelector.H"
#include "IOobjectList.H"
#include "hashedWordList.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noParallel();
argList::addOption("re", "wordReList");
// timeSelector::addOptions();
timeSelector::addOptions(true, true);
#include "setRootCase.H"
#include "createTime.H"
wordReList matcher;
if (args.optionFound("re"))
{
matcher = args.optionReadList<wordRe>("re");
Info<<"limit names: " << matcher << nl;
}
const hashedWordList subsetTypes
{
volScalarField::typeName,
volScalarField::Internal::typeName,
volVectorField::typeName,
};
instantList timeDirs = timeSelector::select0(runTime, args);
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
// Objects at this time
IOobjectList objects(runTime, runTime.timeName());
HashTable<wordHashSet> classes =
(
matcher.size()
? objects.classes(matcher)
: objects.classes()
);
Info<< "Time: " << runTime.timeName() << nl;
Info<<"Name: " << flatOutput(objects.sortedNames()) << nl
<<"Objects: " << objects << nl
<<"Classes: " << classes << nl;
classes.filterKeys(subsetTypes);
Info<<"only retain: " << flatOutput(subsetTypes) << nl;
Info<<"Pruned: " << classes << nl;
classes = objects.classes();
classes.erase(subsetTypes);
Info<<"remove: " << flatOutput(subsetTypes) << nl;
Info<<"Pruned: " << classes << nl;
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //
......@@ -180,9 +180,9 @@ int main(int argc, char *argv[])
// A regex with a zero length matcher doesn't work at all:
// eg "(png|jpg|txt|)" regex matcher itself
wordRe matcher0("()", wordRe::REGEXP);
wordRe matcher1("(png|jpg|txt)", wordRe::REGEXP);
wordRe matcher2("(png|txt)", wordRe::REGEXP);
wordRe matcher0("()", wordRe::REGEX);
wordRe matcher1("(png|jpg|txt)", wordRe::REGEX);
wordRe matcher2("(png|txt)", wordRe::REGEX);
Info<<"Has extension(s):" << nl
<< "input: " << endWithDot << nl;
......
Test-predicates.C
EXE = $(FOAM_USER_APPBIN)/Test-predicates
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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-predicates
Description
Simple tests using predicates
\*---------------------------------------------------------------------------*/
#include "IOstreams.H"
#include "labelList.H"
#include "wordList.H"
#include "predicates.H"
#include "FlatOutput.H"
#include "regExp.H"
using namespace Foam;
template<class ListType, class UnaryPredicate>
label printMatching(const ListType& list, const UnaryPredicate& pred)
{
label count = 0;
Info<< "(";
for (const auto& val : list)
{
if (pred(val))
{
if (count) Info<< ' ';
Info<< val;
++count;
}
}
Info<< ") => " << count << nl;
return count;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
wordList words
{
"abc",
"def",
"hij",
"abc_",
"def_",
"hij_",
};
labelRange range(-10, 40);
labelList values(range.begin(), range.end());
Info<<"words: " << flatOutput(words) << endl;
Info<<"values: " << flatOutput(values) << endl;
regExp matcher(".*_.*");
Info<<"With '_': ";
printMatching(words, matcher);
Info<<"All: ";
printMatching(words, predicates::always());
Info<<"None: ";
printMatching(words, predicates::never());
Info<<"Neg values: ";
printMatching(values, [](const label v) { return v < 0; });
Info<<"Even values: ";
printMatching(values, [](const label v) { return !(v % 2); });
Info<<"All: ";
printMatching(values, predicates::always());
Info<<"None: ";
printMatching(values, predicates::never());
return 0;
}
// ************************************************************************* //
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -30,7 +30,10 @@ Description
#include "IFstream.H"
#include "List.H"
#include "Tuple2.H"
#include "keyType.H"
#include "wordRe.H"
#include "wordRes.H"
#include "predicates.H"
using namespace Foam;
......@@ -44,12 +47,37 @@ int main(int argc, char *argv[])
Foam::string s2("this .* file");
const char * s3 = "this .* file";
keyType keyre("x.*", true);
wordReList wordrelist
{
{"this", wordRe::LITERAL},
{"x.*", wordRe::REGEX},
{"file[a-b]", wordRe::REGEX},
};
wordRes wrelist(wordrelist);
Info<< "re-list:" << wrelist() << endl;
Info<< "match this: " << wrelist("this") << endl;
Info<< "match xyz: " << wrelist("xyz") << endl;
Info<< "match zyx: " << wrelist("zyx") << endl;
Info<< "match xyz: " << wrelist.match("xyz") << endl;
Info<< "match any: " << predicates::always()("any junk") << endl;
Info<< "keyre match: " << keyre("xyz") << endl;
Info<< "string match: " << string("this").match("xyz") << endl;
Info<< "string match: " << string("x.*")("xyz") << endl;
Info<< "string match: " << string("x.*")(keyre) << endl;
wordRe(s1, wordRe::DETECT).info(Info) << endl;
wordRe(s2).info(Info) << endl;
wordRe(s2, wordRe::DETECT).info(Info) << endl;
wordRe(s3, wordRe::REGEXP).info(Info) << endl;
wordRe(s3, wordRe::REGEX).info(Info) << endl;
wre = "this .* file";
Info<<"substring: " << wre(4) << endl;
wre.info(Info) << endl;
wre = s1;
wre.info(Info) << endl;
......
......@@ -24,7 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "doxygenXmlParser.H"
#include "wordRe.H"
#include "regExp.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......@@ -40,8 +40,8 @@ Foam::doxygenXmlParser::doxygenXmlParser
dictionary(dictionary::null)
{
// Pre-construct and compile regular expressions
const wordRe nameRe(".*.H", wordRe::DETECT);
const wordRe searchStrRe(searchStr, wordRe::DETECT);
const regExp nameRe(".*.H");
const regExp searchStrRe(searchStr);
// Pre-construct constant strings and names to speed-up comparisons
const string slashStartTag('/' + startTag);
......@@ -163,7 +163,7 @@ Foam::doxygenXmlParser::doxygenXmlParser
(
!exactMatch
&& !found(tName) // not already added
&& wordRe(".*" + tName + ".*", wordRe::DETECT).match(name)
&& regExp(".*" + tName + ".*").match(name)
)
{
dictionary dict(dictionary::null);
......
......@@ -23,7 +23,7 @@ if (!fieldsToUse.found(fieldName))
).typeHeaderOk<volScalarField>(false, false)
);
if (variableGood)
if (!variableGood)
{
break;
}
......
......@@ -35,36 +35,25 @@ if (timeDirs.size() && !noLagrangian)
cloudPrefix/cloudName
);
// clouds always require "positions"
// Clouds always have "positions"
if (cloudObjs.found("positions"))
{
HashTable<HashTable<word>>::iterator cloudIter =
cloudFields.find(cloudName);
// Save the cloud fields on a per cloud basis
auto fieldsPerCloud = cloudFields(cloudName);
if (cloudIter == cloudFields.end())
forAllConstIters(cloudObjs, fieldIter)
{
// A newly discovered cloud
cloudFields.insert(cloudName, HashTable<word>());
cloudIter = cloudFields.find(cloudName);
}
const IOobject* obj = fieldIter();
forAllConstIter(IOobjectList, cloudObjs, fieldIter)
{
const IOobject& obj = *fieldIter();
// Add field and field type
cloudIter().insert
(
obj.name(),
obj.headerClassName()
);
// Field name/type
fieldsPerCloud.insert(obj->name(), obj->headerClassName());
}
}
}
}
// prune out "positions" again since it gets treated specially
forAllIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
// Prune out "positions" again since it gets treated specially
forAllIters(cloudFields, cloudIter)
{
cloudIter().erase("positions");
}
......@@ -76,18 +65,13 @@ if (timeDirs.size() && !noLagrangian)
}
// sorted list of cloud names
// Sorted list of cloud names
const wordList cloudNames(cloudFields.sortedToc());
if (cloudNames.size())
{
// complete the echo information
Info<< "(";
forAll(cloudNames, cloudNo)
{
Info<< ' ' << cloudNames[cloudNo];
}
Info<< " ) " << endl;
// Complete the echo information - as flatOutput
cloudNames.writeList(Info) << endl;
}
// ************************************************************************* //
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -78,6 +78,7 @@ Note
#include "fvc.H"
#include "volFields.H"
#include "hashedWordList.H"
#include "labelIOField.H"
#include "scalarIOField.H"
......@@ -190,7 +191,7 @@ int main(int argc, char *argv[])
);
// The volume field types that we handle
const wordList volFieldTypes
const hashedWordList volFieldTypes
{
volScalarField::typeName,
volVectorField::typeName,
......@@ -207,7 +208,7 @@ int main(int argc, char *argv[])
#include "setRootCase.H"
// default to binary output, unless otherwise specified
// Default to binary output, unless otherwise specified
const IOstream::streamFormat format =
(
args.optionFound("ascii")
......@@ -234,7 +235,7 @@ int main(int argc, char *argv[])
}
//
// general (case) output options
// General (case) output options
//
ensightCase::options caseOpts(format);
......@@ -257,7 +258,7 @@ int main(int argc, char *argv[])
//
// output configuration (geometry related)
// Output configuration (geometry related)
//
ensightMesh::options writeOpts(format);
writeOpts.noPatches(args.optionFound("noPatches"));
......@@ -313,12 +314,6 @@ int main(int argc, char *argv[])
ensCase.printInfo(Info) << endl;
}
// Set Time to the last time before looking for lagrangian objects
runTime.setTime(timeDirs.last(), timeDirs.size()-1);
IOobjectList objects(mesh, runTime.timeName());
#include "checkMeshMoving.H"
#include "findCloudFields.H"
......@@ -331,6 +326,40 @@ int main(int argc, char *argv[])
<< timer.cpuTimeIncrement() << " s, "
<< mem.update().size() << " kB" << nl << endl;
// Get the list of supported classes/fields
HashTable<wordHashSet> usableObjects;
{
// Initially all possible objects that are available at the final time
IOobjectList objects(mesh, timeDirs.last().name());
// Categorize by classes, pre-filter on name (if requested)
usableObjects =
(
fieldPatterns.empty()
? objects.classes()
: objects.classes(fieldPatterns)
);
// Limit to types that we explicitly handle
usableObjects.filterKeys(volFieldTypes);
// Force each field-type into existence (simplifies code logic