mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: bounding box clipping for ensightWrite function object (issue #973)
- for larger problems with a smaller region of interest, can apply a bounding to limit the size of the ensight geometry and fields created. Since the implementation uses a fvMeshSubset, there is an additional per-process memory overhead. A high output frequency should be avoided with moving meshes, since this indirectly forces a frequent update of the submesh.
This commit is contained in:
@ -4,6 +4,7 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/fileFormats/lnInclude \
|
||||
-I$(LIB_SRC)/conversion/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/ODE/lnInclude \
|
||||
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
||||
-I$(LIB_SRC)/transportModels/compressible/lnInclude
|
||||
@ -13,6 +14,7 @@ LIB_LIBS = \
|
||||
-lfiniteArea \
|
||||
-lconversion \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-lfluidThermophysicalModels \
|
||||
-lcompressibleTransportModels \
|
||||
-lODE
|
||||
|
||||
@ -47,6 +47,39 @@ namespace functionObjects
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::bitSet Foam::functionObjects::ensightWrite::cellSelection() const
|
||||
{
|
||||
bitSet cellsToSelect;
|
||||
|
||||
// Could also deal with cellZones here, as required
|
||||
|
||||
if (bounds_.empty())
|
||||
{
|
||||
return cellsToSelect;
|
||||
}
|
||||
|
||||
|
||||
const auto& cellCentres = static_cast<const fvMesh&>(mesh_).C();
|
||||
|
||||
const label len = mesh_.nCells();
|
||||
|
||||
cellsToSelect.resize(len);
|
||||
|
||||
for (label celli=0; celli < len; ++celli)
|
||||
{
|
||||
const point& cc = cellCentres[celli];
|
||||
|
||||
if (bounds_.contains(cc))
|
||||
{
|
||||
cellsToSelect.set(celli);
|
||||
}
|
||||
}
|
||||
|
||||
return cellsToSelect;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Foam::functionObjects::ensightWrite::process(const word& fieldName)
|
||||
{
|
||||
int state = 0;
|
||||
@ -83,7 +116,8 @@ Foam::functionObjects::ensightWrite::ensightWrite
|
||||
caseOpts_(writeOpts_.format()),
|
||||
selectFields_(),
|
||||
dirName_("ensightWrite"),
|
||||
consecutive_(false)
|
||||
consecutive_(false),
|
||||
bounds_()
|
||||
{
|
||||
if (postProcess)
|
||||
{
|
||||
@ -104,6 +138,12 @@ bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
|
||||
{
|
||||
fvMeshFunctionObject::read(dict);
|
||||
|
||||
// Ensure consistency
|
||||
|
||||
meshSubset_.clear();
|
||||
ensMesh_.clear();
|
||||
|
||||
|
||||
//
|
||||
// writer options
|
||||
//
|
||||
@ -123,6 +163,10 @@ bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
bounds_.clear();
|
||||
dict.readIfPresent("bounds", bounds_);
|
||||
|
||||
|
||||
//
|
||||
// case options
|
||||
//
|
||||
@ -197,7 +241,25 @@ bool Foam::functionObjects::ensightWrite::write()
|
||||
if (!ensMesh_.valid())
|
||||
{
|
||||
writeGeom = true;
|
||||
ensMesh_.reset(new ensightMesh(mesh_, writeOpts_));
|
||||
|
||||
bitSet selection = this->cellSelection();
|
||||
|
||||
if (returnReduce(!selection.empty(), orOp<bool>()))
|
||||
{
|
||||
meshSubset_.clear();
|
||||
meshSubset_.reset(new fvMeshSubset(mesh_, selection));
|
||||
ensMesh_.reset
|
||||
(
|
||||
new ensightMesh(meshSubset_->subMesh(), writeOpts_)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensMesh_.reset
|
||||
(
|
||||
new ensightMesh(mesh_, writeOpts_)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (ensMesh_().needsUpdate())
|
||||
{
|
||||
@ -219,12 +281,12 @@ bool Foam::functionObjects::ensightWrite::write()
|
||||
DynamicList<word> missing(selectFields_.size());
|
||||
DynamicList<word> ignored(selectFields_.size());
|
||||
|
||||
// check exact matches first
|
||||
// Check exact matches first
|
||||
for (const wordRe& select : selectFields_)
|
||||
{
|
||||
if (!select.isPattern())
|
||||
{
|
||||
const word& fieldName = static_cast<const word&>(select);
|
||||
const word& fieldName = select;
|
||||
|
||||
if (!candidates.erase(fieldName))
|
||||
{
|
||||
@ -271,7 +333,14 @@ void Foam::functionObjects::ensightWrite::updateMesh(const mapPolyMesh& mpm)
|
||||
{
|
||||
// fvMeshFunctionObject::updateMesh(mpm);
|
||||
|
||||
if (ensMesh_.valid())
|
||||
// This is heavy-handed, but with a bounding-box limited sub-mesh,
|
||||
// we don't readily know if the updates affect the subsetted mesh.
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
ensMesh_.clear();
|
||||
meshSubset_.clear();
|
||||
}
|
||||
else if (ensMesh_.valid())
|
||||
{
|
||||
ensMesh_->expire();
|
||||
}
|
||||
@ -282,7 +351,14 @@ void Foam::functionObjects::ensightWrite::movePoints(const polyMesh& mpm)
|
||||
{
|
||||
// fvMeshFunctionObject::updateMesh(mpm);
|
||||
|
||||
if (ensMesh_.valid())
|
||||
// This is heavy-handed, but with a bounding-box limited sub-mesh,
|
||||
// we don't readily know if the updates affect the subsetted mesh.
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
ensMesh_.clear();
|
||||
meshSubset_.clear();
|
||||
}
|
||||
else if (ensMesh_.valid())
|
||||
{
|
||||
ensMesh_->expire();
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ Description
|
||||
faceZones | Select faceZones to write | no |
|
||||
consecutive | Consecutive output numbering | no | false
|
||||
nodeValues | Write values at nodes | no | false
|
||||
bounds | Limit with a bounding box | no |
|
||||
\endtable
|
||||
|
||||
Note that if the \c patches entry is an empty list, this will select all
|
||||
@ -93,6 +94,7 @@ SourceFiles
|
||||
|
||||
#include "interpolation.H"
|
||||
#include "volFields.H"
|
||||
#include "fvMeshSubset.H"
|
||||
#include "surfaceFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -129,6 +131,12 @@ class ensightWrite
|
||||
//- Consecutive output numbering
|
||||
bool consecutive_;
|
||||
|
||||
//- Restrict to bounding box
|
||||
boundBox bounds_;
|
||||
|
||||
//- Mesh subset handler
|
||||
autoPtr<fvMeshSubset> meshSubset_;
|
||||
|
||||
//- Ensight case handler
|
||||
autoPtr<ensightCase> ensCase_;
|
||||
|
||||
@ -150,6 +158,9 @@ class ensightWrite
|
||||
return *ensMesh_;
|
||||
}
|
||||
|
||||
//- Define cell selection from bounding box.
|
||||
// An empty set if no bounding box is specified.
|
||||
bitSet cellSelection() const;
|
||||
|
||||
//- Apply for the volume field type
|
||||
template<class Type>
|
||||
|
||||
@ -38,20 +38,39 @@ int Foam::functionObjects::ensightWrite::writeVolField
|
||||
// State: return 0 (not-processed), -1 (skip), +1 ok
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
||||
|
||||
const VolFieldType* fldPtr;
|
||||
|
||||
// Already done, or not available
|
||||
if (state || !foundObject<VolFieldType>(inputName))
|
||||
if (state || !(fldPtr = lookupObjectPtr<VolFieldType>(inputName)))
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
autoPtr<ensightFile> os = ensCase().newData<Type>(inputName);
|
||||
|
||||
|
||||
if (meshSubset_.valid())
|
||||
{
|
||||
tmp<VolFieldType> tfield = meshSubset_->interpolate(*fldPtr);
|
||||
|
||||
ensightOutput::writeField<Type>
|
||||
(
|
||||
lookupObject<VolFieldType>(inputName),
|
||||
tfield(),
|
||||
ensMesh(),
|
||||
os,
|
||||
caseOpts_.nodeValues()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensightOutput::writeField<Type>
|
||||
(
|
||||
*fldPtr,
|
||||
ensMesh(),
|
||||
os,
|
||||
caseOpts_.nodeValues()
|
||||
);
|
||||
}
|
||||
|
||||
Log << " " << inputName;
|
||||
|
||||
|
||||
16
tutorials/incompressible/simpleFoam/windAroundBuildings/Allrun-parallel
Executable file
16
tutorials/incompressible/simpleFoam/windAroundBuildings/Allrun-parallel
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # Run from this directory
|
||||
. $WM_PROJECT_DIR/bin/tools/RunFunctions # Tutorial run functions
|
||||
|
||||
runApplication surfaceFeatureExtract
|
||||
|
||||
runApplication blockMesh
|
||||
runApplication snappyHexMesh -overwrite
|
||||
|
||||
runApplication decomposePar
|
||||
|
||||
runParallel $(getApplication)
|
||||
|
||||
runApplication reconstructPar
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -0,0 +1,23 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1806 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object decomposeParDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
numberOfSubdomains 6;
|
||||
|
||||
// method kahip;
|
||||
method scotch;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -12,6 +12,9 @@ ensightWrite
|
||||
// Fields to output (words or regex)
|
||||
fields (U p "(k|epsilon|omega)");
|
||||
|
||||
// Limit output region
|
||||
bounds (0 0 0) (245 180 80);
|
||||
|
||||
//- Write more frequent than fields
|
||||
writeControl timeStep;
|
||||
writeInterval 5;
|
||||
|
||||
Reference in New Issue
Block a user