mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support patch group selection
- vtkWrite, foamToVTK, surfaceMeshExtract
This commit is contained in:
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2021-2023 OpenCFD Ltd.
|
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||||
@ -44,10 +44,10 @@ forAll(meshes, regioni)
|
|||||||
IOobjectOption::NO_REGISTER
|
IOobjectOption::NO_REGISTER
|
||||||
);
|
);
|
||||||
|
|
||||||
if (fieldSelector && !fieldSelector().empty())
|
if (fieldSelector)
|
||||||
{
|
{
|
||||||
objects.filterObjects(fieldSelector());
|
objects.filterObjects(fieldSelector);
|
||||||
faObjects.filterObjects(fieldSelector());
|
faObjects.filterObjects(fieldSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove "*_0" restart fields
|
// Remove "*_0" restart fields
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
Copyright (C) 2016-2025 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -406,34 +406,27 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Field selection/deselection
|
// Field selection/deselection
|
||||||
wordRes includedFields, excludedFields;
|
wordRes includedFields, excludedFields;
|
||||||
autoPtr<wordRes::filter> fieldSelector(nullptr);
|
|
||||||
const bool doConvertFields = !args.found("no-fields");
|
const bool doConvertFields = !args.found("no-fields");
|
||||||
if (doConvertFields)
|
if (doConvertFields)
|
||||||
{
|
{
|
||||||
bool resetFilter = false;
|
|
||||||
if (args.readListIfPresent<wordRe>("fields", includedFields))
|
if (args.readListIfPresent<wordRe>("fields", includedFields))
|
||||||
{
|
{
|
||||||
resetFilter = true;
|
|
||||||
Info<< "Including fields "
|
Info<< "Including fields "
|
||||||
<< flatOutput(includedFields) << nl << endl;
|
<< flatOutput(includedFields) << nl << endl;
|
||||||
}
|
}
|
||||||
if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields))
|
if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields))
|
||||||
{
|
{
|
||||||
resetFilter = true;
|
|
||||||
Info<< "Excluding fields "
|
Info<< "Excluding fields "
|
||||||
<< flatOutput(excludedFields) << nl << endl;
|
<< flatOutput(excludedFields) << nl << endl;
|
||||||
}
|
}
|
||||||
if (resetFilter)
|
|
||||||
{
|
|
||||||
fieldSelector =
|
|
||||||
autoPtr<wordRes::filter>::New(includedFields, excludedFields);
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else if (doConvertFields)
|
|
||||||
{
|
{
|
||||||
Info<< "Field conversion disabled with the '-no-fields' option" << nl;
|
Info<< "Field conversion disabled with the '-no-fields' option" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wordRes::filter fieldSelector(includedFields, excludedFields);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "createTime.H"
|
#include "createTime.H"
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
Copyright (C) 2018-2025 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||||
@ -136,7 +136,7 @@ Description
|
|||||||
labelList patchIds;
|
labelList patchIds;
|
||||||
if (doBoundary)
|
if (doBoundary)
|
||||||
{
|
{
|
||||||
patchIds = getSelectedPatches(patches, patchSelector);
|
patchIds = patchSelector.indices(patches);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oneBoundary && patchIds.size())
|
if (oneBoundary && patchIds.size())
|
||||||
|
|||||||
@ -166,56 +166,54 @@ Note
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
labelList getSelectedPatches
|
namespace Foam
|
||||||
(
|
|
||||||
const polyBoundaryMesh& patches,
|
|
||||||
const autoPtr<wordRes::filter>& patchSelector
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
labelList indices;
|
|
||||||
|
|
||||||
if (patchSelector && !patchSelector().empty())
|
// Simple wrapper for polyBoundaryMesh::indices() with some additional logic
|
||||||
|
struct polyBoundaryPatchSelector
|
||||||
|
{
|
||||||
|
wordRes allow_;
|
||||||
|
wordRes deny_;
|
||||||
|
|
||||||
|
void clear()
|
||||||
{
|
{
|
||||||
// Name-based selection
|
allow_.clear();
|
||||||
indices =
|
deny_.clear();
|
||||||
(
|
|
||||||
stringListOps::findMatching
|
|
||||||
(
|
|
||||||
patches,
|
|
||||||
patchSelector(),
|
|
||||||
nameOp<polyPatch>()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
indices = identity(patches.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove undesirable patches
|
//- Forward to polyBoundaryMesh::indices() with additional handling.
|
||||||
|
// Prune emptyPolyPatch (always) and processorPolyPatch (in parallel)
|
||||||
|
labelList indices(const polyBoundaryMesh& pbm) const
|
||||||
|
{
|
||||||
|
labelList ids = pbm.indices(allow_, deny_);
|
||||||
|
|
||||||
|
const bool excludeProcPatches = UPstream::parRun();
|
||||||
|
|
||||||
|
// Prune undesirable patches
|
||||||
label count = 0;
|
label count = 0;
|
||||||
for (const label patchi : indices)
|
for (const label patchi : ids)
|
||||||
{
|
{
|
||||||
const polyPatch& pp = patches[patchi];
|
const auto& pp = pbm[patchi];
|
||||||
|
|
||||||
if (isType<emptyPolyPatch>(pp))
|
if (isType<emptyPolyPatch>(pp))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (UPstream::parRun() && bool(isA<processorPolyPatch>(pp)))
|
else if (excludeProcPatches && bool(isA<processorPolyPatch>(pp)))
|
||||||
{
|
{
|
||||||
break; // No processor patches for parallel output
|
break; // No processor patches for parallel output
|
||||||
}
|
}
|
||||||
|
|
||||||
indices[count] = patchi;
|
ids[count] = patchi;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
indices.resize(count);
|
ids.resize(count);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return indices;
|
} // End namespace Foam
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -552,45 +550,38 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Patch selection/deselection
|
// Patch selection/deselection
|
||||||
wordRes includedPatches, excludedPatches;
|
polyBoundaryPatchSelector patchSelector;
|
||||||
autoPtr<wordRes::filter> patchSelector(nullptr);
|
|
||||||
if (doBoundary)
|
if (doBoundary)
|
||||||
{
|
{
|
||||||
bool resetFilter = false;
|
if
|
||||||
if (args.readListIfPresent<wordRe>("patches", includedPatches))
|
(
|
||||||
|
auto& slot = patchSelector.allow_;
|
||||||
|
args.readListIfPresent<wordRe>("patches", slot)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
resetFilter = true;
|
Info<< "Including patches " << flatOutput(slot) << nl << endl;
|
||||||
Info<< "Including patches "
|
|
||||||
<< flatOutput(includedPatches) << nl << endl;
|
|
||||||
}
|
}
|
||||||
if (args.readListIfPresent<wordRe>("exclude-patches", excludedPatches))
|
if
|
||||||
|
(
|
||||||
|
auto& slot = patchSelector.deny_;
|
||||||
|
args.readListIfPresent<wordRe>("exclude-patches", slot)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
resetFilter = true;
|
Info<< "Excluding patches " << flatOutput(slot) << nl << endl;
|
||||||
Info<< "Excluding patches "
|
|
||||||
<< flatOutput(excludedPatches) << nl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resetFilter)
|
|
||||||
{
|
|
||||||
patchSelector =
|
|
||||||
autoPtr<wordRes::filter>::New(includedPatches, excludedPatches);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Field selection/deselection
|
// Field selection/deselection
|
||||||
wordRes includedFields, excludedFields;
|
wordRes includedFields, excludedFields;
|
||||||
autoPtr<wordRes::filter> fieldSelector(nullptr);
|
|
||||||
bool doConvertFields = !args.found("no-fields");
|
bool doConvertFields = !args.found("no-fields");
|
||||||
if (doConvertFields)
|
if (doConvertFields)
|
||||||
{
|
{
|
||||||
bool resetFilter = false;
|
|
||||||
if (args.readListIfPresent<wordRe>("fields", includedFields))
|
if (args.readListIfPresent<wordRe>("fields", includedFields))
|
||||||
{
|
{
|
||||||
Info<< "Including fields "
|
Info<< "Including fields "
|
||||||
<< flatOutput(includedFields) << nl << endl;
|
<< flatOutput(includedFields) << nl << endl;
|
||||||
|
|
||||||
resetFilter = !includedFields.empty();
|
|
||||||
|
|
||||||
if (includedFields.empty())
|
if (includedFields.empty())
|
||||||
{
|
{
|
||||||
// Compat: Can be specified as empty (ie, no fields)
|
// Compat: Can be specified as empty (ie, no fields)
|
||||||
@ -603,22 +594,22 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields))
|
if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields))
|
||||||
{
|
{
|
||||||
resetFilter = true;
|
|
||||||
Info<< "Excluding fields "
|
Info<< "Excluding fields "
|
||||||
<< flatOutput(excludedFields) << nl << endl;
|
<< flatOutput(excludedFields) << nl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resetFilter && doConvertFields)
|
if (!doConvertFields)
|
||||||
{
|
{
|
||||||
fieldSelector =
|
includedFields.clear();
|
||||||
autoPtr<wordRes::filter>::New(includedFields, excludedFields);
|
excludedFields.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (doConvertFields)
|
else
|
||||||
{
|
{
|
||||||
Info<< "Field conversion disabled with the '-no-fields' option" << nl;
|
Info<< "Field conversion disabled with the '-no-fields' option" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wordRes::filter fieldSelector(includedFields, excludedFields);
|
||||||
|
|
||||||
// Non-mandatory
|
// Non-mandatory
|
||||||
const wordRes selectedFaceZones(args.getList<wordRe>("faceZones", false));
|
const wordRes selectedFaceZones(args.getList<wordRe>("faceZones", false));
|
||||||
@ -799,10 +790,10 @@ int main(int argc, char *argv[])
|
|||||||
IOobjectOption::NO_REGISTER
|
IOobjectOption::NO_REGISTER
|
||||||
);
|
);
|
||||||
|
|
||||||
if (fieldSelector && !fieldSelector().empty())
|
if (fieldSelector)
|
||||||
{
|
{
|
||||||
objects.filterObjects(fieldSelector());
|
objects.filterObjects(fieldSelector);
|
||||||
faObjects.filterObjects(fieldSelector());
|
faObjects.filterObjects(fieldSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove "*_0" restart fields
|
// Remove "*_0" restart fields
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2024 OpenCFD Ltd.
|
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -155,50 +155,39 @@ void writeOBJ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple wrapper for polyBoundaryMesh::indices() with some additional logic
|
||||||
|
// - prune emptyPolyPatch (always) and (maybe) processorPolyPatch
|
||||||
labelList getSelectedPatches
|
labelList getSelectedPatches
|
||||||
(
|
(
|
||||||
const polyBoundaryMesh& patches,
|
const polyBoundaryMesh& pbm,
|
||||||
const wordRes& allow,
|
const wordRes& allow,
|
||||||
const wordRes& deny
|
const wordRes& deny,
|
||||||
|
const bool excludeProcPatches
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Name-based selection
|
labelList ids = pbm.indices(allow, deny);
|
||||||
labelList indices
|
|
||||||
(
|
|
||||||
stringListOps::findMatching
|
|
||||||
(
|
|
||||||
patches,
|
|
||||||
allow,
|
|
||||||
deny,
|
|
||||||
nameOp<polyPatch>()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Remove undesirable patches
|
// Remove undesirable patches
|
||||||
|
|
||||||
label count = 0;
|
label count = 0;
|
||||||
for (const label patchi : indices)
|
for (const label patchi : ids)
|
||||||
{
|
{
|
||||||
const polyPatch& pp = patches[patchi];
|
const polyPatch& pp = pbm[patchi];
|
||||||
|
|
||||||
if (isType<emptyPolyPatch>(pp))
|
if (isType<emptyPolyPatch>(pp))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (Pstream::parRun() && bool(isA<processorPolyPatch>(pp)))
|
else if (excludeProcPatches && bool(isA<processorPolyPatch>(pp)))
|
||||||
{
|
{
|
||||||
break; // No processor patches for parallel output
|
break; // No processor patches for parallel output
|
||||||
}
|
}
|
||||||
|
|
||||||
indices[count] = patchi;
|
ids[count] = patchi;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
indices.resize(count);
|
ids.resize(count);
|
||||||
|
return ids;
|
||||||
return indices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -668,11 +657,14 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
const labelList patchIds =
|
const labelList patchIds =
|
||||||
(
|
(
|
||||||
(includePatches.size() || excludePatches.size())
|
getSelectedPatches
|
||||||
? getSelectedPatches(bMesh, includePatches, excludePatches)
|
(
|
||||||
: includeProcPatches
|
bMesh,
|
||||||
? identity(bMesh.size())
|
includePatches,
|
||||||
: identity(bMesh.nNonProcessor())
|
excludePatches,
|
||||||
|
// No processor patches? (parallel output or excluded)
|
||||||
|
(UPstream::parRun() || !includeProcPatches)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
labelList faceZoneIds;
|
labelList faceZoneIds;
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
Copyright (C) 2018-2025 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,6 +27,7 @@ License
|
|||||||
|
|
||||||
#include "vtkWrite.H"
|
#include "vtkWrite.H"
|
||||||
#include "cellBitSet.H"
|
#include "cellBitSet.H"
|
||||||
|
#include "emptyPolyPatch.H"
|
||||||
#include "processorPolyPatch.H"
|
#include "processorPolyPatch.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
@ -54,15 +55,17 @@ bool Foam::functionObjects::vtkWrite::updateSubset
|
|||||||
|
|
||||||
Foam::labelList Foam::functionObjects::vtkWrite::getSelectedPatches
|
Foam::labelList Foam::functionObjects::vtkWrite::getSelectedPatches
|
||||||
(
|
(
|
||||||
const polyBoundaryMesh& patches
|
const polyBoundaryMesh& pbm
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
DynamicList<label> patchIDs(patches.size());
|
labelList ids = pbm.indices(selectPatches_, blockPatches_);
|
||||||
|
|
||||||
wordRes::filter patchFilter(selectPatches_, blockPatches_);
|
// Prune undesirable patches
|
||||||
|
label count = 0;
|
||||||
for (const polyPatch& pp : patches)
|
for (const label patchi : ids)
|
||||||
{
|
{
|
||||||
|
const auto& pp = pbm[patchi];
|
||||||
|
|
||||||
if (isType<emptyPolyPatch>(pp))
|
if (isType<emptyPolyPatch>(pp))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -72,13 +75,12 @@ Foam::labelList Foam::functionObjects::vtkWrite::getSelectedPatches
|
|||||||
break; // No processor patches
|
break; // No processor patches
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patchFilter(pp.name()))
|
ids[count] = patchi;
|
||||||
{
|
++count;
|
||||||
patchIDs.append(pp.index());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return labelList(std::move(patchIDs));
|
ids.resize(count);
|
||||||
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user