diff --git a/src/functionObjects/utilities/Make/options b/src/functionObjects/utilities/Make/options index a9844b6d0e..9cccdbc1a4 100644 --- a/src/functionObjects/utilities/Make/options +++ b/src/functionObjects/utilities/Make/options @@ -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 diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.C b/src/functionObjects/utilities/ensightWrite/ensightWrite.C index c228b5964a..518c74c17e 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.C +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.C @@ -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(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())) + { + 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 missing(selectFields_.size()); DynamicList ignored(selectFields_.size()); - // check exact matches first + // Check exact matches first for (const wordRe& select : selectFields_) { if (!select.isPattern()) { - const word& fieldName = static_cast(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(); } diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.H b/src/functionObjects/utilities/ensightWrite/ensightWrite.H index 25954ea89c..d549623a20 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.H +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.H @@ -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 meshSubset_; + //- Ensight case handler autoPtr 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 diff --git a/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C b/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C index e68858f3fd..a1da699b44 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C +++ b/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C @@ -38,20 +38,39 @@ int Foam::functionObjects::ensightWrite::writeVolField // State: return 0 (not-processed), -1 (skip), +1 ok typedef GeometricField VolFieldType; + const VolFieldType* fldPtr; + // Already done, or not available - if (state || !foundObject(inputName)) + if (state || !(fldPtr = lookupObjectPtr(inputName))) { return state; } autoPtr os = ensCase().newData(inputName); - ensightOutput::writeField - ( - lookupObject(inputName), - ensMesh(), - os, - caseOpts_.nodeValues() - ); + + + if (meshSubset_.valid()) + { + tmp tfield = meshSubset_->interpolate(*fldPtr); + + ensightOutput::writeField + ( + tfield(), + ensMesh(), + os, + caseOpts_.nodeValues() + ); + } + else + { + ensightOutput::writeField + ( + *fldPtr, + ensMesh(), + os, + caseOpts_.nodeValues() + ); + } Log << " " << inputName; diff --git a/tutorials/incompressible/simpleFoam/windAroundBuildings/Allrun-parallel b/tutorials/incompressible/simpleFoam/windAroundBuildings/Allrun-parallel new file mode 100755 index 0000000000..444dc97cc9 --- /dev/null +++ b/tutorials/incompressible/simpleFoam/windAroundBuildings/Allrun-parallel @@ -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 + +#------------------------------------------------------------------------------ diff --git a/tutorials/incompressible/simpleFoam/windAroundBuildings/system/decomposeParDict b/tutorials/incompressible/simpleFoam/windAroundBuildings/system/decomposeParDict new file mode 100644 index 0000000000..c2c0de8e69 --- /dev/null +++ b/tutorials/incompressible/simpleFoam/windAroundBuildings/system/decomposeParDict @@ -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; + + +// ************************************************************************* // diff --git a/tutorials/incompressible/simpleFoam/windAroundBuildings/system/ensightWrite b/tutorials/incompressible/simpleFoam/windAroundBuildings/system/ensightWrite index 238ba01963..4fb96ac6f4 100644 --- a/tutorials/incompressible/simpleFoam/windAroundBuildings/system/ensightWrite +++ b/tutorials/incompressible/simpleFoam/windAroundBuildings/system/ensightWrite @@ -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;