ENH: geometric selection mode for cellSetOption

- similar to the geometric decomposition constraint,
  allows a compositing selection of cells based on topoSet sources
  which also include various searchableSurface mechanisms.

  This makes for potentially easier placement of sources without
  resorting to defining a cellSet.

ENH: support zone group selection for fv::cellSetOption and fa::faceSetOption
This commit is contained in:
Mark Olesen 2022-05-24 20:34:19 +02:00
parent f0f893c4b8
commit 937b4898ae
14 changed files with 252 additions and 133 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd.
Copyright (C) 2019-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -62,7 +62,7 @@ void Foam::fa::faceSetOption::setSelection(const dictionary& dict)
}
case smVolFaceZone:
{
dict.readEntry("faceZone", faceSetName_);
dict.readEntry("faceZone", zoneName_);
break;
}
default:
@ -113,41 +113,39 @@ void Foam::fa::faceSetOption::setFaceSelection()
{
Info<< indent
<< "- selecting faces using volume-mesh faceZone "
<< faceSetName_ << endl;
<< zoneName_ << nl;
label zoneID = mesh_.faceZones().findZoneID(faceSetName_);
if (zoneID == -1)
// Also handles groups, multiple zones (as wordRe match) ...
labelList zoneIDs = mesh_.faceZones().indices(zoneName_);
if (zoneIDs.empty())
{
FatalErrorInFunction
<< "Cannot find faceZone " << faceSetName_ << endl
<< "Valid faceZones are " << mesh_.faceZones().names()
<< "No matching faceZones: " << zoneName_ << nl
<< "Valid zones : "
<< flatOutput(mesh_.faceZones().names()) << nl
<< "Valid groups: "
<< flatOutput(mesh_.faceZones().groupNames())
<< nl
<< exit(FatalError);
}
const faceZone& addr = mesh_.faceZones()[zoneID];
const bitSet isZoneFace(mesh_.faceZones().selection(zoneIDs));
const bitSet isZoneFace(mesh_.nFaces(), addr);
// Do we loop over faMesh faces or over faceZone faces?
const labelUList& faceLabels = regionMesh().faceLabels();
label n = 0;
faces_.resize_nocopy(faceLabels.size());
label nUsed = 0;
for (const label facei : faceLabels)
{
if (isZoneFace[facei])
{
n++;
}
}
faces_.setSize(n);
n = 0;
for (const label facei : faceLabels)
{
if (isZoneFace[facei])
{
faces_[n++] = facei;
faces_[nUsed] = facei;
++nUsed;
}
}
faces_.resize(nUsed);
break;
}
@ -185,7 +183,7 @@ Foam::fa::faceSetOption::faceSetOption
timeStart_(-1),
duration_(0),
selectionMode_(selectionModeTypeNames_.get("selectionMode", coeffs_)),
faceSetName_("none"),
zoneName_(),
A_(0)
{
if (isActive())

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd.
Copyright (C) 2019-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -81,8 +81,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef faceSetOption_H
#define faceSetOption_H
#ifndef Foam_fa_faceSetOption_H
#define Foam_fa_faceSetOption_H
#include "faOption.H"
#include "faceSet.H"
@ -132,8 +132,8 @@ protected:
//- Face selection mode
selectionModeType selectionMode_;
//- Name of "volFaceZone" selection
word faceSetName_;
//- Name of zone for (volume) "faceZone" selection
wordRe zoneName_;
//- Set of faces to apply source to
labelList faces_;
@ -195,9 +195,9 @@ public:
//- True if sub-selection should be used
inline bool useSubMesh() const noexcept;
//- Return const access to the name of face set for "faceZone"
//- selectionMode
inline const word& faceSetName() const noexcept;
//- Return const access to the name of (volume) face zone
//- for "faceZone" selection mode
const wordRe& zoneName() const noexcept { return zoneName_; }
//- Return const access to the total face area
inline scalar A() const noexcept;

View File

@ -66,12 +66,6 @@ inline bool Foam::fa::faceSetOption::useSubMesh() const noexcept
}
inline const Foam::word& Foam::fa::faceSetOption::faceSetName() const noexcept
{
return faceSetName_;
}
inline Foam::scalar Foam::fa::faceSetOption::A() const noexcept
{
return A_;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,6 +27,9 @@ License
\*---------------------------------------------------------------------------*/
#include "cellSetOption.H"
#include "cellSet.H"
#include "cellBitSet.H"
#include "topoSetCellSource.H"
#include "volFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -46,6 +49,7 @@ const Foam::Enum
>
Foam::fv::cellSetOption::selectionModeTypeNames_
({
{ selectionModeType::smGeometric, "geometric" },
{ selectionModeType::smPoints, "points" },
{ selectionModeType::smCellSet, "cellSet" },
{ selectionModeType::smCellZone, "cellZone" },
@ -59,6 +63,11 @@ void Foam::fv::cellSetOption::setSelection(const dictionary& dict)
{
switch (selectionMode_)
{
case smGeometric:
{
geometricSelection_ = dict.subDict("selection");
break;
}
case smPoints:
{
dict.readEntry("points", points_);
@ -66,12 +75,12 @@ void Foam::fv::cellSetOption::setSelection(const dictionary& dict)
}
case smCellSet:
{
dict.readEntry("cellSet", cellSetName_);
dict.readEntry("cellSet", zoneName_);
break;
}
case smCellZone:
{
dict.readEntry("cellZone", cellSetName_);
dict.readEntry("cellZone", zoneName_);
break;
}
case smAll:
@ -95,7 +104,7 @@ void Foam::fv::cellSetOption::setVol()
{
// Set volume information
scalar sumVol = 0.0;
scalar sumVol = 0;
for (const label celli : cells_)
{
sumVol += mesh_.V()[celli];
@ -122,28 +131,62 @@ void Foam::fv::cellSetOption::setCellSelection()
{
switch (selectionMode_)
{
case smGeometric:
{
// Modify bitSet via topoSetCellSource
cellBitSet selectedCells(mesh_);
Info<< indent << "- selecting cells geometrically" << endl;
for (const entry& dEntry : geometricSelection_)
{
if (!dEntry.isDict())
{
WarningInFunction
<< "Ignoring non-dictionary entry "
<< dEntry << endl;
continue;
}
const dictionary& spec = dEntry.dict();
auto source = topoSetCellSource::New
(
spec.get<word>("source"),
mesh_,
spec.optionalSubDict("sourceInfo")
);
// source->verbose(false);
source->applyToSet(topoSetSource::ADD, selectedCells);
}
// Retrieve bitSet
cells_ = selectedCells.addressing().sortedToc();
break;
}
case smPoints:
{
Info<< indent << "- selecting cells using points" << endl;
labelHashSet selectedCells;
forAll(points_, i)
for (const point& p : points_)
{
label celli = mesh_.findCell(points_[i]);
if (celli >= 0)
const label celli = mesh_.findCell(p);
const bool found = (celli >= 0);
if (found)
{
selectedCells.insert(celli);
}
label globalCelli = returnReduce(celli, maxOp<label>());
if (globalCelli < 0)
if (!returnReduce(found, orOp<bool>()))
{
WarningInFunction
<< "Unable to find owner cell for point " << points_[i]
<< endl;
<< "No owner cell found for point " << p << endl;
}
}
cells_ = selectedCells.sortedToc();
@ -152,26 +195,39 @@ void Foam::fv::cellSetOption::setCellSelection()
case smCellSet:
{
Info<< indent
<< "- selecting cells using cellSet " << cellSetName_ << endl;
<< "- selecting cells using cellSet " << zoneName_ << endl;
cells_ = cellSet(mesh_, cellSetName_).sortedToc();
cells_ = cellSet(mesh_, zoneName_).sortedToc();
break;
}
case smCellZone:
{
Info<< indent
<< "- selecting cells using cellZone " << cellSetName_ << endl;
<< "- selecting cells using cellZone " << zoneName_ << endl;
label zoneID = mesh_.cellZones().findZoneID(cellSetName_);
if (zoneID == -1)
// Also handles groups, multiple zones (as wordRe match) ...
labelList zoneIDs = mesh_.cellZones().indices(zoneName_);
if (zoneIDs.empty())
{
FatalErrorInFunction
<< "Cannot find cellZone " << cellSetName_ << endl
<< "Valid cellZones are " << mesh_.cellZones().names()
<< "No matching cellZones: " << zoneName_ << nl
<< "Valid zones : "
<< flatOutput(mesh_.cellZones().names()) << nl
<< "Valid groups: "
<< flatOutput(mesh_.cellZones().groupNames())
<< nl
<< exit(FatalError);
}
cells_ = mesh_.cellZones()[zoneID];
if (zoneIDs.size() == 1)
{
cells_ = mesh_.cellZones()[zoneIDs.first()];
}
else
{
cells_ = mesh_.cellZones().selection(zoneIDs).sortedToc();
}
break;
}
case smAll:
@ -191,6 +247,16 @@ void Foam::fv::cellSetOption::setCellSelection()
<< exit(FatalError);
}
}
if
(
smAll != selectionMode_
&& returnReduce(cells_.empty(), andOp<bool>())
)
{
WarningInFunction
<< "No cells selected!" << endl;
}
}
@ -208,7 +274,9 @@ Foam::fv::cellSetOption::cellSetOption
timeStart_(-1),
duration_(0),
selectionMode_(selectionModeTypeNames_.get("selectionMode", coeffs_)),
cellSetName_("none"),
zoneName_(),
points_(),
geometricSelection_(),
V_(0)
{
Info<< incrIndent;
@ -235,9 +303,13 @@ bool Foam::fv::cellSetOption::isActive()
// Force printing of new set volume
V_ = -GREAT;
}
else if (selectionMode_ == smPoints)
else if
(
selectionMode_ == smGeometric
|| selectionMode_ == smPoints
)
{
// This is the only geometric selection mode
// Geometric selection mode(s)
setCellSelection();
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -51,14 +51,32 @@ Usage
duration 1.4;
// when selectionMode=cellSet
cellSet <cellSetName>;
cellSet <name>;
// when selectionMode=cellZone
cellZone <cellZoneName>;
cellZone <name>;
// when selectionMode=points
points (<point1> <point2> ... <pointN>);
// when selectionMode=geometric
selection
{
box1
{
source box;
min (-0.1 -0.01 -0.1);
max (0.1 0.30 0.1);
}
ball
{
source sphere;
origin (-0.1 -0.01 -0.1);
radius 0.25;
}
...
}
// Mandatory/Optional (derived) entries
...
}
@ -75,19 +93,26 @@ Usage
cellZone | Name of operand cellZone | word | cndtnl | -
points | Set of points in global coordinate <!--
--> system | vectorList | cndtnl | -
selection | Dictionary of geometric selections | dict | cndtnl | -
\endtable
Options for the \c selectionMode entry:
\verbatim
all | Use all cells in the computational domain
cellZone | Use a given cellZone
cellSet | Use a given cellSet
cellZone | Use specified cellZone
cellSet | Use specified cellSet
points | Use cells containing a given set of points
geometric | Select cells based on topoSetCellSource
\endverbatim
The inherited entries are elaborated in:
- \link fvOption.H \endlink
The geometric selection uses topoSetCellSource to select cells.
The combined cell selections are treated as an OR operation.
Any searchableSurface selections must describe a closed volume.
Ie, its hasVolumeType() method must be true.
Note
- Source/sink options are to be added to the right-hand side of equations.
@ -96,12 +121,12 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef cellSetOption_H
#define cellSetOption_H
#ifndef Foam_fv_cellSetOption_H
#define Foam_fv_cellSetOption_H
#include "fvOption.H"
#include "cellSet.H"
#include "fvMesh.H"
#include "dictionary.H"
#include "Time.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -126,10 +151,11 @@ public:
//- Enumeration for selection mode types
enum selectionModeType
{
smAll,
smCellSet,
smCellZone,
smPoints
smAll, //!< "all" cells
smCellSet, //!< "cellSet"
smCellZone, //!< "cellZone"
smPoints, //!< "points"
smGeometric //!< "geometric"
};
//- List of selection mode type names
@ -150,11 +176,14 @@ protected:
selectionModeType selectionMode_;
//- Name of set/zone for "cellSet" and "cellZone" selectionMode
word cellSetName_;
wordRe zoneName_;
//- List of points for "points" selectionMode
List<point> points_;
//- Dictionary entries for "geometric" (topoSetCellSource) selection
dictionary geometricSelection_;
//- Set of cells to apply source to
labelList cells_;
@ -215,9 +244,9 @@ public:
//- True if sub-selection should be used
inline bool useSubMesh() const noexcept;
//- Return const access to the name of cell set/zone for
//- "cellSet" / "cellZone" selection modes
inline const word& cellSetName() const noexcept;
//- Return const access to the name of cell set/zone
//- for "cellSet" / "cellZone" selection modes
const wordRe& zoneName() const noexcept { return zoneName_; }
//- Return const access to the total cell volume
inline scalar V() const noexcept;
@ -245,6 +274,13 @@ public:
//- Read source dictionary
virtual bool read(const dictionary& dict);
// Housekeeping
//- The name of the cell set/zone [as a word]
//- for "cellSet" / "cellZone" selection modes)
const word& cellSetName() const noexcept { return zoneName_; }
};

View File

@ -67,12 +67,6 @@ inline bool Foam::fv::cellSetOption::useSubMesh() const noexcept
}
inline const Foam::word& Foam::fv::cellSetOption::cellSetName() const noexcept
{
return cellSetName_;
}
inline Foam::scalar Foam::fv::cellSetOption::V() const noexcept
{
return V_;

View File

@ -7,7 +7,7 @@
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 ENERCON GmbH
Copyright (C) 2018-2021 OpenCFD Ltd
Copyright (C) 2018-2022 OpenCFD Ltd
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,6 +29,7 @@ License
#include "actuationDiskSource.H"
#include "geometricOneField.H"
#include "cellSet.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -118,20 +119,22 @@ void Foam::fv::actuationDiskSource::setMonitorCells(const dictionary& dict)
dict.readEntry("upstreamPoint", monitorPoints.first());
}
for (const auto& monitorPoint : monitorPoints)
for (const point& p : monitorPoints)
{
const label celli = mesh_.findCell(monitorPoint);
if (celli >= 0)
const label celli = mesh_.findCell(p);
const bool found = (celli >= 0);
if (found)
{
selectedCells.insert(celli);
}
const label globalCelli = returnReduce(celli, maxOp<label>());
if (globalCelli < 0)
if (!returnReduce(found, orOp<bool>()))
{
WarningInFunction
<< "Unable to find owner cell for point "
<< monitorPoint << endl;
<< "No owner cell found for point "
<< p << endl;
}
}
@ -141,9 +144,9 @@ void Foam::fv::actuationDiskSource::setMonitorCells(const dictionary& dict)
case monitorMethodType::CELLSET:
{
Info<< " - selecting cells using cellSet "
<< cellSetName_ << endl;
<< zoneName() << endl;
monitorCells_ = cellSet(mesh_, cellSetName_).sortedToc();
monitorCells_ = cellSet(mesh_, zoneName()).sortedToc();
break;
}
default:

View File

@ -362,7 +362,7 @@ void Foam::fv::directionalPressureGradientExplicitSource::correct
{
FatalErrorInFunction
<< "Did not find cell " << masterCellI
<< "in cellZone :" << cellSetName()
<< "in cellZone :" << zoneName()
<< exit(FatalError);
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2018 OpenFOAM Foundation
Copyright (C) 2020-2021 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -59,16 +59,7 @@ Foam::fv::explicitPorositySource::explicitPorositySource
{
read(dict);
porosityPtr_.reset
(
porosityModel::New
(
name_,
mesh_,
coeffs_,
cellSetName_
).ptr()
);
porosityPtr_.reset(porosityModel::New(name_, mesh_, coeffs_, zoneName()));
}

View File

@ -115,8 +115,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef explicitPorositySource_H
#define explicitPorositySource_H
#ifndef Foam_explicitPorositySource_H
#define Foam_explicitPorositySource_H
#include "cellSetOption.H"
@ -177,7 +177,7 @@ public:
// Member Functions
//- Access to the porosityModel
const porosityModel& model() const
const porosityModel& model() const noexcept
{
return *porosityPtr_;
}

View File

@ -1,7 +1,7 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2112 |
| \\ / O peration | Version: v2206 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
@ -48,5 +48,10 @@ adjustTimeStep yes;
maxCo 1;
functions
{
#include "scalarTransport"
}
// ************************************************************************* //

View File

@ -1,7 +1,7 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2112 |
| \\ / O peration | Version: v2206 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
@ -32,6 +32,7 @@ divSchemes
div(phi,h) Gauss limitedLinear 1;
div(phi,K) Gauss linear;
div(phi,tracer0) Gauss limitedLinear 1;
div(phi,k) Gauss limitedLinear 1;
div(phi,epsilon) Gauss limitedLinear 1;

View File

@ -1,7 +1,7 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2112 |
| \\ / O peration | Version: v2206 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
@ -27,23 +27,6 @@ solvers
rhoFinal
{
$rho;
tolerance 1e-5;
relTol 0;
}
U
{
solver smoothSolver;
smoother symGaussSeidel;
tolerance 1e-5;
relTol 0.1;
}
UFinal
{
solver smoothSolver;
smoother symGaussSeidel;
tolerance 1e-5;
relTol 0;
}
@ -58,14 +41,11 @@ solvers
pFinal
{
solver GAMG;
tolerance 1e-6;
$p;
relTol 0;
smoother GaussSeidel;
nCellsInCoarsestLevel 20;
}
"(U|h|k|epsilon)"
"(U|h|k|epsilon|tracer0)"
{
solver smoothSolver;
smoother symGaussSeidel;
@ -73,7 +53,7 @@ solvers
relTol 0.1;
}
"(U|h|k|epsilon)Final"
"(U|h|k|epsilon|tracer0)Final"
{
$U;
tolerance 1e-5;

View File

@ -0,0 +1,45 @@
// -*- C++ -*-
tracer0
{
type scalarTransport;
libs (solverFunctionObjects);
log off;
resetOnStartUp false;
writeControl writeTime;
writeInterval 1;
field tracer0;
D 0.001;
fvOptions
{
source1
{
type scalarSemiImplicitSource;
volumeMode specific;
selectionMode geometric;
selection
{
cylinder
{
source cylinder;
point1 (0.050 0 -1);
point2 (0.050 0 1);
radius 0.01;
}
}
injectionRateSuSp
{
tracer0 (0.01 0);
}
}
}
}
// ************************************************************************* //