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)/fileFormats/lnInclude \
|
||||||
-I$(LIB_SRC)/conversion/lnInclude \
|
-I$(LIB_SRC)/conversion/lnInclude \
|
||||||
-I$(LIB_SRC)/sampling/lnInclude \
|
-I$(LIB_SRC)/sampling/lnInclude \
|
||||||
|
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/ODE/lnInclude \
|
-I$(LIB_SRC)/ODE/lnInclude \
|
||||||
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
||||||
-I$(LIB_SRC)/transportModels/compressible/lnInclude
|
-I$(LIB_SRC)/transportModels/compressible/lnInclude
|
||||||
@ -13,6 +14,7 @@ LIB_LIBS = \
|
|||||||
-lfiniteArea \
|
-lfiniteArea \
|
||||||
-lconversion \
|
-lconversion \
|
||||||
-lsampling \
|
-lsampling \
|
||||||
|
-ldynamicMesh \
|
||||||
-lfluidThermophysicalModels \
|
-lfluidThermophysicalModels \
|
||||||
-lcompressibleTransportModels \
|
-lcompressibleTransportModels \
|
||||||
-lODE
|
-lODE
|
||||||
|
|||||||
@ -47,6 +47,39 @@ namespace functionObjects
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * 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 Foam::functionObjects::ensightWrite::process(const word& fieldName)
|
||||||
{
|
{
|
||||||
int state = 0;
|
int state = 0;
|
||||||
@ -83,7 +116,8 @@ Foam::functionObjects::ensightWrite::ensightWrite
|
|||||||
caseOpts_(writeOpts_.format()),
|
caseOpts_(writeOpts_.format()),
|
||||||
selectFields_(),
|
selectFields_(),
|
||||||
dirName_("ensightWrite"),
|
dirName_("ensightWrite"),
|
||||||
consecutive_(false)
|
consecutive_(false),
|
||||||
|
bounds_()
|
||||||
{
|
{
|
||||||
if (postProcess)
|
if (postProcess)
|
||||||
{
|
{
|
||||||
@ -104,6 +138,12 @@ bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
|
|||||||
{
|
{
|
||||||
fvMeshFunctionObject::read(dict);
|
fvMeshFunctionObject::read(dict);
|
||||||
|
|
||||||
|
// Ensure consistency
|
||||||
|
|
||||||
|
meshSubset_.clear();
|
||||||
|
ensMesh_.clear();
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// writer options
|
// writer options
|
||||||
//
|
//
|
||||||
@ -123,6 +163,10 @@ bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bounds_.clear();
|
||||||
|
dict.readIfPresent("bounds", bounds_);
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// case options
|
// case options
|
||||||
//
|
//
|
||||||
@ -197,7 +241,25 @@ bool Foam::functionObjects::ensightWrite::write()
|
|||||||
if (!ensMesh_.valid())
|
if (!ensMesh_.valid())
|
||||||
{
|
{
|
||||||
writeGeom = true;
|
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())
|
if (ensMesh_().needsUpdate())
|
||||||
{
|
{
|
||||||
@ -219,12 +281,12 @@ bool Foam::functionObjects::ensightWrite::write()
|
|||||||
DynamicList<word> missing(selectFields_.size());
|
DynamicList<word> missing(selectFields_.size());
|
||||||
DynamicList<word> ignored(selectFields_.size());
|
DynamicList<word> ignored(selectFields_.size());
|
||||||
|
|
||||||
// check exact matches first
|
// Check exact matches first
|
||||||
for (const wordRe& select : selectFields_)
|
for (const wordRe& select : selectFields_)
|
||||||
{
|
{
|
||||||
if (!select.isPattern())
|
if (!select.isPattern())
|
||||||
{
|
{
|
||||||
const word& fieldName = static_cast<const word&>(select);
|
const word& fieldName = select;
|
||||||
|
|
||||||
if (!candidates.erase(fieldName))
|
if (!candidates.erase(fieldName))
|
||||||
{
|
{
|
||||||
@ -271,7 +333,14 @@ void Foam::functionObjects::ensightWrite::updateMesh(const mapPolyMesh& mpm)
|
|||||||
{
|
{
|
||||||
// fvMeshFunctionObject::updateMesh(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();
|
ensMesh_->expire();
|
||||||
}
|
}
|
||||||
@ -282,7 +351,14 @@ void Foam::functionObjects::ensightWrite::movePoints(const polyMesh& mpm)
|
|||||||
{
|
{
|
||||||
// fvMeshFunctionObject::updateMesh(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();
|
ensMesh_->expire();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,6 +67,7 @@ Description
|
|||||||
faceZones | Select faceZones to write | no |
|
faceZones | Select faceZones to write | no |
|
||||||
consecutive | Consecutive output numbering | no | false
|
consecutive | Consecutive output numbering | no | false
|
||||||
nodeValues | Write values at nodes | no | false
|
nodeValues | Write values at nodes | no | false
|
||||||
|
bounds | Limit with a bounding box | no |
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
Note that if the \c patches entry is an empty list, this will select all
|
Note that if the \c patches entry is an empty list, this will select all
|
||||||
@ -93,6 +94,7 @@ SourceFiles
|
|||||||
|
|
||||||
#include "interpolation.H"
|
#include "interpolation.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
|
#include "fvMeshSubset.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -129,6 +131,12 @@ class ensightWrite
|
|||||||
//- Consecutive output numbering
|
//- Consecutive output numbering
|
||||||
bool consecutive_;
|
bool consecutive_;
|
||||||
|
|
||||||
|
//- Restrict to bounding box
|
||||||
|
boundBox bounds_;
|
||||||
|
|
||||||
|
//- Mesh subset handler
|
||||||
|
autoPtr<fvMeshSubset> meshSubset_;
|
||||||
|
|
||||||
//- Ensight case handler
|
//- Ensight case handler
|
||||||
autoPtr<ensightCase> ensCase_;
|
autoPtr<ensightCase> ensCase_;
|
||||||
|
|
||||||
@ -150,6 +158,9 @@ class ensightWrite
|
|||||||
return *ensMesh_;
|
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
|
//- Apply for the volume field type
|
||||||
template<class Type>
|
template<class Type>
|
||||||
|
|||||||
@ -38,20 +38,39 @@ int Foam::functionObjects::ensightWrite::writeVolField
|
|||||||
// State: return 0 (not-processed), -1 (skip), +1 ok
|
// State: return 0 (not-processed), -1 (skip), +1 ok
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
||||||
|
|
||||||
|
const VolFieldType* fldPtr;
|
||||||
|
|
||||||
// Already done, or not available
|
// Already done, or not available
|
||||||
if (state || !foundObject<VolFieldType>(inputName))
|
if (state || !(fldPtr = lookupObjectPtr<VolFieldType>(inputName)))
|
||||||
{
|
{
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
autoPtr<ensightFile> os = ensCase().newData<Type>(inputName);
|
autoPtr<ensightFile> os = ensCase().newData<Type>(inputName);
|
||||||
ensightOutput::writeField<Type>
|
|
||||||
(
|
|
||||||
lookupObject<VolFieldType>(inputName),
|
if (meshSubset_.valid())
|
||||||
ensMesh(),
|
{
|
||||||
os,
|
tmp<VolFieldType> tfield = meshSubset_->interpolate(*fldPtr);
|
||||||
caseOpts_.nodeValues()
|
|
||||||
);
|
ensightOutput::writeField<Type>
|
||||||
|
(
|
||||||
|
tfield(),
|
||||||
|
ensMesh(),
|
||||||
|
os,
|
||||||
|
caseOpts_.nodeValues()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensightOutput::writeField<Type>
|
||||||
|
(
|
||||||
|
*fldPtr,
|
||||||
|
ensMesh(),
|
||||||
|
os,
|
||||||
|
caseOpts_.nodeValues()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Log << " " << inputName;
|
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 to output (words or regex)
|
||||||
fields (U p "(k|epsilon|omega)");
|
fields (U p "(k|epsilon|omega)");
|
||||||
|
|
||||||
|
// Limit output region
|
||||||
|
bounds (0 0 0) (245 180 80);
|
||||||
|
|
||||||
//- Write more frequent than fields
|
//- Write more frequent than fields
|
||||||
writeControl timeStep;
|
writeControl timeStep;
|
||||||
writeInterval 5;
|
writeInterval 5;
|
||||||
|
|||||||
Reference in New Issue
Block a user