diff --git a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMeshDict b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMeshDict index 07288644886b4c72cebd13cd2971df0d972cca6c..d3018d209d1649ed53ae0fe4edebd83ae7fce80b 100644 --- a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMeshDict +++ b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMeshDict @@ -63,6 +63,10 @@ extrudeModel wedge; //- Extrudes into sphere with grading according to pressure (atmospherics) //extrudeModel sigmaRadial; +//- Extrudes by interpolating along path inbetween two (topologically identical) +// surfaces (e.g. one is an offsetted version of the other) +//extrudeModel offsetSurface; + nLayers 10; expansionRatio 1.0; @@ -105,6 +109,16 @@ sigmaRadialCoeffs pStrat 1; } +offsetSurfaceCoeffs +{ + // Surface that mesh has been meshed to + baseSurface "$FOAM_CASE/constant/triSurface/DTC-scaled-inflated.obj"; + + // Surface to fill in to + offsetSurface "$FOAM_CASE/constant/triSurface/DTC-scaled.obj"; +} + + // Do front and back need to be merged? Usually only makes sense for 360 // degree wedges. mergeFaces false; diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/Make/options b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/Make/options index 44c1d87758d5258e02108d66f7a3ce1d089c6826..bad58b9d588786375ccdde15117e3b5a64052c54 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/Make/options +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/Make/options @@ -16,6 +16,7 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \ + -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \ -I$(LIB_SRC)/edgeMesh/lnInclude \ -I$(LIB_SRC)/fileFormats/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ @@ -29,6 +30,7 @@ EXE_INC = \ LIB_LIBS = \ ${CGAL_LIBS} \ -lmeshTools \ + -ldecompose \ -ledgeMesh \ -lfileFormats \ -ltriSurface \ diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C index 25e0f9a73e73b81c545e522f80914719b4d36358..b4428c3df84fb14cfc4a2bf7e41ccc79bcb056e0 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C @@ -30,6 +30,7 @@ License #include "Time.H" #include "Random.H" #include "pointConversion.H" +#include "decompositionModel.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -149,7 +150,8 @@ void Foam::backgroundMeshDecomposition::initialRefinement() const conformationSurfaces& geometry = geometryToConformTo_; - decompositionMethod& decomposer = decomposerPtr_(); + decompositionMethod& decomposer = + decompositionModel::New(mesh_).decomposer(); volScalarField::InternalField& icellWeights = cellWeights.internalField(); @@ -782,7 +784,8 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition const Time& runTime, Random& rndGen, const conformationSurfaces& geometryToConformTo, - const dictionary& coeffsDict + const dictionary& coeffsDict, + const fileName& decompDictFile ) : runTime_(runTime), @@ -810,18 +813,6 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition bFTreePtr_(), allBackgroundMeshBounds_(Pstream::nProcs()), globalBackgroundBounds_(), - decomposeDict_ - ( - IOobject - ( - "decomposeParDict", - runTime_.system(), - runTime_, - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) - ), - decomposerPtr_(decompositionMethod::New(decomposeDict_)), mergeDist_(1e-6*mesh_.bounds().mag()), spanScale_(readScalar(coeffsDict.lookup("spanScale"))), minCellSizeLimit_ @@ -846,14 +837,17 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition << exit(FatalError); } - if (!decomposerPtr_().parallelAware()) + const decompositionMethod& decomposer = + decompositionModel::New(mesh_, decompDictFile).decomposer(); + + if (!decomposer.parallelAware()) { FatalErrorIn ( "void Foam::backgroundMeshDecomposition::initialRefinement() const" ) << "You have selected decomposition method " - << decomposerPtr_().typeName + << decomposer.typeName << " which is not parallel aware." << endl << exit(FatalError); } @@ -1008,7 +1002,10 @@ Foam::backgroundMeshDecomposition::distribute << endl; } - labelList newDecomp = decomposerPtr_().decompose + decompositionMethod& decomposer = + decompositionModel::New(mesh_).decomposer(); + + labelList newDecomp = decomposer.decompose ( mesh_, mesh_.cellCentres(), diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H index 90dde14aa4a8e1ff1aefd20f42d3e16c308654cb..9d597732cb7e8647ac847666114e753b82c30437 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H @@ -127,13 +127,7 @@ class backgroundMeshDecomposition // a point that is not found on any processor is in the domain at all treeBoundBox globalBackgroundBounds_; - //- Decomposition dictionary - IOdictionary decomposeDict_; - - //- Decomposition method - autoPtr<decompositionMethod> decomposerPtr_; - - //- Merge distance required by fvMeshDistribute + //- merge distance required by fvMeshDistribute scalar mergeDist_; //- Scale of a cell span vs cell size used to decide to refine a cell @@ -204,7 +198,8 @@ public: const Time& runTime, Random& rndGen, const conformationSurfaces& geometryToConformTo, - const dictionary& coeffsDict + const dictionary& coeffsDict, + const fileName& decompDictFile = "" ); @@ -324,8 +319,6 @@ public: //- Return the point level of the underlying mesh inline const labelList& pointLevel() const; - //- Return the current decomposition method - inline const decompositionMethod& decomposer() const; }; diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H index 199f4ae4ff0152fa283c52e38992c3b298612034..b8dcb5187f151844e36013c14fa441a3da869fd1 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H @@ -57,11 +57,4 @@ const Foam::labelList& Foam::backgroundMeshDecomposition::pointLevel() const } -const Foam::decompositionMethod& -Foam::backgroundMeshDecomposition::decomposer() const -{ - return decomposerPtr_(); -} - - // ************************************************************************* // diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C index e7f7f5816c275755708d215f50877255812d2e38..9b6f71ffac5dc8dcd020caf744c80eb4cca754ee 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C @@ -392,61 +392,59 @@ Foam::cellShapeControlMesh::cellShapeControlMesh(const Time& runTime) if (mesh.nPoints() == this->vertexCount()) { - pointScalarField sizes + IOobject io ( - IOobject - ( - "sizes", - runTime.timeName(), - meshSubDir, - runTime, - IOobject::READ_IF_PRESENT, - IOobject::NO_WRITE, - false - ), - pointMesh::New(mesh) - ); - - triadIOField alignments - ( - IOobject - ( - "alignments", - mesh.time().timeName(), - meshSubDir, - mesh.time(), - IOobject::READ_IF_PRESENT, - IOobject::AUTO_WRITE, - false - ) + "sizes", + runTime.timeName(), + meshSubDir, + runTime, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false ); - if - ( - sizes.size() == this->vertexCount() - && alignments.size() == this->vertexCount() - ) + if (io.headerOk()) { - for + pointScalarField sizes(io, pointMesh::New(mesh)); + + triadIOField alignments ( - Finite_vertices_iterator vit = finite_vertices_begin(); - vit != finite_vertices_end(); - ++vit - ) + IOobject + ( + "alignments", + mesh.time().timeName(), + meshSubDir, + mesh.time(), + IOobject::MUST_READ, + IOobject::NO_WRITE, + false + ) + ); + + if (alignments.size() == this->vertexCount()) { - vit->targetCellSize() = sizes[vit->index()]; - vit->alignment() = alignments[vit->index()]; + for + ( + Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + vit->targetCellSize() = sizes[vit->index()]; + vit->alignment() = alignments[vit->index()]; + } + } + else + { + FatalErrorIn + ( + "Foam::cellShapeControlMesh::cellShapeControlMesh" + "(const Time&)" + ) << "Cell alignments point field " << alignments.size() + << " is not the same size as the number of vertices" + << " in the mesh " << this->vertexCount() + << abort(FatalError); } - } - else - { - FatalErrorIn - ( - "Foam::cellShapeControlMesh::cellShapeControlMesh" - "(const Time&)" - ) << "Cell size point field is not the same size as the " - << "mesh." - << abort(FatalError); } } } @@ -672,7 +670,7 @@ void Foam::cellShapeControlMesh::write() const IOobject::AUTO_WRITE ), pointMesh::New(mesh), - scalar(0) + dimensionedScalar("zero", dimLength, scalar(0)) ); triadIOField alignments diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C index 9cc9862129a2a130ce8305a7f825537dfbdc06cd..a10f19be224ee191fa7f2781a63c4402a33f4837 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C @@ -837,7 +837,8 @@ bool Foam::conformalVoronoiMesh::ownerAndNeighbour Foam::conformalVoronoiMesh::conformalVoronoiMesh ( const Time& runTime, - const dictionary& foamyHexMeshDict + const dictionary& foamyHexMeshDict, + const fileName& decompDictFile ) : DistributedDelaunayMesh<Delaunay>(runTime), @@ -876,7 +877,8 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh foamyHexMeshControls().foamyHexMeshDict().subDict ( "backgroundMeshDecomposition" - ) + ), + decompDictFile ) : NULL ), diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H index f6d44489b78de107ea77849ebd8774edbaedd3b7..59fbba90a960e731eedff8c88ac2c225f65410b9 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H @@ -163,10 +163,8 @@ private: //- Limiting bound box before infinity begins treeBoundBox limitBounds_; - //- mutable pointPairs<Delaunay> ptPairs_; - //- featurePointConformer ftPtConformer_; //- Search tree for edge point locations @@ -546,7 +544,7 @@ private: ) const; //- Check if a location is in the exclusion range of an existing feature - //- Edge conformation location + // edge conformation location bool nearFeatureEdgeLocation ( const pointIndexHit& pHit, @@ -730,8 +728,7 @@ private: label classifyBoundaryPoint(Cell_handle cit) const; - //- Index all of the the Delaunay cells and calculate their - //- Dual points + //- Index all of the the Delaunay cells and calculate their dual points void indexDualVertices ( pointField& pts, @@ -874,7 +871,8 @@ public: conformalVoronoiMesh ( const Time& runTime, - const dictionary& foamyHexMeshDict + const dictionary& foamyHexMeshDict, + const fileName& decompDictFile = "" ); diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C index e88ee943690b8f05742b05845965c4e50dc791ab..85c49a9ccdd1b6dc7429410be942210262be6195 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C @@ -1292,9 +1292,9 @@ void Foam::conformalVoronoiMesh::indexDualVertices } } - OBJstream snapping1("snapToSurface1.obj"); - OBJstream snapping2("snapToSurface2.obj"); - OFstream tetToSnapTo("tetsToSnapTo.obj"); + //OBJstream snapping1("snapToSurface1.obj"); + //OBJstream snapping2("snapToSurface2.obj"); + //OFstream tetToSnapTo("tetsToSnapTo.obj"); for ( diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell/indexedCell.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell/indexedCell.H index a2eeb21c99135da690d8b19734a365cacd2ecbc6..7a19a25ba212a8e65d205c3d02289381864925d8 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell/indexedCell.H +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell/indexedCell.H @@ -88,15 +88,13 @@ class indexedCell // Private data //- The index for this Delaunay tetrahedral cell. Type information is - //- Also carried: - + // also carried: // ctFar : the dual point of this cell does not form part of the // internal or boundary of the dual mesh // >=0 : the (local) index of an internal or boundary dual point, // not on a processor face // < 0 && > ctFar : the (global) index of a dual point on a processor // face - Foam::label index_; //- The number of times that this Delaunay cell has been limited diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/Make/options b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/Make/options index b3f2e7dd7ceed3f5a69ecb53a20f978ea2a58abf..7aa621f26e126d3e3f8c07c0c6bd700821eea678 100644 --- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/Make/options +++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/Make/options @@ -30,7 +30,8 @@ EXE_LIBS = \ -lconformalVoronoiMesh \ -lmeshTools \ -ldecompositionMethods \ - -L$(FOAM_LIBBIN)/dummy -lptscotchDecomp \ + -ldecompose \ + -L$(FOAM_LIBBIN)/dummy -lptscotchDecomp -lscotchDecomp \ -ledgeMesh \ -lfileFormats \ -ltriSurface \ diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMesh.C b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMesh.C index 6e68f1c80e616956753d45207e4ec87fb6b4b369..c83800e03133c255e590dcfbe90484e24a248b4b 100644 --- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMesh.C +++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMesh.C @@ -62,6 +62,17 @@ int main(int argc, char *argv[]) const bool checkGeometry = args.optionFound("checkGeometry"); const bool conformationOnly = args.optionFound("conformationOnly"); + // Allow override of decomposeParDict location + fileName decompDictFile; + if (args.optionReadIfPresent("decomposeParDict", decompDictFile)) + { + if (isDir(decompDictFile)) + { + decompDictFile = decompDictFile / "decomposeParDict"; + } + } + + IOdictionary foamyHexMeshDict ( IOobject @@ -114,7 +125,7 @@ int main(int argc, char *argv[]) Info<< "Create mesh for time = " << runTime.timeName() << nl << endl; - conformalVoronoiMesh mesh(runTime, foamyHexMeshDict); + conformalVoronoiMesh mesh(runTime, foamyHexMeshDict, decompDictFile); if (conformationOnly) @@ -145,7 +156,7 @@ int main(int argc, char *argv[]) } - Info<< nl << "End" << nl << endl; + Info<< "\nEnd\n" << endl; return 0; } diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMeshDict b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMeshDict index deca4e0edb24a5505535b6250d994fdd9e14db56..78f22b4e49283202d8b8173ca418c49a0ff375b8 100644 --- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMeshDict +++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMeshDict @@ -271,11 +271,18 @@ motionControl forceInitialPointInsertion on; priority 1; mode inside; + + // Cell size at surface surfaceCellSizeFunction uniformValue; uniformValueCoeffs { surfaceCellSizeCoeff 0.5; } + + // Cell size inside domain by having a region of thickness + // surfaceOffsetaround the surface with the surface cell size + // (so constant) and then down to distanceCellSize over a distance + // of linearDistance. cellSizeFunction surfaceOffsetLinearDistance; surfaceOffsetLinearDistanceCoeffs { @@ -375,9 +382,17 @@ polyMeshFiltering // Filter small and sliver faces filterFaces off; - // Write the underlying Delaunay tet mesh at output time + // Write the underlying Delaunay tet mesh (at output time) writeTetDualMesh false; + // Write the Delaunay tet mesh used for interpolating cell size and + // alignment (at output time) + writeCellShapeControlMesh true; + + // Write the hex/split-hex mesh used for parallel load balancing + // (at output time) + writeBackgroundMeshDecomposition true; + // Upper limit on the size of faces to be filtered. // fraction of the local target cell size filterSizeCoeff 0.2; diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/Make/options b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/Make/options index 07f6800de62364583b2cf2105c5c654ac066e319..00d889c6c603f24a4dc4e96309926138039f0502 100644 --- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/Make/options +++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/Make/options @@ -9,6 +9,7 @@ EXE_INC = \ ${CGAL_INC} \ -I../conformalVoronoiMesh/lnInclude \ -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \ + -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \ -I$(LIB_SRC)/edgeMesh/lnInclude \ -I$(LIB_SRC)/mesh/autoMesh/lnInclude \ -I$(LIB_SRC)/triSurface/lnInclude \ @@ -26,6 +27,7 @@ EXE_LIBS = \ -lgmp \ -lconformalVoronoiMesh \ -ldecompositionMethods /* -L$(FOAM_LIBBIN)/dummy -lscotchDecomp */ \ + -ldecompose \ -ledgeMesh \ -ltriSurface \ -lmeshTools \ diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C index fc99f0fd0545c94e0907a7f4486c9818c635591e..62be3f1efed769e18ef7a725c230301927afd790 100644 --- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C +++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C @@ -44,6 +44,7 @@ Description #include "isoSurfaceCell.H" #include "vtkSurfaceWriter.H" #include "syncTools.H" +#include "decompositionModel.H" using namespace Foam; @@ -467,7 +468,7 @@ int main(int argc, char *argv[]) // Determine the number of cells in each direction. const vector span = bb.span(); - vector nScalarCells = span/cellShapeControls().defaultCellSize(); + vector nScalarCells = span/cellShapeControls.defaultCellSize(); // Calculate initial cell size to be a little bit smaller than the // defaultCellSize to avoid initial refinement triggering. @@ -521,28 +522,21 @@ int main(int argc, char *argv[]) Info<< "Loaded mesh:" << endl; printMeshData(mesh); - // Allocate a decomposer - IOdictionary decompositionDict - ( - IOobject - ( - "decomposeParDict", - runTime.system(), - mesh, - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) - ); + // Allow override of decomposeParDict location + fileName decompDictFile; + if (args.optionReadIfPresent("decomposeParDict", decompDictFile)) + { + if (isDir(decompDictFile)) + { + decompDictFile = decompDictFile / "decomposeParDict"; + } + } - autoPtr<decompositionMethod> decomposer + labelList decomp = decompositionModel::New ( - decompositionMethod::New - ( - decompositionDict - ) - ); - - labelList decomp = decomposer().decompose(mesh, mesh.cellCentres()); + mesh, + decompDictFile + ).decomposer().decompose(mesh, mesh.cellCentres()); // Global matching tolerance const scalar tolDim = getMergeDistance @@ -574,18 +568,15 @@ int main(int argc, char *argv[]) Info<< "Refining backgroud mesh according to cell size specification" << nl << endl; + const dictionary& backgroundMeshDict = + foamyHexMeshDict.subDict("backgroundMeshDecomposition"); + backgroundMeshDecomposition backgroundMesh ( - 1.0, //spanScale,ratio of poly cell size v.s. hex cell size - 0.0, //minCellSizeLimit - 0, //minLevels - 4, //volRes, check multiple points per cell - 20.0, //maxCellWeightCoeff runTime, - geometryToConformTo, - cellShapeControls(), rndGen, - foamyHexMeshDict + geometryToConformTo, + backgroundMeshDict ); if (writeMesh) diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/foamyQuadMesh.C b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/foamyQuadMesh.C index 066bc8205c268a233f8dd90e2c71044cd59713f9..997726bba6b0a272d53442af9cee12f6469ffec5 100644 --- a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/foamyQuadMesh.C +++ b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/foamyQuadMesh.C @@ -221,7 +221,7 @@ int main(int argc, char *argv[]) Info<< "Finished extruding in = " << runTime.cpuTimeIncrement() << " s." << endl; - Info<< nl << "End\n" << endl; + Info<< "\nEnd\n" << endl; return 0; } diff --git a/applications/utilities/mesh/generation/snappyHexMesh/Make/options b/applications/utilities/mesh/generation/snappyHexMesh/Make/options index 219e3d419c848efd02e7e363825c5ebece691a80..d62b82a23949f7d27e553f79820f900678fedfcb 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/Make/options +++ b/applications/utilities/mesh/generation/snappyHexMesh/Make/options @@ -8,14 +8,18 @@ EXE_INC = \ -I$(LIB_SRC)/surfMesh/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/edgeMesh/lnInclude \ + -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude EXE_LIBS = \ -lfiniteVolume \ -ldecompositionMethods \ -L$(FOAM_LIBBIN)/dummy -lptscotchDecomp \ + /* note: scotch < 6.0 does not like both scotch and ptscotch together */ \ + -lscotchDecomp \ -lmeshTools \ -lsurfMesh \ -lfileFormats \ -ldynamicMesh \ + -ldecompose \ -lautoMesh diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C index 7b4d8577c4e7ace8293bf50a703c234bcc3193f2..15bd5e965fd74de974b3bb152ac6bc2135b028ae 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -57,6 +57,7 @@ Description #include "MeshedSurface.H" #include "globalIndex.H" #include "IOmanip.H" +#include "decompositionModel.H" using namespace Foam; @@ -819,15 +820,28 @@ int main(int argc, char *argv[]) { if (Pstream::parRun()) { + fileName decompDictFile; + if (args.optionReadIfPresent("decomposeParDict", decompDictFile)) + { + if (isDir(decompDictFile)) + { + decompDictFile = decompDictFile/"decomposeParDict"; + } + } + decomposeDict = IOdictionary ( - IOobject + decompositionModel::selectIO ( - "decomposeParDict", - runTime.system(), - mesh, - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE + IOobject + ( + "decomposeParDict", + runTime.system(), + mesh, + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE + ), + decompDictFile ) ); } diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index 63303d9f8c5b1a63ecb7e18acad49adfcce7f0bd..9c62a1283705006dd641d850940a9f63306631a7 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -143,7 +143,7 @@ int main(int argc, char *argv[]) ); argList::noParallel(); - Foam::argList::addOption + argList::addOption ( "decomposeParDict", "file", diff --git a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/Make/options b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/Make/options index 518432cbd9ef33a2e7edcffd1e7ea19f429406a6..0d74d0b44ca05ad8d253ab552452c486c057d5bf 100644 --- a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/Make/options +++ b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/Make/options @@ -1,9 +1,8 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ - -I$(LIB_SRC)/meshTools/lnInclude + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/postProcessing/functionObjects/jobControl/lnInclude EXE_LIBS = \ - -lturbulenceModels \ - -lcompressibleTurbulenceModels \ -lfiniteVolume \ - -lmeshTools + -ljobControl diff --git a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometry.C b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometry.C index 3b9ed64abb35d0f1ba4dd798e315c9736addef0e..51818b378741ee10d3cf18fa4dac9dc0d0f8a9bf 100644 --- a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometry.C +++ b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometry.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -26,15 +26,19 @@ Application Description Application to generate the patch geometry (points and faces) for use - with the externalCoupled boundary condition. + with the externalCoupled functionObject. - Usage: +Usage + - createExternalCoupledPatchGeometry \<patchGroup\> [OPTION] - createExternalCoupledPatchGeometry \<fieldName\> + \param -commsDir \<commsDir\> \n + Specify an alternative communications directory (default is comms + in the case directory) - On execution, the field \<fieldName\> is read, and its boundary conditions - interrogated for the presence of an \c externalCoupled type. If found, - the patch geometry (points and faces) for the coupled patches are output + \param -region \<name\> \n + Specify an alternative mesh region. + + On execution, the combined patch geometry (points and faces) are output to the communications directory. Note: @@ -42,12 +46,12 @@ Note: used for face addressing starts at index 0. SeeAlso - externalCoupledMixedFvPatchField + externalCoupledFunctionObject \*---------------------------------------------------------------------------*/ #include "fvCFD.H" -#include "createExternalCoupledPatchGeometryTemplates.H" +#include "externalCoupledFunctionObject.H" #include "IOobjectList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -55,28 +59,25 @@ SeeAlso int main(int argc, char *argv[]) { #include "addRegionOption.H" - argList::validArgs.append("fieldName"); + argList::validArgs.append("patchGroup"); + argList::addOption + ( + "commsDir", + "dir", + "specify alternate communications directory. default is 'comms'" + ); #include "setRootCase.H" #include "createTime.H" #include "createNamedMesh.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - const word fieldName = args[1]; - - IOobjectList objects(IOobjectList(mesh, mesh.time().timeName())); + const wordRe patchGroup(args[1]); - label processed = -1; - processField<scalar>(mesh, objects, fieldName, processed); - processField<vector>(mesh, objects, fieldName, processed); - processField<sphericalTensor>(mesh, objects, fieldName, processed); - processField<symmTensor>(mesh, objects, fieldName, processed); - processField<tensor>(mesh, objects, fieldName, processed); + fileName commsDir(runTime.path()/"comms"); + args.optionReadIfPresent("commsDir", commsDir); - if (processed == -1) - { - Info<< "Field " << fieldName << " not found" << endl; - } + externalCoupledFunctionObject::writeGeometry(mesh, commsDir, patchGroup); Info<< "\nEnd\n" << endl; diff --git a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.C b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.C deleted file mode 100644 index c5d842237e157e1208c779215e883fd05129df00..0000000000000000000000000000000000000000 --- a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.C +++ /dev/null @@ -1,90 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "createExternalCoupledPatchGeometryTemplates.H" -#include "externalCoupledMixedFvPatchField.H" -#include "IOobjectList.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -template<class Type> -void processField -( - const fvMesh& mesh, - const IOobjectList& objects, - const word& fieldName, - label& processed -) -{ - if (processed != -1) - { - return; - } - - typedef GeometricField<Type, fvPatchField, volMesh> fieldType; - - const word timeName(mesh.time().timeName()); - - IOobjectList fieldObjbjects(objects.lookupClass(fieldType::typeName)); - - if (fieldObjbjects.lookup(fieldName) != NULL) - { - fieldType vtf(*fieldObjbjects.lookup(fieldName), mesh); - const typename fieldType::GeometricBoundaryField& bf = - vtf.boundaryField(); - - forAll(bf, patchI) - { - if (isA<externalCoupledMixedFvPatchField<Type> >(bf[patchI])) - { - Info<< "Generating external coupled geometry for field " - << fieldName << endl; - - const externalCoupledMixedFvPatchField<Type>& pf = - refCast<const externalCoupledMixedFvPatchField<Type> > - ( - bf[patchI] - ); - - pf.writeGeometry(); - processed = 1; - - break; - } - } - - if (processed != 1) - { - processed = 0; - - Info<< "Field " << fieldName << " found, but does not have any " - << externalCoupledMixedFvPatchField<Type>::typeName - << " boundary conditions" << endl; - } - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/preProcessing/mapFields/Make/options b/applications/utilities/preProcessing/mapFields/Make/options index 7bd964094e47227f22d57a6b880ef940b5579b16..383ac3c12c66d86a5d14ea1f9cfcaf0f7e39164a 100644 --- a/applications/utilities/preProcessing/mapFields/Make/options +++ b/applications/utilities/preProcessing/mapFields/Make/options @@ -2,6 +2,8 @@ EXE_INC = \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \ + -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude EXE_LIBS = \ @@ -9,4 +11,5 @@ EXE_LIBS = \ -lmeshTools \ -llagrangian \ -lfiniteVolume \ + -ldecompose \ -lgenericPatchFields diff --git a/applications/utilities/preProcessing/mapFields/mapFields.C b/applications/utilities/preProcessing/mapFields/mapFields.C index 929776d9df6a38d2982f8fb669119b898d5d4bc8..6f72053a08a9dc22594ced979a56cfcb5bceb172 100644 --- a/applications/utilities/preProcessing/mapFields/mapFields.C +++ b/applications/utilities/preProcessing/mapFields/mapFields.C @@ -36,9 +36,48 @@ Description #include "meshToMesh0.H" #include "processorFvPatch.H" #include "MapMeshes.H" +#include "decompositionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +int readNumProcs +( + const argList& args, + const word& optionName, + const Time& runTime +) +{ + fileName dictFile; + if (args.optionReadIfPresent(optionName, dictFile)) + { + if (isDir(dictFile)) + { + dictFile = dictFile/"decomposeParDict"; + } + } + + return readInt + ( + IOdictionary + ( + decompositionModel::selectIO + ( + IOobject + ( + "decomposeParDict", + runTime.system(), + runTime, + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE, + false + ), + dictFile + ) + ).lookup("numberOfSubdomains") + ); +} + + void mapConsistentMesh ( const fvMesh& meshSource, @@ -225,6 +264,19 @@ int main(int argc, char *argv[]) "subtract", "subtract mapped source from target" ); + argList::addOption + ( + "sourceDecomposeParDict", + "file", + "read decomposePar dictionary from specified location" + ); + argList::addOption + ( + "targetDecomposeParDict", + "file", + "read decomposePar dictionary from specified location" + ); + argList args(argc, argv); @@ -320,20 +372,13 @@ int main(int argc, char *argv[]) if (parallelSource && !parallelTarget) { - IOdictionary decompositionDict + int nProcs = readNumProcs ( - IOobject - ( - "decomposeParDict", - runTimeSource.system(), - runTimeSource, - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) + args, + "sourceDecomposeParDict", + runTimeSource ); - int nProcs(readInt(decompositionDict.lookup("numberOfSubdomains"))); - Info<< "Create target mesh\n" << endl; fvMesh meshTarget @@ -399,19 +444,13 @@ int main(int argc, char *argv[]) } else if (!parallelSource && parallelTarget) { - IOdictionary decompositionDict + int nProcs = readNumProcs ( - IOobject - ( - "decomposeParDict", - runTimeTarget.system(), - runTimeTarget, - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) + args, + "targetDecomposeParDict", + runTimeTarget ); - int nProcs(readInt(decompositionDict.lookup("numberOfSubdomains"))); Info<< "Create source mesh\n" << endl; @@ -478,39 +517,17 @@ int main(int argc, char *argv[]) } else if (parallelSource && parallelTarget) { - IOdictionary decompositionDictSource + int nProcsSource = readNumProcs ( - IOobject - ( - "decomposeParDict", - runTimeSource.system(), - runTimeSource, - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) + args, + "sourceDecomposeParDict", + runTimeSource ); - - int nProcsSource - ( - readInt(decompositionDictSource.lookup("numberOfSubdomains")) - ); - - - IOdictionary decompositionDictTarget - ( - IOobject - ( - "decomposeParDict", - runTimeTarget.system(), - runTimeTarget, - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) - ); - - int nProcsTarget + int nProcsTarget = readNumProcs ( - readInt(decompositionDictTarget.lookup("numberOfSubdomains")) + args, + "targetDecomposeParDict", + runTimeTarget ); List<boundBox> bbsTarget(nProcsTarget); diff --git a/applications/utilities/preProcessing/mapFieldsPar/MapLagrangianFields.H b/applications/utilities/preProcessing/mapFieldsPar/MapLagrangianFields.H index e0455221456ce198a574607ca734a93335ce4b0e..d1a010ce21e19e37d378e1be7bf587a0e0a4ca65 100644 --- a/applications/utilities/preProcessing/mapFieldsPar/MapLagrangianFields.H +++ b/applications/utilities/preProcessing/mapFieldsPar/MapLagrangianFields.H @@ -104,6 +104,8 @@ void MapLagrangianFields Info<< " mapping lagrangian fieldField " << fieldName << endl; // Read field (does not need mesh) + // Note: some fieldFields are 0 size (e.g. collision records) if + // not used IOField<Field<Type> > fieldSource(*fieldIter()); // Map - use CompactIOField to automatically write in @@ -120,12 +122,22 @@ void MapLagrangianFields IOobject::NO_WRITE, false ), - addParticles.size() + min(fieldSource.size(), addParticles.size()) // handle 0 size ); - forAll(addParticles, i) + if (fieldSource.size()) { - fieldTarget[i] = fieldSource[addParticles[i]]; + forAll(addParticles, i) + { + fieldTarget[i] = fieldSource[addParticles[i]]; + } + } + else if (cloud::debug) + { + Pout<< "Not mapping " << fieldName << " since source size " + << fieldSource.size() << " different to" + << " cloud size " << addParticles.size() + << endl; } // Write field @@ -139,8 +151,9 @@ void MapLagrangianFields forAllIter(IOobjectList, fieldFields, fieldIter) { - Info<< " mapping lagrangian fieldField " - << fieldIter()->name() << endl; + const word& fieldName = fieldIter()->name(); + + Info<< " mapping lagrangian fieldField " << fieldName << endl; // Read field (does not need mesh) CompactIOField<Field<Type>, Type> fieldSource(*fieldIter()); @@ -150,7 +163,7 @@ void MapLagrangianFields ( IOobject ( - fieldIter()->name(), + fieldName, meshTarget.time().timeName(), cloud::prefix/cloudName, meshTarget, @@ -158,12 +171,22 @@ void MapLagrangianFields IOobject::NO_WRITE, false ), - addParticles.size() + min(fieldSource.size(), addParticles.size()) // handle 0 size ); - forAll(addParticles, i) + if (fieldSource.size()) { - fieldTarget[i] = fieldSource[addParticles[i]]; + forAll(addParticles, i) + { + fieldTarget[i] = fieldSource[addParticles[i]]; + } + } + else if (cloud::debug) + { + Pout<< "Not mapping " << fieldName << " since source size " + << fieldSource.size() << " different to" + << " cloud size " << addParticles.size() + << endl; } // Write field diff --git a/applications/utilities/preProcessing/mapFieldsPar/mapLagrangian.C b/applications/utilities/preProcessing/mapFieldsPar/mapLagrangian.C index d2ed7da591a3a3621b158136433c22148aeca02f..6196b5e5e59b01dd0843f4e0b7aa705bb665d8ba 100644 --- a/applications/utilities/preProcessing/mapFieldsPar/mapLagrangian.C +++ b/applications/utilities/preProcessing/mapFieldsPar/mapLagrangian.C @@ -110,9 +110,10 @@ void mapLagrangian(const meshToMesh& interp) cloud::prefix/cloudDirs[cloudI] ); - IOobject* positionsPtr = objects.lookup(word("positions")); + bool foundPositions = + returnReduce(objects.found("positions"), orOp<bool>());; - if (positionsPtr) + if (foundPositions) { Info<< nl << " processing cloud " << cloudDirs[cloudI] << endl; diff --git a/applications/utilities/preProcessing/viewFactorsGen/shootRays.H b/applications/utilities/preProcessing/viewFactorsGen/shootRays.H index d20b204f0360b9dd06d655d12977bdca92245c29..8b5dcd6db7708ae52bccc98803980f361bcb9642 100644 --- a/applications/utilities/preProcessing/viewFactorsGen/shootRays.H +++ b/applications/utilities/preProcessing/viewFactorsGen/shootRays.H @@ -89,7 +89,7 @@ for (label procI = 0; procI < Pstream::nProcs(); procI++) DynamicList<label> dRayIs; - // Collect the rays which has not abstacle in bettween in rayStartFace + // Collect the rays which has not hit obstacle inbetween rayStartFace // and rayEndFace. If the ray hit itself get stored in dRayIs forAll(hitInfo, rayI) { diff --git a/src/OpenFOAM/db/Time/timeSelector.H b/src/OpenFOAM/db/Time/timeSelector.H index 836264f1da76e6cb5e70785136ce754d60fb6fa6..197f558f61906e42356965481ea8c16b15ffd083 100644 --- a/src/OpenFOAM/db/Time/timeSelector.H +++ b/src/OpenFOAM/db/Time/timeSelector.H @@ -162,7 +162,7 @@ public: //- Return the set of times selected based on the argList options // including support for \b -newTimes in which times are selected - // if the file <fName> does not exist in the time directory. + // if the file \<fName\> does not exist in the time directory. // Also set the runTime to the first instance or the // \c constant/ directory if no instances are specified or available static instantList select diff --git a/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C b/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C index 5ddb9d564baf86a642f69c9975ce5860a6d1a5e1..e220d9a4c4aa02e2630360d9908222d206cbda4a 100644 --- a/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C +++ b/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -31,7 +31,7 @@ License namespace Foam { template<> - const char* NamedEnum<outputFilterOutputControl::outputControls, 7>:: + const char* NamedEnum<outputFilterOutputControl::outputControls, 8>:: names[] = { "timeStep", @@ -40,11 +40,12 @@ namespace Foam "runTime", "clockTime", "cpuTime", + "onEnd", "none" }; } -const Foam::NamedEnum<Foam::outputFilterOutputControl::outputControls, 7> +const Foam::NamedEnum<Foam::outputFilterOutputControl::outputControls, 8> Foam::outputFilterOutputControl::outputControlNames_; @@ -113,6 +114,7 @@ void Foam::outputFilterOutputControl::read(const dictionary& dict) break; } + case ocOnEnd: default: { // do nothing @@ -196,6 +198,13 @@ bool Foam::outputFilterOutputControl::output() break; } + case ocOnEnd: + { + scalar endTime = time_.endTime().value() - 0.5*time_.deltaTValue(); + return time_.value() > endTime; + break; + } + case ocNone: { return false; diff --git a/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.H b/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.H index 1818fe17009da1beab37ff6ed12c650b57364f58..6cef209c15ac76cf11be82eefe5983d2ba30213a 100644 --- a/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.H +++ b/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -62,6 +62,7 @@ public: ocRunTime, /*!< run time for dumping */ ocClockTime, /*!< clock time for dumping */ ocCpuTime, /*!< cpu time for dumping */ + ocOnEnd, /*!< on end of run*/ ocNone /*!< no output */ }; @@ -77,7 +78,7 @@ private: const word prefix_; //- String representation of outputControls enums - static const NamedEnum<outputControls, 7> outputControlNames_; + static const NamedEnum<outputControls, 8> outputControlNames_; //- Type of output outputControls outputControl_; diff --git a/src/TurbulenceModels/compressible/Make/files b/src/TurbulenceModels/compressible/Make/files index c4aab942510cd628afd489cab84fe998245e32d0..2c2366c37dcfa6a8f31b1ba7c3c385eecc664898 100644 --- a/src/TurbulenceModels/compressible/Make/files +++ b/src/TurbulenceModels/compressible/Make/files @@ -10,7 +10,6 @@ $(BCs)/totalFlowRateAdvectiveDiffusive/totalFlowRateAdvectiveDiffusiveFvPatchSca $(BCs)/turbulentTemperatureRadCoupledMixed/turbulentTemperatureRadCoupledMixedFvPatchScalarField.C $(BCs)/externalWallHeatFluxTemperature/externalWallHeatFluxTemperatureFvPatchScalarField.C $(BCs)/wallHeatTransfer/wallHeatTransferFvPatchScalarField.C -$(BCs)/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C $(BCs)/convectiveHeatTransfer/convectiveHeatTransferFvPatchScalarField.C turbulentFluidThermoModels/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.C diff --git a/src/TurbulenceModels/compressible/turbulenceModelDoc.H b/src/TurbulenceModels/compressible/turbulenceModelDoc.H index 5722cee54e88064bceebbb4f56a89404dd989583..941e205368208e83151d1e10358fec60d7a354ca 100644 --- a/src/TurbulenceModels/compressible/turbulenceModelDoc.H +++ b/src/TurbulenceModels/compressible/turbulenceModelDoc.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,6 +25,7 @@ License \defgroup grpCmpTurbulence Compressible turbulence @{ + \ingroup grpTurbulence This group contains compressible turbulence models. @} diff --git a/src/TurbulenceModels/incompressible/turbulenceModelDoc.H b/src/TurbulenceModels/incompressible/turbulenceModelDoc.H index 2e5547351f1a35a65c933524b4b2c24385aa5160..a0357f18d1c7b0b357d4f0edb3e021c0c102e992 100644 --- a/src/TurbulenceModels/incompressible/turbulenceModelDoc.H +++ b/src/TurbulenceModels/incompressible/turbulenceModelDoc.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,6 +25,7 @@ License \defgroup grpIcoTurbulence Incompressible turbulence @{ + \ingroup grpTurbulence This group contains incompressible turbulence models. @} diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 3dec7db1683466ad4add2cba78691d5b022d0475..1c159ff7cb802320276f78394a7745c751256405 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -133,7 +133,6 @@ $(derivedFvPatchFields)/advective/advectiveFvPatchFields.C $(derivedFvPatchFields)/codedFixedValue/codedFixedValueFvPatchFields.C $(derivedFvPatchFields)/codedMixed/codedMixedFvPatchFields.C $(derivedFvPatchFields)/cylindricalInletVelocity/cylindricalInletVelocityFvPatchVectorField.C -$(derivedFvPatchFields)/externalCoupledMixed/externalCoupledMixedFvPatchFields.C $(derivedFvPatchFields)/fan/fanFvPatchFields.C $(derivedFvPatchFields)/fanPressure/fanPressureFvPatchScalarField.C $(derivedFvPatchFields)/fixedFluxPressure/fixedFluxPressureFvPatchScalarField.C @@ -168,6 +167,7 @@ $(derivedFvPatchFields)/pressureInletOutletVelocity/pressureInletOutletVelocityF $(derivedFvPatchFields)/pressureInletUniformVelocity/pressureInletUniformVelocityFvPatchVectorField.C $(derivedFvPatchFields)/pressureInletVelocity/pressureInletVelocityFvPatchVectorField.C $(derivedFvPatchFields)/pressureNormalInletOutletVelocity/pressureNormalInletOutletVelocityFvPatchVectorField.C +$(derivedFvPatchFields)/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.C $(derivedFvPatchFields)/fixedNormalInletOutletVelocity/fixedNormalInletOutletVelocityFvPatchVectorField.C $(derivedFvPatchFields)/rotatingPressureInletOutletVelocity/rotatingPressureInletOutletVelocityFvPatchVectorField.C $(derivedFvPatchFields)/rotatingTotalPressure/rotatingTotalPressureFvPatchScalarField.C diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.C deleted file mode 100644 index f930a1ef5c705682a36e7a20fe0f4c98fd8b412f..0000000000000000000000000000000000000000 --- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.C +++ /dev/null @@ -1,851 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "externalCoupledMixedFvPatchField.H" -#include "fvPatchFieldMapper.H" -#include "volFields.H" -#include "IFstream.H" -#include "globalIndex.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -template<class Type> -Foam::word Foam::externalCoupledMixedFvPatchField<Type>::lockName = "OpenFOAM"; - -template<class Type> -Foam::string -Foam::externalCoupledMixedFvPatchField<Type>::patchKey = "# Patch: "; - - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -Foam::fileName Foam::externalCoupledMixedFvPatchField<Type>::baseDir() const -{ - word regionName(this->dimensionedInternalField().mesh().name()); - if (regionName == polyMesh::defaultRegion) - { - regionName = "."; - } - - fileName result(commsDir_/regionName); - result.clean(); - - return result; -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::setMaster -( - const labelList& patchIDs -) -{ - const volFieldType& cvf = - static_cast<const volFieldType&>(this->dimensionedInternalField()); - - volFieldType& vf = const_cast<volFieldType&>(cvf); - - typename volFieldType::GeometricBoundaryField& bf = vf.boundaryField(); - - // number of patches can be different in parallel... - label nPatch = bf.size(); - reduce(nPatch, maxOp<label>()); - - offsets_.setSize(nPatch); - forAll(offsets_, i) - { - offsets_[i].setSize(Pstream::nProcs()); - offsets_[i] = 0; - } - - // set the master patch - forAll(patchIDs, i) - { - label patchI = patchIDs[i]; - - patchType& pf = refCast<patchType>(bf[patchI]); - - offsets_[patchI][Pstream::myProcNo()] = pf.size(); - - if (i == 0) - { - pf.master() = true; - } - else - { - pf.master() = false; - } - } - - // set the patch offsets - int tag = Pstream::msgType() + 1; - forAll(offsets_, i) - { - Pstream::gatherList(offsets_[i], tag); - Pstream::scatterList(offsets_[i], tag); - } - - label patchOffset = 0; - forAll(offsets_, patchI) - { - label sumOffset = 0; - List<label>& procOffsets = offsets_[patchI]; - - forAll(procOffsets, procI) - { - label o = procOffsets[procI]; - if (o > 0) - { - procOffsets[procI] = patchOffset + sumOffset; - sumOffset += o; - } - } - patchOffset += sumOffset; - } -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::writeGeometry -( - OFstream& osPoints, - OFstream& osFaces -) const -{ - int tag = Pstream::msgType() + 1; - - const label procI = Pstream::myProcNo(); - const polyPatch& p = this->patch().patch(); - const polyMesh& mesh = p.boundaryMesh().mesh(); - - labelList pointToGlobal; - labelList uniquePointIDs; - (void)mesh.globalData().mergePoints - ( - p.meshPoints(), - p.meshPointMap(), - pointToGlobal, - uniquePointIDs - ); - - List<pointField> allPoints(Pstream::nProcs()); - allPoints[procI] = pointField(mesh.points(), uniquePointIDs); - Pstream::gatherList(allPoints, tag); - - List<faceList> allFaces(Pstream::nProcs()); - faceList& patchFaces = allFaces[procI]; - patchFaces = p.localFaces(); - forAll(patchFaces, faceI) - { - inplaceRenumber(pointToGlobal, patchFaces[faceI]); - } - - Pstream::gatherList(allFaces, tag); - - if (Pstream::master()) - { - pointField pts - ( - ListListOps::combine<pointField>(allPoints, accessOp<pointField>()) - ); - - // write points - osPoints << patchKey.c_str() << this->patch().name() << pts << endl; - - faceList fcs - ( - ListListOps::combine<faceList>(allFaces, accessOp<faceList>()) - ); - - // write faces - osFaces<< patchKey.c_str() << this->patch().name() << fcs << endl; - } -} - - -template<class Type> -Foam::fileName Foam::externalCoupledMixedFvPatchField<Type>::lockFile() const -{ - return fileName(baseDir()/(lockName + ".lock")); -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::createLockFile() const -{ - if (!master_ || !Pstream::master()) - { - return; - } - - const fileName fName(lockFile()); - IFstream is(fName); - - // only create lock file if it doesn't already exist - if (!is.good()) - { - if (log_) - { - Info<< type() << ": creating lock file" << endl; - } - - OFstream os(fName); - os << "lock file"; - os.flush(); - } -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::removeLockFile() const -{ - if (!master_ || !Pstream::master()) - { - return; - } - - if (log_) - { - Info<< type() << ": removing lock file" << endl; - } - - rm(lockFile()); -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::startWait() const -{ - // only wait on master patch - - const volFieldType& cvf = - static_cast<const volFieldType&>(this->dimensionedInternalField()); - - const typename volFieldType::GeometricBoundaryField& bf = - cvf.boundaryField(); - - forAll(coupledPatchIDs_, i) - { - label patchI = coupledPatchIDs_[i]; - - const patchType& pf = refCast<const patchType>(bf[patchI]); - - if (pf.master()) - { - pf.wait(); - break; - } - } -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::wait() const -{ - const fileName fName(lockFile()); - label found = 0; - label totalTime = 0; - - if (log_) - { - Info<< type() << ": beginning wait for lock file " << fName << endl; - } - - while (found == 0) - { - if (Pstream::master()) - { - if (totalTime > timeOut_) - { - FatalErrorIn - ( - "void " - "Foam::externalCoupledMixedFvPatchField<Type>::wait() " - "const" - ) - << "Wait time exceeded time out time of " << timeOut_ - << " s" << abort(FatalError); - } - - IFstream is(fName); - - if (is.good()) - { - found++; - - if (log_) - { - Info<< type() << ": found lock file " << fName << endl; - } - } - else - { - sleep(waitInterval_); - totalTime += waitInterval_; - - if (log_) - { - Info<< type() << ": wait time = " << totalTime << endl; - } - } - } - - // prevent other procs from racing ahead - reduce(found, sumOp<label>()); - } -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::initialiseRead -( - IFstream& is -) const -{ - if (!is.good()) - { - FatalErrorIn - ( - "void Foam::externalCoupledMixedFvPatchField<Type>::" - "initialiseRead" - "(" - "IFstream&" - ") const" - ) - << "Unable to open data transfer file " << is.name() - << " for patch " << this->patch().name() - << exit(FatalError); - } - - label offset = offsets_[this->patch().index()][Pstream::myProcNo()]; - - // scan forward to start reading at relevant line/position - string line; - for (label i = 0; i < offset; i++) - { - if (is.good()) - { - is.getLine(line); - } - else - { - FatalErrorIn - ( - "void Foam::externalCoupledMixedFvPatchField<Type>::" - "initialiseRead" - "(" - "IFstream&" - ") const" - ) - << "Unable to scan forward to appropriate read position for " - << "data transfer file " << is.name() - << " for patch " << this->patch().name() - << exit(FatalError); - } - } -} - - -// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::readData -( - const fileName& transferFile -) -{ - // read data passed back from external source - IFstream is(transferFile + ".in"); - - // pre-process the input transfer file - initialiseRead(is); - - // read data from file - forAll(this->patch(), faceI) - { - if (is.good()) - { - is >> this->refValue()[faceI] - >> this->refGrad()[faceI] - >> this->valueFraction()[faceI]; - } - else - { - FatalErrorIn - ( - "void Foam::externalCoupledMixedFvPatchField<Type>::readData" - "(" - "const fileName&" - ")" - ) - << "Insufficient data for patch " - << this->patch().name() - << " in file " << is.name() - << exit(FatalError); - } - } - - initialised_ = true; - - // update the value from the mixed condition - mixedFvPatchField<Type>::evaluate(); -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::writeData -( - const fileName& transferFile -) const -{ - if (!master_) - { - return; - } - - OFstream os(transferFile); - - writeHeader(os); - - const volFieldType& cvf = - static_cast<const volFieldType&>(this->dimensionedInternalField()); - - const typename volFieldType::GeometricBoundaryField& bf = - cvf.boundaryField(); - - forAll(coupledPatchIDs_, i) - { - label patchI = coupledPatchIDs_[i]; - - const patchType& pf = refCast<const patchType>(bf[patchI]); - - pf.transferData(os); - } -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::writeHeader -( - OFstream& os -) const -{ - os << "# Values: magSf value snGrad" << endl; -} - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -template<class Type> -Foam::externalCoupledMixedFvPatchField<Type>:: -externalCoupledMixedFvPatchField -( - const fvPatch& p, - const DimensionedField<Type, volMesh>& iF -) -: - mixedFvPatchField<Type>(p, iF), - commsDir_("unknown-commsDir"), - fName_("unknown-fName"), - waitInterval_(0), - timeOut_(0), - calcFrequency_(0), - initByExternal_(false), - log_(false), - master_(false), - offsets_(), - initialised_(false), - coupledPatchIDs_() -{ - this->refValue() = pTraits<Type>::zero; - this->refGrad() = pTraits<Type>::zero; - this->valueFraction() = 0.0; -} - - -template<class Type> -Foam::externalCoupledMixedFvPatchField<Type>:: -externalCoupledMixedFvPatchField -( - const externalCoupledMixedFvPatchField& ptf, - const fvPatch& p, - const DimensionedField<Type, volMesh>& iF, - const fvPatchFieldMapper& mapper -) -: - mixedFvPatchField<Type>(ptf, p, iF, mapper), - commsDir_(ptf.commsDir_), - fName_(ptf.fName_), - waitInterval_(ptf.waitInterval_), - timeOut_(ptf.timeOut_), - calcFrequency_(ptf.calcFrequency_), - initByExternal_(ptf.initByExternal_), - log_(ptf.log_), - master_(ptf.master_), - offsets_(ptf.offsets_), - initialised_(ptf.initialised_), - coupledPatchIDs_(ptf.coupledPatchIDs_) -{} - - -template<class Type> -Foam::externalCoupledMixedFvPatchField<Type>:: -externalCoupledMixedFvPatchField -( - const fvPatch& p, - const DimensionedField<Type, volMesh>& iF, - const dictionary& dict -) -: - mixedFvPatchField<Type>(p, iF), - commsDir_(dict.lookup("commsDir")), - fName_(dict.lookup("fileName")), - waitInterval_(dict.lookupOrDefault("waitInterval", 1)), - timeOut_(dict.lookupOrDefault("timeOut", 100*waitInterval_)), - calcFrequency_(dict.lookupOrDefault("calcFrequency", 1)), - initByExternal_(readBool(dict.lookup("initByExternal"))), - log_(dict.lookupOrDefault("log", false)), - master_(true), - offsets_(), - initialised_(false), - coupledPatchIDs_() -{ - if (dict.found("value")) - { - fvPatchField<Type>::operator= - ( - Field<Type>("value", dict, p.size()) - ); - } - else - { - fvPatchField<Type>::operator=(this->patchInternalField()); - } - - commsDir_.expand(); - - if (Pstream::master()) - { - mkDir(baseDir()); - } - - if (!initByExternal_) - { - createLockFile(); - } - - // initialise as a fixed value - this->refValue() = *this; - this->refGrad() = pTraits<Type>::zero; - this->valueFraction() = 1.0; -} - - -template<class Type> -Foam::externalCoupledMixedFvPatchField<Type>:: -externalCoupledMixedFvPatchField -( - const externalCoupledMixedFvPatchField& ecmpf -) -: - mixedFvPatchField<Type>(ecmpf), - commsDir_(ecmpf.commsDir_), - fName_(ecmpf.fName_), - waitInterval_(ecmpf.waitInterval_), - timeOut_(ecmpf.timeOut_), - calcFrequency_(ecmpf.calcFrequency_), - initByExternal_(ecmpf.initByExternal_), - log_(ecmpf.log_), - master_(ecmpf.master_), - offsets_(ecmpf.offsets_), - initialised_(ecmpf.initialised_), - coupledPatchIDs_(ecmpf.coupledPatchIDs_) -{} - - -template<class Type> -Foam::externalCoupledMixedFvPatchField<Type>:: -externalCoupledMixedFvPatchField -( - const externalCoupledMixedFvPatchField& ecmpf, - const DimensionedField<Type, volMesh>& iF -) -: - mixedFvPatchField<Type>(ecmpf, iF), - commsDir_(ecmpf.commsDir_), - fName_(ecmpf.fName_), - waitInterval_(ecmpf.waitInterval_), - timeOut_(ecmpf.timeOut_), - calcFrequency_(ecmpf.calcFrequency_), - initByExternal_(ecmpf.initByExternal_), - log_(ecmpf.log_), - master_(ecmpf.master_), - offsets_(ecmpf.offsets_), - initialised_(ecmpf.initialised_), - coupledPatchIDs_(ecmpf.coupledPatchIDs_) -{} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -template<class Type> -Foam::externalCoupledMixedFvPatchField<Type>:: -~externalCoupledMixedFvPatchField() -{ - removeLockFile(); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::initialise -( - const fileName& transferFile -) -{ - if (initialised_) - { - return; - } - - const volFieldType& cvf = - static_cast<const volFieldType&>(this->dimensionedInternalField()); - - volFieldType& vf = const_cast<volFieldType&>(cvf); - - typename volFieldType::GeometricBoundaryField& bf = vf.boundaryField(); - - // identify all coupled patches - DynamicList<label> coupledPatchIDs(bf.size()); - - forAll(bf, patchI) - { - if (isA<patchType>(bf[patchI])) - { - coupledPatchIDs.append(patchI); - } - } - - coupledPatchIDs_.transfer(coupledPatchIDs); - - - // initialise by external solver, or just set the master patch - if (initByExternal_) - { - // remove lock file, signalling external source to execute -// removeLockFile(); - - forAll(coupledPatchIDs_, i) - { - label patchI = coupledPatchIDs_[i]; - - patchType& pf = refCast<patchType>(bf[patchI]); - - pf.setMaster(coupledPatchIDs_); - } - - - // wait for initial data to be made available - startWait(); - - // read the initial data - if (master_) - { - forAll(coupledPatchIDs_, i) - { - label patchI = coupledPatchIDs_[i]; - - patchType& pf = refCast<patchType>(bf[patchI]); - - pf.readData(transferFile); - } - } - } - else - { - setMaster(coupledPatchIDs_); - } - - initialised_ = true; -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::evaluate -( - const Pstream::commsTypes comms -) -{ - if (!initialised_ || this->db().time().timeIndex() % calcFrequency_ == 0) - { - const fileName transferFile(baseDir()/fName_); - - // initialise the coupling - initialise(transferFile); - - // write data for external source - writeData(transferFile + ".out"); - - // remove lock file, signalling external source to execute - removeLockFile(); - - // wait for response - startWait(); - - if (master_ && Pstream::master()) - { - // remove old data file from OpenFOAM - rm(transferFile + ".out"); - } - - // read data passed back from external source - readData(transferFile); - - // create lock file for external source - createLockFile(); - } -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::transferData -( - OFstream& os -) const -{ - if (log_) - { - Info<< type() << ": writing data to " << os.name() << endl; - } - - if (Pstream::parRun()) - { - int tag = Pstream::msgType() + 1; - - List<Field<scalar> > magSfs(Pstream::nProcs()); - magSfs[Pstream::myProcNo()].setSize(this->patch().size()); - magSfs[Pstream::myProcNo()] = this->patch().magSf(); - Pstream::gatherList(magSfs, tag); - - List<Field<Type> > values(Pstream::nProcs()); - values[Pstream::myProcNo()].setSize(this->patch().size()); - values[Pstream::myProcNo()] = this->refValue(); - Pstream::gatherList(values, tag); - - List<Field<Type> > snGrads(Pstream::nProcs()); - snGrads[Pstream::myProcNo()].setSize(this->patch().size()); - snGrads[Pstream::myProcNo()] = this->snGrad(); - Pstream::gatherList(snGrads, tag); - - if (Pstream::master()) - { - forAll(values, procI) - { - const Field<scalar>& magSf = magSfs[procI]; - const Field<Type>& value = values[procI]; - const Field<Type>& snGrad = snGrads[procI]; - - forAll(magSf, faceI) - { - os << magSf[faceI] << token::SPACE - << value[faceI] << token::SPACE - << snGrad[faceI] << nl; - } - } - - os.flush(); - } - } - else - { - const Field<scalar>& magSf(this->patch().magSf()); - const Field<Type>& value(this->refValue()); - const Field<Type> snGrad(this->snGrad()); - - forAll(magSf, faceI) - { - os << magSf[faceI] << token::SPACE - << value[faceI] << token::SPACE - << snGrad[faceI] << nl; - } - - os.flush(); - } -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::writeGeometry() const -{ - const volFieldType& cvf = - static_cast<const volFieldType&>(this->dimensionedInternalField()); - - const typename volFieldType::GeometricBoundaryField& bf = - cvf.boundaryField(); - - OFstream osPoints(baseDir()/"patchPoints"); - OFstream osFaces(baseDir()/"patchFaces"); - - if (log_) - { - Info<< "writing collated patch points to: " << osPoints.name() << nl - << "writing collated patch faces to: " << osFaces.name() << endl; - } - - forAll(bf, patchI) - { - if (isA<patchType>(bf[patchI])) - { - const patchType& pf = refCast<const patchType>(bf[patchI]); - - pf.writeGeometry(osPoints, osFaces); - } - } -} - - -template<class Type> -void Foam::externalCoupledMixedFvPatchField<Type>::write(Ostream& os) const -{ - mixedFvPatchField<Type>::write(os); - - os.writeKeyword("commsDir") << commsDir_ << token::END_STATEMENT << nl; - os.writeKeyword("fileName") << fName_ << token::END_STATEMENT << nl; - os.writeKeyword("waitInterval") << waitInterval_ << token::END_STATEMENT - << nl; - os.writeKeyword("timeOut") << timeOut_ << token::END_STATEMENT << nl; - os.writeKeyword("calcFrequency") << calcFrequency_ << token::END_STATEMENT - << nl; - os.writeKeyword("initByExternal") << initByExternal_ << token::END_STATEMENT - << nl; - os.writeKeyword("log") << log_ << token::END_STATEMENT << nl; - - this->writeEntry("value", os); -} - - -// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.H deleted file mode 100644 index 322ba3810b71d0bec8b025054b7893130baeecae..0000000000000000000000000000000000000000 --- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.H +++ /dev/null @@ -1,355 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::externalCoupledMixedFvPatchField - -Group - grpGenericBoundaryConditions grpCoupledBoundaryConditions - -Description - This boundary condition provides an interface to an external application. - Values are transferred as plain text files, where OpenFOAM data is written - as: - - # Patch: <patch name> - <magSf1> <value1> <surfaceNormalGradient1> - <magSf2> <value2> <surfaceNormalGradient2> - <magSf3> <value3> <surfaceNormalGradient3> - ... - <magSfN> <valueN> <surfaceNormalGradientN> - - and received as the constituent pieces of the `mixed' condition, i.e. - - # Patch: <patch name> - <value1> <gradient1> <valueFracion1> - <value2> <gradient2> <valueFracion2> - <value3> <gradient3> <valueFracion3> - ... - <valueN> <gradientN> <valueFracionN> - - Data is sent/received as a single file for all patches from the directory - - $FOAM_CASE/<commsDir> - - At start-up, the boundary creates a lock file, i.e.. - - OpenFOAM.lock - - ... to signal the external source to wait. During the boundary condition - update, boundary values are written to file, e.g. - - <fileName>.out - - The lock file is then removed, instructing the external source to take - control of the program execution. When ready, the external program - should create the return values, e.g. to file - - <fileName>.in - - ... and then re-instate the lock file. The boundary condition will then - read the return values, and pass program execution back to OpenFOAM. - - - \heading Patch usage - - \table - Property | Description | Required | Default value - commsDir | communications directory | yes | - fileName | transfer file name | yes | - waitInterval | interval [s] between file checks | no | 1 - timeOut | time after which error invoked [s] |no |100*waitInterval - calcFrequency | calculation frequency | no | 1 - initByExternal | external app to initialises values | yes | - log | log program control | no | no - \endtable - - Example of the boundary condition specification: - \verbatim - myPatch - { - type externalCoupled; - commsDir "$FOAM_CASE/comms"; - fileName data; - calcFrequency 1; - initByExternal yes; - } - \endverbatim - -SeeAlso - mixedFvPatchField - -SourceFiles - externalCoupledMixedFvPatchField.C - -\*---------------------------------------------------------------------------*/ - -#ifndef externalCoupledMixedFvPatchField_H -#define externalCoupledMixedFvPatchField_H - -#include "mixedFvPatchFields.H" -#include "OFstream.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -class IFstream; - -/*---------------------------------------------------------------------------*\ - Class externalCoupledMixedFvPatchField Declaration -\*---------------------------------------------------------------------------*/ - -template<class Type> -class externalCoupledMixedFvPatchField -: - public mixedFvPatchField<Type> -{ - -private: - - // Private data - - //- Convenience typedefs - typedef externalCoupledMixedFvPatchField<Type> patchType; - typedef GeometricField<Type, fvPatchField, volMesh> volFieldType; - - //- Path to communications directory - fileName commsDir_; - - //- Name of data file - word fName_; - - //- Interval time between checking for return data [s] - label waitInterval_; - - //- Time out time [s] - label timeOut_; - - //- Calculation frequency - label calcFrequency_; - - //- Flag to indicate values are initialised by external application - bool initByExternal_; - - //- Log flag - bool log_; - - //- Master patch flag - controls when to pause/resume execution - // Note: only valid when collate option is selected - bool master_; - - //- Offsets in data file to start reading at correct position - List<List<label> > offsets_; - - //- Initialised flag - bool initialised_; - - //- List of coupled patch IDs - List<label> coupledPatchIDs_; - - - // Private Member Functions - - //- Initialise - void initialise(const fileName& transferFile); - - //- Set the master flag when collate option is selected - void setMaster(const labelList& patchIDs); - - //- Return the file path to the base communications directory - fileName baseDir() const; - - //- Write the geometry to the comms dir - void writeGeometry(OFstream& osPoints, OFstream& osFaces) const; - - //- Return the file path to the lock file - fileName lockFile() const; - - //- Create lock file - void createLockFile() const; - - //- Remove lock file - void removeLockFile() const; - - //- Wait for response from external source - void startWait() const; - - //- Wait for response from external source - void wait() const; - - //- Initialise input stream for reading - void initialiseRead(IFstream& is) const; - - -protected: - - // Protected Member Functions - - //- Read data from external source - virtual void readData(const fileName& transferFile); - - //- Write data for external source - calls transferData - virtual void writeData(const fileName& transferFile) const; - - //- Write header to transfer file - virtual void writeHeader(OFstream& os) const; - - -public: - - //- Runtime type information - TypeName("externalCoupled"); - - //- Name of lock file - static word lockName; - - //- Name of patch key, e.g. '# Patch:' when looking for start of patch data - static string patchKey; - - - // Constructors - - //- Construct from patch and internal field - externalCoupledMixedFvPatchField - ( - const fvPatch&, - const DimensionedField<Type, volMesh>& - ); - - //- Construct from patch, internal field and dictionary - externalCoupledMixedFvPatchField - ( - const fvPatch&, - const DimensionedField<Type, volMesh>&, - const dictionary& - ); - - //- Construct by mapping given externalCoupledMixedFvPatchField - // onto a new patch - externalCoupledMixedFvPatchField - ( - const externalCoupledMixedFvPatchField<Type>&, - const fvPatch&, - const DimensionedField<Type, volMesh>&, - const fvPatchFieldMapper& - ); - - //- Construct as copy - externalCoupledMixedFvPatchField - ( - const externalCoupledMixedFvPatchField& - ); - - //- Construct and return a clone - virtual tmp<fvPatchField<Type> > clone() const - { - return tmp<fvPatchField<Type> > - ( - new externalCoupledMixedFvPatchField<Type>(*this) - ); - } - - //- Construct as copy setting internal field reference - externalCoupledMixedFvPatchField - ( - const externalCoupledMixedFvPatchField&, - const DimensionedField<Type, volMesh>& - ); - - //- Construct and return a clone setting internal field reference - virtual tmp<fvPatchField<Type> > clone - ( - const DimensionedField<Type, volMesh>& iF - ) const - { - return tmp<fvPatchField<Type> > - ( - new externalCoupledMixedFvPatchField<Type>(*this, iF) - ); - } - - - //- Destructor - virtual ~externalCoupledMixedFvPatchField(); - - - // Member functions - - // Access - - //- Return the log flag - bool log() const - { - return log_; - } - - //- Return the master flag - bool master() const - { - return master_; - } - - //- Return the master flag - bool& master() - { - return master_; - } - - - // Evaluation functions - - //- Evaluate the patch field - virtual void evaluate - ( - const Pstream::commsTypes commsType=Pstream::blocking - ); - - //- Transfer data for external source - virtual void transferData(OFstream& os) const; - - - //- Write the geometry to the comms dir - void writeGeometry() const; - - //- Write - virtual void write(Ostream&) const; -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#ifdef NoRepository -# include "externalCoupledMixedFvPatchField.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.C new file mode 100644 index 0000000000000000000000000000000000000000..b7d36f1a6da272499521f07fc2c6979eca885e12 --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.C @@ -0,0 +1,438 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "pressurePIDControlInletVelocityFvPatchVectorField.H" +#include "volFields.H" +#include "addToRunTimeSelectionTable.H" +#include "fvPatchFieldMapper.H" +#include "surfaceFields.H" +#include "linear.H" +#include "steadyStateDdtScheme.H" + +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // + +const Foam::surfaceScalarField& +Foam::pressurePIDControlInletVelocityFvPatchVectorField::facePressure() const +{ + const volScalarField& p(db().lookupObject<volScalarField>(pName_)); + + const word pfName(pName_ + "f"); + + if (!db().foundObject<surfaceScalarField>(pfName)) + { + surfaceScalarField* pfPtr + ( + new surfaceScalarField(pfName, linearInterpolate(p)) + ); + + pfPtr->store(); + } + + surfaceScalarField& pf + ( + const_cast<surfaceScalarField&> + ( + db().lookupObject<surfaceScalarField>(pfName) + ) + ); + + if (!pf.upToDate(p)) + { + pf = linearInterpolate(p); + } + + return pf; +} + + +template <class Type> +void Foam::pressurePIDControlInletVelocityFvPatchVectorField::faceZoneAverage +( + const word& name, + const GeometricField<Type, fvsPatchField, surfaceMesh>& field, + scalar& area, + Type& average +) const +{ + const fvMesh& mesh(patch().boundaryMesh().mesh()); + + const faceZone& zone = mesh.faceZones()[name]; + + area = 0; + average = pTraits<Type>::zero; + + forAll(zone, faceI) + { + const label f(zone[faceI]); + + const scalar da(mesh.magSf()[f]); + + area += da; + average += da*field[f]; + } + + reduce(area, sumOp<scalar>()); + reduce(average, sumOp<Type>()); + + average /= area; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::pressurePIDControlInletVelocityFvPatchVectorField:: +pressurePIDControlInletVelocityFvPatchVectorField +( + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF +) +: + fixedValueFvPatchField<vector>(p, iF), + upstreamName_(word::null), + downstreamName_(word::null), + deltaP_(1), + shapeFactor_(0), + pName_("p"), + phiName_("phi"), + rhoName_("none"), + P_(0), + I_(0), + D_(0), + Q_(- gSum(*this & patch().Sf())), + error_(0), + errorIntegral_(0), + oldQ_(0), + oldError_(0), + oldErrorIntegral_(0), + timeIndex_(db().time().timeIndex()) +{} + + +Foam::pressurePIDControlInletVelocityFvPatchVectorField:: +pressurePIDControlInletVelocityFvPatchVectorField +( + const pressurePIDControlInletVelocityFvPatchVectorField& ptf, + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF, + const fvPatchFieldMapper& mapper +) +: + fixedValueFvPatchField<vector>(ptf, p, iF, mapper), + upstreamName_(ptf.upstreamName_), + downstreamName_(ptf.downstreamName_), + deltaP_(ptf.deltaP_), + shapeFactor_(ptf.shapeFactor_), + pName_(ptf.pName_), + phiName_(ptf.phiName_), + rhoName_(ptf.rhoName_), + P_(ptf.P_), + I_(ptf.I_), + D_(ptf.D_), + Q_(ptf.Q_), + error_(ptf.error_), + errorIntegral_(ptf.errorIntegral_), + oldQ_(ptf.oldQ_), + oldError_(ptf.oldError_), + oldErrorIntegral_(ptf.oldErrorIntegral_), + timeIndex_(ptf.timeIndex_) +{} + + +Foam::pressurePIDControlInletVelocityFvPatchVectorField:: +pressurePIDControlInletVelocityFvPatchVectorField +( + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF, + const dictionary& dict +) +: + fixedValueFvPatchField<vector>(p, iF, dict), + upstreamName_(dict.lookup("upstream")), + downstreamName_(dict.lookup("downstream")), + deltaP_(readScalar(dict.lookup("deltaP"))), + shapeFactor_(dict.lookupOrDefault<scalar>("shapeFactor", 0)), + pName_(dict.lookupOrDefault<word>("p", "p")), + phiName_(dict.lookupOrDefault<word>("phi", "phi")), + rhoName_(dict.lookupOrDefault<word>("rho", "none")), + P_(readScalar(dict.lookup("P"))), + I_(readScalar(dict.lookup("I"))), + D_(readScalar(dict.lookup("D"))), + Q_(- gSum(*this & patch().Sf())), + error_(dict.lookupOrDefault<scalar>("error", 0)), + errorIntegral_(dict.lookupOrDefault<scalar>("errorIntegral", 0)), + oldQ_(0), + oldError_(0), + oldErrorIntegral_(0), + timeIndex_(db().time().timeIndex()) +{} + + +Foam::pressurePIDControlInletVelocityFvPatchVectorField:: +pressurePIDControlInletVelocityFvPatchVectorField +( + const pressurePIDControlInletVelocityFvPatchVectorField& ptf +) +: + fixedValueFvPatchField<vector>(ptf), + upstreamName_(ptf.upstreamName_), + downstreamName_(ptf.downstreamName_), + deltaP_(ptf.deltaP_), + shapeFactor_(ptf.shapeFactor_), + pName_(ptf.pName_), + phiName_(ptf.phiName_), + rhoName_(ptf.rhoName_), + P_(ptf.P_), + I_(ptf.I_), + D_(ptf.D_), + Q_(ptf.Q_), + error_(ptf.error_), + errorIntegral_(ptf.errorIntegral_), + oldQ_(ptf.oldQ_), + oldError_(ptf.oldError_), + oldErrorIntegral_(ptf.oldErrorIntegral_), + timeIndex_(ptf.timeIndex_) +{} + + +Foam::pressurePIDControlInletVelocityFvPatchVectorField:: +pressurePIDControlInletVelocityFvPatchVectorField +( + const pressurePIDControlInletVelocityFvPatchVectorField& ptf, + const DimensionedField<vector, volMesh>& iF +) +: + fixedValueFvPatchField<vector>(ptf, iF), + upstreamName_(ptf.upstreamName_), + downstreamName_(ptf.downstreamName_), + deltaP_(ptf.deltaP_), + shapeFactor_(ptf.shapeFactor_), + pName_(ptf.pName_), + phiName_(ptf.phiName_), + rhoName_(ptf.rhoName_), + P_(ptf.P_), + I_(ptf.I_), + D_(ptf.D_), + Q_(ptf.Q_), + error_(ptf.error_), + errorIntegral_(ptf.errorIntegral_), + oldQ_(ptf.oldQ_), + oldError_(ptf.oldError_), + oldErrorIntegral_(ptf.oldErrorIntegral_), + timeIndex_(ptf.timeIndex_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::pressurePIDControlInletVelocityFvPatchVectorField::updateCoeffs() +{ + if (updated()) + { + return; + } + + // Get the mesh + const fvMesh& mesh(patch().boundaryMesh().mesh()); + + // Get the time step + const scalar deltaT(db().time().deltaTValue()); + + // Get the flux field + const surfaceScalarField& phi + ( + db().lookupObject<surfaceScalarField>(phiName_) + ); + + // Update the old-time quantities + if (timeIndex_ != db().time().timeIndex()) + { + timeIndex_ = db().time().timeIndex(); + oldQ_ = Q_; + oldError_ = error_; + oldErrorIntegral_ = errorIntegral_; + } + + // Get the density + scalar rho = 1; + if (phi.dimensions() == dimVelocity*dimArea) + { + // do nothing ... + } + else if (phi.dimensions() == dimDensity*dimVelocity*dimArea) + { + const fvPatchField<scalar>& rhoField = + patch().lookupPatchField<volScalarField, scalar>(rhoName_); + + rho = gSum(rhoField*patch().magSf())/gSum(patch().magSf()); + } + else + { + FatalErrorIn + ( + "void Foam::" + "pressurePIDControlInletVelocityFvPatchVectorField::" + "updateCoeffs()" + ) << "The dimensions of the field " << phiName_ + << "are not recognised. The dimensions are " << phi.dimensions() + << ". The dimensions should be either " << dimVelocity*dimArea + << " for an incompressible case, or " + << dimDensity*dimVelocity*dimArea << " for a compressible case." + << exit(FatalError); + } + + // Patch properties + const scalar patchA = gSum(patch().magSf()); + Q_ = - gSum(*this & patch().Sf()); + + // Face-zone properties (a is upstream, b is downstream) + scalar Aa, Ab; + vector xa, xb; + faceZoneAverage(upstreamName_, mesh.Cf(), Aa, xa); + faceZoneAverage(downstreamName_, mesh.Cf(), Ab, xb); + const scalar L = mag(xa - xb); + const scalar LbyALinear = L/(Aa - Ab)*log(Aa/Ab); + const scalar LbyAStep = L/2*(1/Aa + 1/Ab); + const scalar LbyA = (1 - shapeFactor_)*LbyALinear + shapeFactor_*LbyAStep; + + // Initialise the pressure drop. If the pressure field does not exist, the + // pressure drop is assumed to be that specified. This removes the error, + // so there is no control and the analytic inlet velocity is applied. This + // scenario only ever going to be applicable to potentialFoam. + scalar deltaP = deltaP_; + if (db().foundObject<volScalarField>(pName_)) + { + scalar pa, pb; + faceZoneAverage(upstreamName_, facePressure(), Aa, pa); + faceZoneAverage(downstreamName_, facePressure(), Ab, pb); + deltaP = pa - pb; + } + else + { + WarningIn + ( + "void Foam::pressurePIDControlInletVelocityFvPatchVectorField::" + "updateCoeffs()" + ) << "The pressure field name, \"pName\", is \"" << pName_ << "\", " + << "but a field of that name was not found. The inlet velocity " + << "will be set to an analytical value calculated from the " + << "specified pressure drop. No PID control will be done and " + << "transient effects will be ignored. This behaviour is designed " + << "to be appropriate for potentialFoam solutions. If you are " + << "getting this warning from another solver, you have probably " + << "specified an incorrect pressure name." + << endl << endl; + } + + // Target and measured flow rates + scalar QTarget, QMeasured; + const scalar a = (1/sqr(Ab) - 1/sqr(Aa))/(2*rho); + if (!mesh.steady() && db().foundObject<volScalarField>(pName_)) + { + const scalar b = LbyA/deltaT; + const scalar c = - LbyA/deltaT*oldQ_ /* - deltaP */; + QTarget = (- b + sqrt(sqr(b) - 4*a*(c - deltaP_)))/(2*a); + QMeasured = (- b + sqrt(sqr(b) - 4*a*(c - deltaP)))/(2*a); + } + else + { + QTarget = sqrt(deltaP_/a); + QMeasured = sqrt(deltaP/a); + } + + // Errors + error_ = QTarget - QMeasured; + errorIntegral_ = oldErrorIntegral_ + 0.5*(error_ + oldError_); + const scalar errorDifferential = oldError_ - error_; + + // Update the field + operator== + ( + - patch().nf() + *( + QTarget + + P_*error_ + + I_*errorIntegral_ + + D_*errorDifferential + )/patchA + ); + + // Log output + if (debug) + { + const dimensionSet pDimensions(phi.dimensions()*dimVelocity/dimArea); + const scalar error = deltaP/deltaP_ - 1; + const scalar newQ = - gSum(*this & patch().Sf()); + Info<< "pressurePIDControlInletVelocityFvPatchField " << patch().name() + << endl << " " + << dimensionedScalar("U", dimVelocity, newQ/patchA) + << endl << " " + << dimensionedScalar("deltaP", pDimensions, deltaP) + << " (" << mag(error)*100 << "\% " + << (error < 0 ? "below" : "above") << " the target)" << endl; + } + + fixedValueFvPatchField<vector>::updateCoeffs(); +} + + +void Foam::pressurePIDControlInletVelocityFvPatchVectorField::write +( + Ostream& os +) const +{ + fvPatchField<vector>::write(os); + + os.writeKeyword("deltaP") << deltaP_ << token::END_STATEMENT << nl; + os.writeKeyword("upstream") << upstreamName_ << token::END_STATEMENT << nl; + os.writeKeyword("downstream") + << downstreamName_ << token::END_STATEMENT << nl; + os.writeKeyword("shapeFactor") << shapeFactor_ + << token::END_STATEMENT << nl; + writeEntryIfDifferent<word>(os, "p", "p", pName_); + writeEntryIfDifferent<word>(os, "rho", "none", rhoName_); + os.writeKeyword("P") << P_ << token::END_STATEMENT << nl; + os.writeKeyword("I") << I_ << token::END_STATEMENT << nl; + os.writeKeyword("D") << D_ << token::END_STATEMENT << nl; + os.writeKeyword("error") << error_ << token::END_STATEMENT << nl; + os.writeKeyword("errorIntegral") + << errorIntegral_ << token::END_STATEMENT << nl; + + writeEntry("value", os); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + makePatchTypeField + ( + fvPatchVectorField, + pressurePIDControlInletVelocityFvPatchVectorField + ); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.H b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.H new file mode 100644 index 0000000000000000000000000000000000000000..d6f6cf765e5137971cece89b50c19c6f7734401d --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.H @@ -0,0 +1,279 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::pressurePIDControlInletVelocityFvPatchVectorField + +Group + grpInletBoundaryConditions + +Description + This boundary condition tries to generate an inlet velocity that maintains + a specified pressure drop between two face zones downstream. The zones + should fully span a duct through which all the inlet flow passes. + + An incompressible, lossless analysis of the flow between the inlet and the + two face-zones is performed. An ideal inlet velocity is thereby calculated + from the user-specified pressure drop. This analysis can include the + transient effect of the inlet velocity change. In this case, a shape factor + is included to represent non-linearity in the duct cross section. + + The average pressure drop between the two face zones is measured. The same + incompressible, lossless analysis is performed using this pressure drop. + The difference between the two computed velocities is considered as an + error. The ideal inlet is modified so as to drive this error to zero. This + is accomplished by means of a PID control algorithm, for which + non-dimensional gains are specified by the user. + + The shape factor takes a value of 0 for a linear change in cross sectional + area between the two face zones. A value of 1 represents a step change in + area at the mid-point between the zones. A smooth cubic or cosine profile + between two zones with zero divergence is typically represented by a factor + of between 0.2 and 0.25. + + \heading Patch usage + + \table + Property | Description | Required | Default value + upstream | upstream face zone name | yes | + downstream | downstream face zone name | yes | + deltaP | desired pressure drop | yes | + shapeFactor | non-linearity in the nozzle | no | 0 + p | pressure field name | no | p + phi | flux field name | yes | phi + rho | density field name | no | none + P | proportional gain | yes | + I | integral gain | yes | + D | differential gain | yes | + \endtable + + Example of the boundary condition specification: + + \verbatim + myPatch + { + type pressurePIDControlInletVelocity; + upstream upstream; + downstream downstream; + deltaP 200; + shapeFactor 0; + p p; + phi phi; + rho none; + P 0.5; + I 0.5; + D 0.1; + value uniform (0 0 0); + } + +SeeAlso + Foam::fixedValueFvPatchField + +SourceFiles + pressurePIDControlInletVelocityFvPatchVectorField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef pressurePIDControlInletVelocityFvPatchVectorField_H +#define pressurePIDControlInletVelocityFvPatchVectorField_H + +#include "fixedValueFvPatchFields.H" +#include "Switch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +/*---------------------------------------------------------------------------*\ + Class pressurePIDControlInletVelocityFvPatchVectorField Declaration +\*---------------------------------------------------------------------------*/ + +class pressurePIDControlInletVelocityFvPatchVectorField +: + public fixedValueFvPatchVectorField +{ + // Private data + + //- Name of the upstream face zone + const word upstreamName_; + + //- Name of the downstream face zone + const word downstreamName_; + + //- Desired pressure difference between upstream and downstream + const scalar deltaP_; + + //- Nozzle shape factor + const scalar shapeFactor_; + + //- Name of the pressure field + const word pName_; + + //- Name of the flux field + const word phiName_; + + //- Name of the density field (if any) + const word rhoName_; + + //- Proportional gain + const scalar P_; + + //- Integral gain + const scalar I_; + + //- Derivative gain + const scalar D_; + + //- Volumetric flow rate + scalar Q_; + + //- Error + scalar error_; + + //- Error integral w.r.t. time + scalar errorIntegral_; + + //- Old volumetric flow rate + scalar oldQ_; + + //- Old error + scalar oldError_; + + //- Old error integral w.r.t. time + scalar oldErrorIntegral_; + + //- Time index of the last update + label timeIndex_; + + + // Private member functions + + //- Return the pressure interpolated to the faces + const surfaceScalarField& facePressure() const; + + //- Calculate the average on a face zone + template <class Type> + void faceZoneAverage + ( + const word& name, + const GeometricField<Type, fvsPatchField, surfaceMesh>& field, + scalar& area, + Type& average + ) const; + + +public: + + //- Runtime type information + TypeName("pressurePIDControlInletVelocity"); + + + // Constructors + + //- Construct from patch and internal field + pressurePIDControlInletVelocityFvPatchVectorField + ( + const fvPatch&, + const DimensionedField<vector, volMesh>& + ); + + //- Construct from patch, internal field and dictionary + pressurePIDControlInletVelocityFvPatchVectorField + ( + const fvPatch&, + const DimensionedField<vector, volMesh>&, + const dictionary& + ); + + //- Construct by mapping given + // flowRateInletVelocityFvPatchVectorField + // onto a new patch + pressurePIDControlInletVelocityFvPatchVectorField + ( + const pressurePIDControlInletVelocityFvPatchVectorField&, + const fvPatch&, + const DimensionedField<vector, volMesh>&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + pressurePIDControlInletVelocityFvPatchVectorField + ( + const pressurePIDControlInletVelocityFvPatchVectorField& + ); + + //- Construct and return a clone + virtual tmp<fvPatchVectorField> clone() const + { + return tmp<fvPatchVectorField> + ( + new pressurePIDControlInletVelocityFvPatchVectorField + ( + *this + ) + ); + } + + //- Construct as copy setting internal field reference + pressurePIDControlInletVelocityFvPatchVectorField + ( + const pressurePIDControlInletVelocityFvPatchVectorField&, + const DimensionedField<vector, volMesh>& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp<fvPatchVectorField> clone + ( + const DimensionedField<vector, volMesh>& iF + ) const + { + return tmp<fvPatchVectorField> + ( + new pressurePIDControlInletVelocityFvPatchVectorField + ( + *this, + iF + ) + ); + } + + + // Member functions + + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(); + + //- Write + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.C b/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.C index 63c718375bf950119b8592ddd0966eb3cc796d64..7d8294b1e68c796c4c51f78a79766c6d3965a333 100644 --- a/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.C +++ b/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -45,7 +45,8 @@ template<class Type, class CombineOp> tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce ( const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf, - const CombineOp& cop + const CombineOp& cop, + const Type& nullValue ) { typedef GeometricField<Type, fvPatchField, volMesh> volFieldType; @@ -65,7 +66,7 @@ tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce IOobject::NO_WRITE ), mesh, - dimensioned<Type>("0", ssf.dimensions(), pTraits<Type>::zero), + dimensioned<Type>("initialValue", ssf.dimensions(), nullValue), zeroGradientFvPatchField<Type>::typeName ) ); @@ -75,15 +76,29 @@ tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce const labelUList& own = mesh.owner(); const labelUList& nbr = mesh.neighbour(); - forAll(own, i) + // Internal field + const Field<Type>& iField = ssf.internalField(); + forAll(iField, faceI) { - label cellI = own[i]; - cop(result[cellI], ssf[i]); + label cellOwn = own[faceI]; + cop(result[cellOwn], iField[faceI]); + + label cellNbr = nbr[faceI]; + cop(result[cellNbr], iField[faceI]); } - forAll(nbr, i) + + // Boundary field + forAll(ssf.boundaryField(), patchI) { - label cellI = nbr[i]; - cop(result[cellI], ssf[i]); + const fvsPatchField<Type>& pf = ssf.boundaryField()[patchI]; + const label start = pf.patch().start(); + + forAll(pf, i) + { + label faceI = start + i; + label cellI = own[faceI]; + cop(result[cellI], pf[i]); + } } result.correctBoundaryConditions(); @@ -96,13 +111,14 @@ template<class Type, class CombineOp> tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce ( const tmp<GeometricField<Type, fvsPatchField, surfaceMesh>&> tssf, - const CombineOp& cop + const CombineOp& cop, + const Type& nullValue ) { tmp<GeometricField<Type, fvPatchField, volMesh> > - tvf(cellReduce(cop, tssf)); + tvf(cellReduce(cop, tssf, nullValue)); - tssf.clear(); + tssf.clear(); return tvf; } diff --git a/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.H b/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.H index 19bd24135af0a4dd75a11ca446192301e0e6443a..d355fd4a51bf9f6c0ea5f4dddc6b0ce3c44fdf29 100644 --- a/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.H +++ b/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -53,14 +53,16 @@ namespace fvc tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce ( const GeometricField<Type, fvsPatchField, surfaceMesh>&, - const CombineOp& cop + const CombineOp& cop, + const Type& nullValue = pTraits<Type>::zero ); template<class Type, class CombineOp> tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce ( const tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >&, - const CombineOp& cop + const CombineOp& cop, + const Type& nullValue = pTraits<Type>::zero ); } diff --git a/src/mesh/extrudeModel/Make/files b/src/mesh/extrudeModel/Make/files index f6c2f50b04edb8f625e1c867315d7369e3890a07..e18ad638e171829cbf7c1e7179b39142b9c7a75f 100644 --- a/src/mesh/extrudeModel/Make/files +++ b/src/mesh/extrudeModel/Make/files @@ -4,6 +4,7 @@ linearNormal/linearNormal.C planeExtrusion/planeExtrusion.C linearDirection/linearDirection.C linearRadial/linearRadial.C +offsetSurface/offsetSurface.C radial/radial.C sigmaRadial/sigmaRadial.C sector/sector.C diff --git a/src/mesh/extrudeModel/Make/options b/src/mesh/extrudeModel/Make/options index eabd0b53a8ffd8a16a228d71ae038fac7e2ea6a2..2dd02e7d86ab8098d1cd1605d70c1bc4423d0bde 100644 --- a/src/mesh/extrudeModel/Make/options +++ b/src/mesh/extrudeModel/Make/options @@ -1,5 +1,6 @@ EXE_INC = \ -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/triSurface/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude LIB_LIBS = \ diff --git a/src/mesh/extrudeModel/offsetSurface/offsetSurface.C b/src/mesh/extrudeModel/offsetSurface/offsetSurface.C new file mode 100644 index 0000000000000000000000000000000000000000..1b2872279f0d08e55956dce9156d030d17329fca --- /dev/null +++ b/src/mesh/extrudeModel/offsetSurface/offsetSurface.C @@ -0,0 +1,165 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2014 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "offsetSurface.H" +#include "addToRunTimeSelectionTable.H" +#include "triSurface.H" +#include "triSurfaceSearch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace extrudeModels +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(offsetSurface, 0); + +addToRunTimeSelectionTable(extrudeModel, offsetSurface, dictionary); + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +offsetSurface::offsetSurface(const dictionary& dict) +: + extrudeModel(typeName, dict), + project_(coeffDict_.lookupOrDefault("project", false)) +{ + // Read surface + fileName baseName(coeffDict_.lookup("baseSurface")); + baseName.expand(); + baseSurfPtr_.reset(new triSurface(baseName)); + + // Construct search engine + baseSearchPtr_.reset(new triSurfaceSearch(baseSurfPtr_())); + + // Read offsetted surface + fileName offsetName(coeffDict_.lookup("offsetSurface")); + offsetName.expand(); + offsetSurfPtr_.reset(new triSurface(offsetName)); + + // Construct search engine + offsetSearchPtr_.reset(new triSurfaceSearch(offsetSurfPtr_())); + + + const triSurface& b = baseSurfPtr_(); + const triSurface& o = offsetSurfPtr_(); + + if + ( + b.size() != o.size() + || b.nPoints() != o.nPoints() + || b.nEdges() != o.nEdges() + ) + { + FatalIOErrorIn("offsetSurface::offsetSurface(const dictionary&)", dict) + << "offsetSurface " << offsetName + << " should have exactly the same topology as the baseSurface " + << baseName << exit(FatalIOError); + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +offsetSurface::~offsetSurface() +{} + + +// * * * * * * * * * * * * * * * * Operators * * * * * * * * * * * * * * * * // + +point offsetSurface::operator() +( + const point& surfacePoint, + const vector& surfaceNormal, + const label layer +) const +{ + if (layer == 0) + { + return surfacePoint; + } + else + { + pointField samples(1, surfacePoint); + scalarField nearestDistSqr(1, GREAT); + List<pointIndexHit> info; + baseSearchPtr_().findNearest(samples, nearestDistSqr, info); + + label triI = info[0].index(); + + + const triSurface& base = baseSurfPtr_(); + const triPointRef baseTri(base[triI].tri(base.points())); + + List<scalar> bary; + baseTri.barycentric(surfacePoint, bary); + + const triSurface& offset = offsetSurfPtr_(); + const triPointRef offsetTri(offset[triI].tri(offset.points())); + + const point offsetPoint + ( + bary[0]*offsetTri.a() + +bary[1]*offsetTri.b() + +bary[2]*offsetTri.c() + ); + + point interpolatedPoint + ( + surfacePoint + sumThickness(layer)*(offsetPoint-surfacePoint) + ); + + + //- Either return interpolatedPoint or re-project onto surface (since + // snapping might not have do so exactly) + + if (project_) + { + // Re-project onto surface + offsetSearchPtr_().findNearest + ( + pointField(1, interpolatedPoint), + scalarField(1, GREAT), + info + ); + return info[0].hitPoint(); + } + else + { + return interpolatedPoint; + } + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace extrudeModels +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/mesh/extrudeModel/offsetSurface/offsetSurface.H b/src/mesh/extrudeModel/offsetSurface/offsetSurface.H new file mode 100644 index 0000000000000000000000000000000000000000..f5df55cfd8d6859a89b7ff9abdf14489dcab7966 --- /dev/null +++ b/src/mesh/extrudeModel/offsetSurface/offsetSurface.H @@ -0,0 +1,114 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2014 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::extrudeModels::offsetSurface + +Description + Extrudes by interpolating points from one surface to the other. Surfaces + have to be topologically identical i.e. one has to be an offsetted version + of the other. + +\*---------------------------------------------------------------------------*/ + +#ifndef offsetSurface_H +#define offsetSurface_H + +#include "point.H" +#include "extrudeModel.H" +#include "Switch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class triSurface; +class triSurfaceSearch; + + +namespace extrudeModels +{ + +/*---------------------------------------------------------------------------*\ + Class offsetSurface Declaration +\*---------------------------------------------------------------------------*/ + +class offsetSurface +: + public extrudeModel +{ + // Private data + + //- surface + autoPtr<triSurface> baseSurfPtr_; + + //- search engine + autoPtr<triSurfaceSearch> baseSearchPtr_; + + //- offsets + autoPtr<triSurface> offsetSurfPtr_; + + //- search engine + autoPtr<triSurfaceSearch> offsetSearchPtr_; + + // Whether to re-project onto offsetted surface + const Switch project_; + +public: + + //- Runtime type information + TypeName("offsetSurface"); + + // Constructors + + //- Construct from dictionary + offsetSurface(const dictionary& dict); + + + //- Destructor + virtual ~offsetSurface(); + + + // Member Operators + + //- Return point + point operator() + ( + const point& surfacePoint, + const vector& surfaceNormal, + const label layer + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace extrudeModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.C b/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.C index cb3cfc7d5a91f4b21056cb55086938baa2e3fd38..9c5055de5d0f9ad38f21443a35af605d5ce7aa32 100644 --- a/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.C +++ b/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2014 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -49,7 +49,8 @@ Foam::partialWrite::partialWrite ) : name_(name), - obr_(obr) + obr_(obr), + log_(true) { read(dict); } @@ -65,16 +66,39 @@ Foam::partialWrite::~partialWrite() void Foam::partialWrite::read(const dictionary& dict) { + log_.readIfPresent("log", dict); dict.lookup("objectNames") >> objectNames_; dict.lookup("writeInterval") >> writeInterval_; writeInstance_ = 0; - Info<< type() << " " << name() << ":" << nl - << " dumping every " << writeInterval_ - << " th outputTime : " << nl << endl ; - forAllConstIter(HashSet<word>, objectNames_, iter) + if (log_) { - Info<< ' ' << iter.key(); + Info<< type() << " " << name() << ":" << nl + << " dumping every outputTime :"; + + forAllConstIter(HashSet<word>, objectNames_, iter) + { + Info<< ' ' << iter.key(); + } + + word postStr = ""; + if (writeInterval_ == 2) + { + postStr = "nd "; + } + else if (writeInterval_ == 3) + { + postStr = "rd "; + } + else + { + postStr = "th "; + } + + Info<< nl + << " dumping all other fields every " + << writeInterval_ << postStr << " outputTime" << nl + << endl; } if (writeInterval_ < 1) diff --git a/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.H b/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.H index 09197a671d84e4aa9108b8bdad8a381b02a76465..95c3f2f5000e78c621dceb866a2c1c45186dea67 100644 --- a/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.H +++ b/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -50,6 +50,7 @@ Description type | type name: partialWrite | yes | objectNames | objects to write | yes | writeInterval | write interval | yes | + log | Log to standard output | no | yes \endtable SeeAlso @@ -91,11 +92,15 @@ protected: // Private data - //- Name of this set of partialWrite + //- Name of this set of partialWrite object word name_; + //- Refefence to the database const objectRegistry& obr_; + //- Switch to send output to Info as well as to file + Switch log_; + //- Loaded fields UPtrList<volScalarField> vsf_; UPtrList<volVectorField> vvf_; diff --git a/src/postProcessing/functionObjects/IO/partialWrite/partialWriteTemplates.C b/src/postProcessing/functionObjects/IO/partialWrite/partialWriteTemplates.C index 56e00893131b54fcdb7315f063e417faab71dc1b..16551f4b79d1aeb08affecb156712a7c09be9455 100644 --- a/src/postProcessing/functionObjects/IO/partialWrite/partialWriteTemplates.C +++ b/src/postProcessing/functionObjects/IO/partialWrite/partialWriteTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -68,7 +68,7 @@ void Foam::partialWrite::loadField << " found in database" << endl; } - sfType& sField = + sfType& sField = const_cast<sfType&> ( obr_.lookupObject<sfType>(fieldName) diff --git a/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.C b/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.C index 28bb18292eb5ba423f00f42f863c8b04f797a651..fee807a9a63ec7eaf663a4f2a310120860bb6299 100644 --- a/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.C +++ b/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,7 +31,7 @@ License namespace Foam { -defineTypeNameAndDebug(removeRegisteredObject, 0); + defineTypeNameAndDebug(removeRegisteredObject, 0); } @@ -47,7 +47,8 @@ Foam::removeRegisteredObject::removeRegisteredObject : name_(name), obr_(obr), - objectNames_() + objectNames_(), + log_(true) { read(dict); } @@ -78,7 +79,8 @@ void Foam::removeRegisteredObject::execute() if (obj.ownedByRegistry()) { - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " removing object " << obj.name() << nl << endl; diff --git a/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.H b/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.H index fc02432ad89c246a840a64cd2e7e9bce87ee4584..42aa1f3546366553ef08bb3846ac2ee9bdafce4f 100644 --- a/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.H +++ b/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -46,6 +46,7 @@ Description Property | Description | Required | Default value type | type name: removeRegisteredObject | yes | objectNames | objects to remove | yes | + log | Log to standard output | no | yes \endtable SeeAlso @@ -63,6 +64,7 @@ SourceFiles #include "wordList.H" #include "runTimeSelectionTables.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -85,9 +87,10 @@ protected: // Private data - //- Name of this set of removeRegisteredObject + //- Name of this set of removeRegisteredObject object word name_; + //- Refefence to the database const objectRegistry& obr_; // Read from dictionary @@ -95,6 +98,9 @@ protected: //- Names of objects to control wordList objectNames_; + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.C b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.C index 81b58a1a5cdfdf800112297ca347c923b7753b6e..f450c11093c7bdb85a3e60675499c9f49858f74e 100644 --- a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.C +++ b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.C @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -48,7 +48,8 @@ Foam::writeRegisteredObject::writeRegisteredObject name_(name), exclusiveWriting_(false), obr_(obr), - objectNames_() + objectNames_(), + log_(true) { read(dict); } @@ -64,6 +65,8 @@ Foam::writeRegisteredObject::~writeRegisteredObject() void Foam::writeRegisteredObject::read(const dictionary& dict) { + log_.readIfPresent("log", dict); + dict.lookup("objectNames") >> objectNames_; dict.readIfPresent("exclusiveWriting", exclusiveWriting_); } @@ -89,7 +92,7 @@ void Foam::writeRegisteredObject::timeSet() void Foam::writeRegisteredObject::write() { - Info<< type() << " " << name_ << " output:" << nl; + if (log_) Info<< type() << " " << name_ << " output:" << nl; DynamicList<word> allNames(obr_.toc().size()); forAll(objectNames_, i) @@ -123,7 +126,7 @@ void Foam::writeRegisteredObject::write() obj.writeOpt() = IOobject::NO_WRITE; } - Info<< " writing object " << obj.name() << nl << endl; + if (log_) Info<< " writing object " << obj.name() << nl << endl; obj.write(); } diff --git a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H index d08dc7c914c5d97a1cd574563e08f863650135fe..c3f282bfa576e03dd961bb9ea9dcf4f3879fd0e2 100644 --- a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H +++ b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -30,13 +30,13 @@ Group Description This function object allows specification of different writing frequency of objects registered to the database. It has similar functionality - as the main time database through the outputControl setting: - timeStep - outputTime - adjustableTime - runTime - clockTime - cpuTime + as the main time database through the \c outputControl setting: + - timeStep + - outputTime + - adjustableTime + - runTime + - clockTime + - cpuTime Example of function object specification: \verbatim @@ -56,6 +56,7 @@ Description type | type name: writeRegisteredObject | yes | objectNames | objects to write | yes | exclusiveWriting | Takes over object writing | no | yes + log | Log to standard output | no | yes \endtable exclusiveWriting disables automatic writing (i.e through database) of the @@ -76,6 +77,7 @@ SourceFiles #include "wordReList.H" #include "runTimeSelectionTables.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -104,7 +106,7 @@ protected: //- Takes over the writing from Db bool exclusiveWriting_; - //- Refererence to Db + //- Refererence to the database const objectRegistry& obr_; // Read from dictionary @@ -112,6 +114,9 @@ protected: //- Names of objects to control wordReList objectNames_; + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C b/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C index fd58741bd7419a3aa5d40cd19aacde1361b35c22..fabdc11b756e5b9c674df6166b3f2b31c0e10eee 100644 --- a/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C +++ b/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C @@ -172,16 +172,14 @@ void Foam::cloudInfo::write() << endl; } - if (log_) - { - Info<< type() << " " << name_ << " output:" << nl - << " number of parcels : " << nParcels << nl - << " mass in system : " << massInSystem << nl - << " maximum diameter : " << Dmax << nl - << " D10 diameter : " << D10 << nl - << " D32 diameter : " << D32 << nl - << endl; - } + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " number of parcels : " << nParcels << nl + << " mass in system : " << massInSystem << nl + << " maximum diameter : " << Dmax << nl + << " D10 diameter : " << D10 << nl + << " D32 diameter : " << D32 << nl + << endl; } } } diff --git a/src/postProcessing/functionObjects/doc/functionObjects.dox b/src/postProcessing/functionObjects/doc/functionObjects.dox index dc0b395fe8c3efb6b17360e24de7b5c47f8205ec..5651f5554510aae50a6ea424b7bbbc17c8af3c0a 100644 --- a/src/postProcessing/functionObjects/doc/functionObjects.dox +++ b/src/postProcessing/functionObjects/doc/functionObjects.dox @@ -40,6 +40,7 @@ The current range of features comprises of: - \ref grpFieldFunctionObjects - \ref grpForcesFunctionObjects - \ref grpFVFunctionObjects +- \ref grpGraphicsFunctionObjects - \ref grpIOFunctionObjects - \ref grpJobControlFunctionObjects - \ref grpUtilitiesFunctionObjects diff --git a/src/postProcessing/functionObjects/field/Make/files b/src/postProcessing/functionObjects/field/Make/files index 75464c40139f6cd10a231b39aa23a81f4fbbf873..3f2b8f9f50c4c31aa4ae522d16474e2997ebc229 100644 --- a/src/postProcessing/functionObjects/field/Make/files +++ b/src/postProcessing/functionObjects/field/Make/files @@ -30,20 +30,24 @@ readFields/readFields.C readFields/readFieldsFunctionObject.C streamLine/streamLine.C +streamLine/streamLineBase.C streamLine/streamLineParticle.C streamLine/streamLineParticleCloud.C streamLine/streamLineFunctionObject.C -wallBoundedStreamLine/wallBoundedStreamLine.C -wallBoundedStreamLine/wallBoundedStreamLineFunctionObject.C -wallBoundedStreamLine/wallBoundedStreamLineParticle.C -wallBoundedStreamLine/wallBoundedStreamLineParticleCloud.C -wallBoundedStreamLine/wallBoundedParticle.C - surfaceInterpolateFields/surfaceInterpolateFields.C surfaceInterpolateFields/surfaceInterpolateFieldsFunctionObject.C regionSizeDistribution/regionSizeDistribution.C regionSizeDistribution/regionSizeDistributionFunctionObject.C +valueAverage/valueAverage.C +valueAverage/valueAverageFunctionObject.C + +wallBoundedStreamLine/wallBoundedStreamLine.C +wallBoundedStreamLine/wallBoundedStreamLineFunctionObject.C +wallBoundedStreamLine/wallBoundedStreamLineParticle.C +wallBoundedStreamLine/wallBoundedStreamLineParticleCloud.C +wallBoundedStreamLine/wallBoundedParticle.C + LIB = $(FOAM_LIBBIN)/libfieldFunctionObjects diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C index 5652904ffa30b7df27e6d0971ef16709c2400aea..08dcd5aa732c9691068952f72e722a748fcfb227 100644 --- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C +++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C @@ -124,11 +124,9 @@ void Foam::fieldAverage::calcAverages() prevTimeIndex_ = currentTimeIndex; } - if (log_) - { - Info<< type() << " " << name_ << " output:" << nl - << " Calculating averages" << nl; - } + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " Calculating averages" << nl; addMeanSqrToPrime2Mean<scalar, scalar>(); addMeanSqrToPrime2Mean<vector, symmTensor>(); @@ -204,21 +202,17 @@ void Foam::fieldAverage::readAveragingProperties() totalIter_[fieldI] = readLabel(fieldDict.lookup("totalIter")); totalTime_[fieldI] = readScalar(fieldDict.lookup("totalTime")); - if (log_) - { - Info<< " " << fieldName - << " iters = " << totalIter_[fieldI] - << " time = " << totalTime_[fieldI] << nl; - } + if (log_) Info + << " " << fieldName + << " iters = " << totalIter_[fieldI] + << " time = " << totalTime_[fieldI] << nl; } else { - if (log_) - { - Info<< " " << fieldName - << ": starting averaging at time " - << obr_.time().timeName() << endl; - } + if (log_) Info + << " " << fieldName + << ": starting averaging at time " + << obr_.time().timeName() << endl; } } } @@ -315,11 +309,9 @@ void Foam::fieldAverage::write() if (resetOnOutput_) { - if (log_) - { - Info<< " Restarting averaging at time " << obr_.time().timeName() - << nl << endl; - } + if (log_) Info + << " Restarting averaging at time " << obr_.time().timeName() + << nl << endl; totalIter_.clear(); totalIter_.setSize(faItems_.size(), 1); diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C index 4f3a2d7cab670b971b0bac60ffb5d30f5ce69f10..2e20c4ab0195723ac6cde1a3aedfb934b3227404 100644 --- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C @@ -46,12 +46,10 @@ void Foam::fieldAverage::addMeanFieldType(const label fieldI) } else if (obr_.found(meanFieldName)) { - if (log_) - { - Info<< " Cannot allocate average field " << meanFieldName - << " since an object with that name already exists." - << " Disabling averaging for field." << endl; - } + if (log_) Info + << " Cannot allocate average field " << meanFieldName + << " since an object with that name already exists." + << " Disabling averaging for field." << endl; faItems_[fieldI].mean() = false; } @@ -110,10 +108,8 @@ void Foam::fieldAverage::addPrime2MeanFieldType(const label fieldI) const word& meanFieldName = faItems_[fieldI].meanFieldName(); const word& prime2MeanFieldName = faItems_[fieldI].prime2MeanFieldName(); - if (log_) - { - Info << " Reading/initialising field " << prime2MeanFieldName << nl; - } + if (log_) Info + << " Reading/initialising field " << prime2MeanFieldName << endl; if (obr_.foundObject<Type2>(prime2MeanFieldName)) { @@ -121,12 +117,10 @@ void Foam::fieldAverage::addPrime2MeanFieldType(const label fieldI) } else if (obr_.found(prime2MeanFieldName)) { - if (log_) - { - Info<< " Cannot allocate average field " << prime2MeanFieldName - << " since an object with that name already exists." - << " Disabling averaging for field." << nl; - } + if (log_) Info + << " Cannot allocate average field " << prime2MeanFieldName + << " since an object with that name already exists." + << " Disabling averaging for field." << endl; faItems_[fieldI].prime2Mean() = false; } diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C index 4e30b881ca63036130f5c1c53171220aef266c66..844a15cb36551ab4192a289bb2cbec364e6fecd8 100644 --- a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C +++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C @@ -48,14 +48,16 @@ Foam::fieldCoordinateSystemTransform::fieldCoordinateSystemTransform obr_(obr), active_(true), fieldSet_(), - coordSys_(obr, dict) + coordSys_(obr, dict), + log_(true) { // Check if the available mesh is an fvMesh otherise deactivate if (isA<fvMesh>(obr_)) { read(dict); - Info<< type() << " " << name_ << ":" << nl + if (log_) Info + << type() << " " << name_ << ":" << nl << " Applying transformation from global Cartesian to local " << coordSys_ << nl << endl; } @@ -89,6 +91,7 @@ void Foam::fieldCoordinateSystemTransform::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); dict.lookup("fields") >> fieldSet_; } } @@ -98,7 +101,7 @@ void Foam::fieldCoordinateSystemTransform::execute() { if (active_) { - Info<< type() << " " << name_ << " output:" << nl; + if (log_) Info<< type() << " " << name_ << " output:" << nl; forAll(fieldSet_, fieldI) { @@ -132,7 +135,7 @@ void Foam::fieldCoordinateSystemTransform::write() { if (active_) { - Info<< type() << " " << name_ << " output:" << nl; + if (log_) Info<< type() << " " << name_ << " output:" << nl; forAll(fieldSet_, fieldI) { @@ -141,12 +144,12 @@ void Foam::fieldCoordinateSystemTransform::write() const regIOobject& field = obr_.lookupObject<regIOobject>(fieldName); - Info<< " writing field " << field.name() << nl; + if (log_) Info << " writing field " << field.name() << nl; field.write(); } - Info<< endl; + if (log_) Info<< endl; } } diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H index edd1f13b502437f9d545a0e26ecb5689d83d1f85..f18e90ca05e65bb902b1630bb3e767786e3b5f84 100644 --- a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H +++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -60,6 +60,7 @@ Description type | type name: fieldCoordinateSystemTransform | yes | fields | list of fields to be transformed |yes | coordinateSystem | local co-ordinate system | yes | + log | Log to standard output | no | yes \endtable SeeAlso @@ -117,6 +118,9 @@ protected: //- Co-ordinate system to transform to coordinateSystem coordSys_; + //- Switch to send output to Info as well as to file + Switch log_; + // Protected Member Functions diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C index 627414b9e4e29d61925f598373c7eeedf5608738..d56aa1e71af45f896ab1777bfadacb3dd4a7aa1e 100644 --- a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -67,7 +67,7 @@ void Foam::fieldCoordinateSystemTransform::transformField Foam::transform(transField, R, transField); - Info<< " writing field " << transField.name() << nl << endl; + if (log_) Info<< " writing field " << transField.name() << nl << endl; transField.write(); } diff --git a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C index 6e8db76804f50f5a30e76cfe9b231f4525e9d69b..a255ed8b188f118c91e30eb5d179bae101eca648 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C +++ b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C @@ -144,14 +144,12 @@ void Foam::fieldValues::cellSource::initialise(const dictionary& dict) volume_ = volume(); - if (log_) - { - Info<< type() << " " << name_ << ":" - << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl - << " total cells = " << nCells_ << nl - << " total volume = " << volume_ - << nl << endl; - } + if (log_) Info + << type() << " " << name_ << ":" + << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl + << " total cells = " << nCells_ << nl + << " total volume = " << volume_ + << nl << endl; if (dict.readIfPresent("weightField", weightFieldName_)) { diff --git a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C index f6f67d55e620a50efc74afb2680fed7c3879183b..28102fc892c026d86f9714bd52dddc137c60db03 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C @@ -217,12 +217,10 @@ bool Foam::fieldValues::cellSource::writeValues file()<< tab << result; - if (log_) - { - Info<< " " << operationTypeNames_[operation_] - << "(" << sourceName_ << ") of " << fieldName - << " = " << result << endl; - } + if (log_) Info + << " " << operationTypeNames_[operation_] + << "(" << sourceName_ << ") of " << fieldName + << " = " << result << endl; // write state/results information const word& opName = operationTypeNames_[operation_]; diff --git a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C index 1598eb881fac32047c25c10567bdf8711e075722..504f4a7d1585ca907a66a2ff81edd42b4c4616cd 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C @@ -366,12 +366,10 @@ bool Foam::fieldValues::faceSource::writeValues file()<< tab << result; - if (log_) - { - Info<< " " << operationTypeNames_[operation_] - << "(" << sourceName_ << ") for " << fieldName - << " = " << result << endl; - } + if (log_) Info + << " " << operationTypeNames_[operation_] + << "(" << sourceName_ << ") for " << fieldName + << " = " << result << endl; // Write state/results information const word& opName = operationTypeNames_[operation_]; diff --git a/src/postProcessing/functionObjects/field/nearWallFields/nearWallFields.H b/src/postProcessing/functionObjects/field/nearWallFields/nearWallFields.H index 014313b2aad3129775db79822811d97135206752..9fcfa0ccee4bb7ac709a8711dc228928fcddb500 100644 --- a/src/postProcessing/functionObjects/field/nearWallFields/nearWallFields.H +++ b/src/postProcessing/functionObjects/field/nearWallFields/nearWallFields.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -55,9 +55,10 @@ Description \table Property | Description | Required | Default value type | type name: nearWallFields | yes | - fields | list of fields with correspoding output field names | yes | + fields | list of fields with corresponding output field names | yes | patches | list of patches to sample | yes | distance | distance from patch to sample | yes | + log | Log to standard output | no | yes \endtable SeeAlso @@ -111,6 +112,9 @@ protected: //- Fields to process List<Tuple2<word, word> > fieldSet_; + //- Switch to send output to Info as well as to file + Switch log_; + //- Patches to sample labelHashSet patchSet_; diff --git a/src/postProcessing/functionObjects/field/nearWallFields/nearWallFieldsTemplates.C b/src/postProcessing/functionObjects/field/nearWallFields/nearWallFieldsTemplates.C index 42b1b2abef16bae5e1b093897e786a1f584f2e1d..ab7fe8878727dafaf1568f9c6abacf6f0171508e 100644 --- a/src/postProcessing/functionObjects/field/nearWallFields/nearWallFieldsTemplates.C +++ b/src/postProcessing/functionObjects/field/nearWallFields/nearWallFieldsTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -47,8 +47,15 @@ void Foam::nearWallFields::createFields if (obr_.found(sampleFldName)) { - Info<< " a field " << sampleFldName - << " already exists on the mesh." + WarningIn + ( + "void Foam::nearWallFields::createFields" + "(" + "PtrList<GeometricField<Type, fvPatchField, volMesh> >&" + ") const" + ) + << " a field named " << sampleFldName + << " already exists on the mesh" << endl; } else @@ -63,7 +70,8 @@ void Foam::nearWallFields::createFields sflds.set(sz, new vfType(io, fld)); - Info<< " created " << sflds[sz].name() << " to sample " + if (log_) Info + << " created " << sflds[sz].name() << " to sample " << fld.name() << endl; } } diff --git a/src/postProcessing/functionObjects/field/processorField/processorField.C b/src/postProcessing/functionObjects/field/processorField/processorField.C index a57ee9a293026fa8c7ed30f13ebc12e716911192..73b7a89978739f76495b8f4d593307bbaf131722 100644 --- a/src/postProcessing/functionObjects/field/processorField/processorField.C +++ b/src/postProcessing/functionObjects/field/processorField/processorField.C @@ -47,7 +47,9 @@ Foam::processorField::processorField : name_(name), obr_(obr), - active_(true) + active_(true), + resultName_(name), + log_(true) { // Check if the available mesh is an fvMesh otherise deactivate if (isA<fvMesh>(obr_)) @@ -62,7 +64,7 @@ Foam::processorField::processorField ( IOobject ( - "processorID", + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -103,7 +105,10 @@ Foam::processorField::~processorField() void Foam::processorField::read(const dictionary& dict) { - // do nothing + if (active_) + { + log_.readIfPresent("log", dict); + } } @@ -112,7 +117,7 @@ void Foam::processorField::execute() if (active_) { const volScalarField& procField = - obr_.lookupObject<volScalarField>("processorID"); + obr_.lookupObject<volScalarField>(resultName_); const_cast<volScalarField&>(procField) == dimensionedScalar("procI", dimless, Pstream::myProcNo()); @@ -140,7 +145,12 @@ void Foam::processorField::write() if (active_) { const volScalarField& procField = - obr_.lookupObject<volScalarField>("processorID"); + obr_.lookupObject<volScalarField>(resultName_); + + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " writing field " << procField.name() << nl + << endl; procField.write(); } diff --git a/src/postProcessing/functionObjects/field/processorField/processorField.H b/src/postProcessing/functionObjects/field/processorField/processorField.H index 6d45e32acbc71c49f9333617f30dd63a808e111a..560c302e92cc4e355881bb68a45205a631e1f101 100644 --- a/src/postProcessing/functionObjects/field/processorField/processorField.H +++ b/src/postProcessing/functionObjects/field/processorField/processorField.H @@ -45,6 +45,7 @@ Description \table Property | Description | Required | Default value type | type name: processorField | yes | + log | Log to standard output | no | yes \endtable SeeAlso @@ -95,6 +96,12 @@ protected: //- on/off switch bool active_; + //- Result name + word resultName_; + + //- Switch to send output to Info as well as to file + Switch log_; + // Protected Member Functions diff --git a/src/postProcessing/functionObjects/field/readFields/readFields.C b/src/postProcessing/functionObjects/field/readFields/readFields.C index 869f46beb013da8a1b89a0b2f4e638e516fd97a6..6bac8da6d49f2baf2ec3a9e73eb9a524339eb544 100644 --- a/src/postProcessing/functionObjects/field/readFields/readFields.C +++ b/src/postProcessing/functionObjects/field/readFields/readFields.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -47,7 +47,8 @@ Foam::readFields::readFields name_(name), obr_(obr), active_(true), - fieldSet_() + fieldSet_(), + log_(true) { // Check if the available mesh is an fvMesh otherise deactivate if (isA<fvMesh>(obr_)) @@ -84,6 +85,7 @@ void Foam::readFields::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); dict.lookup("fields") >> fieldSet_; } } @@ -93,29 +95,16 @@ void Foam::readFields::execute() { if (active_) { - // Clear out any previously loaded fields - vsf_.clear(); - vvf_.clear(); - vSpheretf_.clear(); - vSymmtf_.clear(); - vtf_.clear(); - - ssf_.clear(); - svf_.clear(); - sSpheretf_.clear(); - sSymmtf_.clear(); - stf_.clear(); - forAll(fieldSet_, fieldI) { const word& fieldName = fieldSet_[fieldI]; // If necessary load field - loadField<scalar>(fieldName, vsf_, ssf_); - loadField<vector>(fieldName, vvf_, svf_); - loadField<sphericalTensor>(fieldName, vSpheretf_, sSpheretf_); - loadField<symmTensor>(fieldName, vSymmtf_, sSymmtf_); - loadField<tensor>(fieldName, vtf_, stf_); + loadField<scalar>(fieldName); + loadField<vector>(fieldName); + loadField<sphericalTensor>(fieldName); + loadField<symmTensor>(fieldName); + loadField<tensor>(fieldName); } } } diff --git a/src/postProcessing/functionObjects/field/readFields/readFields.H b/src/postProcessing/functionObjects/field/readFields/readFields.H index bf13dac4e4fb388167c06c342b99ed5b973c134e..be1d012783d42ec3cdafa81dbc1b344e0b7cd0a6 100644 --- a/src/postProcessing/functionObjects/field/readFields/readFields.H +++ b/src/postProcessing/functionObjects/field/readFields/readFields.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,8 +28,8 @@ Group grpFieldFunctionObjects Description - This function object reads fields from the time directories and adds them to - the mesh database for further post-processing. + This function object reads fields from the time directories and adds them + to the mesh database for further post-processing. Example of function object specification: \verbatim @@ -38,11 +38,7 @@ Description type readFields; functionObjectLibs ("libfieldFunctionObjects.so"); ... - fields - ( - U - p - ); + fields (U p); } \endverbatim @@ -51,6 +47,7 @@ Description Property | Description | Required | Default value type | type name: readFields | yes | fields | list of fields to read | no | + log | Log to standard output | no | yes \endtable SeeAlso @@ -102,18 +99,8 @@ protected: //- Fields to load wordList fieldSet_; - //- Loaded fields - PtrList<volScalarField> vsf_; - PtrList<volVectorField> vvf_; - PtrList<volSphericalTensorField> vSpheretf_; - PtrList<volSymmTensorField> vSymmtf_; - PtrList<volTensorField> vtf_; - - PtrList<surfaceScalarField> ssf_; - PtrList<surfaceVectorField> svf_; - PtrList<surfaceSphericalTensorField> sSpheretf_; - PtrList<surfaceSymmTensorField> sSymmtf_; - PtrList<surfaceTensorField> stf_; + //- Switch to send output to Info as well as to file + Switch log_; // Protected Member Functions @@ -125,12 +112,7 @@ protected: void operator=(const readFields&); template<class Type> - void loadField - ( - const word&, - PtrList<GeometricField<Type, fvPatchField, volMesh> >&, - PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >& - ) const; + void loadField(const word&) const; public: diff --git a/src/postProcessing/functionObjects/field/readFields/readFieldsTemplates.C b/src/postProcessing/functionObjects/field/readFields/readFieldsTemplates.C index 0d7a89bc003f767c358dd152ed482f4bf8379037..57973a1da62a635ef3a4c9a7f09573d0fe7c015c 100644 --- a/src/postProcessing/functionObjects/field/readFields/readFieldsTemplates.C +++ b/src/postProcessing/functionObjects/field/readFields/readFieldsTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,12 +31,7 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // template<class Type> -void Foam::readFields::loadField -( - const word& fieldName, - PtrList<GeometricField<Type, fvPatchField, volMesh> >& vflds, - PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >& sflds -) const +void Foam::readFields::loadField(const word& fieldName) const { typedef GeometricField<Type, fvPatchField, volMesh> vfType; typedef GeometricField<Type, fvsPatchField, surfaceMesh> sfType; @@ -45,7 +40,8 @@ void Foam::readFields::loadField { if (debug) { - Info<< "readFields : Field " << fieldName << " already in database" + Info<< "readFields: " << vfType::typeName << " " + << fieldName << " already exists in database" << endl; } } @@ -53,7 +49,8 @@ void Foam::readFields::loadField { if (debug) { - Info<< "readFields : Field " << fieldName << " already in database" + Info<< "readFields: " << sfType::typeName << " " + << fieldName << " already exists in database" << endl; } } @@ -76,11 +73,10 @@ void Foam::readFields::loadField && fieldHeader.headerClassName() == vfType::typeName ) { - // store field locally - Info<< " Reading " << fieldName << endl; - label sz = vflds.size(); - vflds.setSize(sz+1); - vflds.set(sz, new vfType(fieldHeader, mesh)); + // Store field on mesh database + if (log_) Info<< " Reading " << fieldName << endl; + vfType* vfPtr = new vfType(fieldHeader, mesh); + mesh.objectRegistry::store(vfPtr); } else if ( @@ -88,11 +84,10 @@ void Foam::readFields::loadField && fieldHeader.headerClassName() == sfType::typeName ) { - // store field locally - Info<< " Reading " << fieldName << endl; - label sz = sflds.size(); - sflds.setSize(sz+1); - sflds.set(sz, new sfType(fieldHeader, mesh)); + // Store field on mesh database + if (log_) Info<< " Reading " << fieldName << endl; + sfType* sfPtr = new sfType(fieldHeader, mesh); + mesh.objectRegistry::store(sfPtr); } } } diff --git a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C index 809d1d35b225f94a35024e3d8826c7d90d958caa..b71b0b44abd97e8cedd3009f2853231f65458590 100644 --- a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C +++ b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C @@ -72,11 +72,9 @@ void Foam::regionSizeDistribution::writeGraph OFstream str(outputPath/formatterPtr_().getFileName(coords, valNames)); - if (log_) - { - Info<< "Writing distribution of " << valueName << " to " << str.name() - << endl; - } + if (log_) Info + << "Writing distribution of " << valueName << " to " << str.name() + << endl; List<const scalarField*> valPtrs(1); valPtrs[0] = &values; @@ -162,16 +160,12 @@ void Foam::regionSizeDistribution::writeAlphaFields << endl; } - if (log_) - { - Info<< "Writing liquid-core field to " << liquidCore.name() << endl; - } + if (log_) Info + << "Writing liquid-core field to " << liquidCore.name() << endl; liquidCore.write(); - if (log_) - { - Info<< "Writing background field to " << backgroundAlpha.name() << endl; - } + if (log_) Info + << "Writing background field to " << backgroundAlpha.name() << endl; backgroundAlpha.write(); } @@ -398,11 +392,9 @@ void Foam::regionSizeDistribution::read(const dictionary& dict) { coordSysPtr_.reset(new coordinateSystem(obr_, dict)); - if (log_) - { - Info<< "Transforming all vectorFields with coordinate system " - << coordSysPtr_().name() << endl; - } + if (log_) Info + << "Transforming all vectorFields with coordinate system " + << coordSysPtr_().name() << endl; } } } @@ -467,24 +459,20 @@ void Foam::regionSizeDistribution::write() : obr_.lookupObject<volScalarField>(alphaName_) ); - if (log_) - { - Info<< " Volume of alpha = " - << fvc::domainIntegrate(alpha).value() - << endl; - } + if (log_) Info + << " Volume of alpha = " + << fvc::domainIntegrate(alpha).value() + << endl; const scalar meshVol = gSum(mesh.V()); const scalar maxDropletVol = 1.0/6.0*pow(maxDiam_, 3); const scalar delta = (maxDiam_-minDiam_)/nBins_; - if (log_) - { - Info<< " Mesh volume = " << meshVol << nl - << " Maximum droplet diameter = " << maxDiam_ << nl - << " Maximum droplet volume = " << maxDropletVol - << endl; - } + if (log_) Info + << " Mesh volume = " << meshVol << nl + << " Maximum droplet diameter = " << maxDiam_ << nl + << " Maximum droplet volume = " << maxDropletVol + << endl; // Determine blocked faces @@ -543,11 +531,9 @@ void Foam::regionSizeDistribution::write() regionSplit regions(mesh, blockedFace); - if (log_) - { - Info<< " Determined " << regions.nRegions() - << " disconnected regions" << endl; - } + if (log_) Info + << " Determined " << regions.nRegions() + << " disconnected regions" << endl; if (debug) @@ -566,12 +552,9 @@ void Foam::regionSizeDistribution::write() dimensionedScalar("zero", dimless, 0) ); - if (log_) - { - Info<< " Dumping region as " << volScalarField::typeName - << " to " << region.name() - << endl; - } + if (log_) Info + << " Dumping region as " << volScalarField::typeName + << " to " << region.name() << endl; forAll(regions, cellI) { @@ -602,14 +585,12 @@ void Foam::regionSizeDistribution::write() if (debug) { - if (log_) - { - Info<< " " << token::TAB << "Region" - << token::TAB << "Volume(mesh)" - << token::TAB << "Volume(" << alpha.name() << "):" - << token::TAB << "nCells" - << endl; - } + if (log_) Info + << " " << token::TAB << "Region" + << token::TAB << "Volume(mesh)" + << token::TAB << "Volume(" << alpha.name() << "):" + << token::TAB << "nCells" + << endl; scalar meshSumVol = 0.0; scalar alphaSumVol = 0.0; @@ -626,28 +607,24 @@ void Foam::regionSizeDistribution::write() ++vIter, ++aIter, ++numIter ) { - if (log_) - { - Info<< " " << token::TAB << vIter.key() - << token::TAB << vIter() - << token::TAB << aIter() - << token::TAB << numIter() - << endl; - } + if (log_) Info + << " " << token::TAB << vIter.key() + << token::TAB << vIter() + << token::TAB << aIter() + << token::TAB << numIter() + << endl; meshSumVol += vIter(); alphaSumVol += aIter(); nCells += numIter(); } - if (log_) - { - Info<< " " << token::TAB << "Total:" - << token::TAB << meshSumVol - << token::TAB << alphaSumVol - << token::TAB << nCells - << nl << endl; - } + if (log_) Info + << " " << token::TAB << "Total:" + << token::TAB << meshSumVol + << token::TAB << alphaSumVol + << token::TAB << nCells + << nl << endl; } @@ -876,13 +853,10 @@ void Foam::regionSizeDistribution::write() if (coordSysPtr_.valid()) { - if (log_) - { - Info<< "Transforming vector field " << fldName - << " with coordinate system " - << coordSysPtr_().name() - << endl; - } + if (log_) Info + << "Transforming vector field " << fldName + << " with coordinate system " + << coordSysPtr_().name() << endl; fld = coordSysPtr_().localVector(fld); } diff --git a/src/postProcessing/functionObjects/field/streamLine/controlDict b/src/postProcessing/functionObjects/field/streamLine/controlDict index 4f4ccd80551ad503b844c0e30666e2b0a10179f1..1b6f1c829fe11fe97506191f8034cd3c2a501bc8 100644 --- a/src/postProcessing/functionObjects/field/streamLine/controlDict +++ b/src/postProcessing/functionObjects/field/streamLine/controlDict @@ -84,6 +84,10 @@ functions // subcycling. nSubCycle 5; + + // Optional clipping + //bounds (0.2 -10 -10)(0.22 10 10); + // Cloud name to use cloudName particleTracks; diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLine.C b/src/postProcessing/functionObjects/field/streamLine/streamLine.C index bd360cada69fcbfe606136d4ad010f3f8a4b3e9f..1015b61887e8eeeaefc60fadecbfeb695d9e7088 100644 --- a/src/postProcessing/functionObjects/field/streamLine/streamLine.C +++ b/src/postProcessing/functionObjects/field/streamLine/streamLine.C @@ -23,18 +23,10 @@ License \*---------------------------------------------------------------------------*/ -#include "Pstream.H" -#include "functionObjectList.H" #include "streamLine.H" #include "fvMesh.H" #include "streamLineParticleCloud.H" -#include "ReadFields.H" -#include "meshSearch.H" #include "sampledSet.H" -#include "globalIndex.H" -#include "mapDistribute.H" -#include "interpolationCellPoint.H" -#include "PatchTools.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -46,60 +38,8 @@ defineTypeNameAndDebug(streamLine, 0); // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -Foam::autoPtr<Foam::indirectPrimitivePatch> -Foam::streamLine::wallPatch() const -{ - const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); - - const polyBoundaryMesh& patches = mesh.boundaryMesh(); - - label nFaces = 0; - - forAll(patches, patchI) - { - //if (!polyPatch::constraintType(patches[patchI].type())) - if (isA<wallPolyPatch>(patches[patchI])) - { - nFaces += patches[patchI].size(); - } - } - - labelList addressing(nFaces); - - nFaces = 0; - - forAll(patches, patchI) - { - //if (!polyPatch::constraintType(patches[patchI].type())) - if (isA<wallPolyPatch>(patches[patchI])) - { - const polyPatch& pp = patches[patchI]; - - forAll(pp, i) - { - addressing[nFaces++] = pp.start()+i; - } - } - } - - return autoPtr<indirectPrimitivePatch> - ( - new indirectPrimitivePatch - ( - IndirectList<face> - ( - mesh.faces(), - addressing - ), - mesh.points() - ) - ); -} - - void Foam::streamLine::track() { - const Time& runTime = obr_.time(); const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); IDLList<streamLineParticle> initialParticles; @@ -128,173 +68,26 @@ void Foam::streamLine::track() label nSeeds = returnReduce(particles.size(), sumOp<label>()); - Info << " seeded " << nSeeds << " particles" << endl; + if (log_) Info<< " seeded " << nSeeds << " particles" << endl; // Read or lookup fields PtrList<volScalarField> vsFlds; PtrList<interpolation<scalar> > vsInterp; PtrList<volVectorField> vvFlds; PtrList<interpolation<vector> > vvInterp; - label UIndex = -1; - if (loadFromFiles_) - { - IOobjectList allObjects(mesh, runTime.timeName()); - - IOobjectList objects(2*fields_.size()); - forAll(fields_, i) - { - objects.add(*allObjects[fields_[i]]); - } - - ReadFields(mesh, objects, vsFlds); - vsInterp.setSize(vsFlds.size()); - forAll(vsFlds, i) - { - vsInterp.set - ( - i, - interpolation<scalar>::New - ( - interpolationScheme_, - vsFlds[i] - ) - ); - } - ReadFields(mesh, objects, vvFlds); - vvInterp.setSize(vvFlds.size()); - forAll(vvFlds, i) - { - vvInterp.set - ( - i, - interpolation<vector>::New - ( - interpolationScheme_, - vvFlds[i] - ) - ); - } - } - else - { - label nScalar = 0; - label nVector = 0; - - forAll(fields_, i) - { - if (mesh.foundObject<volScalarField>(fields_[i])) - { - nScalar++; - } - else if (mesh.foundObject<volVectorField>(fields_[i])) - { - nVector++; - } - else - { - FatalErrorIn("streamLine::track()") - << "Cannot find field " << fields_[i] << nl - << "Valid scalar fields are:" - << mesh.names(volScalarField::typeName) << nl - << "Valid vector fields are:" - << mesh.names(volVectorField::typeName) - << exit(FatalError); - } - } - vsInterp.setSize(nScalar); - nScalar = 0; - vvInterp.setSize(nVector); - nVector = 0; - - forAll(fields_, i) - { - if (mesh.foundObject<volScalarField>(fields_[i])) - { - const volScalarField& f = mesh.lookupObject<volScalarField> - ( - fields_[i] - ); - vsInterp.set - ( - nScalar++, - interpolation<scalar>::New - ( - interpolationScheme_, - f - ) - ); - } - else if (mesh.foundObject<volVectorField>(fields_[i])) - { - const volVectorField& f = mesh.lookupObject<volVectorField> - ( - fields_[i] - ); - - if (f.name() == UName_) - { - UIndex = nVector; - } - - vvInterp.set - ( - nVector++, - interpolation<vector>::New - ( - interpolationScheme_, - f - ) - ); - } - } - } - - // Store the names - scalarNames_.setSize(vsInterp.size()); - forAll(vsInterp, i) - { - scalarNames_[i] = vsInterp[i].psi().name(); - } - vectorNames_.setSize(vvInterp.size()); - forAll(vvInterp, i) - { - vectorNames_[i] = vvInterp[i].psi().name(); - } - - // Check that we know the index of U in the interpolators. - - if (UIndex == -1) - { - FatalErrorIn("streamLine::track()") - << "Cannot find field to move particles with : " << UName_ << nl - << "This field has to be present in the sampled fields " << fields_ - << " and in the objectRegistry." - << exit(FatalError); - } - - // Sampled data - // ~~~~~~~~~~~~ - - // Size to maximum expected sizes. - allTracks_.clear(); - allTracks_.setCapacity(nSeeds); - allScalars_.setSize(vsInterp.size()); - forAll(allScalars_, i) - { - allScalars_[i].clear(); - allScalars_[i].setCapacity(nSeeds); - } - allVectors_.setSize(vvInterp.size()); - forAll(allVectors_, i) - { - allVectors_[i].clear(); - allVectors_[i].setCapacity(nSeeds); - } - + initInterpolations + ( + nSeeds, + UIndex, + vsFlds, + vsInterp, + vvFlds, + vvInterp + ); - // additional particle info + // Additional particle info streamLineParticle::trackingData td ( particles, @@ -330,33 +123,13 @@ Foam::streamLine::streamLine const bool loadFromFiles ) : - dict_(dict), - name_(name), - obr_(obr), - loadFromFiles_(loadFromFiles), - active_(true), - nSubCycle_(0) + streamLineBase(name, obr, dict, loadFromFiles) { - // Only active if a fvMesh is available - if (isA<fvMesh>(obr_)) + // Check if the available mesh is an fvMesh otherise deactivate + if (setActive<fvMesh>()) { read(dict_); } - else - { - active_ = false; - WarningIn - ( - "streamLine::streamLine\n" - "(\n" - "const word&,\n" - "const objectRegistry&,\n" - "const dictionary&,\n" - "const bool\n" - ")" - ) << "No fvMesh available, deactivating." - << nl << endl; - } } @@ -372,45 +145,7 @@ void Foam::streamLine::read(const dictionary& dict) { if (active_) { - Info<< type() << " " << name_ << ":" << nl; - - //dict_ = dict; - dict.lookup("fields") >> fields_; - if (dict.found("UName")) - { - dict.lookup("UName") >> UName_; - } - else - { - UName_ = "U"; - if (dict.found("U")) - { - IOWarningIn("streamLine::read(const dictionary&)", dict) - << "Using deprecated entry \"U\"." - << " Please use \"UName\" instead." - << endl; - dict.lookup("U") >> UName_; - } - } - - if (findIndex(fields_, UName_) == -1) - { - FatalIOErrorIn("streamLine::read(const dictionary&)", dict) - << "Velocity field for tracking " << UName_ - << " should be present in the list of fields " << fields_ - << exit(FatalIOError); - } - - - dict.lookup("trackForward") >> trackForward_; - dict.lookup("lifeTime") >> lifeTime_; - if (lifeTime_ < 1) - { - FatalErrorIn(":streamLine::read(const dictionary&)") - << "Illegal value " << lifeTime_ << " for lifeTime" - << exit(FatalError); - } - + streamLineBase::read(dict); bool subCycling = dict.found("nSubCycle"); bool fixedLength = dict.found("trackLength"); @@ -424,7 +159,6 @@ void Foam::streamLine::read(const dictionary& dict) << exit(FatalIOError); } - nSubCycle_ = 1; if (dict.readIfPresent("nSubCycle", nSubCycle_)) { @@ -433,361 +167,14 @@ void Foam::streamLine::read(const dictionary& dict) { nSubCycle_ = 1; } - Info<< " automatic track length specified through" - << " number of sub cycles : " << nSubCycle_ << nl << endl; - } - else - { - dict.lookup("trackLength") >> trackLength_; - Info<< " fixed track length specified : " - << trackLength_ << nl << endl; + if (log_) Info + << " automatic track length specified through" + << " number of sub cycles : " << nSubCycle_ << nl + << endl; } - - - interpolationScheme_ = dict.lookupOrDefault - ( - "interpolationScheme", - interpolationCellPoint<scalar>::typeName - ); - - //Info<< " using interpolation " << interpolationScheme_ - // << endl; - - cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamLine"); - dict.lookup("seedSampleSet") >> seedSet_; - - const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); - - meshSearchPtr_.reset(new meshSearch(mesh)); - - const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs"); - sampledSetPtr_ = sampledSet::New - ( - seedSet_, - mesh, - meshSearchPtr_(), - coeffsDict - ); - coeffsDict.lookup("axis") >> sampledSetAxis_; - - scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat")); - vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat")); } } -void Foam::streamLine::execute() -{ -// const Time& runTime = obr_.time(); -// Pout<< "**streamLine::execute : time:" << runTime.timeName() << endl; -// -// bool isOutputTime = false; -// -// const functionObjectList& fobs = runTime.functionObjects(); -// -// forAll(fobs, i) -// { -// if (isA<streamLineFunctionObject>(fobs[i])) -// { -// const streamLineFunctionObject& fo = -// dynamic_cast<const streamLineFunctionObject&>(fobs[i]); -// -// if (fo.name() == name_) -// { -// Pout<< "found me:" << i << endl; -// if (fo.outputControl().output()) -// { -// isOutputTime = true; -// break; -// } -// } -// } -// } -// -// -// if (active_ && isOutputTime) -// { -// track(); -// } -} - - -void Foam::streamLine::end() -{} - - -void Foam::streamLine::timeSet() -{} - - -void Foam::streamLine::write() -{ - if (active_) - { - Info<< type() << " " << name_ << " output:" << nl; - - const Time& runTime = obr_.time(); - const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); - - - // Do all injection and tracking - track(); - - - if (Pstream::parRun()) - { - // Append slave tracks to master ones - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - globalIndex globalTrackIDs(allTracks_.size()); - - // Construct a distribution map to pull all to the master. - labelListList sendMap(Pstream::nProcs()); - labelListList recvMap(Pstream::nProcs()); - - if (Pstream::master()) - { - // Master: receive all. My own first, then consecutive - // processors. - label trackI = 0; - - forAll(recvMap, procI) - { - labelList& fromProc = recvMap[procI]; - fromProc.setSize(globalTrackIDs.localSize(procI)); - forAll(fromProc, i) - { - fromProc[i] = trackI++; - } - } - } - - labelList& toMaster = sendMap[0]; - toMaster.setSize(globalTrackIDs.localSize()); - forAll(toMaster, i) - { - toMaster[i] = i; - } - - const mapDistribute distMap - ( - globalTrackIDs.size(), - sendMap.xfer(), - recvMap.xfer() - ); - - - // Distribute the track positions. Note: use scheduled comms - // to prevent buffering. - allTracks_.shrink(); - mapDistributeBase::distribute - ( - Pstream::scheduled, - distMap.schedule(), - distMap.constructSize(), - distMap.subMap(), - false, - distMap.constructMap(), - false, - allTracks_, - flipOp() - ); - - // Distribute the scalars - forAll(allScalars_, scalarI) - { - allScalars_[scalarI].shrink(); - mapDistributeBase::distribute - ( - Pstream::scheduled, - distMap.schedule(), - distMap.constructSize(), - distMap.subMap(), - false, - distMap.constructMap(), - false, - allScalars_[scalarI], - flipOp() - ); - allScalars_[scalarI].setCapacity(allScalars_[scalarI].size()); - } - // Distribute the vectors - forAll(allVectors_, vectorI) - { - allVectors_[vectorI].shrink(); - mapDistributeBase::distribute - ( - Pstream::scheduled, - distMap.schedule(), - distMap.constructSize(), - distMap.subMap(), - false, - distMap.constructMap(), - false, - allVectors_[vectorI], - flipOp() - ); - allVectors_[vectorI].setCapacity(allVectors_[vectorI].size()); - } - } - - - label n = 0; - forAll(allTracks_, trackI) - { - n += allTracks_[trackI].size(); - } - - Info<< " Tracks:" << allTracks_.size() << nl - << " Total samples:" << n - << endl; - - - // Massage into form suitable for writers - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - if (Pstream::master() && allTracks_.size()) - { - // Make output directory - - fileName vtkPath - ( - Pstream::parRun() - ? runTime.path()/".."/"postProcessing"/"sets"/name() - : runTime.path()/"postProcessing"/"sets"/name() - ); - if (mesh.name() != fvMesh::defaultRegion) - { - vtkPath = vtkPath/mesh.name(); - } - vtkPath = vtkPath/mesh.time().timeName(); - - mkDir(vtkPath); - - // Convert track positions - - PtrList<coordSet> tracks(allTracks_.size()); - forAll(allTracks_, trackI) - { - tracks.set - ( - trackI, - new coordSet - ( - "track" + Foam::name(trackI), - sampledSetAxis_ //"xyz" - ) - ); - tracks[trackI].transfer(allTracks_[trackI]); - } - - // Convert scalar values - - if (allScalars_.size() > 0) - { - List<List<scalarField> > scalarValues(allScalars_.size()); - - forAll(allScalars_, scalarI) - { - DynamicList<scalarList>& allTrackVals = - allScalars_[scalarI]; - scalarValues[scalarI].setSize(allTrackVals.size()); - - forAll(allTrackVals, trackI) - { - scalarList& trackVals = allTrackVals[trackI]; - scalarValues[scalarI][trackI].transfer(trackVals); - } - } - - fileName vtkFile - ( - vtkPath - / scalarFormatterPtr_().getFileName - ( - tracks[0], - scalarNames_ - ) - ); - - Info<< " Writing data to " << vtkFile.path() << endl; - - scalarFormatterPtr_().write - ( - true, // writeTracks - tracks, - scalarNames_, - scalarValues, - OFstream(vtkFile)() - ); - } - - // Convert vector values - - if (allVectors_.size() > 0) - { - List<List<vectorField> > vectorValues(allVectors_.size()); - - forAll(allVectors_, vectorI) - { - DynamicList<vectorList>& allTrackVals = - allVectors_[vectorI]; - vectorValues[vectorI].setSize(allTrackVals.size()); - - forAll(allTrackVals, trackI) - { - vectorList& trackVals = allTrackVals[trackI]; - vectorValues[vectorI][trackI].transfer(trackVals); - } - } - - fileName vtkFile - ( - vtkPath - / vectorFormatterPtr_().getFileName - ( - tracks[0], - vectorNames_ - ) - ); - - //Info<< " Writing vector data to " << vtkFile << endl; - - vectorFormatterPtr_().write - ( - true, // writeTracks - tracks, - vectorNames_, - vectorValues, - OFstream(vtkFile)() - ); - } - } - } -} - - -void Foam::streamLine::updateMesh(const mapPolyMesh&) -{ - read(dict_); -} - - -void Foam::streamLine::movePoints(const polyMesh&) -{ - // Moving mesh affects the search tree - read(dict_); -} - - -//void Foam::streamLine::readUpdate(const polyMesh::readUpdateState state) -//{ -// if (state != UNCHANGED) -// { -// read(dict_); -// } -//} - - // ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLine.H b/src/postProcessing/functionObjects/field/streamLine/streamLine.H index 59d9d9026e0e8e90d94abda60171904661af8611..d1f319b490b7850b9ef225643f07d2a1403f1e7f 100644 --- a/src/postProcessing/functionObjects/field/streamLine/streamLine.H +++ b/src/postProcessing/functionObjects/field/streamLine/streamLine.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -50,6 +50,7 @@ Description lifeTime 10000; trackLength 1e-3; nSubCycle 5; + bounds (0.2 -10 -10)(0.22 10 10); cloudName particleTracks; seedSampleSet uniform; uniformCoeffs @@ -74,6 +75,8 @@ Description trackLength | tracking segment length | no | nSubCycle | number of tracking steps per cell | no| cloudName | cloud name to use | yes | + log | Log to standard output | no | yes + bounds | Bounding box to trim tracks | no | greatBox seedSampleSet| seeding method (see below)| yes | \endtable @@ -94,6 +97,7 @@ SeeAlso Foam::OutputFilterFunctionObject Foam::sampledSet Foam::wallBoundedStreamLine + Foam::streamLineBase SourceFiles streamLine.C @@ -103,15 +107,7 @@ SourceFiles #ifndef streamLine_H #define streamLine_H -#include "volFieldsFwd.H" -#include "pointFieldFwd.H" -#include "Switch.H" -#include "DynamicList.H" -#include "scalarList.H" -#include "vectorList.H" -#include "polyMesh.H" -#include "writer.H" -#include "indirectPrimitivePatch.H" +#include "streamLineBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -121,103 +117,22 @@ namespace Foam // Forward declaration of classes class objectRegistry; class dictionary; -class mapPolyMesh; -class meshSearch; -class sampledSet; /*---------------------------------------------------------------------------*\ Class streamLine Declaration \*---------------------------------------------------------------------------*/ class streamLine +: + public streamLineBase { // Private data - //- Input dictionary - dictionary dict_; - - //- Name of this set of field averages. - word name_; - - //- Database this class is registered to - const objectRegistry& obr_; - - //- Load fields from files (not from objectRegistry) - bool loadFromFiles_; - - //- On/off switch - bool active_; - - //- List of fields to sample - wordList fields_; - - //- Field to transport particle with - word UName_; - - //- Interpolation scheme to use - word interpolationScheme_; - - //- Whether to use +u or -u - bool trackForward_; - - //- Maximum lifetime (= number of cells) of particle - label lifeTime_; - //- Number of subcycling steps label nSubCycle_; - //- Track length - scalar trackLength_; - - //- Optional specified name of particles - word cloudName_; - - //- Type of seed - word seedSet_; - - //- Names of scalar fields - wordList scalarNames_; - - //- Names of vector fields - wordList vectorNames_; - - - - // Demand driven - - //- Mesh searching enigne - autoPtr<meshSearch> meshSearchPtr_; - - //- Seed set engine - autoPtr<sampledSet> sampledSetPtr_; - //- Axis of the sampled points to output - word sampledSetAxis_; - - //- File writer for scalar data - autoPtr<writer<scalar> > scalarFormatterPtr_; - - //- File writer for vector data - autoPtr<writer<vector> > vectorFormatterPtr_; - - - // Generated data - - //- All tracks. Per particle the points it passed through - DynamicList<List<point> > allTracks_; - - //- Per scalarField, per particle, the sampled value. - List<DynamicList<scalarList> > allScalars_; - - //- Per scalarField, per particle, the sampled value. - List<DynamicList<vectorList> > allVectors_; - - - //- Construct patch out of all wall patch faces - autoPtr<indirectPrimitivePatch> wallPatch() const; - - //- Do all seeding and tracking - void track(); + // Private Member Functions //- Disallow default bitwise copy construct streamLine(const streamLine&); @@ -251,35 +166,11 @@ public: // Member Functions - //- Return name of the set of field averages - virtual const word& name() const - { - return name_; - } - - //- Read the field average data + //- Read settings virtual void read(const dictionary&); - //- Execute the averaging - virtual void execute(); - - //- Execute the averaging at the final time-loop, currently does nothing - virtual void end(); - - //- Called when time was set at the end of the Time::operator++ - virtual void timeSet(); - - //- Calculate the field average data and write - virtual void write(); - - //- Update for changes of mesh - virtual void updateMesh(const mapPolyMesh&); - - //- Update for mesh point-motion - virtual void movePoints(const polyMesh&); - - ////- Update for changes of mesh due to readUpdate - //virtual void readUpdate(const polyMesh::readUpdateState state); + //- Do the actual tracking to fill the track data + virtual void track(); }; diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLineBase.C b/src/postProcessing/functionObjects/field/streamLine/streamLineBase.C new file mode 100644 index 0000000000000000000000000000000000000000..e319081bf9a84855a2260997de51feaf8a72602e --- /dev/null +++ b/src/postProcessing/functionObjects/field/streamLine/streamLineBase.C @@ -0,0 +1,977 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "streamLineBase.H" +#include "fvMesh.H" +#include "ReadFields.H" +#include "sampledSet.H" +#include "globalIndex.H" +#include "mapDistribute.H" +#include "interpolationCellPoint.H" +#include "wallPolyPatch.H" +#include "meshSearchMeshObject.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(streamLineBase, 0); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::autoPtr<Foam::indirectPrimitivePatch> +Foam::streamLineBase::wallPatch() const +{ + const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); + + const polyBoundaryMesh& patches = mesh.boundaryMesh(); + + label nFaces = 0; + + forAll(patches, patchI) + { + //if (!polyPatch::constraintType(patches[patchI].type())) + if (isA<wallPolyPatch>(patches[patchI])) + { + nFaces += patches[patchI].size(); + } + } + + labelList addressing(nFaces); + + nFaces = 0; + + forAll(patches, patchI) + { + //if (!polyPatch::constraintType(patches[patchI].type())) + if (isA<wallPolyPatch>(patches[patchI])) + { + const polyPatch& pp = patches[patchI]; + + forAll(pp, i) + { + addressing[nFaces++] = pp.start()+i; + } + } + } + + return autoPtr<indirectPrimitivePatch> + ( + new indirectPrimitivePatch + ( + IndirectList<face> + ( + mesh.faces(), + addressing + ), + mesh.points() + ) + ); +} + + +void Foam::streamLineBase::initInterpolations +( + const label nSeeds, + label& UIndex, + PtrList<volScalarField>& vsFlds, + PtrList<interpolation<scalar> >& vsInterp, + PtrList<volVectorField>& vvFlds, + PtrList<interpolation<vector> >& vvInterp +) +{ + const Time& runTime = obr_.time(); + const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); + + // Read or lookup fields + + if (loadFromFiles_) + { + IOobjectList allObjects(mesh, runTime.timeName()); + + IOobjectList objects(2*fields_.size()); + forAll(fields_, i) + { + objects.add(*allObjects[fields_[i]]); + } + + ReadFields(mesh, objects, vsFlds); + vsInterp.setSize(vsFlds.size()); + forAll(vsFlds, i) + { + vsInterp.set + ( + i, + interpolation<scalar>::New + ( + interpolationScheme_, + vsFlds[i] + ) + ); + } + ReadFields(mesh, objects, vvFlds); + vvInterp.setSize(vvFlds.size()); + forAll(vvFlds, i) + { + vvInterp.set + ( + i, + interpolation<vector>::New + ( + interpolationScheme_, + vvFlds[i] + ) + ); + } + } + else + { + label nScalar = 0; + label nVector = 0; + + forAll(fields_, i) + { + if (mesh.foundObject<volScalarField>(fields_[i])) + { + nScalar++; + } + else if (mesh.foundObject<volVectorField>(fields_[i])) + { + nVector++; + } + else + { + FatalErrorIn("streamLineBase::track()") + << "Cannot find field " << fields_[i] << nl + << "Valid scalar fields are:" + << mesh.names(volScalarField::typeName) << nl + << "Valid vector fields are:" + << mesh.names(volVectorField::typeName) + << exit(FatalError); + } + } + vsInterp.setSize(nScalar); + nScalar = 0; + vvInterp.setSize(nVector); + nVector = 0; + + forAll(fields_, i) + { + if (mesh.foundObject<volScalarField>(fields_[i])) + { + const volScalarField& f = mesh.lookupObject<volScalarField> + ( + fields_[i] + ); + vsInterp.set + ( + nScalar++, + interpolation<scalar>::New + ( + interpolationScheme_, + f + ) + ); + } + else if (mesh.foundObject<volVectorField>(fields_[i])) + { + const volVectorField& f = mesh.lookupObject<volVectorField> + ( + fields_[i] + ); + + if (f.name() == UName_) + { + UIndex = nVector; + } + + vvInterp.set + ( + nVector++, + interpolation<vector>::New + ( + interpolationScheme_, + f + ) + ); + } + } + } + + // Store the names + scalarNames_.setSize(vsInterp.size()); + forAll(vsInterp, i) + { + scalarNames_[i] = vsInterp[i].psi().name(); + } + vectorNames_.setSize(vvInterp.size()); + forAll(vvInterp, i) + { + vectorNames_[i] = vvInterp[i].psi().name(); + } + + // Check that we know the index of U in the interpolators. + + if (UIndex == -1) + { + FatalErrorIn("streamLineBase::track()") + << "Cannot find field to move particles with : " << UName_ << nl + << "This field has to be present in the sampled fields " << fields_ + << " and in the objectRegistry." + << exit(FatalError); + } + + // Sampled data + // ~~~~~~~~~~~~ + + // Size to maximum expected sizes. + allTracks_.clear(); + allTracks_.setCapacity(nSeeds); + allScalars_.setSize(vsInterp.size()); + forAll(allScalars_, i) + { + allScalars_[i].clear(); + allScalars_[i].setCapacity(nSeeds); + } + allVectors_.setSize(vvInterp.size()); + forAll(allVectors_, i) + { + allVectors_[i].clear(); + allVectors_[i].setCapacity(nSeeds); + } +} + + +void Foam::streamLineBase::storePoint +( + const label trackI, + + const scalar w, + const label leftI, + const label rightI, + + DynamicList<point>& newTrack, + DynamicList<scalarList>& newScalars, + DynamicList<vectorList>& newVectors +) const +{ + label sz = newTrack.size(); + + const List<point>& track = allTracks_[trackI]; + + newTrack.append((1.0-w)*track[leftI] + w*track[rightI]); + + // Scalars + { + newScalars.append(scalarList(allScalars_.size())); + scalarList& newVals = newScalars[sz]; + + forAll(allScalars_, scalarI) + { + const scalarList& trackVals = allScalars_[scalarI][trackI]; + newVals[scalarI] = (1.0-w)*trackVals[leftI] + w*trackVals[rightI]; + } + } + + // Vectors + { + newVectors.append(vectorList(allVectors_.size())); + vectorList& newVals = newVectors[sz]; + + forAll(allVectors_, vectorI) + { + const vectorList& trackVals = allVectors_[vectorI][trackI]; + newVals[vectorI] = (1.0-w)*trackVals[leftI] + w*trackVals[rightI]; + } + } +} + + +// Can split a track into multiple tracks +void Foam::streamLineBase::trimToBox +( + const treeBoundBox& bb, + const label trackI, + PtrList<DynamicList<point> >& newTracks, + PtrList<DynamicList<scalarList> >& newScalars, + PtrList<DynamicList<vectorList> >& newVectors +) const +{ + const List<point>& track = allTracks_[trackI]; + if (track.size()) + { + for + ( + label segmentI = 1; + segmentI < track.size(); + segmentI++ + ) + { + const point& startPt = track[segmentI-1]; + const point& endPt = track[segmentI]; + + const vector d(endPt-startPt); + scalar magD = mag(d); + if (magD > ROOTVSMALL) + { + if (bb.contains(startPt)) + { + // Store 1.0*track[segmentI-1]+0*track[segmentI] + storePoint + ( + trackI, + + 0.0, + segmentI-1, + segmentI, + + newTracks.last(), + newScalars.last(), + newVectors.last() + ); + + if (!bb.contains(endPt)) + { + point clipPt; + if (bb.intersects(endPt, startPt, clipPt)) + { + // End of track. Store point and interpolated + // values + storePoint + ( + trackI, + + mag(clipPt-startPt)/magD, + segmentI-1, + segmentI, + + newTracks.last(), + newScalars.last(), + newVectors.last() + ); + + newTracks.last().shrink(); + newScalars.last().shrink(); + newVectors.last().shrink(); + } + } + } + else + { + // startPt outside box. New track. Get starting point + + point clipPt; + if (bb.intersects(startPt, endPt, clipPt)) + { + // New track + newTracks.append + ( + new DynamicList<point>(track.size()/10) + ); + newScalars.append + ( + new DynamicList<scalarList>(track.size()/10) + ); + newVectors.append + ( + new DynamicList<vectorList>(track.size()/10) + ); + + // Store point and interpolated values + storePoint + ( + trackI, + + mag(clipPt-startPt)/magD, + segmentI-1, + segmentI, + + newTracks.last(), + newScalars.last(), + newVectors.last() + ); + + if (!bb.contains(endPt)) + { + bb.intersects + ( + endPt, + point(clipPt), + clipPt + ); + + // Store point and interpolated values + storePoint + ( + trackI, + + mag(clipPt-startPt)/magD, + segmentI-1, + segmentI, + + newTracks.last(), + newScalars.last(), + newVectors.last() + ); + + newTracks.last().shrink(); + newScalars.last().shrink(); + newVectors.last().shrink(); + } + } + } + } + } + + // Last point + if (bb.contains(track.last())) + { + storePoint + ( + trackI, + + 1.0, + track.size()-2, + track.size()-1, + + newTracks.last(), + newScalars.last(), + newVectors.last() + ); + } + } +} + + +void Foam::streamLineBase::trimToBox(const treeBoundBox& bb) +{ + // Storage for new tracks. Per track, per sample the coordinate (newTracks) + // or values for all the sampled fields (newScalars, newVectors) + PtrList<DynamicList<point> > newTracks; + PtrList<DynamicList<scalarList> > newScalars; + PtrList<DynamicList<vectorList> > newVectors; + + forAll(allTracks_, trackI) + { + const List<point>& track = allTracks_[trackI]; + + if (track.size()) + { + // New track. Assume it consists of the whole track + newTracks.append(new DynamicList<point>(track.size())); + newScalars.append(new DynamicList<scalarList>(track.size())); + newVectors.append(new DynamicList<vectorList>(track.size())); + + // Trim, split and append to newTracks + trimToBox(bb, trackI, newTracks, newScalars, newVectors); + } + } + + // Transfer newTracks to allTracks_ + allTracks_.setSize(newTracks.size()); + forAll(allTracks_, trackI) + { + allTracks_[trackI].transfer(newTracks[trackI]); + } + // Replace track scalars + forAll(allScalars_, scalarI) + { + DynamicList<scalarList>& fieldVals = allScalars_[scalarI]; + fieldVals.setSize(newTracks.size()); + + forAll(fieldVals, trackI) + { + scalarList& trackVals = allScalars_[scalarI][trackI]; + trackVals.setSize(newScalars[trackI].size()); + forAll(trackVals, sampleI) + { + trackVals[sampleI] = newScalars[trackI][sampleI][scalarI]; + } + } + } + // Replace track vectors + forAll(allVectors_, vectorI) + { + DynamicList<vectorList>& fieldVals = allVectors_[vectorI]; + fieldVals.setSize(newTracks.size()); + forAll(fieldVals, trackI) + { + vectorList& trackVals = allVectors_[vectorI][trackI]; + trackVals.setSize(newVectors[trackI].size()); + forAll(trackVals, sampleI) + { + trackVals[sampleI] = newVectors[trackI][sampleI][vectorI]; + } + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::streamLineBase::streamLineBase +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + const bool loadFromFiles +) +: + functionObjectState(obr, name), + dict_(dict), + obr_(obr), + loadFromFiles_(loadFromFiles), + log_(true) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::streamLineBase::~streamLineBase() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::streamLineBase::read(const dictionary& dict) +{ + if (active_) + { + log_.readIfPresent("log", dict); + + if (log_) Info<< type() << " " << name_ << ":" << nl; + + dict.lookup("fields") >> fields_; + if (dict.found("UName")) + { + dict.lookup("UName") >> UName_; + } + else + { + UName_ = "U"; + if (dict.found("U")) + { + IOWarningIn("streamLineBase::read(const dictionary&)", dict) + << "Using deprecated entry \"U\"." + << " Please use \"UName\" instead." + << endl; + dict.lookup("U") >> UName_; + } + } + + if (findIndex(fields_, UName_) == -1) + { + FatalIOErrorIn("streamLineBase::read(const dictionary&)", dict) + << "Velocity field for tracking " << UName_ + << " should be present in the list of fields " << fields_ + << exit(FatalIOError); + } + + + dict.lookup("trackForward") >> trackForward_; + dict.lookup("lifeTime") >> lifeTime_; + if (lifeTime_ < 1) + { + FatalErrorIn(":streamLineBase::read(const dictionary&)") + << "Illegal value " << lifeTime_ << " for lifeTime" + << exit(FatalError); + } + + + trackLength_ = VGREAT; + if (dict.found("trackLength")) + { + dict.lookup("trackLength") >> trackLength_; + + if (log_) + { + Info<< type() << " : fixed track length specified : " + << trackLength_ << nl << endl; + } + } + + + bounds_ = boundBox::greatBox; + if (dict.readIfPresent("bounds", bounds_)) + { + if (log_) Info<< " clipping all segments to " << bounds_ << nl << endl; + } + + + interpolationScheme_ = dict.lookupOrDefault + ( + "interpolationScheme", + interpolationCellPoint<scalar>::typeName + ); + + //if (log_) Info<< " using interpolation " << interpolationScheme_ + // << endl; + + cloudName_ = dict.lookupOrDefault<word>("cloudName", type()); + dict.lookup("seedSampleSet") >> seedSet_; + + const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); + + const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs"); + + sampledSetPtr_ = sampledSet::New + ( + seedSet_, + mesh, + meshSearchMeshObject::New(mesh), + coeffsDict + ); + coeffsDict.lookup("axis") >> sampledSetAxis_; + + scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat")); + vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat")); + } +} + + +void Foam::streamLineBase::execute() +{} + + +void Foam::streamLineBase::end() +{} + + +void Foam::streamLineBase::timeSet() +{} + + +void Foam::streamLineBase::write() +{ + if (active_) + { + if (log_) Info<< type() << " " << name_ << " output:" << nl; + + const Time& runTime = obr_.time(); + const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); + + + // Do all injection and tracking + track(); + + + if (Pstream::parRun()) + { + // Append slave tracks to master ones + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + globalIndex globalTrackIDs(allTracks_.size()); + + // Construct a distribution map to pull all to the master. + labelListList sendMap(Pstream::nProcs()); + labelListList recvMap(Pstream::nProcs()); + + if (Pstream::master()) + { + // Master: receive all. My own first, then consecutive + // processors. + label trackI = 0; + + forAll(recvMap, procI) + { + labelList& fromProc = recvMap[procI]; + fromProc.setSize(globalTrackIDs.localSize(procI)); + forAll(fromProc, i) + { + fromProc[i] = trackI++; + } + } + } + + labelList& toMaster = sendMap[0]; + toMaster.setSize(globalTrackIDs.localSize()); + forAll(toMaster, i) + { + toMaster[i] = i; + } + + const mapDistribute distMap + ( + globalTrackIDs.size(), + sendMap.xfer(), + recvMap.xfer() + ); + + + // Distribute the track positions. Note: use scheduled comms + // to prevent buffering. + allTracks_.shrink(); + mapDistributeBase::distribute + ( + Pstream::scheduled, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + false, + distMap.constructMap(), + false, + allTracks_, + flipOp() + ); + allTracks_.setCapacity(allTracks_.size()); + + // Distribute the scalars + forAll(allScalars_, scalarI) + { + allScalars_[scalarI].shrink(); + mapDistributeBase::distribute + ( + Pstream::scheduled, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + false, + distMap.constructMap(), + false, + allScalars_[scalarI], + flipOp() + ); + allScalars_[scalarI].setCapacity(allScalars_[scalarI].size()); + } + // Distribute the vectors + forAll(allVectors_, vectorI) + { + allVectors_[vectorI].shrink(); + mapDistributeBase::distribute + ( + Pstream::scheduled, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + false, + distMap.constructMap(), + false, + allVectors_[vectorI], + flipOp() + ); + allVectors_[vectorI].setCapacity(allVectors_[vectorI].size()); + } + } + + + if (Pstream::master()) + { + if (bounds_ != boundBox::greatBox) + { + // Clip to bounding box + trimToBox(treeBoundBox(bounds_)); + } + + + label nTracks = 0; + label n = 0; + forAll(allTracks_, trackI) + { + if (allTracks_[trackI].size()) + { + nTracks++; + n += allTracks_[trackI].size(); + } + } + + if (log_) + { + Info<< " Tracks:" << nTracks << nl + << " Total samples:" << n + << endl; + } + + + // Massage into form suitable for writers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Make output directory + + fileName vtkPath + ( + Pstream::parRun() + ? runTime.path()/".."/"postProcessing"/"sets"/name() + : runTime.path()/"postProcessing"/"sets"/name() + ); + if (mesh.name() != fvMesh::defaultRegion) + { + vtkPath = vtkPath/mesh.name(); + } + vtkPath = vtkPath/mesh.time().timeName(); + + mkDir(vtkPath); + + // Convert track positions (and compact out empty tracks) + + PtrList<coordSet> tracks(nTracks); + nTracks = 0; + labelList oldToNewTrack(allTracks_.size(), -1); + + forAll(allTracks_, trackI) + { + if (allTracks_[trackI].size()) + { + tracks.set + ( + nTracks, + new coordSet + ( + "track" + Foam::name(nTracks), + sampledSetAxis_ //"xyz" + ) + ); + oldToNewTrack[trackI] = nTracks; + tracks[nTracks].transfer(allTracks_[trackI]); + nTracks++; + } + } + + // Convert scalar values + + if (allScalars_.size() > 0) + { + List<List<scalarField> > scalarValues(allScalars_.size()); + + forAll(allScalars_, scalarI) + { + DynamicList<scalarList>& allTrackVals = + allScalars_[scalarI]; + scalarValues[scalarI].setSize(nTracks); + + forAll(allTrackVals, trackI) + { + scalarList& vals = allTrackVals[trackI]; + if (vals.size()) + { + label newTrackI = oldToNewTrack[trackI]; + scalarValues[scalarI][newTrackI].transfer(vals); + } + } + } + + fileName vtkFile + ( + vtkPath + / scalarFormatterPtr_().getFileName + ( + tracks[0], + scalarNames_ + ) + ); + + if (log_) Info + << " Writing data to " << vtkFile.path() << endl; + + scalarFormatterPtr_().write + ( + true, // writeTracks + tracks, + scalarNames_, + scalarValues, + OFstream(vtkFile)() + ); + + forAll(scalarNames_, nameI) + { + dictionary propsDict; + propsDict.add("file", vtkFile); + const word& fieldName = scalarNames_[nameI]; + setProperty(fieldName, propsDict); + } + } + + // Convert vector values + + if (allVectors_.size() > 0) + { + List<List<vectorField> > vectorValues(allVectors_.size()); + + forAll(allVectors_, vectorI) + { + DynamicList<vectorList>& allTrackVals = + allVectors_[vectorI]; + vectorValues[vectorI].setSize(nTracks); + + forAll(allTrackVals, trackI) + { + vectorList& vals = allTrackVals[trackI]; + if (vals.size()) + { + label newTrackI = oldToNewTrack[trackI]; + vectorValues[vectorI][newTrackI].transfer(vals); + } + } + } + + fileName vtkFile + ( + vtkPath + / vectorFormatterPtr_().getFileName + ( + tracks[0], + vectorNames_ + ) + ); + + //if (log_) Info<< " Writing vector data to " << vtkFile << endl; + + vectorFormatterPtr_().write + ( + true, // writeTracks + tracks, + vectorNames_, + vectorValues, + OFstream(vtkFile)() + ); + + forAll(vectorNames_, nameI) + { + dictionary propsDict; + propsDict.add("file", vtkFile); + const word& fieldName = vectorNames_[nameI]; + setProperty(fieldName, propsDict); + } + } + } + } +} + + +void Foam::streamLineBase::updateMesh(const mapPolyMesh&) +{ + read(dict_); +} + + +void Foam::streamLineBase::movePoints(const polyMesh&) +{ + // Moving mesh affects the search tree + read(dict_); +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLineBase.H b/src/postProcessing/functionObjects/field/streamLine/streamLineBase.H new file mode 100644 index 0000000000000000000000000000000000000000..cc4346b98bb58e36339d710e0b45cbf3795277e8 --- /dev/null +++ b/src/postProcessing/functionObjects/field/streamLine/streamLineBase.H @@ -0,0 +1,246 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::streamLineBase + +SeeAlso + Foam::streamLine + Foam::wallBoundedStreamLine + +SourceFiles + streamLineBase.C + +\*---------------------------------------------------------------------------*/ + +#ifndef streamLineBase_H +#define streamLineBase_H + +#include "functionObjectState.H" +#include "DynamicList.H" +#include "scalarList.H" +#include "vectorList.H" +#include "writer.H" +#include "indirectPrimitivePatch.H" +#include "interpolation.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class objectRegistry; +class dictionary; +class mapPolyMesh; +class meshSearch; +class sampledSet; + +/*---------------------------------------------------------------------------*\ + Class streamLineBase Declaration +\*---------------------------------------------------------------------------*/ + +class streamLineBase +: + public functionObjectState +{ +protected: + + //- Input dictionary + dictionary dict_; + + //- Database this class is registered to + const objectRegistry& obr_; + + //- Load fields from files (not from objectRegistry) + bool loadFromFiles_; + + //- Switch to send output to Info as well as to file + Switch log_; + + //- List of fields to sample + wordList fields_; + + //- Field to transport particle with + word UName_; + + //- Interpolation scheme to use + word interpolationScheme_; + + //- Whether to use +u or -u + bool trackForward_; + + //- Maximum lifetime (= number of cells) of particle + label lifeTime_; + + //- Track length + scalar trackLength_; + + //- Optional trimming of tracks + boundBox bounds_; + + //- Optional specified name of particles + word cloudName_; + + //- Type of seed + word seedSet_; + + //- Names of scalar fields + wordList scalarNames_; + + //- Names of vector fields + wordList vectorNames_; + + + // Demand driven + + //- Mesh searching enigne + autoPtr<meshSearch> meshSearchPtr_; + + //- Seed set engine + autoPtr<sampledSet> sampledSetPtr_; + + //- Axis of the sampled points to output + word sampledSetAxis_; + + //- File writer for scalar data + autoPtr<writer<scalar> > scalarFormatterPtr_; + + //- File writer for vector data + autoPtr<writer<vector> > vectorFormatterPtr_; + + + // Generated data + + //- All tracks. Per track the points it passed through + DynamicList<List<point> > allTracks_; + + //- Per scalarField, per track, the sampled values + List<DynamicList<scalarList> > allScalars_; + + //- Per vectorField, per track, the sampled values + List<DynamicList<vectorList> > allVectors_; + + + //- Construct patch out of all wall patch faces + autoPtr<indirectPrimitivePatch> wallPatch() const; + + //- Initialise fields, interpolators and track storage + void initInterpolations + ( + const label nSeeds, + label& UIndex, + PtrList<volScalarField>& vsFlds, + PtrList<interpolation<scalar> >& vsInterp, + PtrList<volVectorField>& vvFlds, + PtrList<interpolation<vector> >& vvInterp + ); + + //- Generate point and values by interpolating from existing values + void storePoint + ( + const label trackI, + + const scalar w, + const label leftI, + const label rightI, + + DynamicList<point>& newTrack, + DynamicList<List<scalar> >& newScalars, + DynamicList<List<vector> >& newVectors + ) const; + + //- Trim and possibly split a track + void trimToBox + ( + const treeBoundBox& bb, + const label trackI, + PtrList<DynamicList<point> >& newTracks, + PtrList<DynamicList<scalarList> >& newScalars, + PtrList<DynamicList<vectorList> >& newVectors + ) const; + + //- Trim tracks to bounding box + void trimToBox(const treeBoundBox& bb); + + //- Do the actual tracking to fill the track data + virtual void track() = 0; + + +public: + + //- Runtime type information + TypeName("streamLineBase"); + + + // Constructors + + //- Construct for given objectRegistry and dictionary. + // Allow the possibility to load fields from files + streamLineBase + ( + const word& name, + const objectRegistry&, + const dictionary&, + const bool loadFromFiles = false + ); + + + //- Destructor + virtual ~streamLineBase(); + + + // Member Functions + + //- Read the field average data + virtual void read(const dictionary&); + + //- Execute the averaging + virtual void execute(); + + //- Execute the averaging at the final time-loop, currently does nothing + virtual void end(); + + //- Called when time was set at the end of the Time::operator++ + virtual void timeSet(); + + //- Track and write + virtual void write(); + + //- Update for changes of mesh + virtual void updateMesh(const mapPolyMesh&); + + //- Update for mesh point-motion + virtual void movePoints(const polyMesh&); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.C b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.C index 0048f0d15abef09ff1bbcd30ceb2ddbe65698a0d..f877a6d0868729b982ddee904c007dbf74733a33 100644 --- a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.C +++ b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -46,7 +46,8 @@ Foam::surfaceInterpolateFields::surfaceInterpolateFields name_(name), obr_(obr), active_(true), - fieldSet_() + fieldSet_(), + log_(true) { // Check if the available mesh is an fvMesh otherise deactivate if (isA<fvMesh>(obr_)) @@ -83,6 +84,7 @@ void Foam::surfaceInterpolateFields::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); dict.lookup("fields") >> fieldSet_; } } @@ -92,7 +94,7 @@ void Foam::surfaceInterpolateFields::execute() { if (active_) { - Info<< type() << " " << name_ << " output:" << nl; + if (log_) Info<< type() << " " << name_ << " output:" << nl; // Clear out any previously loaded fields ssf_.clear(); @@ -107,7 +109,7 @@ void Foam::surfaceInterpolateFields::execute() interpolateFields<symmTensor>(sSymmtf_); interpolateFields<tensor>(stf_); - Info<< endl; + if (log_) Info<< endl; } } @@ -131,9 +133,9 @@ void Foam::surfaceInterpolateFields::write() { if (active_) { - Info<< type() << " " << name_ << " output:" << nl; - - Info<< " Writing interpolated surface fields to " + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " Writing interpolated surface fields to " << obr_.time().timeName() << endl; forAll(ssf_, i) diff --git a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.H b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.H index 1a5d38a0759cd6d009c52aa91b8398351eaf30ae..b71503f3936970ce88c651a86e4f62810f8e96e3 100644 --- a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.H +++ b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -54,6 +54,7 @@ Description Property | Description | Required | Default value type | type name: nearWallFields | yes | fields | list of fields with correspoding output field names | yes | + log | Log to standard output | no | yes \endtable @@ -103,9 +104,11 @@ protected: bool active_; //- Fields to process - //wordList fieldSet_; List<Tuple2<word, word> > fieldSet_; + //- Switch to send output to Info as well as to file + Switch log_; + //- Locally constructed fields PtrList<surfaceScalarField> ssf_; PtrList<surfaceVectorField> svf_; diff --git a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFieldsTemplates.C b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFieldsTemplates.C index f302ae1f2cbb731ea6d91fd6174da471be1bbf58..ad89ee2716b0b47adbb18779564f5184e65d4990 100644 --- a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFieldsTemplates.C +++ b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFieldsTemplates.C @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -59,7 +59,8 @@ void Foam::surfaceInterpolateFields::interpolateFields if (obr_.found(sName)) { - Info<< " surface field " << sName << " already exists" + if (log_) Info + << " surface field " << sName << " already exists" << endl; } else @@ -68,7 +69,8 @@ void Foam::surfaceInterpolateFields::interpolateFields sflds.setSize(sz+1); sflds.set(sz, new sfType(sName, linearInterpolate(fld))); - Info<< " interpolated " << fld.name() << " to create " + if (log_) Info + << " interpolated " << fld.name() << " to create " << sflds[sz].name() << endl; } } diff --git a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.H b/src/postProcessing/functionObjects/field/valueAverage/IOvalueAverage.H similarity index 74% rename from applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.H rename to src/postProcessing/functionObjects/field/valueAverage/IOvalueAverage.H index 0c1391f80a13b78181c78a65ea01ee8ab3194c8a..d6d58060b9b070f2fe7db6f8205d00dfec6fe8c2 100644 --- a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.H +++ b/src/postProcessing/functionObjects/field/valueAverage/IOvalueAverage.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -21,29 +21,29 @@ License You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. +Typedef + Foam::IOvalueAverage + +Description + Instance of the generic IOOutputFilter for valueAverage. + \*---------------------------------------------------------------------------*/ -#ifndef createExternalCoupledPatchGeometryTemplates_H -#define createExternalCoupledPatchGeometryTemplates_H +#ifndef IOvalueAverage_H +#define IOvalueAverage_H -#include "word.H" +#include "valueAverage.H" +#include "IOOutputFilter.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { - template<class Type> - void processField(bool& processed, const word& fieldName); + typedef IOOutputFilter<valueAverage> IOvalueAverage; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#ifdef NoRepository - #include "createExternalCoupledPatchGeometryTemplates.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - #endif // ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverage.C b/src/postProcessing/functionObjects/field/valueAverage/valueAverage.C new file mode 100644 index 0000000000000000000000000000000000000000..a8e0a8d51e5695acedc895edeb784e3323d386a9 --- /dev/null +++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverage.C @@ -0,0 +1,202 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "valueAverage.H" +#include "Time.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(valueAverage, 0); +} + + +// * * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * // + +void Foam::valueAverage::writeFileHeader(Ostream& os) const +{ + writeHeader(os, "Value averages"); + writeCommented(os, "Time"); + forAll(fieldNames_, fieldI) + { + writeTabbed(os, fieldNames_[fieldI]); + } + os << endl; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::valueAverage::valueAverage +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + const bool loadFromFiles +) +: + functionObjectState(obr, name), + functionObjectFile(obr, name, typeName, dict), + obr_(obr), + functionObjectName_(dict.lookup("functionObjectName")), + fieldNames_(dict.lookup("fields")), + window_(dict.lookupOrDefault<scalar>("window", -1)), + totalTime_(fieldNames_.size(), obr_.time().deltaTValue()), + resetOnRestart_(false), + log_(true) +{ + if (resetOnRestart_) + { + forAll(fieldNames_, fieldI) + { + const word& fieldName = fieldNames_[fieldI]; + + if (dict.found(fieldName)) + { + const dictionary& valueDict = dict.subDict(fieldName); + totalTime_[fieldI] = readScalar(valueDict.lookup("totalTime")); + } + } + } + + writeFileHeader(file()); +} + + +// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // + +Foam::valueAverage::~valueAverage() +{} + + +// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * // + +void Foam::valueAverage::read(const dictionary& dict) +{ + if (active_) + { + functionObjectFile::read(dict); + + log_ = dict.lookupOrDefault<Switch>("log", true); + } +} + + +void Foam::valueAverage::execute() +{ + if (!active_) + { + return; + } + + scalar dt = obr_.time().deltaTValue(); + + if (log_) Info<< type() << ": " << name_ << " averages:" << nl; + + file() << obr_.time().timeName(); + + DynamicList<label> unprocessedFields(fieldNames_.size()); + + forAll(fieldNames_, fieldI) + { + const word& fieldName(fieldNames_[fieldI]); + const word meanName(fieldName + "Mean"); + + scalar Dt = totalTime_[fieldI]; + scalar alpha = (Dt - dt)/Dt; + scalar beta = dt/Dt; + + if (window_ > 0) + { + if (Dt - dt >= window_) + { + alpha = (window_ - dt)/window_; + beta = dt/window_; + } + } + + bool processed = false; + calc<scalar>(fieldName, meanName, alpha, beta, processed); + calc<vector>(fieldName, meanName, alpha, beta, processed); + calc<sphericalTensor>(fieldName, meanName, alpha, beta, processed); + calc<symmTensor>(fieldName, meanName, alpha, beta, processed); + calc<tensor>(fieldName, meanName, alpha, beta, processed); + + if (!processed) + { + unprocessedFields.append(fieldI); + + if (writeToFile()) + { + file() << tab << "n/a"; + } + } + + totalTime_[fieldI] += dt; + } + + file()<< endl; + + if (unprocessedFields.size()) + { + WarningIn("bool Foam::valueAverage::execute()") + << "From function object: " << functionObjectName_ << nl + << "Unprocessed fields:" << nl; + + forAll(unprocessedFields, i) + { + label fieldI = unprocessedFields[i]; + Info<< " " << fieldNames_[fieldI] << nl; + } + Info<< endl; + } + + if (log_) Info<< endl; +} + + +void Foam::valueAverage::end() +{ + if (active_) + { + execute(); + } +} + + +void Foam::valueAverage::timeSet() +{ + // Do nothing +} + + +void Foam::valueAverage::write() +{ + // Do nothing +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverage.H b/src/postProcessing/functionObjects/field/valueAverage/valueAverage.H new file mode 100644 index 0000000000000000000000000000000000000000..584e1481066ab172f3ba05c55e97117af1dd429b --- /dev/null +++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverage.H @@ -0,0 +1,209 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::valueAverage + +Group + grpFieldFunctionObjects + +Description + This function object calculates the average value from the output of + function objects that generate singular values. + + Example of function object specification: + \verbatim + valueAverage1 + { + type valueAverage; + functionObjectLibs ("libfieldFunctionObjects.so"); + ... + writeToFile yes; + log yes; + functionObjectName forceCoeffs1; + fields (Cm Cd Cl); + window 0.5; + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | type name: valueAverage | yes | + writeToFile | write average data to file | no | yes + log | write average data to standard output | no | yes + fields | list of fields to process | yes | + \endtable + + Output data is written to the file \<timeDir\>/valueAverage.dat + +SeeAlso + Foam::functionObject + Foam::functionObjectFile + Foam::functionObjectState + Foam::OutputFilterFunctionObject + +SourceFiles + valueAverage.C + valueAverageTemplates.C + IOvalueAverage.H + +\*---------------------------------------------------------------------------*/ + +#ifndef valueAverage_H +#define valueAverage_H + +#include "functionObjectState.H" +#include "functionObjectFile.H" +#include "Switch.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class objectRegistry; +class dictionary; +class polyMesh; +class mapPolyMesh; + +/*---------------------------------------------------------------------------*\ + Class valueAverage Declaration +\*---------------------------------------------------------------------------*/ + +class valueAverage +: + public functionObjectState, + public functionObjectFile +{ +protected: + + // Protected data + + //- Reference to the database + const objectRegistry& obr_; + + //- Name of function object to retrueve data from + word functionObjectName_; + + //- List of fields on which to operate + wordList fieldNames_; + + //- Averaging window + const scalar window_; + + //- Average time per field + List<scalar> totalTime_; + + //- Reset the averaging process on restart flag + Switch resetOnRestart_; + + //- Switch to send output to Info as well + Switch log_; + + + // Protected Member Functions + + //- Templated function to calculate the average + template<class Type> + void calc + ( + const word& fieldName, + const word& meanName, + const scalar alpha, + const scalar beta, + bool& processed + ); + + //- Output file header information + virtual void writeFileHeader(Ostream& os) const; + + //- Disallow default bitwise copy construct + valueAverage(const valueAverage&); + + //- Disallow default bitwise assignment + void operator=(const valueAverage&); + + +public: + + //- Runtime type information + TypeName("valueAverage"); + + //- Constructor + valueAverage + ( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + const bool loadFromFiles = false + ); + + //- Destructor + virtual ~valueAverage(); + + + // Public Member Functions + + //- Read the field min/max data + virtual void read(const dictionary&); + + //- Execute, currently does nothing + virtual void execute(); + + //- Execute at the final time-loop, currently does nothing + virtual void end(); + + //- Called when time was set at the end of the Time::operator++ + virtual void timeSet(); + + //- Write the fieldMinMax + virtual void write(); + + //- Update for changes of mesh + virtual void updateMesh(const mapPolyMesh&) + {} + + //- Update for changes of mesh + virtual void movePoints(const polyMesh&) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "valueAverageTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.C b/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.C new file mode 100644 index 0000000000000000000000000000000000000000..347cc28b52c115449bc613277b00acbad7d3bcb3 --- /dev/null +++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.C @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "valueAverageFunctionObject.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineNamedTemplateTypeNameAndDebug(valueAverageFunctionObject, 0); + + addToRunTimeSelectionTable + ( + functionObject, + valueAverageFunctionObject, + dictionary + ); +} + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.H b/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.H new file mode 100644 index 0000000000000000000000000000000000000000..0845bc655cc11a11b6e478fc0b0dfdb7e1e8abf9 --- /dev/null +++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.H @@ -0,0 +1,54 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedef + Foam::valueAverageFunctionObject + +Description + FunctionObject wrapper around valueAverageFunctionObject to allow them + to be created via the functions entry within controlDict. + +SourceFiles + fieldMinMaxFunctionObject.C + +\*---------------------------------------------------------------------------*/ + +#ifndef valueAverageFunctionObject_H +#define valueAverageFunctionObject_H + +#include "valueAverage.H" +#include "OutputFilterFunctionObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + typedef OutputFilterFunctionObject<valueAverage> + valueAverageFunctionObject; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverageTemplates.C b/src/postProcessing/functionObjects/field/valueAverage/valueAverageTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..10bff887799ac235a1ff04cec6638b15a99b4ced --- /dev/null +++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverageTemplates.C @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +template<class Type> +void Foam::valueAverage::calc +( + const word& fieldName, + const word& meanName, + const scalar alpha, + const scalar beta, + bool& processed +) +{ + const word valueType = objectResultType(functionObjectName_, fieldName); + + if (pTraits<Type>::typeName != valueType) + { + return; + } + + Type currentValue = getObjectResult<Type>(functionObjectName_, fieldName); + + Type meanValue = getResult<Type>(meanName); + meanValue = alpha*meanValue + beta*currentValue; + + setResult(meanName, meanValue); + + file() << tab << meanValue; + + if (log_) Info<< " " << meanName << ": " << meanValue << nl; + + processed = true; +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict index 3cf1f74d8856e146e279639e2f9479e04f5d8d82..deb3199c2934958617387394eb5106c4e3fe2815 100644 --- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict +++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict @@ -112,6 +112,9 @@ functions // Size of single track segment [m] //trackLength 1e-3; + // Optional clipping + //bounds (0.2 -10 -10)(0.22 10 10); + // Cloud name to use cloudName particleTracks; diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.C b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.C index f9d1407c1e051ae83ebfffab642dcdc01034eb08..52ca5a7d6279988af8447d133be4f4ca2690cbc2 100644 --- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.C +++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.C @@ -190,9 +190,7 @@ Foam::scalar Foam::wallBoundedParticle::trackFaceTri currentE = currentEdge(); } - // Determine path along line position+s*d to see where intersections - // are. - + // Determine path along line position+s*d to see where intersections are. forAll(tri, i) { label j = tri.fcIndex(i); @@ -259,23 +257,20 @@ bool Foam::wallBoundedParticle::isTriAlongTrack const triFace triVerts(currentTetIndices().faceTriIs(mesh_)); const edge currentE = currentEdge(); - //if (debug) + if + ( + currentE[0] == currentE[1] + || findIndex(triVerts, currentE[0]) == -1 + || findIndex(triVerts, currentE[1]) == -1 + ) { - if + FatalErrorIn ( - currentE[0] == currentE[1] - || findIndex(triVerts, currentE[0]) == -1 - || findIndex(triVerts, currentE[1]) == -1 - ) - { - FatalErrorIn - ( - "wallBoundedParticle::isTriAlongTrack" - "(const point&)" - ) << "Edge " << currentE << " not on triangle " << triVerts - << info() - << abort(FatalError); - } + "wallBoundedParticle::isTriAlongTrack" + "(const point&)" + ) << "Edge " << currentE << " not on triangle " << triVerts + << info() + << abort(FatalError); } @@ -344,12 +339,7 @@ Foam::wallBoundedParticle::wallBoundedParticle } else { - is.read - ( - reinterpret_cast<char*>(&meshEdgeStart_), - sizeof(meshEdgeStart_) - + sizeof(diagEdge_) - ); + is.read(reinterpret_cast<char*>(&meshEdgeStart_), sizeofFields_); } } diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H index 0054ec2bb956545c18f44c42802b181de79ef3d4..2be575b54e489135017c2914fc976ea2fd7d36a6 100644 --- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H +++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H @@ -115,15 +115,6 @@ protected: //- Construct current edge edge currentEdge() const; - //- Check if inside current tet - //void checkInside() const; - - //- Check if on current edge - //void checkOnEdge() const; - - //- Check if point on triangle - //void checkOnTriangle(const point&) const; - //- Cross mesh edge into different face on same cell void crossEdgeConnectedFace(const edge& meshEdge); diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C index 6b6823121e06eaca74a9d0ea77d853a6daa6eb6d..03a37bc518f4654f7846b50b08f41f143c050da0 100644 --- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C +++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License @@ -23,82 +23,22 @@ License \*---------------------------------------------------------------------------*/ -#include "Pstream.H" -#include "functionObjectList.H" #include "wallBoundedStreamLine.H" #include "fvMesh.H" #include "wallBoundedStreamLineParticleCloud.H" -#include "ReadFields.H" -#include "meshSearch.H" #include "sampledSet.H" -#include "globalIndex.H" -#include "mapDistribute.H" -#include "interpolationCellPoint.H" -#include "PatchTools.H" -#include "meshSearchMeshObject.H" #include "faceSet.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { -defineTypeNameAndDebug(wallBoundedStreamLine, 0); + defineTypeNameAndDebug(wallBoundedStreamLine, 0); } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -Foam::autoPtr<Foam::indirectPrimitivePatch> -Foam::wallBoundedStreamLine::wallPatch() const -{ - const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); - - const polyBoundaryMesh& patches = mesh.boundaryMesh(); - - label nFaces = 0; - - forAll(patches, patchI) - { - //if (!polyPatch::constraintType(patches[patchI].type())) - if (isA<wallPolyPatch>(patches[patchI])) - { - nFaces += patches[patchI].size(); - } - } - - labelList addressing(nFaces); - - nFaces = 0; - - forAll(patches, patchI) - { - //if (!polyPatch::constraintType(patches[patchI].type())) - if (isA<wallPolyPatch>(patches[patchI])) - { - const polyPatch& pp = patches[patchI]; - - forAll(pp, i) - { - addressing[nFaces++] = pp.start()+i; - } - } - } - - return autoPtr<indirectPrimitivePatch> - ( - new indirectPrimitivePatch - ( - IndirectList<face> - ( - mesh.faces(), - addressing - ), - mesh.points() - ) - ); -} - - Foam::tetIndices Foam::wallBoundedStreamLine::findNearestTet ( const PackedBoolList& isWallPatch, @@ -158,7 +98,7 @@ Foam::tetIndices Foam::wallBoundedStreamLine::findNearestTet void Foam::wallBoundedStreamLine::track() { - const Time& runTime = obr_.time(); + //const Time& runTime = obr_.time(); const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); @@ -227,14 +167,14 @@ void Foam::wallBoundedStreamLine::track() else { Pout<< type() << " : ignoring seed " << seedPt - << " since not in wall cell." << endl; + << " since not in wall cell" << endl; } } } label nSeeds = returnReduce(particles.size(), sumOp<label>()); - Info<< type() << " : seeded " << nSeeds << " particles." << endl; + if (log_) Info<< type() << " : seeded " << nSeeds << " particles" << endl; @@ -243,168 +183,19 @@ void Foam::wallBoundedStreamLine::track() PtrList<interpolation<scalar> > vsInterp; PtrList<volVectorField> vvFlds; PtrList<interpolation<vector> > vvInterp; - label UIndex = -1; - if (loadFromFiles_) - { - IOobjectList allObjects(mesh, runTime.timeName()); - - IOobjectList objects(2*fields_.size()); - forAll(fields_, i) - { - objects.add(*allObjects[fields_[i]]); - } - - ReadFields(mesh, objects, vsFlds); - vsInterp.setSize(vsFlds.size()); - forAll(vsFlds, i) - { - vsInterp.set - ( - i, - interpolation<scalar>::New - ( - interpolationScheme_, - vsFlds[i] - ) - ); - } - ReadFields(mesh, objects, vvFlds); - vvInterp.setSize(vvFlds.size()); - forAll(vvFlds, i) - { - vvInterp.set - ( - i, - interpolation<vector>::New - ( - interpolationScheme_, - vvFlds[i] - ) - ); - } - } - else - { - label nScalar = 0; - label nVector = 0; - - forAll(fields_, i) - { - if (mesh.foundObject<volScalarField>(fields_[i])) - { - nScalar++; - } - else if (mesh.foundObject<volVectorField>(fields_[i])) - { - nVector++; - } - else - { - FatalErrorIn("wallBoundedStreamLine::execute()") - << "Cannot find field " << fields_[i] << endl - << "Valid scalar fields are:" - << mesh.names(volScalarField::typeName) << endl - << "Valid vector fields are:" - << mesh.names(volVectorField::typeName) - << exit(FatalError); - } - } - vsInterp.setSize(nScalar); - nScalar = 0; - vvInterp.setSize(nVector); - nVector = 0; - - forAll(fields_, i) - { - if (mesh.foundObject<volScalarField>(fields_[i])) - { - const volScalarField& f = mesh.lookupObject<volScalarField> - ( - fields_[i] - ); - vsInterp.set - ( - nScalar++, - interpolation<scalar>::New - ( - interpolationScheme_, - f - ) - ); - } - else if (mesh.foundObject<volVectorField>(fields_[i])) - { - const volVectorField& f = mesh.lookupObject<volVectorField> - ( - fields_[i] - ); - - if (f.name() == UName_) - { - UIndex = nVector; - } - - vvInterp.set - ( - nVector++, - interpolation<vector>::New - ( - interpolationScheme_, - f - ) - ); - } - } - } - - // Store the names - scalarNames_.setSize(vsInterp.size()); - forAll(vsInterp, i) - { - scalarNames_[i] = vsInterp[i].psi().name(); - } - vectorNames_.setSize(vvInterp.size()); - forAll(vvInterp, i) - { - vectorNames_[i] = vvInterp[i].psi().name(); - } - - // Check that we know the index of U in the interpolators. - - if (UIndex == -1) - { - FatalErrorIn("wallBoundedStreamLine::execute()") - << "Cannot find field to move particles with : " << UName_ - << endl - << "This field has to be present in the sampled fields " - << fields_ - << " and in the objectRegistry." << endl - << exit(FatalError); - } - - // Sampled data - // ~~~~~~~~~~~~ - - // Size to maximum expected sizes. - allTracks_.clear(); - allTracks_.setCapacity(nSeeds); - allScalars_.setSize(vsInterp.size()); - forAll(allScalars_, i) - { - allScalars_[i].clear(); - allScalars_[i].setCapacity(nSeeds); - } - allVectors_.setSize(vvInterp.size()); - forAll(allVectors_, i) - { - allVectors_[i].clear(); - allVectors_[i].setCapacity(nSeeds); - } - + initInterpolations + ( + nSeeds, + UIndex, + vsFlds, + vsInterp, + vvFlds, + vvInterp + ); - // additional particle info + // Additional particle info wallBoundedStreamLineParticle::trackingData td ( particles, @@ -440,32 +231,13 @@ Foam::wallBoundedStreamLine::wallBoundedStreamLine const bool loadFromFiles ) : - dict_(dict), - name_(name), - obr_(obr), - loadFromFiles_(loadFromFiles), - active_(true) + streamLineBase(name, obr, dict, loadFromFiles) { - // Only active if a fvMesh is available - if (isA<fvMesh>(obr_)) + // Check if the available mesh is an fvMesh otherise deactivate + if (setActive<fvMesh>()) { read(dict_); } - else - { - active_ = false; - WarningIn - ( - "wallBoundedStreamLine::wallBoundedStreamLine\n" - "(" - "const word&, " - "const objectRegistry&, " - "const dictionary&, " - "const bool " - ")" - ) << "No fvMesh available, deactivating " << name_ - << nl << endl; - } } @@ -481,94 +253,13 @@ void Foam::wallBoundedStreamLine::read(const dictionary& dict) { if (active_) { - //dict_ = dict; - dict.lookup("fields") >> fields_; - if (dict.found("UName")) - { - dict.lookup("UName") >> UName_; - } - else - { - UName_ = "U"; - if (dict.found("U")) - { - IOWarningIn - ( - "wallBoundedStreamLine::read(const dictionary&)", - dict - ) << "Using deprecated entry \"U\"." - << " Please use \"UName\" instead." - << endl; - dict.lookup("U") >> UName_; - } - } - - if (findIndex(fields_, UName_) == -1) - { - FatalIOErrorIn - ( - "wallBoundedStreamLine::read(const dictionary&)", - dict - ) << "Velocity field for tracking " << UName_ - << " should be present in the list of fields " << fields_ - << exit(FatalIOError); - } - - - dict.lookup("trackForward") >> trackForward_; - dict.lookup("lifeTime") >> lifeTime_; - if (lifeTime_ < 1) - { - FatalErrorIn(":wallBoundedStreamLine::read(const dictionary&)") - << "Illegal value " << lifeTime_ << " for lifeTime" - << exit(FatalError); - } - trackLength_ = VGREAT; - if (dict.found("trackLength")) - { - dict.lookup("trackLength") >> trackLength_; - - Info<< type() << " : fixed track length specified : " - << trackLength_ << nl << endl; - } - - - interpolationScheme_ = dict.lookupOrDefault - ( - "interpolationScheme", - interpolationCellPoint<scalar>::typeName - ); - - //Info<< typeName << " using interpolation " << interpolationScheme_ - // << endl; - - cloudName_ = dict.lookupOrDefault<word> - ( - "cloudName", - "wallBoundedStreamLine" - ); - dict.lookup("seedSampleSet") >> seedSet_; - - const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); - - const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs"); - - sampledSetPtr_ = sampledSet::New - ( - seedSet_, - mesh, - meshSearchMeshObject::New(mesh), - coeffsDict - ); - coeffsDict.lookup("axis") >> sampledSetAxis_; - - scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat")); - vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat")); - + streamLineBase::read(dict); // Make sure that the mesh is trackable if (debug) { + const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); + // 1. positive volume decomposition tets faceSet faces(mesh, "lowQualityTetFaces", mesh.nFaces()/100+1); if @@ -636,283 +327,4 @@ void Foam::wallBoundedStreamLine::read(const dictionary& dict) } -void Foam::wallBoundedStreamLine::execute() -{} - - -void Foam::wallBoundedStreamLine::end() -{} - - -void Foam::wallBoundedStreamLine::timeSet() -{} - - -void Foam::wallBoundedStreamLine::write() -{ - if (active_) - { - const Time& runTime = obr_.time(); - const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_); - - - // Do all injection and tracking - track(); - - - if (Pstream::parRun()) - { - // Append slave tracks to master ones - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - globalIndex globalTrackIDs(allTracks_.size()); - - // Construct a distribution map to pull all to the master. - labelListList sendMap(Pstream::nProcs()); - labelListList recvMap(Pstream::nProcs()); - - if (Pstream::master()) - { - // Master: receive all. My own first, then consecutive - // processors. - label trackI = 0; - - forAll(recvMap, procI) - { - labelList& fromProc = recvMap[procI]; - fromProc.setSize(globalTrackIDs.localSize(procI)); - forAll(fromProc, i) - { - fromProc[i] = trackI++; - } - } - } - - labelList& toMaster = sendMap[0]; - toMaster.setSize(globalTrackIDs.localSize()); - forAll(toMaster, i) - { - toMaster[i] = i; - } - - const mapDistribute distMap - ( - globalTrackIDs.size(), - sendMap.xfer(), - recvMap.xfer() - ); - - - // Distribute the track positions. Note: use scheduled comms - // to prevent buffering. - allTracks_.shrink(); - mapDistributeBase::distribute - ( - Pstream::scheduled, - distMap.schedule(), - distMap.constructSize(), - distMap.subMap(), - false, - distMap.constructMap(), - false, - allTracks_, - flipOp() - ); - - // Distribute the scalars - forAll(allScalars_, scalarI) - { - allScalars_[scalarI].shrink(); - mapDistributeBase::distribute - ( - Pstream::scheduled, - distMap.schedule(), - distMap.constructSize(), - distMap.subMap(), - false, - distMap.constructMap(), - false, - allScalars_[scalarI], - flipOp() - ); - allScalars_[scalarI].setCapacity(allScalars_[scalarI].size()); - } - // Distribute the vectors - forAll(allVectors_, vectorI) - { - allVectors_[vectorI].shrink(); - mapDistributeBase::distribute - ( - Pstream::scheduled, - distMap.schedule(), - distMap.constructSize(), - distMap.subMap(), - false, - distMap.constructMap(), - false, - allVectors_[vectorI], - flipOp() - ); - allVectors_[vectorI].setCapacity(allVectors_[vectorI].size()); - } - } - - - label n = 0; - forAll(allTracks_, trackI) - { - n += allTracks_[trackI].size(); - } - - Info<< " Tracks:" << allTracks_.size() << nl - << " Total samples:" << n << endl; - - - // Massage into form suitable for writers - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - if (Pstream::master() && allTracks_.size()) - { - // Make output directory - - fileName vtkPath - ( - Pstream::parRun() - ? runTime.path()/".."/"postProcessing"/"sets"/name() - : runTime.path()/"postProcessing"/"sets"/name() - ); - if (mesh.name() != fvMesh::defaultRegion) - { - vtkPath = vtkPath/mesh.name(); - } - vtkPath = vtkPath/mesh.time().timeName(); - - mkDir(vtkPath); - - // Convert track positions - - PtrList<coordSet> tracks(allTracks_.size()); - forAll(allTracks_, trackI) - { - tracks.set - ( - trackI, - new coordSet - ( - "track" + Foam::name(trackI), - sampledSetAxis_ //"xyz" - ) - ); - tracks[trackI].transfer(allTracks_[trackI]); - } - - // Convert scalar values - - if (allScalars_.size() > 0) - { - List<List<scalarField> > scalarValues(allScalars_.size()); - - forAll(allScalars_, scalarI) - { - DynamicList<scalarList>& allTrackVals = - allScalars_[scalarI]; - scalarValues[scalarI].setSize(allTrackVals.size()); - - forAll(allTrackVals, trackI) - { - scalarList& trackVals = allTrackVals[trackI]; - scalarValues[scalarI][trackI].transfer(trackVals); - } - } - - fileName vtkFile - ( - vtkPath - / scalarFormatterPtr_().getFileName - ( - tracks[0], - scalarNames_ - ) - ); - - Info<< "Writing data to " << vtkFile.path() << endl; - - scalarFormatterPtr_().write - ( - true, // writeTracks - tracks, - scalarNames_, - scalarValues, - OFstream(vtkFile)() - ); - } - - // Convert vector values - - if (allVectors_.size() > 0) - { - List<List<vectorField> > vectorValues(allVectors_.size()); - - forAll(allVectors_, vectorI) - { - DynamicList<vectorList>& allTrackVals = - allVectors_[vectorI]; - vectorValues[vectorI].setSize(allTrackVals.size()); - - forAll(allTrackVals, trackI) - { - vectorList& trackVals = allTrackVals[trackI]; - vectorValues[vectorI][trackI].transfer(trackVals); - } - } - - fileName vtkFile - ( - vtkPath - / vectorFormatterPtr_().getFileName - ( - tracks[0], - vectorNames_ - ) - ); - - //Info<< "Writing vector data to " << vtkFile << endl; - - vectorFormatterPtr_().write - ( - true, // writeTracks - tracks, - vectorNames_, - vectorValues, - OFstream(vtkFile)() - ); - } - } - } -} - - -void Foam::wallBoundedStreamLine::updateMesh(const mapPolyMesh&) -{ - read(dict_); -} - - -void Foam::wallBoundedStreamLine::movePoints(const polyMesh&) -{ - // Moving mesh affects the search tree - read(dict_); -} - - -//void Foam::wallBoundedStreamLine::readUpdate -//(const polyMesh::readUpdateState state) -//{ -// if (state != UNCHANGED) -// { -// read(dict_); -// } -//} - - // ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H index 98956ba9caa2111e22aa5c53c6ae791887d18652..fe7d3366ac01c004c85acd91e1ffeb87a5991864 100644 --- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H +++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -49,7 +49,7 @@ Description ); lifeTime 10000; trackLength 1e-3; - nSubCycle 5; + bounds (0.2 -10 -10)(0.22 10 10); cloudName particleTracks; seedSampleSet patchSeed; patchSeedCoeffs @@ -71,8 +71,9 @@ Description fields | fields to sample | yes | lifetime | maximum number of particle tracking steps | yes | trackLength | tracking segment length | no | - nSubCycle | number of tracking steps per cell | no| cloudName | cloud name to use | yes | + log | Log to standard output | no | yes + bounds | Bounding box to trim tracks | no | greatBox seedSampleSet| seeding method (see below)| yes | \endtable @@ -85,14 +86,11 @@ Description triSurfaceMeshPointSet | points according to a tri-surface mesh \endplaintable -Note - When specifying the track resolution, the \c trackLength OR \c nSubCycle - option should be used - SeeAlso Foam::functionObject Foam::OutputFilterFunctionObject Foam::sampledSet + Foam::streamLineBase Foam::streamLine SourceFiles @@ -103,16 +101,7 @@ SourceFiles #ifndef wallBoundedStreamLine_H #define wallBoundedStreamLine_H -#include "volFieldsFwd.H" -#include "pointFieldFwd.H" -#include "Switch.H" -#include "DynamicList.H" -#include "scalarList.H" -#include "vectorList.H" -#include "polyMesh.H" -#include "writer.H" -#include "indirectPrimitivePatch.H" -#include "tetIndices.H" +#include "streamLineBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -120,99 +109,15 @@ SourceFiles namespace Foam { -// Forward declaration of classes -class objectRegistry; -class dictionary; -class mapPolyMesh; -class meshSearch; -class sampledSet; - /*---------------------------------------------------------------------------*\ Class wallBoundedStreamLine Declaration \*---------------------------------------------------------------------------*/ class wallBoundedStreamLine +: + public streamLineBase { - // Private data - - //- Input dictionary - dictionary dict_; - - //- Name of this set of field averages. - word name_; - - //- Database this class is registered to - const objectRegistry& obr_; - - //- Load fields from files (not from objectRegistry) - bool loadFromFiles_; - - //- On/off switch - bool active_; - - - //- List of fields to sample - wordList fields_; - - //- Field to transport particle with - word UName_; - - //- Interpolation scheme to use - word interpolationScheme_; - - //- Whether to use +u or -u - bool trackForward_; - - //- Maximum lifetime (= number of cells) of particle - label lifeTime_; - - //- Track length - scalar trackLength_; - - //- Optional specified name of particles - word cloudName_; - - //- Type of seed - word seedSet_; - - //- Names of scalar fields - wordList scalarNames_; - - //- Names of vector fields - wordList vectorNames_; - - - // Demand driven - - //- Mesh searching enigne - autoPtr<meshSearch> meshSearchPtr_; - - //- Seed set engine - autoPtr<sampledSet> sampledSetPtr_; - - //- Axis of the sampled points to output - word sampledSetAxis_; - - //- File output writer - autoPtr<writer<scalar> > scalarFormatterPtr_; - - autoPtr<writer<vector> > vectorFormatterPtr_; - - - // Generated data - - //- All tracks. Per particle the points it passed through - DynamicList<List<point> > allTracks_; - - //- Per scalarField, per particle, the sampled value. - List<DynamicList<scalarList> > allScalars_; - - //- Per scalarField, per particle, the sampled value. - List<DynamicList<vectorList> > allVectors_; - - - //- Construct patch out of all wall patch faces - autoPtr<indirectPrimitivePatch> wallPatch() const; + // Private Member Functions //- Find wall tet on cell tetIndices findNearestTet @@ -222,9 +127,6 @@ class wallBoundedStreamLine const label cellI ) const; - //- Do all seeding and tracking - void track(); - //- Disallow default bitwise copy construct wallBoundedStreamLine(const wallBoundedStreamLine&); @@ -257,35 +159,11 @@ public: // Member Functions - //- Return name of the set of field averages - virtual const word& name() const - { - return name_; - } - - //- Read the field average data + //- Read settings virtual void read(const dictionary&); - //- Execute the averaging - virtual void execute(); - - //- Execute the averaging at the final time-loop, currently does nothing - virtual void end(); - - //- Called when time was set at the end of the Time::operator++ - virtual void timeSet(); - - //- Calculate the field average data and write - virtual void write(); - - //- Update for changes of mesh - virtual void updateMesh(const mapPolyMesh&); - - //- Update for mesh point-motion - virtual void movePoints(const polyMesh&); - - ////- Update for changes of mesh due to readUpdate - //virtual void readUpdate(const polyMesh::readUpdateState state); + //- Do the actual tracking to fill the track data + virtual void track(); }; diff --git a/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C b/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C index da2f58847274c4dbb3ea877dc935a756fadf1359..e3417e26f82f5fab44fd3e103b4f03f26019e14b 100644 --- a/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C +++ b/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C @@ -343,20 +343,18 @@ void Foam::forceCoeffs::execute() scalar ClfTot = ClTot/2.0 + CmTot; scalar ClrTot = ClTot/2.0 - CmTot; - if (log_) - { - Info<< type() << " " << name_ << " output:" << nl - << " Coefficients" << nl; - } + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " Coefficients" << nl; + writeIntegratedData("Cm", momentCoeffs); writeIntegratedData("Cd", dragCoeffs); writeIntegratedData("Cl", liftCoeffs); - if (log_) - { - Info<< " Cl(f) : " << ClfTot << nl - << " Cl(r) : " << ClrTot << nl - << endl; - } + + if (log_) Info + << " Cl(f) : " << ClfTot << nl + << " Cl(r) : " << ClrTot << nl + << endl; if (writeToFile()) { diff --git a/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.C b/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.C index 8c951de8ecfe0a73440c5e48d4b7d2c7251d7bab..9c5e5873288d686d3fa6dd0df2908b671e26d24e 100644 --- a/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.C +++ b/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -88,7 +88,8 @@ Foam::calcFvcDiv::calcFvcDiv obr_(obr), active_(true), fieldName_("undefined-fieldName"), - resultName_("undefined-resultName") + resultName_(word::null), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -123,10 +124,12 @@ void Foam::calcFvcDiv::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); + dict.lookup("fieldName") >> fieldName_; - dict.lookup("resultName") >> resultName_; + dict.readIfPresent("resultName", resultName_); - if (resultName_ == "none") + if (resultName_ == word::null) { resultName_ = "fvc::div(" + fieldName_ + ")"; } @@ -176,7 +179,8 @@ void Foam::calcFvcDiv::write() const regIOobject& field = obr_.lookupObject<regIOobject>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << field.name() << nl << endl; field.write(); diff --git a/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.H b/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.H index 447b00c92c8b36168ed5d42061964247700de7a5..bc498be4ec8140c723c8dbd21ad2a6d43b58a5e2 100644 --- a/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.H +++ b/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -28,9 +28,29 @@ Group grpFVFunctionObjects Description - This function object calculates the divergence of a field. The operation is - limited to surfaceScalarFields and volumeVector fields, and the output is a - volume scalar field. + This function object calculates the divergence of a field. The operation + is limited to surfaceScalarFields and volumeVector fields, and the output + is a volume scalar field. + + Example of function object specification: + \verbatim + calcFvcDiv1 + { + type calcFvcDiv; + functionObjectLibs ("libFVFunctionObjects.so"); + ... + fieldName U; + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | type name: calcFvcDiv | yes | + fieldName | Name of field to process | yes | + resultName | Name of divergence field | no | fvc::div(fieldName) + log | Log to standard output | no | yes + \endtable SourceFiles calcFvcDiv.C @@ -82,6 +102,9 @@ class calcFvcDiv //- Name of result field word resultName_; + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.C b/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.C index c0642ecf01baeb6edce31cf09e2ca6cdd1a228ef..ff97fa0f3ffa730639124b3e50d8e1671414d27f 100644 --- a/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.C +++ b/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -50,7 +50,8 @@ Foam::calcFvcGrad::calcFvcGrad obr_(obr), active_(true), fieldName_("undefined-fieldName"), - resultName_("undefined-resultName") + resultName_(word::null), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -85,10 +86,12 @@ void Foam::calcFvcGrad::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); + dict.lookup("fieldName") >> fieldName_; - dict.lookup("resultName") >> resultName_; + dict.readIfPresent("resultName", resultName_); - if (resultName_ == "none") + if (resultName_ == word::null) { resultName_ = "fvc::grad(" + fieldName_ + ")"; } @@ -138,7 +141,8 @@ void Foam::calcFvcGrad::write() const regIOobject& field = obr_.lookupObject<regIOobject>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << field.name() << nl << endl; field.write(); diff --git a/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.H b/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.H index bdaf5383ed5b7aa90f1e51063e5d7587dea5b1d9..45b6d9c7277bca4f1a144df257c4d9aaa29dbe04 100644 --- a/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.H +++ b/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -28,9 +28,29 @@ Group grpFVFunctionObjects Description - This function object calculates the gradient of a field. The operation is - limited to scalar and vector volume or surface fields, and the output is a - volume vector or tensor field. + This function object calculates the gradient of a field. The operation + is limited to scalar and vector volume or surface fields, and the output + is a volume vector or tensor field. + + Example of function object specification: + \verbatim + calcFvcGrad1 + { + type calcFvcGrad; + functionObjectLibs ("libFVFunctionObjects.so"); + ... + fieldName U; + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | type name: calcFvcGrad | yes | + fieldName | Name of field to process | yes | + resultName | Name of gradient field | no | fvc::grad(fieldName) + log | Log to standard output | no | yes + \endtable SourceFiles calcFvcGrad.C @@ -82,6 +102,9 @@ class calcFvcGrad //- Name of result field word resultName_; + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.C b/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.C index d853aaf00dca833f0b4d60ff51c43daf7c0abde5..ea11e28b4c60ba91d95adc548b87bdc6d102d9ed 100644 --- a/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.C +++ b/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -50,7 +50,8 @@ Foam::calcMag::calcMag obr_(obr), active_(true), fieldName_("undefined-fieldName"), - resultName_("undefined-resultName") + resultName_(word::null), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -85,10 +86,12 @@ void Foam::calcMag::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); + dict.lookup("fieldName") >> fieldName_; - dict.lookup("resultName") >> resultName_; + dict.readIfPresent("resultName", resultName_); - if (resultName_ == "none") + if (resultName_ == word::null) { resultName_ = "mag(" + fieldName_ + ")"; } @@ -141,7 +144,8 @@ void Foam::calcMag::write() const regIOobject& field = obr_.lookupObject<regIOobject>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << field.name() << nl << endl; field.write(); diff --git a/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.H b/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.H index 76f10721117618a00c503b554b219c8e91c69fc7..1df80da3aa1ac0bc5f453aa7d6437fc088877bb6 100644 --- a/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.H +++ b/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -32,6 +32,25 @@ Description can be applied to any volume or surface fieldsm and the output is a volume or surface scalar field. + Example of function object specification: + \verbatim + calcMag1 + { + type calcMag; + functionObjectLibs ("libFVFunctionObjects.so"); + ... + fieldName U; + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | type name: calcMag | yes | + fieldName | Name of field to process | yes | + resultName | Name of magnitude field | no | mag(fieldName) + log | Log to standard output | no | yes + \endtable SourceFiles calcMag.C IOcalcMag.H @@ -82,6 +101,9 @@ class calcMag //- Name of result field word resultName_; + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/graphics/doc/graphicsFunctionObjectsDoc.H b/src/postProcessing/functionObjects/graphics/doc/graphicsFunctionObjectsDoc.H new file mode 100644 index 0000000000000000000000000000000000000000..9839333c7687a84fbe94a9590954ccea5dcdf2b0 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/doc/graphicsFunctionObjectsDoc.H @@ -0,0 +1,30 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\defgroup grpGraphicsFunctionObjects Graphics function objects +@{ + \ingroup grpFunctionObjects + This group contains graphics-based function objects +@} + +\*---------------------------------------------------------------------------*/ diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H index 087942b92d5627cbc3aea430a7fd715f2c9eb564..d386aae369fe4a0f7a53fb6d5e1f9b516b423647 100644 --- a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,6 +24,9 @@ License Class Foam::runTimePostProcessing +Group + grpGraphicsFunctionObjects + Description Function object to generate images during run-time. diff --git a/src/postProcessing/functionObjects/jobControl/Make/files b/src/postProcessing/functionObjects/jobControl/Make/files index c86cc727f689b657f05d9f02987279385353246e..9d4ebe3aebe70c86c331b466dc679ddf3075506f 100644 --- a/src/postProcessing/functionObjects/jobControl/Make/files +++ b/src/postProcessing/functionObjects/jobControl/Make/files @@ -1,4 +1,20 @@ abortCalculation/abortCalculation.C abortCalculation/abortCalculationFunctionObject.C +runTimeControl/runTimeControl.C +runTimeControl/runTimeControlFunctionObject.C +runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.C +runTimeControl/runTimeCondition/runTimeCondition/runTimeConditionNew.C +runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.C +runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.C +runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.C +runTimeControl/runTimeCondition/averageCondition/averageCondition.C +runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.C + +externalCoupled = externalCoupled +$(externalCoupled)/externalCoupledFunctionObject.C +$(externalCoupled)/externalCoupledMixed/externalCoupledMixedFvPatchFields.C +$(externalCoupled)/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C + + LIB = $(FOAM_LIBBIN)/libjobControl diff --git a/src/postProcessing/functionObjects/jobControl/Make/options b/src/postProcessing/functionObjects/jobControl/Make/options index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c6867bf0d19075542c973348e71a4ce1f971e0e4 100644 --- a/src/postProcessing/functionObjects/jobControl/Make/options +++ b/src/postProcessing/functionObjects/jobControl/Make/options @@ -0,0 +1,10 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ + -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ + -I$(LIB_SRC)/transportModels/compressible/lnInclude + +LIB_LIBS = \ + -lfiniteVolume \ + -lcompressibleTurbulenceModels diff --git a/src/postProcessing/functionObjects/jobControl/jobControlFunctionObjectsDoc.H b/src/postProcessing/functionObjects/jobControl/doc/jobControlFunctionObjectsDoc.H similarity index 100% rename from src/postProcessing/functionObjects/jobControl/jobControlFunctionObjectsDoc.H rename to src/postProcessing/functionObjects/jobControl/doc/jobControlFunctionObjectsDoc.H diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C new file mode 100644 index 0000000000000000000000000000000000000000..ca7e2d3951d40e63de4a97b2e1f2c668ce05ed77 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C @@ -0,0 +1,947 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "externalCoupledFunctionObject.H" +#include "addToRunTimeSelectionTable.H" +#include "OSspecific.H" +#include "IFstream.H" +#include "OFstream.H" +#include "volFields.H" +#include "globalIndex.H" +#include "fvMesh.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(externalCoupledFunctionObject, 0); + + addToRunTimeSelectionTable + ( + functionObject, + externalCoupledFunctionObject, + dictionary + ); +} + +Foam::word Foam::externalCoupledFunctionObject::lockName = "OpenFOAM"; + +Foam::string Foam::externalCoupledFunctionObject::patchKey = "# Patch: "; + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::fileName Foam::externalCoupledFunctionObject::baseDir() const +{ + fileName result(commsDir_); + result.clean(); + + return result; +} + + +Foam::fileName Foam::externalCoupledFunctionObject::groupDir +( + const fileName& commsDir, + const word& regionName, + const wordRe& groupName +) +{ + fileName result(commsDir/regionName/string::validate<fileName>(groupName)); + result.clean(); + + return result; +} + + +Foam::fileName Foam::externalCoupledFunctionObject::lockFile() const +{ + return fileName(baseDir()/(lockName + ".lock")); +} + + +void Foam::externalCoupledFunctionObject::createLockFile() const +{ + if (!Pstream::master()) + { + return; + } + + const fileName fName(lockFile()); + IFstream is(fName); + + // Only create lock file if it doesn't already exist + if (!is.good()) + { + if (log_) Info<< type() << ": creating lock file" << endl; + + OFstream os(fName); + os << "lock file"; + os.flush(); + } +} + + +void Foam::externalCoupledFunctionObject::removeLockFile() const +{ + if (!Pstream::master()) + { + return; + } + + if (log_) Info<< type() << ": removing lock file" << endl; + + rm(lockFile()); +} + + +void Foam::externalCoupledFunctionObject::removeReadFiles() const +{ + if (!Pstream::master()) + { + return; + } + + if (log_) Info<< type() << ": removing all read files" << endl; + + forAll(regionNames_, regionI) + { + const word& regionName = regionNames_[regionI]; + const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); + const labelList& groups = regionToGroups_[regionName]; + forAll(groups, i) + { + label groupI = groups[i]; + const wordRe& groupName = groupNames_[groupI]; + + forAll(groupReadFields_[groupI], fieldI) + { + const word& fieldName = groupReadFields_[groupI][fieldI]; + rm + ( + groupDir(commsDir_, mesh.dbDir(), groupName) + / fieldName + ".in" + ); + } + } + } +} + + +void Foam::externalCoupledFunctionObject::removeWriteFiles() const +{ + if (!Pstream::master()) + { + return; + } + + if (log_) Info<< type() << ": removing all write files" << endl; + + forAll(regionNames_, regionI) + { + const word& regionName = regionNames_[regionI]; + const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); + const labelList& groups = regionToGroups_[regionName]; + forAll(groups, i) + { + label groupI = groups[i]; + const wordRe& groupName = groupNames_[groupI]; + + forAll(groupWriteFields_[groupI], fieldI) + { + const word& fieldName = groupWriteFields_[groupI][fieldI]; + rm + ( + groupDir(commsDir_, mesh.dbDir(), groupName) + / fieldName + ".out" + ); + } + } + } +} + + +void Foam::externalCoupledFunctionObject::wait() const +{ + const fileName fName(lockFile()); + label found = 0; + label totalTime = 0; + + if (log_) Info<< type() << ": beginning wait for lock file " << fName << nl; + + while (found == 0) + { + if (Pstream::master()) + { + if (totalTime > timeOut_) + { + FatalErrorIn + ( + "void " + "Foam::externalCoupledFunctionObject::wait() " + "const" + ) + << "Wait time exceeded time out time of " << timeOut_ + << " s" << abort(FatalError); + } + + IFstream is(fName); + + if (is.good()) + { + found++; + + if (log_) + { + Info<< type() << ": found lock file " << fName << endl; + } + } + else + { + sleep(waitInterval_); + totalTime += waitInterval_; + + if (log_) + { + Info<< type() << ": wait time = " << totalTime << endl; + } + } + } + + // prevent other procs from racing ahead + reduce(found, sumOp<label>()); + } +} + + +void Foam::externalCoupledFunctionObject::readColumns +( + const label nRows, + const label nColumns, + autoPtr<IFstream>& masterFilePtr, + List<scalarField>& data +) const +{ + // Get sizes for all processors + const globalIndex globalFaces(nRows); + + PstreamBuffers pBufs(Pstream::nonBlocking); + if (Pstream::master()) + { + string line; + + // Read data from file and send to destination processor + + for (label procI = 0; procI < Pstream::nProcs(); procI++) + { + // Temporary storage + List<scalarField> values(nColumns); + + // Number of rows to read for processor procI + label procNRows = globalFaces.localSize(procI); + + forAll(values, columnI) + { + values[columnI].setSize(procNRows); + } + + for (label rowI = 0; rowI < procNRows; rowI++) + { + // Get a line + do + { + if (!masterFilePtr().good()) + { + FatalIOErrorIn + ( + "externalCoupledFunctionObject::readColumns()", + masterFilePtr() + ) << "Trying to read data for processor " << procI + << " row " << rowI + << ". Does your file have as many rows as there are" + << " patch faces (" << globalFaces.size() + << ") ?" << exit(FatalIOError); + } + + masterFilePtr().getLine(line); + } while (line.empty() || line[0] == '#'); + + IStringStream lineStr(line); + + for (label columnI = 0; columnI < nColumns; columnI++) + { + lineStr >> values[columnI][rowI]; + } + } + + // Send to procI + UOPstream str(procI, pBufs); + str << values; + } + } + pBufs.finishedSends(); + + // Read from PstreamBuffers + UIPstream str(Pstream::masterNo(), pBufs); + str >> data; +} + + +void Foam::externalCoupledFunctionObject::readLines +( + const label nRows, + autoPtr<IFstream>& masterFilePtr, + OStringStream& lines +) const +{ + // Get sizes for all processors + const globalIndex globalFaces(nRows); + + PstreamBuffers pBufs(Pstream::nonBlocking); + + if (Pstream::master()) + { + string line; + + // Read line from file and send to destination processor + + for (label procI = 0; procI < Pstream::nProcs(); procI++) + { + // Number of rows to read for processor procI + label procNRows = globalFaces.localSize(procI); + + UOPstream toProc(procI, pBufs); + + for (label rowI = 0; rowI < procNRows; rowI++) + { + // Get a line + do + { + if (!masterFilePtr().good()) + { + FatalIOErrorIn + ( + "externalCoupledFunctionObject::readColumns()", + masterFilePtr() + ) << "Trying to read data for processor " << procI + << " row " << rowI + << ". Does your file have as many rows as there are" + << " patch faces (" << globalFaces.size() + << ") ?" << exit(FatalIOError); + } + + masterFilePtr().getLine(line); + } while (line.empty() || line[0] == '#'); + + // Send line to the destination processor + toProc << line; + } + } + } + + + pBufs.finishedSends(); + + // Read lines from PstreamBuffers + UIPstream str(Pstream::masterNo(), pBufs); + for (label rowI = 0; rowI < nRows; rowI++) + { + string line(str); + lines << line.c_str() << nl; + } +} + + +void Foam::externalCoupledFunctionObject::writeGeometry +( + const fvMesh& mesh, + const fileName& commsDir, + const wordRe& groupName +) +{ + fileName dir(groupDir(commsDir, mesh.dbDir(), groupName)); + + //if (log_) + { + Info<< typeName << ": writing geometry to " << dir << endl; + } + + autoPtr<OFstream> osPointsPtr; + autoPtr<OFstream> osFacesPtr; + if (Pstream::master()) + { + mkDir(dir); + osPointsPtr.reset(new OFstream(dir/"patchPoints")); + osFacesPtr.reset(new OFstream(dir/"patchFaces")); + } + + const labelList patchIDs + ( + mesh.boundaryMesh().patchSet + ( + List<wordRe>(1, groupName) + ).sortedToc() + ); + + forAll(patchIDs, i) + { + label patchI = patchIDs[i]; + + const polyPatch& p = mesh.boundaryMesh()[patchI]; + + labelList pointToGlobal; + labelList uniquePointIDs; + mesh.globalData().mergePoints + ( + p.meshPoints(), + p.meshPointMap(), + pointToGlobal, + uniquePointIDs + ); + + label procI = Pstream::myProcNo(); + + List<pointField> allPoints(Pstream::nProcs()); + allPoints[procI] = pointField(mesh.points(), uniquePointIDs); + Pstream::gatherList(allPoints); + + List<faceList> allFaces(Pstream::nProcs()); + faceList& patchFaces = allFaces[procI]; + patchFaces = p.localFaces(); + forAll(patchFaces, faceI) + { + inplaceRenumber(pointToGlobal, patchFaces[faceI]); + } + Pstream::gatherList(allFaces); + + if (Pstream::master()) + { + pointField pts + ( + ListListOps::combine<pointField> + ( + allPoints, + accessOp<pointField>() + ) + ); + + //if (log_) + { + Info<< typeName << ": for patch " << p.name() + << " writing " << pts.size() << " points to " + << osPointsPtr().name() << endl; + } + + // Write points + osPointsPtr() << patchKey.c_str() << p.name() << pts << endl; + + faceList fcs + ( + ListListOps::combine<faceList>(allFaces, accessOp<faceList>()) + ); + + //if (log_) + { + Info<< typeName << ": for patch " << p.name() + << " writing " << fcs.size() << " faces to " + << osFacesPtr().name() << endl; + } + + // Write faces + osFacesPtr() << patchKey.c_str() << p.name() << fcs << endl; + } + } +} + + +void Foam::externalCoupledFunctionObject::readData() +{ + forAll(regionNames_, regionI) + { + const word& regionName = regionNames_[regionI]; + const labelList& groups = regionToGroups_[regionName]; + + const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); + + forAll(groups, i) + { + label groupI = groups[i]; + const wordRe& groupName = groupNames_[groupI]; + const labelList& patchIDs = groupPatchIDs_[groupI]; + const wordList& fieldNames = groupReadFields_[groupI]; + + forAll(fieldNames, fieldI) + { + const word& fieldName = fieldNames[fieldI]; + + bool ok = readData<scalar> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + ok = ok || readData<vector> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + ok = ok || readData<sphericalTensor> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + ok = ok || readData<symmTensor> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + ok = ok || readData<tensor> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + + if (!ok) + { + WarningIn + ( + "void Foam::externalCoupledFunctionObject::readData()" + ) + << "Field " << fieldName << " in region " << mesh.name() + << " was not found." << endl; + } + } + } + } +} + + +void Foam::externalCoupledFunctionObject::writeData() const +{ + forAll(regionNames_, regionI) + { + const word& regionName = regionNames_[regionI]; + const labelList& groups = regionToGroups_[regionName]; + + const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); + + forAll(groups, i) + { + label groupI = groups[i]; + const wordRe& groupName = groupNames_[groupI]; + const labelList& patchIDs = groupPatchIDs_[groupI]; + const wordList& fieldNames = groupWriteFields_[groupI]; + + forAll(fieldNames, fieldI) + { + const word& fieldName = fieldNames[fieldI]; + bool ok = writeData<scalar> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + ok = ok || writeData<vector> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + ok = ok || writeData<sphericalTensor> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + ok = ok || writeData<symmTensor> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + ok = ok || writeData<tensor> + ( + mesh, + groupName, + patchIDs, + fieldName + ); + + if (!ok) + { + WarningIn + ( + "void Foam::externalCoupledFunctionObject::writeData()" + ) + << "Field " << fieldName << " in region " << mesh.name() + << " was not found." << endl; + } + } + } + } +} + + +void Foam::externalCoupledFunctionObject::initialise() +{ + if (initialised_) + { + return; + } + + // Write the geometry if not already there + forAll(regionNames_, regionI) + { + const word& regionName = regionNames_[regionI]; + const labelList& groups = regionToGroups_[regionName]; + + const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); + + forAll(groups, i) + { + label groupI = groups[i]; + const wordRe& groupName = groupNames_[groupI]; + + bool exists = false; + if (Pstream::master()) + { + fileName dir(groupDir(commsDir_, mesh.dbDir(), groupName)); + + exists = isFile(dir/"patchPoints") || isFile(dir/"patchFaces"); + } + + if (!returnReduce(exists, orOp<bool>())) + { + writeGeometry(mesh, commsDir_, groupName); + } + } + } + + if (initByExternal_) + { + // Wait for initial data to be made available + wait(); + + // Eead data passed back from external source + readData(); + } + + initialised_ = true; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::externalCoupledFunctionObject::externalCoupledFunctionObject +( + const word& name, + const Time& runTime, + const dictionary& dict +) +: + functionObject(name), + time_(runTime), + enabled_(true), + initialised_(false) +{ + read(dict); + + if (Pstream::master()) + { + mkDir(baseDir()); + } + + if (!initByExternal_) + { + createLockFile(); + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::externalCoupledFunctionObject::~externalCoupledFunctionObject() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::externalCoupledFunctionObject::on() +{ + enabled_ = true; +} + + +void Foam::externalCoupledFunctionObject::off() +{ + enabled_ = false; +} + + +bool Foam::externalCoupledFunctionObject::start() +{ + return true; +} + + +bool Foam::externalCoupledFunctionObject::execute(const bool forceWrite) +{ + if + ( + enabled() + && (!initialised_ || time_.timeIndex() % calcFrequency_ == 0) + ) + { + // Initialise the coupling + initialise(); + + // Write data for external source + writeData(); + + // remove lock file, signalling external source to execute + removeLockFile(); + + // Wait for response + wait(); + + // Remove old data files from OpenFOAM + removeWriteFiles(); + + // Read data passed back from external source + readData(); + + // create lock file for external source + createLockFile(); + + return true; + } + else + { + return false; + } +} + + +bool Foam::externalCoupledFunctionObject::end() +{ + if (enabled()) + { + // Remove old data files + removeReadFiles(); + removeWriteFiles(); + removeLockFile(); + } + + return true; +} + + +bool Foam::externalCoupledFunctionObject::timeSet() +{ + // Do nothing - only valid on execute + return true; +} + + +bool Foam::externalCoupledFunctionObject::adjustTimeStep() +{ + return true; +} + + +bool Foam::externalCoupledFunctionObject::read(const dictionary& dict) +{ + dict.readIfPresent("enabled", enabled_); + + if (!enabled_) + { + return true; + } + + dict.lookup("commsDir") >> commsDir_; + commsDir_.expand(); + + waitInterval_ = dict.lookupOrDefault("waitInterval", 1); + timeOut_ = dict.lookupOrDefault("timeOut", 100*waitInterval_); + calcFrequency_ = dict.lookupOrDefault("calcFrequency", 1); + initByExternal_ = readBool(dict.lookup("initByExternal")); + log_ = dict.lookupOrDefault("log", false); + + const dictionary& allRegionsDict = dict.subDict("regions"); + + forAllConstIter(dictionary, allRegionsDict, iter) + { + if (!iter().isDict()) + { + FatalIOErrorIn + ( + "void Foam::externalCoupledFunctionObject::read" + "(const dictionary&)", + allRegionsDict + ) + << "Regions must be specified in dictionary format" + << exit(FatalIOError); + } + + const word& regionName = iter().keyword(); + const dictionary& regionDict = iter().dict(); + regionNames_.append(regionName); + + forAllConstIter(dictionary, regionDict, regionIter) + { + if (!regionIter().isDict()) + { + FatalIOErrorIn + ( + "void Foam::externalCoupledFunctionObject::read" + "(const dictionary&)", + regionDict + ) + << "Regions must be specified in dictionary format" + << exit(FatalIOError); + } + const wordRe groupName(regionIter().keyword()); + const dictionary& groupDict = regionIter().dict(); + + label nGroups = groupNames_.size(); + const wordList readFields(groupDict.lookup("readFields")); + const wordList writeFields(groupDict.lookup("writeFields")); + + HashTable<labelList>::iterator fnd = regionToGroups_.find + ( + regionName + ); + if (fnd != regionToGroups_.end()) + { + fnd().append(nGroups); + } + else + { + regionToGroups_.insert(regionName, labelList(1, nGroups)); + } + groupNames_.append(groupName); + groupReadFields_.append(readFields); + groupWriteFields_.append(writeFields); + + // Pre-calculate the patchIDs + const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); + groupPatchIDs_.append + ( + mesh.boundaryMesh().patchSet + ( + List<wordRe>(1, groupName) + ).sortedToc() + ); + } + } + + + // Print a bit + if (log_) + { + Info<< type() << ": Communicating with regions:" << endl; + forAll(regionNames_, regionI) + { + const word& regionName = regionNames_[regionI]; + const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); + + Info<< "Region: " << mesh.name() << endl << incrIndent; + const labelList& groups = regionToGroups_[regionName]; + forAll(groups, i) + { + label groupI = groups[i]; + const wordRe& groupName = groupNames_[groupI]; + const labelList& patchIDs = groupPatchIDs_[groupI]; + + Info<< indent << "Group: " << groupName << "\t" + << " patches: " << patchIDs << endl + << incrIndent + << indent << "Reading fields: " << groupReadFields_[groupI] + << endl + << indent << "Writing fields: " << groupWriteFields_[groupI] + << endl + << decrIndent; + } + Info<< decrIndent; + } + Info<< endl; + } + + + // Note: we should not have to make directories since the geometry + // should already be written - but just make sure + if (Pstream::master()) + { + forAll(regionNames_, regionI) + { + const word& regionName = regionNames_[regionI]; + const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); + const labelList& groups = regionToGroups_[regionName]; + forAll(groups, i) + { + label groupI = groups[i]; + const wordRe& groupName = groupNames_[groupI]; + + fileName dir(groupDir(commsDir_, mesh.dbDir(), groupName)); + if (!isDir(dir)) + { + if (log_) + { + Info<< type() << ": creating communications directory " + << dir << endl; + } + + mkDir(dir); + } + } + } + } + + return true; +} + + +void Foam::externalCoupledFunctionObject::updateMesh(const mapPolyMesh& mpm) +{} + + +void Foam::externalCoupledFunctionObject::movePoints(const polyMesh& mesh) +{} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H new file mode 100644 index 0000000000000000000000000000000000000000..7806e64d64aa89bfeef74a957bf6fc55f3244fe6 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H @@ -0,0 +1,383 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify i + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::externalCoupledFunctionObject + +Group + grpJobControlFunctionObjects + +Description + This functionObject provides a simple interface for explicit coupling with + an external application. The coupling is through plain text files + where OpenFOAM boundary data is read/written as one line per face + (data from all processors collated): + + # Patch: <patch name> + <fld1> <fld2> .. <fldn> //face0 + <fld1> <fld2> .. <fldn> //face1 + .. + <fld1> <fld2> .. <fldn> //faceN + + where the actual entries depend on the bc type: + - mixed: value, snGrad, refValue, refGrad, valueFraction + - externalCoupledMixed: output of writeData + - other: value, snGrad + + These text files are located in a user specified communications directory + which gets read/written on the master processor only. In the + communications directory the structure will be + + <regionName>/<patchGroup>/<fieldName>.[in|out] + + At start-up, the boundary creates a lock file, i.e.. + + OpenFOAM.lock + + ... to signal the external source to wait. During the functionObject + execution the boundary values are written to files (one per region, + per patch(group), per field), e.g. + + <regionName>/<patchGroup>/<fieldName>.out + + The lock file is then removed, instructing the external source to take + control of the program execution. When ready, the external program + should create the return values, e.g. to files + + <regionName>/<patchGroup>/<fieldName>.in + + ... and then re-instate the lock file. The functionObject will then + read these values, apply them to the boundary conditions and pass + program execution back to OpenFOAM. + + Example of function object specification: + \verbatim + externalCoupled + { + type externalCoupled; + ... + log yes; + commsDir "${FOAM_CASE}/comms"; + initByExternal yes; + + regions + { + region0 + { + TPatchGroup // Name of patch(group) + { + readFields (p); // List of fields to read + writeFields (T); // List of fields to write + } + } + } + } + \endverbatim + + This reads/writes (on the master processor) the directory: + comms/region0/TPatchGroup/ + with contents: + patchPoints (collected points) + patchFaces (collected faces) + p.in (input file of p, written by external application) + T.out (output file of T, written by OpenFOAM) + + The patchPoints/patchFaces files denote the (collated) geometry + which will be written if it does not exist yet or can be written as + a preprocessing step using the createExternalCoupledPatchGeometry + application. + +SourceFiles + externalCoupledFunctionObject.C + +\*---------------------------------------------------------------------------*/ + +#ifndef externalCoupledFunctionObject_H +#define externalCoupledFunctionObject_H + +#include "functionObject.H" +#include "DynamicList.H" +#include "wordReList.H" +#include "scalarField.H" +#include "Switch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class dictionary; +class polyMesh; +class mapPolyMesh; +class IFstream; +class fvMesh; + +/*---------------------------------------------------------------------------*\ + Class externalCoupledFunctionObject Declaration +\*---------------------------------------------------------------------------*/ + +class externalCoupledFunctionObject +: + public functionObject +{ + // Private data + + //- Reference to the time database + const Time& time_; + + //- Switch for the execution - defaults to 'yes/on' + Switch enabled_; + + //- Path to communications directory + fileName commsDir_; + + //- Interval time between checking for return data [s] + label waitInterval_; + + //- Time out time [s] + label timeOut_; + + //- Calculation frequency + label calcFrequency_; + + //- Flag to indicate values are initialised by external application + bool initByExternal_; + + //- Log flag + bool log_; + + //- Names of regions + DynamicList<word> regionNames_; + + // Per region the indices of the group information + HashTable<labelList> regionToGroups_; + + // Per group the names of the patches/patchGroups + DynamicList<wordRe> groupNames_; + + // Per group the indices of the patches + DynamicList<labelList> groupPatchIDs_; + + // Per group the names of the fields to read + DynamicList<wordList> groupReadFields_; + + // Per group the names of the fields to write + DynamicList<wordList> groupWriteFields_; + + //- Initialised flag + bool initialised_; + + + // Private Member Functions + + //- Return the file path to the communications directory for the region + static fileName groupDir + ( + const fileName& commsDir, + const word& regionName, + const wordRe& groupName + ); + + //- Return the file path to the base communications directory + fileName baseDir() const; + + //- Return the file path to the lock file + fileName lockFile() const; + + //- Create lock file + void createLockFile() const; + + //- Remove lock file + void removeLockFile() const; + + //- Remove files written by OpenFOAM + void removeWriteFiles() const; + + //- Remove files written by external code + void removeReadFiles() const; + + //- Wait for response from external source + void wait() const; + + + //- Read data for a single region, single field + template<class Type> + bool readData + ( + const fvMesh& mesh, + const wordRe& groupName, + const labelList& patchIDs, + const word& fieldName + ); + //- Read data for all regions, all fields + void readData(); + + //- Write data for a single region, single field + template<class Type> + bool writeData + ( + const fvMesh& mesh, + const wordRe& groupName, + const labelList& patchIDs, + const word& fieldName + ) const; + + //- Write data for all regions, all fields + void writeData() const; + + void initialise(); + + //- Read (and distribute) scalar columns from stream. Every processor + // gets nRows (= patch size) of these. Note: could make its argument + // ISstream& but then would need additional logic to construct valid + // stream on all processors. + void readColumns + ( + const label nRows, + const label nColumns, + autoPtr<IFstream>& masterFilePtr, + List<scalarField>& data + ) const; + + //- Read (and distribute) lines from stream. Every processor + // gets nRows (= patch size) of these. Data kept as stream (instead + // of strings) for ease of interfacing to readData routines that take + // an Istream. + void readLines + ( + const label nRows, + autoPtr<IFstream>& masterFilePtr, + OStringStream& data + ) const; + + //- Helper: append data from all processors onto master + template<class Type> + static tmp<Field<Type> > gatherAndCombine(const Field<Type>& fld); + + + //- Disallow default bitwise copy construc + externalCoupledFunctionObject(const externalCoupledFunctionObject&); + + //- Disallow default bitwise assignmen + void operator=(const externalCoupledFunctionObject&); + + +public: + + //- Runtime type information + TypeName("externalCoupled"); + + //- Name of lock file + static word lockName; + + //- Name of patch key, e.g. '# Patch:' when looking for start of patch data + static string patchKey; + + + // Constructors + + //- Construct given time and dictionary + externalCoupledFunctionObject + ( + const word& name, + const Time& runTime, + const dictionary& dict + ); + + + //- Destructor + virtual ~externalCoupledFunctionObject(); + + + // Member Functions + + // Access + + //- Return the enabled flag + virtual bool enabled() const + { + return enabled_; + } + + + // Function object control + + //- Switch the function object on + virtual void on(); + + //- Switch the function object off + virtual void off(); + + //- Called at the start of the time-loop + virtual bool start(); + + //- Called at each ++ or += of the time-loop + virtual bool execute(const bool forceWrite); + + //- Called when Time::run() determines that the time-loop exits + virtual bool end(); + + //- Called when time was set at the end of the Time::operator++ + virtual bool timeSet(); + + //- Called at the end of Time::adjustDeltaT() if adjustTime is true + virtual bool adjustTimeStep(); + + //- Read and set the function object if its data have changed + virtual bool read(const dictionary&); + + //- Update for changes of mesh + virtual void updateMesh(const mapPolyMesh& mpm); + + //- Update for changes of mesh + virtual void movePoints(const polyMesh& mesh); + + + // Other + + //- Write geometry for the group/patch + static void writeGeometry + ( + const fvMesh& mesh, + const fileName& commsDir, + const wordRe& groupName + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "externalCoupledFunctionObjectTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObjectTemplates.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObjectTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..88477c5bb64ba253d3f26a24a9d03dfd90cd9def --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObjectTemplates.C @@ -0,0 +1,459 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify i + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "externalCoupledFunctionObject.H" +#include "OSspecific.H" +#include "IFstream.H" +#include "OFstream.H" +#include "volFields.H" +#include "externalCoupledMixedFvPatchFields.H" +#include "mixedFvPatchFields.H" +#include "fixedGradientFvPatchFields.H" +#include "fixedValueFvPatchFields.H" +#include "OStringStream.H" +#include "globalIndex.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +bool Foam::externalCoupledFunctionObject::readData +( + const fvMesh& mesh, + const wordRe& groupName, + const labelList& patchIDs, + const word& fieldName +) +{ + typedef GeometricField<Type, fvPatchField, volMesh> volFieldType; + typedef externalCoupledMixedFvPatchField<Type> patchFieldType; + + if (!mesh.foundObject<volFieldType>(fieldName)) + { + return false; + } + + const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName); + const typename volFieldType::GeometricBoundaryField& bf = + cvf.boundaryField(); + + + // File only opened on master; contains data for all processors, for all + // patchIDs. + autoPtr<IFstream> masterFilePtr; + if (Pstream::master()) + { + const fileName transferFile + ( + groupDir(commsDir_, mesh.dbDir(), groupName) + / fieldName + ".in" + ); + + if (log_) + { + Info<< type() << ": reading data from " << transferFile << endl; + } + masterFilePtr.reset(new IFstream(transferFile)); + + if (!masterFilePtr().good()) + { + FatalIOErrorIn + ( + "void externalCoupledFunctionObject::readData" + "(" + "const fvMesh&, " + "const wordRe&, " + "const labelList&, " + "const word&" + ")", + masterFilePtr() + ) << "Cannot open file for region " << mesh.name() + << ", field " << fieldName << ", patches " << patchIDs + << exit(FatalIOError); + } + } + + // Handle column-wise reading of patch data. Supports most easy types + forAll(patchIDs, i) + { + label patchI = patchIDs[i]; + + if (isA<patchFieldType>(bf[patchI])) + { + // Explicit handling of externalCoupledObjectMixed bcs - they have + // specialised reading routines. + + patchFieldType& pf = const_cast<patchFieldType&> + ( + refCast<const patchFieldType> + ( + bf[patchI] + ) + ); + + // Read from master into local stream + OStringStream os; + readLines + ( + bf[patchI].size(), // number of lines to read + masterFilePtr, + os + ); + + // Pass responsability for all reading over to bc + pf.readData(IStringStream(os.str())()); + + // Update the value from the read coefficicient. Bypass any + // additional processing by derived type. + pf.patchFieldType::evaluate(); + } + else if (isA<mixedFvPatchField<Type> >(bf[patchI])) + { + // Read columns from file for + // value, snGrad, refValue, refGrad, valueFraction + List<scalarField> data; + readColumns + ( + bf[patchI].size(), // number of lines to read + 4*pTraits<Type>::nComponents+1, // nColumns: 4*Type + 1*scalar + masterFilePtr, + data + ); + + mixedFvPatchField<Type>& pf = const_cast<mixedFvPatchField<Type>&> + ( + refCast<const mixedFvPatchField<Type> > + ( + bf[patchI] + ) + ); + + // Transfer read data to bc. + // Skip value, snGrad + direction columnI = 2*pTraits<Type>::nComponents; + + Field<Type>& refValue = pf.refValue(); + for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++) + { + refValue.replace(cmpt, data[columnI++]); + } + Field<Type>& refGrad = pf.refGrad(); + for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++) + { + refGrad.replace(cmpt, data[columnI++]); + } + pf.valueFraction() = data[columnI]; + + // Update the value from the read coefficicient. Bypass any + // additional processing by derived type. + pf.mixedFvPatchField<Type>::evaluate(); + } + else if (isA<fixedGradientFvPatchField<Type> >(bf[patchI])) + { + // Read columns for value and gradient + List<scalarField> data; + readColumns + ( + bf[patchI].size(), // number of lines to read + 2*pTraits<Type>::nComponents, // nColumns: Type + masterFilePtr, + data + ); + + fixedGradientFvPatchField<Type>& pf = + const_cast<fixedGradientFvPatchField<Type>&> + ( + refCast<const fixedGradientFvPatchField<Type> > + ( + bf[patchI] + ) + ); + + // Transfer gradient to bc + Field<Type>& gradient = pf.gradient(); + for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++) + { + gradient.replace(cmpt, data[pTraits<Type>::nComponents+cmpt]); + } + + // Update the value from the read coefficicient. Bypass any + // additional processing by derived type. + pf.fixedGradientFvPatchField<Type>::evaluate(); + } + else if (isA<fixedValueFvPatchField<Type> >(bf[patchI])) + { + // Read columns for value only + List<scalarField> data; + readColumns + ( + bf[patchI].size(), // number of lines to read + pTraits<Type>::nComponents, // number of columns to read + masterFilePtr, + data + ); + + // Transfer read value to bc + Field<Type> value(bf[patchI].size()); + for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++) + { + value.replace(cmpt, data[cmpt]); + } + + fixedValueFvPatchField<Type>& pf = + const_cast<fixedValueFvPatchField<Type>&> + ( + refCast<const fixedValueFvPatchField<Type> > + ( + bf[patchI] + ) + ); + + pf == value; + + // Update the value from the read coefficicient. Bypass any + // additional processing by derived type. + pf.fixedValueFvPatchField<Type>::evaluate(); + } + else + { + FatalErrorIn + ( + "void externalCoupledFunctionObject::readData" + "(" + "const fvMesh&, " + "const wordRe&, " + "const labelList&, " + "const word&" + ")" + ) + << "Unsupported boundary condition " << bf[patchI].type() + << " for patch " << bf[patchI].patch().name() + << " in region " << mesh.name() + << exit(FatalError); + } + + initialised_ = true; + } + + return true; +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > +Foam::externalCoupledFunctionObject::gatherAndCombine +( + const Field<Type>& fld +) +{ + // Collect values from all processors + List<Field<Type> > gatheredValues(Pstream::nProcs()); + gatheredValues[Pstream::myProcNo()] = fld; + Pstream::gatherList(gatheredValues); + + + tmp<Field<Type> > tresult(new Field<Type>(0)); + Field<Type>& result = tresult(); + + if (Pstream::master()) + { + // Combine values into single field + label globalElemI = 0; + + forAll(gatheredValues, lstI) + { + globalElemI += gatheredValues[lstI].size(); + } + + result.setSize(globalElemI); + + globalElemI = 0; + + forAll(gatheredValues, lstI) + { + const Field<Type>& sub = gatheredValues[lstI]; + + forAll(sub, elemI) + { + result[globalElemI++] = sub[elemI]; + } + } + } + + return tresult; +} + + +template<class Type> +bool Foam::externalCoupledFunctionObject::writeData +( + const fvMesh& mesh, + const wordRe& groupName, + const labelList& patchIDs, + const word& fieldName +) const +{ + typedef GeometricField<Type, fvPatchField, volMesh> volFieldType; + typedef externalCoupledMixedFvPatchField<Type> patchFieldType; + + if (!mesh.foundObject<volFieldType>(fieldName)) + { + return false; + } + + const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName); + const typename volFieldType::GeometricBoundaryField& bf = + cvf.boundaryField(); + + + // File only opened on master; contains data for all processors, for all + // patchIDs + autoPtr<OFstream> masterFilePtr; + if (Pstream::master()) + { + const fileName transferFile + ( + groupDir(commsDir_, mesh.dbDir(), groupName) + / fieldName + ".out" + ); + + if (log_) + { + Info<< type() << ": writing data to " << transferFile << endl; + } + masterFilePtr.reset(new OFstream(transferFile)); + + if (!masterFilePtr().good()) + { + FatalIOErrorIn + ( + "externalCoupledFunctionObject::writeData" + "(" + "const fvMesh&, " + "const wordRe&, " + "const labelList&, " + "const word&" + ") const", + masterFilePtr() + ) << "Cannot open file for region " << mesh.name() + << ", field " << fieldName << ", patches " << patchIDs + << exit(FatalIOError); + } + } + + + bool headerDone = false; + + // Handle column-wise writing of patch data. Supports most easy types + forAll(patchIDs, i) + { + label patchI = patchIDs[i]; + + const globalIndex globalFaces(bf[patchI].size()); + + if (isA<patchFieldType>(bf[patchI])) + { + // Explicit handling of externalCoupledObjectMixed bcs - they have + // specialised writing routines + + const patchFieldType& pf = refCast<const patchFieldType> + ( + bf[patchI] + ); + OStringStream os; + + // Pass responsibility for all writing over to bc + pf.writeData(os); + + // Collect contributions from all processors and output them on + // master + if (Pstream::master()) + { + // Output master data first + if (!headerDone) + { + pf.writeHeader(masterFilePtr()); + headerDone = true; + } + masterFilePtr() << os.str().c_str(); + + for (label procI = 1; procI < Pstream::nProcs(); procI++) + { + IPstream fromSlave(Pstream::scheduled, procI); + string str(fromSlave); + masterFilePtr() << str.c_str(); + } + } + else + { + OPstream toMaster(Pstream::scheduled, Pstream::masterNo()); + toMaster << os.str(); + } + } + else if (isA<mixedFvPatchField<Type> >(bf[patchI])) + { + const mixedFvPatchField<Type>& pf = + refCast<const mixedFvPatchField<Type> >(bf[patchI]); + + Field<Type> value(gatherAndCombine(pf)); + Field<Type> snGrad(gatherAndCombine(pf.snGrad()())); + Field<Type> refValue(gatherAndCombine(pf.refValue())); + Field<Type> refGrad(gatherAndCombine(pf.refGrad())); + scalarField valueFraction(gatherAndCombine(pf.valueFraction())); + + if (Pstream::master()) + { + forAll(refValue, faceI) + { + masterFilePtr() + << value[faceI] << token::SPACE + << snGrad[faceI] << token::SPACE + << refValue[faceI] << token::SPACE + << refGrad[faceI] << token::SPACE + << valueFraction[faceI] << nl; + } + } + } + else + { + // Output the value and snGrad + Field<Type> value(gatherAndCombine(bf[patchI])); + Field<Type> snGrad(gatherAndCombine(bf[patchI].snGrad()())); + if (Pstream::master()) + { + forAll(value, faceI) + { + masterFilePtr() + << value[faceI] << token::SPACE + << snGrad[faceI] << nl; + } + } + } + } + + return true; +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.C new file mode 100644 index 0000000000000000000000000000000000000000..c99e3cc1e5a044308357dd30e18e402f1b542412 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.C @@ -0,0 +1,168 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "externalCoupledMixedFvPatchField.H" +#include "fvPatchFieldMapper.H" +#include "ISstream.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class Type> +Foam::externalCoupledMixedFvPatchField<Type>:: +externalCoupledMixedFvPatchField +( + const fvPatch& p, + const DimensionedField<Type, volMesh>& iF +) +: + mixedFvPatchField<Type>(p, iF) +{ + this->refValue() = pTraits<Type>::zero; + this->refGrad() = pTraits<Type>::zero; + this->valueFraction() = 0.0; +} + + +template<class Type> +Foam::externalCoupledMixedFvPatchField<Type>:: +externalCoupledMixedFvPatchField +( + const externalCoupledMixedFvPatchField& ptf, + const fvPatch& p, + const DimensionedField<Type, volMesh>& iF, + const fvPatchFieldMapper& mapper +) +: + mixedFvPatchField<Type>(ptf, p, iF, mapper) +{} + + +template<class Type> +Foam::externalCoupledMixedFvPatchField<Type>:: +externalCoupledMixedFvPatchField +( + const fvPatch& p, + const DimensionedField<Type, volMesh>& iF, + const dictionary& dict +) +: + mixedFvPatchField<Type>(p, iF, dict) +{} + + +template<class Type> +Foam::externalCoupledMixedFvPatchField<Type>:: +externalCoupledMixedFvPatchField +( + const externalCoupledMixedFvPatchField& ecmpf +) +: + mixedFvPatchField<Type>(ecmpf) +{} + + +template<class Type> +Foam::externalCoupledMixedFvPatchField<Type>:: +externalCoupledMixedFvPatchField +( + const externalCoupledMixedFvPatchField& ecmpf, + const DimensionedField<Type, volMesh>& iF +) +: + mixedFvPatchField<Type>(ecmpf, iF) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template<class Type> +Foam::externalCoupledMixedFvPatchField<Type>:: +~externalCoupledMixedFvPatchField() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type> +void Foam::externalCoupledMixedFvPatchField<Type>::writeHeader +( + Ostream& os +) const +{ + os << "# Values: value snGrad refValue refGrad valueFraction" << endl; +} + + +template<class Type> +void Foam::externalCoupledMixedFvPatchField<Type>::writeData +( + Ostream& os +) const +{ + const Field<Type> snGrad(this->snGrad()); + const Field<Type>& refValue(this->refValue()); + const Field<Type>& refGrad(this->refGrad()); + const scalarField& valueFraction(this->valueFraction()); + + forAll(refValue, faceI) + { + os << this->operator[](faceI) << token::SPACE + << snGrad[faceI] << token::SPACE + << refValue[faceI] << token::SPACE + << refGrad[faceI] << token::SPACE + << valueFraction[faceI] << nl; + } +} + + +template<class Type> +void Foam::externalCoupledMixedFvPatchField<Type>::readData(Istream& is) +{ + // Assume generic input stream so we can do line-based format and skip + // unused columns + ISstream& iss = dynamic_cast<ISstream&>(is); + + string line; + + forAll(*this, faceI) + { + iss.getLine(line); + IStringStream lineStr(line); + + // For symmetry with writing ignore value, snGrad columns + + Type value, snGrad; + + lineStr + >> value + >> snGrad + >> this->refValue()[faceI] + >> this->refGrad()[faceI] + >> this->valueFraction()[faceI]; + } +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.H new file mode 100644 index 0000000000000000000000000000000000000000..2d700207d19e9987471585aa76ceb7e51c543473 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.H @@ -0,0 +1,174 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::externalCoupledMixedFvPatchField + +Group + grpGenericBoundaryConditions grpCoupledBoundaryConditions + +Description + This boundary condition extends the mixed boundary condition with + serialisation through + - writeHeader + - writeData + - readData + functions. It is used for coupling to external applications in combination + with the externalCoupled functionObject. The default output is one + line per face, with columns + <value> <snGrad> <refValue> <refGrad> <valueFraction> + +Notes + readData,writeData are not callbacks for regIOobject (since fvPatchField + not derived from it). They do however do exactly the same - streaming of + data. + +SeeAlso + mixedFvPatchField + externalCoupledFunctionObject + +SourceFiles + externalCoupledMixedFvPatchField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef externalCoupledMixedFvPatchField_H +#define externalCoupledMixedFvPatchField_H + +#include "mixedFvPatchFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class externalCoupledMixedFvPatchField Declaration +\*---------------------------------------------------------------------------*/ + +template<class Type> +class externalCoupledMixedFvPatchField +: + public mixedFvPatchField<Type> +{ + +public: + + //- Runtime type information + TypeName("externalCoupled"); + + + // Constructors + + //- Construct from patch and internal field + externalCoupledMixedFvPatchField + ( + const fvPatch&, + const DimensionedField<Type, volMesh>& + ); + + //- Construct from patch, internal field and dictionary + externalCoupledMixedFvPatchField + ( + const fvPatch&, + const DimensionedField<Type, volMesh>&, + const dictionary& + ); + + //- Construct by mapping given externalCoupledMixedFvPatchField + // onto a new patch + externalCoupledMixedFvPatchField + ( + const externalCoupledMixedFvPatchField<Type>&, + const fvPatch&, + const DimensionedField<Type, volMesh>&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + externalCoupledMixedFvPatchField + ( + const externalCoupledMixedFvPatchField& + ); + + //- Construct and return a clone + virtual tmp<fvPatchField<Type> > clone() const + { + return tmp<fvPatchField<Type> > + ( + new externalCoupledMixedFvPatchField<Type>(*this) + ); + } + + //- Construct as copy setting internal field reference + externalCoupledMixedFvPatchField + ( + const externalCoupledMixedFvPatchField&, + const DimensionedField<Type, volMesh>& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp<fvPatchField<Type> > clone + ( + const DimensionedField<Type, volMesh>& iF + ) const + { + return tmp<fvPatchField<Type> > + ( + new externalCoupledMixedFvPatchField<Type>(*this, iF) + ); + } + + + //- Destructor + virtual ~externalCoupledMixedFvPatchField(); + + + // Member functions + + //- Write header + virtual void writeHeader(Ostream&) const; + + //- Write data + virtual void writeData(Ostream&) const; + + //- Read data + virtual void readData(Istream&); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "externalCoupledMixedFvPatchField.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.C similarity index 95% rename from src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.C rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.C index 42ab10636d5cf304bfadc234540066b8e5d62a85..3a5bce74c4f5e1d3ef409b72c10be15d6ce44306 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.C +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.H similarity index 95% rename from src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.H rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.H index 36d457004b0a9992f7fa24ba7048fcef6327a3e8..72b563638ba0423166ab5b900fb08764bc699fb1 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.H +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H similarity index 95% rename from src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H index 7aae5c7b502ea25242f635c936398f08d5873d9f..b39a8d7da5c20c91b0c7bf49a9b02fe2a17a839b 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C similarity index 65% rename from src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C index 9791087190b487ef22cbe9deb6b30f7c57071e6e..7f8e23041b7e6fb8bb8e8fea498007d7be4dfd83 100644 --- a/src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C @@ -28,16 +28,15 @@ License #include "addToRunTimeSelectionTable.H" #include "fvPatchFieldMapper.H" #include "volFields.H" -#include "OFstream.H" // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // void Foam::externalCoupledTemperatureMixedFvPatchScalarField::writeHeader ( - OFstream& os + Ostream& os ) const { - os << "# Values: magSf value qDot htc" << endl; + os << "# Values: magSf T qDot htc" << endl; } @@ -75,8 +74,40 @@ externalCoupledTemperatureMixedFvPatchScalarField const dictionary& dict ) : - externalCoupledMixedFvPatchField<scalar>(p, iF, dict) -{} + //externalCoupledMixedFvPatchField<scalar>(p, iF, dict) + externalCoupledMixedFvPatchField<scalar>(p, iF) +{ + if (dict.found("refValue")) + { + // Initialise same way as mixed + this->refValue() = scalarField("refValue", dict, p.size()); + this->refGrad() = scalarField("refGradient", dict, p.size()); + this->valueFraction() = scalarField("valueFraction", dict, p.size()); + + evaluate(); + } + else + { + // For convenience: initialise as fixedValue with either read value + // or extrapolated value + if (dict.found("value")) + { + fvPatchField<scalar>::operator= + ( + scalarField("value", dict, p.size()) + ); + } + else + { + fvPatchField<scalar>::operator=(this->patchInternalField()); + } + + // Initialise as a fixed value + this->refValue() = *this; + this->refGrad() = pTraits<scalar>::zero; + this->valueFraction() = 1.0; + } +} Foam::externalCoupledTemperatureMixedFvPatchScalarField:: @@ -109,21 +140,14 @@ Foam::externalCoupledTemperatureMixedFvPatchScalarField:: // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData +void Foam::externalCoupledTemperatureMixedFvPatchScalarField::writeData ( - OFstream& os + Ostream& os ) const { - if (log()) - { - Info<< type() << ": " << this->patch().name() - << ": writing data to " << os.name() - << endl; - } - const label patchI = patch().index(); - // heat flux [W/m2] + // Heat flux [W/m2] scalarField qDot(this->patch().size(), 0.0); typedef compressible::turbulenceModel cmpTurbModelType; @@ -137,7 +161,7 @@ void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData ) ); - static word thermoName(basicThermo::dictName); + static word thermoName("thermophysicalProperties"); if (db().foundObject<cmpTurbModelType>(turbName)) { @@ -165,100 +189,55 @@ void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData "void Foam::externalCoupledTemperatureMixedFvPatchScalarField::" "transferData" "(" - "OFstream&" + "Ostream&" ") const" ) << "Condition requires either compressible turbulence and/or " << "thermo model to be available" << exit(FatalError); } - // patch temperature [K] - const scalarField Tp(*this); + // Patch temperature [K] + const scalarField& Tp(*this); - // near wall cell temperature [K] + // Near wall cell temperature [K] const scalarField Tc(patchInternalField()); - // heat transfer coefficient [W/m2/K] + // Heat transfer coefficient [W/m2/K] const scalarField htc(qDot/(Tp - Tc + ROOTVSMALL)); - if (Pstream::parRun()) - { - int tag = Pstream::msgType() + 1; + const Field<scalar>& magSf(this->patch().magSf()); - List<Field<scalar> > magSfs(Pstream::nProcs()); - magSfs[Pstream::myProcNo()].setSize(this->patch().size()); - magSfs[Pstream::myProcNo()] = this->patch().magSf(); - Pstream::gatherList(magSfs, tag); - - List<Field<scalar> > values(Pstream::nProcs()); - values[Pstream::myProcNo()].setSize(this->patch().size()); - values[Pstream::myProcNo()] = Tp; - Pstream::gatherList(values, tag); - - List<Field<scalar> > qDots(Pstream::nProcs()); - qDots[Pstream::myProcNo()].setSize(this->patch().size()); - qDots[Pstream::myProcNo()] = qDot; - Pstream::gatherList(qDots, tag); - - List<Field<scalar> > htcs(Pstream::nProcs()); - htcs[Pstream::myProcNo()].setSize(this->patch().size()); - htcs[Pstream::myProcNo()] = htc; - Pstream::gatherList(htcs, tag); - - if (Pstream::master()) - { - forAll(values, procI) - { - const Field<scalar>& magSf = magSfs[procI]; - const Field<scalar>& value = values[procI]; - const Field<scalar>& qDot = qDots[procI]; - const Field<scalar>& htc = htcs[procI]; - - forAll(magSf, faceI) - { - os << magSf[faceI] << token::SPACE - << value[faceI] << token::SPACE - << qDot[faceI] << token::SPACE - << htc[faceI] << token::SPACE - << nl; - } - } - - os.flush(); - } - } - else + forAll(patch(), faceI) { - const Field<scalar>& magSf(this->patch().magSf()); - - forAll(patch(), faceI) - { - os << magSf[faceI] << token::SPACE - << Tp[faceI] << token::SPACE - << qDot[faceI] << token::SPACE - << htc[faceI] << token::SPACE - << nl; - } - - os.flush(); + os << magSf[faceI] << token::SPACE + << Tp[faceI] << token::SPACE + << qDot[faceI] << token::SPACE + << htc[faceI] << token::SPACE + << nl; } } -void Foam::externalCoupledTemperatureMixedFvPatchScalarField::evaluate +void Foam::externalCoupledTemperatureMixedFvPatchScalarField::readData ( - const Pstream::commsTypes comms + Istream& is ) { - externalCoupledMixedFvPatchField<scalar>::evaluate(comms); -} + // Assume generic input stream so we can do line-based format and skip + // unused columns + ISstream& iss = dynamic_cast<ISstream&>(is); + string line; -void Foam::externalCoupledTemperatureMixedFvPatchScalarField::write -( - Ostream& os -) const -{ - externalCoupledMixedFvPatchField<scalar>::write(os); + forAll(*this, faceI) + { + iss.getLine(line); + IStringStream lineStr(line); + + lineStr + >> this->refValue()[faceI] + >> this->refGrad()[faceI] + >> this->valueFraction()[faceI]; + } } diff --git a/src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H similarity index 67% rename from src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H index 47fb9153185cd3ec0ab3ea2c7943162f2b80e7c6..23679aac309770cf3bf27f9ee8119cadef922f86 100644 --- a/src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H +++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H @@ -29,7 +29,7 @@ Group Description This boundary condition provides a temperatue interface to an external - application. Values are transferred as plain text files, where OpenFOAM + application. Values are transferred as plain text files, where OpenFOAM data is written as: # Patch: <patch name> @@ -42,59 +42,16 @@ Description and received as the constituent pieces of the `mixed' condition, i.e. # Patch: <patch name> - <value1> <gradient1> <valueFracion1> - <value2> <gradient2> <valueFracion2> - <value3> <gradient3> <valueFracion3> - ... - <valueN> <gradientN> <valueFracionN> - - Data is sent/received as a single file for all patches from the directory - - $FOAM_CASE/<commsDir> - - At start-up, the boundary creates a lock file, i.e.. - - OpenFOAM.lock - - ... to signal the external source to wait. During the boundary condition - update, boundary values are written to file, e.g. - - <fileName>.out - - The lock file is then removed, instructing the external source to take - control of the program execution. When ready, the external program - should create the return values, e.g. to file - - <fileName>.in - - ... and then re-instate the lock file. The boundary condition will then - read the return values, and pass program execution back to OpenFOAM. - + <refValue1> <refGrad1> <valueFraction1> + <refValue2> <refGrad2> <valueFraction2> + <refValue3> <refGrad3> <valueFraction3> + ... + <refValueN> <refGradN> <valueFractionN> - \heading Patch usage - - \table - Property | Description | Required | Default value - commsDir | communications directory | yes | - fileName | transfer file name | yes | - waitInterval | interval [s] between file checks | no | 1 - timeOut | time after which error invoked [s] |no |100*waitInterval - calcFrequency | calculation frequency | no | 1 - log | log program control | no | no - \endtable - - Example of the boundary condition specification: - \verbatim - myPatch - { - type externalCoupledTemperature; - commsDir "$FOAM_CASE/comms"; - fileName data; - calcFrequency 1; - } - \endverbatim + To be used in combination with the externalCoupled functionObject. SeeAlso + externalCoupledFunctionObject mixedFvPatchField externalCoupledMixedFvPatchField @@ -113,10 +70,8 @@ SourceFiles namespace Foam { -class IFstream; - /*---------------------------------------------------------------------------*\ - Class externalCoupledTemperatureMixedFvPatchScalarField Declaration + Class externalCoupledTemperatureMixedFvPatchScalarField Declaration \*---------------------------------------------------------------------------*/ class externalCoupledTemperatureMixedFvPatchScalarField @@ -124,14 +79,6 @@ class externalCoupledTemperatureMixedFvPatchScalarField public externalCoupledMixedFvPatchField<scalar> { -protected: - - // Protected Member Functions - - //- Write header to transfer file - virtual void writeHeader(OFstream& os) const; - - public: //- Runtime type information @@ -210,20 +157,14 @@ public: // Member functions - // Evaluation functions - - //- Evaluate the patch field - virtual void evaluate - ( - const Pstream::commsTypes commsType=Pstream::blocking - ); - - //- Transfer data for external source - virtual void transferData(OFstream& os) const; + //- Write header + virtual void writeHeader(Ostream&) const; + //- Write data + virtual void writeData(Ostream&) const; - //- Write - virtual void write(Ostream&) const; + //- Read data + virtual void readData(Istream&); }; diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/IOrunTimeControl.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/IOrunTimeControl.H new file mode 100644 index 0000000000000000000000000000000000000000..da73cb5db366e6cc2223fcb7187b5d9fd6dae7dc --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/IOrunTimeControl.H @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedef + Foam::IOrunTimeControl + +Description + Instance of the generic IOOutputFilter for runTimeControl. + +\*---------------------------------------------------------------------------*/ + +#ifndef IOrunTimeControl_H +#define IOrunTimeControl_H + +#include "runTimeControl.H" +#include "IOOutputFilter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + typedef IOOutputFilter<runTimeControl> IOrunTimeControl; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.C new file mode 100644 index 0000000000000000000000000000000000000000..1c47a2ea1f6500df1e040f1a6143a3c4046d6b63 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.C @@ -0,0 +1,179 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "averageCondition.H" +#include "addToRunTimeSelectionTable.H" +#include "Time.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(averageCondition, 0); + addToRunTimeSelectionTable(runTimeCondition, averageCondition, dictionary); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::averageCondition::averageCondition +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state +) +: + runTimeCondition(name, obr, dict, state), + functionObjectName_(dict.lookup("functionObjectName")), + fieldNames_(dict.lookup("fields")), + tolerance_(readScalar(dict.lookup("tolerance"))), + window_(dict.lookupOrDefault<scalar>("window", -1)), + totalTime_(fieldNames_.size(), obr_.time().deltaTValue()), + resetOnRestart_(false) +{ + if (resetOnRestart_) + { + const dictionary& dict = conditionDict(); + + forAll(fieldNames_, fieldI) + { + const word& fieldName = fieldNames_[fieldI]; + + if (dict.found(fieldName)) + { + const dictionary& valueDict = dict.subDict(fieldName); + totalTime_[fieldI] = readScalar(valueDict.lookup("totalTime")); + } + } + } +} + + +// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // + +Foam::averageCondition::~averageCondition() +{} + + +// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * // + +bool Foam::averageCondition::apply() +{ + bool satisfied = true; + + if (!active_) + { + return satisfied; + } + + scalar dt = obr_.time().deltaTValue(); + + if (log_) Info<< " " << type() << ": " << name_ << " averages:" << nl; + + DynamicList<label> unprocessedFields(fieldNames_.size()); + + forAll(fieldNames_, fieldI) + { + const word& fieldName(fieldNames_[fieldI]); + + scalar Dt = totalTime_[fieldI]; + scalar alpha = (Dt - dt)/Dt; + scalar beta = dt/Dt; + + if (window_ > 0) + { + if (Dt - dt >= window_) + { + alpha = (window_ - dt)/window_; + beta = dt/window_; + } + else + { + // Ensure that averaging is performed over window time + // before condition can be satisfied + satisfied = false; + } + } + + bool processed = false; + calc<scalar>(fieldName, alpha, beta, satisfied, processed); + calc<vector>(fieldName, alpha, beta, satisfied, processed); + calc<sphericalTensor>(fieldName, alpha, beta, satisfied, processed); + calc<symmTensor>(fieldName, alpha, beta, satisfied, processed); + calc<tensor>(fieldName, alpha, beta, satisfied, processed); + + if (!processed) + { + unprocessedFields.append(fieldI); + } + + totalTime_[fieldI] += dt; + } + + if (unprocessedFields.size()) + { + WarningIn("bool Foam::averageCondition::apply()") + << "From function object: " << functionObjectName_ << nl + << "Unprocessed fields:" << nl; + + forAll(unprocessedFields, i) + { + label fieldI = unprocessedFields[i]; + Info<< " " << fieldNames_[fieldI] << nl; + } + } + + if (log_) Info<< endl; + + return satisfied; +} + + +void Foam::averageCondition::write() +{ + dictionary& conditionDict = this->conditionDict(); + + forAll(fieldNames_, fieldI) + { + const word& fieldName = fieldNames_[fieldI]; + + // value dictionary should be present - mean values are written there + if (conditionDict.found(fieldName)) + { + dictionary& valueDict = conditionDict.subDict(fieldName); + valueDict.add("totalTime", totalTime_[fieldI], true); + } + else + { + dictionary valueDict; + valueDict.add("totalTime", totalTime_[fieldI], true); + conditionDict.add(fieldName, valueDict); + } + } +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.H new file mode 100644 index 0000000000000000000000000000000000000000..0734cda8fd9309f9a7abaf7b6496adbeede529f2 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.H @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::averageCondition + +Description + Average run time condition - satisfied when average does not change by + more than a given value. + +SourceFiles + averageCondition.H + averageCondition.C + +\*---------------------------------------------------------------------------*/ + +#ifndef averageCondition_H +#define averageCondition_H + +#include "runTimeCondition.H" +#include "Switch.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class averageCondition Declaration +\*---------------------------------------------------------------------------*/ + +class averageCondition +: + public runTimeCondition +{ +protected: + + // Protected data + + //- Name of function object to retrueve data from + word functionObjectName_; + + //- List of fields on which to operate + wordList fieldNames_; + + //- Satisfied when difference in mean values is less than this value + const scalar tolerance_; + + //- Averaging window + const scalar window_; + + //- Average time per field + List<scalar> totalTime_; + + //- Reset the averaging process on restart flag + Switch resetOnRestart_; + + + // Protected Member Functions + + //- Templated function to calculate the average + template<class Type> + void calc + ( + const word& fieldName, + const scalar alpha, + const scalar beta, + bool& satisfied, + bool& processed + ); + + +public: + + //- Runtime type information + TypeName("average"); + + //- Constructor + averageCondition + ( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state + ); + + //- Destructor + virtual ~averageCondition(); + + + // Public Member Functions + + //- Apply the condition + virtual bool apply(); + + //- Write + virtual void write(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "averageConditionTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageConditionTemplates.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageConditionTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..d5d35ed61d79f155002e197d877db2e67f3c4ac4 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageConditionTemplates.C @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +template<class Type> +void Foam::averageCondition::calc +( + const word& fieldName, + const scalar alpha, + const scalar beta, + bool& satisfied, + bool& processed +) +{ + const word valueType = + state_.objectResultType(functionObjectName_, fieldName); + + if (pTraits<Type>::typeName != valueType) + { + return; + } + + Type currentValue = + state_.getObjectResult<Type>(functionObjectName_, fieldName); + + const word meanName(fieldName + "Mean"); + + Type meanValue = state_.getResult<Type>(meanName); + meanValue = alpha*meanValue + beta*currentValue; + + scalar delta = mag(meanValue - currentValue); + + if (log_) + { + Info<< " " << meanName << ": " << meanValue + << ", delta: " << delta << nl; + } + + state_.setResult(meanName, meanValue); + + if (delta > tolerance_) + { + satisfied = false; + } + + processed = true; +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.C new file mode 100644 index 0000000000000000000000000000000000000000..73de3e3f3d45f7aeee2ba27a0237755fba3bfe98 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.C @@ -0,0 +1,222 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "equationInitialResidualCondition.H" +#include "addToRunTimeSelectionTable.H" +#include "fvMesh.H" +#include "Time.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(equationInitialResidualCondition, 0); + addToRunTimeSelectionTable + ( + runTimeCondition, + equationInitialResidualCondition, + dictionary + ); + + template<> + const char* Foam::NamedEnum + < + equationInitialResidualCondition::operatingMode, + 2 + >::names[] = + { + "minimum", + "maximum" + }; + + const NamedEnum<Foam::equationInitialResidualCondition::operatingMode, 2> + Foam::equationInitialResidualCondition::operatingModeNames; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::equationInitialResidualCondition::equationInitialResidualCondition +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state +) +: + runTimeCondition(name, obr, dict, state), + fieldNames_(dict.lookup("fields")), + value_(readScalar(dict.lookup("value"))), + timeStart_(dict.lookupOrDefault("timeStart", -GREAT)), + mode_(operatingModeNames.read(dict.lookup("mode"))) +{ + if (!fieldNames_.size()) + { + WarningIn + ( + "Foam::equationInitialResidualCondition::" + "equationInitialResidualCondition" + "(" + "const word&, " + "const objectRegistry&, " + "const dictionary&, " + "functionObjectState&" + ")" + ) + << "No fields supplied: deactivating" << endl; + + active_ = false; + } +} + + +// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // + +Foam::equationInitialResidualCondition:: +~equationInitialResidualCondition() +{} + + +// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * // + +bool Foam::equationInitialResidualCondition::apply() +{ + bool satisfied = false; + + if (!active_) + { + return true; + } + + if ((obr_.time().timeIndex() < 3) || (obr_.time().value() < timeStart_)) + { + // Do not start checking until reached start time + return false; + } + + const fvMesh& mesh = refCast<const fvMesh>(obr_); + const dictionary& solverDict = mesh.solverPerformanceDict(); + + List<scalar> result(fieldNames_.size(), -VGREAT); + + forAll(fieldNames_, fieldI) + { + const word& fieldName = fieldNames_[fieldI]; + + if (solverDict.found(fieldName)) + { + const List<solverPerformance> sp(solverDict.lookup(fieldName)); + const scalar residual = sp.first().initialResidual(); + result[fieldI] = residual; + + switch (mode_) + { + case omMin: + { + if (residual < value_) + { + satisfied = true; + } + break; + } + case omMax: + { + if (residual > value_) + { + satisfied = true; + } + break; + } + default: + { + FatalErrorIn + ( + "bool Foam::equationInitialResidualCondition::apply()" + ) + << "Unhandled enumeration " + << operatingModeNames[mode_] + << abort(FatalError); + } + } + } + } + + bool valid = false; + forAll(result, i) + { + if (result[i] < 0) + { + WarningIn("bool Foam::equationInitialResidualCondition::apply()") + << "Initial residual data not found for field " + << fieldNames_[i] << endl; + } + else + { + valid = true; + } + } + + if (!valid) + { + WarningIn("bool Foam::equationInitialResidualCondition::apply()") + << "Initial residual data not found for any fields: " + << "deactivating" << endl; + + active_ = false; + } + + if (satisfied && valid) + { + if (log_) + { + Info<< type() << ": " << name_ + << ": satisfied using threshold value: " << value_ << nl; + } + + forAll(result, resultI) + { + if (result[resultI] > 0) + { + if (log_) + { + Info<< " field: " << fieldNames_[resultI] + << ", residual: " << result[resultI] << nl; + } + } + } + if (log_) Info<< endl; + } + + return satisfied; +} + + +void Foam::equationInitialResidualCondition::write() +{ + // do nothing +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.H new file mode 100644 index 0000000000000000000000000000000000000000..60a2163b7db6e818b6d6c766d9b2e9ed8f4701db --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.H @@ -0,0 +1,119 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::equationInitialResidualCondition + +Description + Minimum or maximum initial residual run time condition + +SourceFiles + equationInitialResidualCondition.H + equationInitialResidualCondition.C + +\*---------------------------------------------------------------------------*/ + +#ifndef equationInitialResidualCondition_H +#define equationInitialResidualCondition_H + +#include "runTimeCondition.H" +#include "NamedEnum.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class equationInitialResidualCondition Declaration +\*---------------------------------------------------------------------------*/ + +class equationInitialResidualCondition +: + public runTimeCondition +{ +public: + + enum operatingMode + { + omMin, + omMax + }; + + static const NamedEnum<operatingMode, 2> operatingModeNames; + + +protected: + + // Protected data + + //- Field name + const wordList fieldNames_; + + //- Value to compare + const scalar value_; + + //- Start checking from time - always skips first iteration + scalar timeStart_; + + //- Operating mode + operatingMode mode_; + + +public: + + //- Runtime type information + TypeName("equationInitialResidual"); + + //- Constructor + equationInitialResidualCondition + ( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state + ); + + //- Destructor + virtual ~equationInitialResidualCondition(); + + + // Public Member Functions + + //- Apply the condition + virtual bool apply(); + + //- Write + virtual void write(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.C new file mode 100644 index 0000000000000000000000000000000000000000..ebad50629d8fc36243e1a035eed16b635f36d286 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.C @@ -0,0 +1,183 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "equationMaxIterCondition.H" +#include "addToRunTimeSelectionTable.H" +#include "fvMesh.H" +#include "Time.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(equationMaxIterCondition, 0); + addToRunTimeSelectionTable + ( + runTimeCondition, + equationMaxIterCondition, + dictionary + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::equationMaxIterCondition::equationMaxIterCondition +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state +) +: + runTimeCondition(name, obr, dict, state), + fieldNames_(dict.lookup("fields")), + threshold_(readLabel(dict.lookup("threshold"))), + startIter_(dict.lookupOrDefault("startIter", 2)) +{ + if (!fieldNames_.size()) + { + WarningIn + ( + "Foam::equationMaxIterCondition::" + "equationMaxIterCondition" + "(" + "const word&, " + "const objectRegistry&, " + "const dictionary&, " + "functionObjectState&" + ")" + ) + << "No fields supplied: deactivating" << endl; + + active_ = false; + } + + startIter_ = max(startIter_, 2); +} + + +// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // + +Foam::equationMaxIterCondition::~equationMaxIterCondition() +{} + + +// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * // + +bool Foam::equationMaxIterCondition::apply() +{ + bool satisfied = false; + + if (!active_) + { + return true; + } + + if (obr_.time().timeIndex() < startIter_) + { + // Do not start checking until start iter + return false; + } + + const fvMesh& mesh = refCast<const fvMesh>(obr_); + const dictionary& solverDict = mesh.solverPerformanceDict(); + + List<label> result(fieldNames_.size(), -1); + + forAll(fieldNames_, fieldI) + { + const word& fieldName = fieldNames_[fieldI]; + + if (solverDict.found(fieldName)) + { + const List<solverPerformance> sp(solverDict.lookup(fieldName)); + const label nIterations = sp.first().nIterations(); + result[fieldI] = nIterations; + + if (nIterations > threshold_) + { + satisfied = true; + } + } + } + + bool valid = false; + forAll(result, i) + { + if (result[i] < 0) + { + WarningIn("bool Foam::equationMaxIterCondition::apply()") + << "Number of iterations data not found for field " + << fieldNames_[i] << endl; + } + else + { + valid = true; + } + } + + if (!valid) + { + WarningIn("bool Foam::equationMaxIterCondition::apply()") + << "Number of iterations data not found for any fields: " + << "deactivating" << endl; + + active_ = false; + } + + if (satisfied && valid) + { + if (log_) + { + Info<< type() << ": " << name_ + << ": satisfied using threshold value: " << threshold_ << nl; + } + + forAll(result, resultI) + { + if (result[resultI] != -1) + { + if (log_) + { + Info<< " field: " << fieldNames_[resultI] + << ", iterations: " << result[resultI] << nl; + } + } + } + if (log_) Info<< endl; + } + + return satisfied; +} + + +void Foam::equationMaxIterCondition::write() +{ + // do nothing +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.H new file mode 100644 index 0000000000000000000000000000000000000000..d77ab68366a7b640fcb046f6e4ae305231194f0f --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.H @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::equationMaxIterCondition + +Description + Maximum number of equation iterations run time condition + +SourceFiles + equationMaxIterCondition.H + equationMaxIterCondition.C + +\*---------------------------------------------------------------------------*/ + +#ifndef equationMaxIterCondition_H +#define equationMaxIterCondition_H + +#include "runTimeCondition.H" +#include "NamedEnum.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class equationMaxIterCondition Declaration +\*---------------------------------------------------------------------------*/ + +class equationMaxIterCondition +: + public runTimeCondition +{ +protected: + + // Protected data + + //- Field name + const wordList fieldNames_; + + //- Threshold for maximum number of iterations + const label threshold_; + + //- Start checking from iteration - always skips first iteration + label startIter_; + + +public: + + //- Runtime type information + TypeName("equationMaxIter"); + + //- Constructor + equationMaxIterCondition + ( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state + ); + + //- Destructor + virtual ~equationMaxIterCondition(); + + + // Public Member Functions + + //- Apply the condition + virtual bool apply(); + + //- Write + virtual void write(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.C new file mode 100644 index 0000000000000000000000000000000000000000..ba86537e0911ec48d022b004443b62970d9a59b1 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.C @@ -0,0 +1,165 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "minMaxCondition.H" +#include "addToRunTimeSelectionTable.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +template<> +void Foam::minMaxCondition::setValue<Foam::scalar> +( + const word& valueType, + const word& fieldName, + scalar& value +) const +{ + state_.getObjectResult(functionObjectName_, fieldName, value); +} + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(minMaxCondition, 0); + addToRunTimeSelectionTable(runTimeCondition, minMaxCondition, dictionary); + + template<> + const char* NamedEnum<minMaxCondition::modeType, 2>::names[] = + { + "minimum", + "maximum" + }; +} + +const Foam::NamedEnum<Foam::minMaxCondition::modeType, 2> + Foam::minMaxCondition::modeTypeNames_; + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::minMaxCondition::minMaxCondition +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state +) +: + runTimeCondition(name, obr, dict, state), + functionObjectName_(dict.lookup("functionObjectName")), + mode_(modeTypeNames_.read(dict.lookup("mode"))), + fieldNames_(dict.lookup("fields")), + value_(readScalar(dict.lookup("value"))) +{} + + +// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // + +Foam::minMaxCondition::~minMaxCondition() +{} + + +// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * // + +bool Foam::minMaxCondition::apply() +{ + bool satisfied = true; + + if (!active_) + { + return satisfied; + } + + forAll(fieldNames_, fieldI) + { + const word& fieldName = fieldNames_[fieldI]; + + const word valueType = + state_.objectResultType(functionObjectName_, fieldName); + + if (valueType == word::null) + { + WarningIn("bool Foam::minMaxCondition::apply()") + << "Unable to find entry " << fieldName + << " for function object " << functionObjectName_ + << ". Condition will not be applied." + << endl; + + continue; + } + + scalar v = 0; + setValue<scalar>(valueType, fieldName, v); + setValue<vector>(valueType, fieldName, v); + setValue<sphericalTensor>(valueType, fieldName, v); + setValue<symmTensor>(valueType, fieldName, v); + setValue<tensor>(valueType, fieldName, v); + + Switch ok = false; + switch (mode_) + { + case mdMin: + { + if (v < value_) + { + ok = true; + } + break; + } + case mdMax: + { + if (v > value_) + { + ok = true; + } + break; + } + } + + if (log_) + { + Info<< " " << type() << ": " << modeTypeNames_[mode_] << " " + << fieldName << ": value = " << v + << ", threshold value = " << value_ + << ", satisfied = " << ok << endl; + } + + satisfied = satisfied && ok; + } + + return satisfied; +} + + +void Foam::minMaxCondition::write() +{ + // do nothing +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.H new file mode 100644 index 0000000000000000000000000000000000000000..7bd899d3fe9cd60aba2b35c073b2df3c2ae26b86 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.H @@ -0,0 +1,145 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::minMaxCondition + +Description + Minimum/maximum run time conditions. If the value type is not scalar, + the magnitude of the value is used in the evaluation. + +SourceFiles + minMaxCondition.H + minMaxCondition.C + +\*---------------------------------------------------------------------------*/ + +#ifndef minMaxCondition_H +#define minMaxCondition_H + +#include "runTimeCondition.H" +#include "NamedEnum.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class minMaxCondition Declaration +\*---------------------------------------------------------------------------*/ + +class minMaxCondition +: + public runTimeCondition +{ +public: + + // Public enumerations + + // Mode type + enum modeType + { + mdMin, + mdMax + }; + + static const NamedEnum<modeType, 2> modeTypeNames_; + + +protected: + + // Protected data + + //- Name of function object to retrueve data from + word functionObjectName_; + + //- Mode + modeType mode_; + + //- Field names + const wordList fieldNames_; + + //- Value to compare + const scalar value_; + + //- Helper function to retrieve the value from the state dictionary + template<class Type> + void setValue + ( + const word& valueType, + const word& fieldName, + scalar& value + ) const; + + +public: + + //- Runtime type information + TypeName("minMax"); + + //- Constructor + minMaxCondition + ( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state + ); + + //- Destructor + virtual ~minMaxCondition(); + + + // Public Member Functions + + //- Apply the condition + virtual bool apply(); + + //- Write + virtual void write(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +template<> +void minMaxCondition::setValue<Foam::scalar> +( + const word& valueType, + const word& fieldName, + scalar& value +) const; + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "minMaxConditionTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxConditionTemplates.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxConditionTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..a8befe9cda9779421e9c12e4ac65689c2cc7e581 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxConditionTemplates.C @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +template<class Type> +void Foam::minMaxCondition::setValue +( + const word& valueType, + const word& fieldName, + scalar& value +) const +{ + if (pTraits<Type>::typeName != valueType) + { + return; + } + + Type v = state_.getObjectResult<Type>(functionObjectName_, fieldName); + value = mag(v); +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.C new file mode 100644 index 0000000000000000000000000000000000000000..4b91fd14dcd3c157a80c243dd06046c61fe23bd7 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.C @@ -0,0 +1,91 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "minTimeStepCondition.H" +#include "addToRunTimeSelectionTable.H" +#include "Time.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(minTimeStepCondition, 0); + addToRunTimeSelectionTable + ( + runTimeCondition, + minTimeStepCondition, + dictionary + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::minTimeStepCondition::minTimeStepCondition +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state +) +: + runTimeCondition(name, obr, dict, state), + minValue_(readScalar(dict.lookup("minValue"))) +{} + + +// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // + +Foam::minTimeStepCondition::~minTimeStepCondition() +{} + + +// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * // + +bool Foam::minTimeStepCondition::apply() +{ + bool satisfied = false; + + if (!active_) + { + return true; + } + + if (obr_.time().deltaTValue() < minValue_) + { + satisfied = true; + } + + return satisfied; +} + + +void Foam::minTimeStepCondition::write() +{ + // do nothing +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.H new file mode 100644 index 0000000000000000000000000000000000000000..b5088a162d62cf6583ccbc2439cb9689b87d5b1c --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.H @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::minTimeStepCondition + +Description + Initial residual run time condition + +SourceFiles + minTimeStepCondition.H + minTimeStepCondition.C + +\*---------------------------------------------------------------------------*/ + +#ifndef minTimeStepCondition_H +#define minTimeStepCondition_H + +#include "runTimeCondition.H" +#include "NamedEnum.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class minTimeStepCondition Declaration +\*---------------------------------------------------------------------------*/ + +class minTimeStepCondition +: + public runTimeCondition +{ +protected: + + // Protected data + + //- Minumim time step value to compare + const scalar minValue_; + + +public: + + //- Runtime type information + TypeName("minTimeStep"); + + //- Constructor + minTimeStepCondition + ( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state + ); + + //- Destructor + virtual ~minTimeStepCondition(); + + + // Public Member Functions + + //- Apply the condition + virtual bool apply(); + + //- Write + virtual void write(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.C new file mode 100644 index 0000000000000000000000000000000000000000..16bcc6cb94090867147a81f71215be1eb04d4422 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.C @@ -0,0 +1,110 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "runTimeCondition.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(runTimeCondition, 0); + defineRunTimeSelectionTable(runTimeCondition, dictionary); +} + + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +Foam::dictionary& Foam::runTimeCondition::setConditionDict() +{ + dictionary& propertyDict = state_.propertyDict(); + + if (!propertyDict.found(name_)) + { + propertyDict.add(name_, dictionary()); + } + + return propertyDict.subDict(name_); +} + + +const Foam::dictionary& Foam::runTimeCondition::conditionDict() const +{ + return conditionDict_; +} + + +Foam::dictionary& Foam::runTimeCondition::conditionDict() +{ + return conditionDict_; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::runTimeCondition::runTimeCondition +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state +) +: + name_(name), + obr_(obr), + state_(state), + active_(dict.lookupOrDefault<bool>("active", true)), + conditionDict_(setConditionDict()), + log_(dict.lookupOrDefault("log", true)), + groupID_(dict.lookupOrDefault("groupID", -1)) +{} + + +// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // + +Foam::runTimeCondition::~runTimeCondition() +{} + + +// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * // + +const Foam::word& Foam::runTimeCondition::name() const +{ + return name_; +} + + +bool Foam::runTimeCondition::active() const +{ + return active_; +} + + +Foam::label Foam::runTimeCondition::groupID() const +{ + return groupID_; +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.H new file mode 100644 index 0000000000000000000000000000000000000000..752a0ad8ec525e3dd95882d9b80c187180aa1ae8 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.H @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::runTimeCondition + +Description + Base class for run time conditions + +SourceFiles + runTimeCondition.C + runTimeConditionNew.C + runTimeCondition.H + +\*---------------------------------------------------------------------------*/ + +#ifndef runTimeCondition_H +#define runTimeCondition_H + +#include "functionObjectState.H" +#include "dictionary.H" +#include "autoPtr.H" +#include "runTimeSelectionTables.H" +#include "Switch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class runTimeCondition Declaration +\*---------------------------------------------------------------------------*/ + +class runTimeCondition +{ + +protected: + + // Protected data + + //- Condition name + word name_; + + //- Reference to the object registry + const objectRegistry& obr_; + + //- State + functionObjectState& state_; + + //- On/off switch + bool active_; + + //- Reference to the condition dictionary + dictionary& conditionDict_; + + //- Switch to send output to Info + Switch log_; + + //- Group index - if applied, all conditions in a group must be + // satisfield before condition is met + label groupID_; + + + // Protected Member Functions + + //- Set the condition dictionary (create if necessary) + dictionary& setConditionDict(); + + //- Return const access to the conditions dictionary + const dictionary& conditionDict() const; + + //- Return non-const access to the conditions dictionary + dictionary& conditionDict(); + + +public: + + //- Runtime type information + TypeName("runTimeCondition"); + + //- Declare runtime constructor selection table + declareRunTimeSelectionTable + ( + autoPtr, + runTimeCondition, + dictionary, + ( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state + ), + (name, obr, dict, state) + ); + + + //- Constructor + runTimeCondition + ( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state + ); + + //- Destructor + virtual ~runTimeCondition(); + + //- Selector + static autoPtr<runTimeCondition> New + ( + const word& conditionName, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state + ); + + + // Public Member Functions + + //- Return the condition name + virtual const word& name() const; + + //- Return the active flag + virtual bool active() const; + + //- Return the group index + virtual label groupID() const; + + //- Apply the condition + virtual bool apply() = 0; + + //- Write + virtual void write() = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeConditionNew.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeConditionNew.C new file mode 100644 index 0000000000000000000000000000000000000000..72c5d99ca6c42676acf61d0825cd8baae19393d3 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeConditionNew.C @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "runTimeCondition.H" + +// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::runTimeCondition> Foam::runTimeCondition::New +( + const word& conditionName, + const objectRegistry& obr, + const dictionary& dict, + functionObjectState& state +) +{ + word conditionType(dict.lookup("type")); + + Info<< "Selecting runTimeCondition " << conditionType << endl; + + dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(conditionType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalErrorIn + ( + "runTimeCondition::New" + "(" + "const word&, " + "const objectRegistry&, " + "const dictionary&, " + "functionObjectState&" + ")" + ) << "Unknown runTimeCondition type " + << conditionType << nl << nl + << "Valid runTimeCondition types are:" << nl + << dictionaryConstructorTablePtr_->sortedToc() + << exit(FatalError); + } + + return autoPtr<runTimeCondition> + ( + cstrIter()(conditionName, obr, dict, state) + ); +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.C new file mode 100644 index 0000000000000000000000000000000000000000..27e1c4e180224b4c4e11b2364b085245aac90056 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.C @@ -0,0 +1,264 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "runTimeControl.H" +#include "dictionary.H" +#include "runTimeCondition.H" +#include "fvMesh.H" +#include "Time.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(runTimeControl, 0); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::runTimeControl::runTimeControl +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + const bool loadFromFiles +) +: + functionObjectState(obr, name), + obr_(obr), + conditions_(), + groupMap_(), + nWriteStep_(0), + writeStepI_(0) +{ + // Check if the available mesh is an fvMesh, otherwise deactivate + if (setActive<fvMesh>()) + { + read(dict); + + // Check that some conditions are set + if (conditions_.empty()) + { + Info<< type() << " " << name_ << " output:" << nl + << " No conditions present - deactivating" << nl + << endl; + + active_ = false; + } + else + { + // Check that at least one condition is active + active_ = false; + forAll(conditions_, conditionI) + { + if (conditions_[conditionI].active()) + { + active_ = true; + break; + } + } + + if (!active_) + { + Info<< type() << " " << name_ << " output:" << nl + << " All conditions inactive - deactivating" << nl + << endl; + } + } + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::runTimeControl::~runTimeControl() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::runTimeControl::read(const dictionary& dict) +{ + if (active_) + { + const dictionary& conditionsDict = dict.subDict("conditions"); + const wordList conditionNames(conditionsDict.toc()); + conditions_.setSize(conditionNames.size()); + + label uniqueGroupI = 0; + forAll(conditionNames, conditionI) + { + const word& conditionName = conditionNames[conditionI]; + const dictionary& dict = conditionsDict.subDict(conditionName); + + conditions_.set + ( + conditionI, + runTimeCondition::New(conditionName, obr_, dict, *this) + ); + + label groupI = conditions_[conditionI].groupID(); + + if (groupMap_.insert(groupI, uniqueGroupI)) + { + uniqueGroupI++; + } + } + + dict.readIfPresent("nWriteStep", nWriteStep_); + } +} + + +void Foam::runTimeControl::execute() +{ + if (!active_) + { + return; + } + + Info<< type() << " " << name_ << " output:" << nl; + + // IDs of satisfied conditions + DynamicList<label> IDs(conditions_.size()); + + // Run stops only if all conditions within a group are satisfied + List<bool> groupSatisfied(groupMap_.size(), true); + List<bool> groupActive(groupMap_.size(), false); + + forAll(conditions_, conditionI) + { + runTimeCondition& condition = conditions_[conditionI]; + + if (condition.active()) + { + bool conditionSatisfied = condition.apply(); + + label groupI = condition.groupID(); + + Map<label>::const_iterator conditionIter = groupMap_.find(groupI); + + if (conditionIter == groupMap_.end()) + { + FatalErrorIn("void Foam::runTimeControl::execute()") + << "group " << groupI << " not found in map" + << abort(FatalError); + } + + if (conditionSatisfied) + { + IDs.append(conditionI); + + groupActive[conditionIter()] = true; + + if (groupI == -1) + { + // Condition not part of a group - only requires this to be + // satisfied for completion flag to be set + groupSatisfied[conditionIter()] = true; + break; + } + } + else + { + groupSatisfied[conditionIter()] = false; + } + } + } + + bool done = false; + forAll(groupSatisfied, groupI) + { + if (groupSatisfied[groupI] && groupActive[groupI]) + { + done = true; + break; + } + } + + if (done) + { + forAll(IDs, conditionI) + { + Info<< " " << conditions_[conditionI].type() << ": " + << conditions_[conditionI].name() + << " condition satisfied" << nl; + } + + + // Set to write a data dump or finalise the calculation + Time& time = const_cast<Time&>(obr_.time()); + + if (writeStepI_ < nWriteStep_ - 1) + { + writeStepI_++; + Info<< " Writing fields - step " << writeStepI_ << nl; + time.writeNow(); + } + else + { + Info<< " Stopping calculation" << nl + << " Writing fields - final step" << nl; + time.writeAndEnd(); + } + } + else + { + Info<< " Conditions not met - calculations proceeding" << nl; + } + + Info<< endl; +} + + +void Foam::runTimeControl::end() +{ + if (active_) + { + execute(); + } +} + + +void Foam::runTimeControl::timeSet() +{ + // Do nothing +} + + +void Foam::runTimeControl::write() +{ + if (active_) + { + forAll(conditions_, conditionI) + { + conditions_[conditionI].write(); + } + } +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.H new file mode 100644 index 0000000000000000000000000000000000000000..fff6c446485755c3ac3e34cba680bcaef25620e4 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.H @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::runTimeControl + +Group + grpJobControlFunctionObjects + +Description + This function object controls when the calculation is terminated based on + satisfying user-specified conditions. + + Optionally specify a number of write steps before the calculation is + terminated. Here, a write is performed each time that all conditons are + satisfied. + +SourceFiles + runTimeControl.C + IOrunTimeControl.H + +\*---------------------------------------------------------------------------*/ + +#ifndef runTimeControl_H +#define runTimeControl_H + +#include "functionObjectState.H" +#include "Map.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class objectRegistry; +class dictionary; +class polyMesh; +class mapPolyMesh; +class runTimeCondition; + +/*---------------------------------------------------------------------------*\ + Class runTimeControl Declaration +\*---------------------------------------------------------------------------*/ + +class runTimeControl +: + public functionObjectState +{ + // Private data + + //- Reference to the database + const objectRegistry& obr_; + + //- List of conditions to satisfy + PtrList<runTimeCondition> conditions_; + + //- Map to define group IDs + Map<label> groupMap_; + + //- Number of write steps before exiting + label nWriteStep_; + + //- Current number of steps written + label writeStepI_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + runTimeControl(const runTimeControl&); + + //- Disallow default bitwise assignment + void operator=(const runTimeControl&); + + +public: + + //- Runtime type information + TypeName("runTimeControl"); + + + // Constructors + + //- Construct for given objectRegistry and dictionary. + // Allow the possibility to load fields from files + runTimeControl + ( + const word& name, + const objectRegistry&, + const dictionary&, + const bool loadFromFiles = false + ); + + + //- Destructor + virtual ~runTimeControl(); + + + // Member Functions + + //- Return name of the set of runTimeControl + virtual const word& name() const + { + return name_; + } + + //- Read the runTimeControl data + virtual void read(const dictionary&); + + //- Execute, currently does nothing + virtual void execute(); + + //- Execute at the final time-loop, currently does nothing + virtual void end(); + + //- Called when time was set at the end of the Time::operator++ + virtual void timeSet(); + + //- Calculate the runTimeControl and write + virtual void write(); + + //- Update for changes of mesh + virtual void updateMesh(const mapPolyMesh&) + {} + + //- Update for changes of mesh + virtual void movePoints(const polyMesh&) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.C new file mode 100644 index 0000000000000000000000000000000000000000..7ba3518564ab65c147dc49eb8096ef0a11620718 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.C @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "runTimeControlFunctionObject.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineNamedTemplateTypeNameAndDebug(runTimeControlFunctionObject, 0); + + addToRunTimeSelectionTable + ( + functionObject, + runTimeControlFunctionObject, + dictionary + ); +} + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.H new file mode 100644 index 0000000000000000000000000000000000000000..6b600c33d158b22a2e438edc985494d0a1608aa6 --- /dev/null +++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.H @@ -0,0 +1,54 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedef + Foam::runTimeControlFunctionObject + +Description + FunctionObject wrapper around runTimeControl to allow it to be created + via the functions entry within controlDict. + +SourceFiles + runTimeControlFunctionObject.C + +\*---------------------------------------------------------------------------*/ + +#ifndef runTimeControlFunctionObject_H +#define runTimeControlFunctionObject_H + +#include "runTimeControl.H" +#include "OutputFilterFunctionObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + typedef OutputFilterFunctionObject<runTimeControl> + runTimeControlFunctionObject; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.C b/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.C index 5653a6a177af2645fef993aa0c463c4f8591ce8e..160481398817b45e5b86db9aa083e13b0d5c3fe3 100644 --- a/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.C +++ b/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -68,7 +68,9 @@ Foam::CourantNo::CourantNo obr_(obr), active_(true), phiName_("phi"), - rhoName_("rho") + rhoName_("rho"), + resultName_(name), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -99,7 +101,7 @@ Foam::CourantNo::CourantNo ( IOobject ( - type(), + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -128,8 +130,11 @@ void Foam::CourantNo::read(const dictionary& dict) { if (active_) { - phiName_ = dict.lookupOrDefault<word>("phiName", "phi"); - rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho"); + log_.readIfPresent("log", dict); + + dict.readIfPresent("phiName", phiName_); + dict.readIfPresent("rhoName", rhoName_); + dict.readIfPresent("resultName", resultName_); } } @@ -146,7 +151,7 @@ void Foam::CourantNo::execute() volScalarField& Co = const_cast<volScalarField&> ( - mesh.lookupObject<volScalarField>(type()) + mesh.lookupObject<volScalarField>(resultName_) ); Co.dimensionedInternalField() = byRho @@ -178,9 +183,10 @@ void Foam::CourantNo::write() if (active_) { const volScalarField& CourantNo = - obr_.lookupObject<volScalarField>(type()); + obr_.lookupObject<volScalarField>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << CourantNo.name() << nl << endl; diff --git a/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.H b/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.H index 7460d74ffb42a7094fb9059cb823885a3c7d7fbd..df22943ae11e873b846bcc014dc89c73db2945e2 100644 --- a/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.H +++ b/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,6 +32,27 @@ Description volScalarField. The field is stored on the mesh database so that it can be retrieved and used for other applications. + Example of function object specification to calculate the Courant number: + \verbatim + CourantNo1 + { + type CourantNo; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: CourantNo | yes | + rhoName | Name of density field | no | rho + phiName | Name of flux field | no | phi + resultName | Name of Courant number field | no | <function name> + log | Log to standard output | no | yes + \endtable + + SourceFiles CourantNo.C IOCourantNo.H @@ -77,6 +98,12 @@ class CourantNo //- Name of density field (optional) word rhoName_; + //- Result name + word resultName_; + + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.C b/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.C index 3c72fbfd9b57032b983996b0e1d24e6cc7f2ccb2..90388fa751dda79e71d526c790c694186afbb1db 100644 --- a/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.C +++ b/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -50,7 +50,9 @@ Foam::Lambda2::Lambda2 name_(name), obr_(obr), active_(true), - UName_("U") + UName_("U"), + resultName_(name), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -81,7 +83,7 @@ Foam::Lambda2::Lambda2 ( IOobject ( - type(), + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -109,7 +111,17 @@ void Foam::Lambda2::read(const dictionary& dict) { if (active_) { - UName_ = dict.lookupOrDefault<word>("UName", "U"); + log_.readIfPresent("log", dict); + dict.readIfPresent("UName", UName_); + + if (!dict.readIfPresent("resultName", resultName_)) + { + resultName_ = name_; + if (UName_ != "U") + { + resultName_ = resultName_ + "(" + UName_ + ")"; + } + } } } @@ -134,7 +146,7 @@ void Foam::Lambda2::execute() volScalarField& Lambda2 = const_cast<volScalarField&> ( - mesh.lookupObject<volScalarField>(type()) + mesh.lookupObject<volScalarField>(resultName_) ); Lambda2 = -eigenValues(SSplusWW)().component(vector::Y); @@ -162,9 +174,10 @@ void Foam::Lambda2::write() if (active_) { const volScalarField& Lambda2 = - obr_.lookupObject<volScalarField>(type()); + obr_.lookupObject<volScalarField>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << Lambda2.name() << nl << endl; diff --git a/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.H b/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.H index f4360f46404b714b6043422eb95bbc71042a307d..3de1eb049b9cc89a21f6bb01d76300cfc0a3d7e2 100644 --- a/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.H +++ b/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -32,6 +32,25 @@ Description of the sum of the square of the symmetrical and anti-symmetrical parts of the velocity gradient tensor. + Example of function object specification to calculate Lambda2: + \verbatim + Lambda2_1 + { + type Lambda2; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: Lambda2 | yes | + UName | Name of velocity field | no | U + resultName | Name of Lambda2 field | no | <function name> + log | Log to standard output | no | yes + \endtable + SourceFiles Lambda2.C IOLambda2.H @@ -77,6 +96,12 @@ class Lambda2 //- Name of velocity field, default is "U" word UName_; + //- Result name + word resultName_; + + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/utilities/Make/files b/src/postProcessing/functionObjects/utilities/Make/files index 4c38b4ba67926fff719b85b654a6782259ecff51..8e4eaaf81cb5b464d7220c9a68150211cda6c168 100644 --- a/src/postProcessing/functionObjects/utilities/Make/files +++ b/src/postProcessing/functionObjects/utilities/Make/files @@ -1,28 +1,28 @@ +blendingFactor/blendingFactor.C +blendingFactor/blendingFactorFunctionObject.C + codedFunctionObject/codedFunctionObject.C CourantNo/CourantNo.C CourantNo/CourantNoFunctionObject.C +dsmcFields/dsmcFields.C +dsmcFields/dsmcFieldsFunctionObject.C + +fluxSummary/fluxSummary.C +fluxSummary/fluxSummaryFunctionObject.C + Lambda2/Lambda2.C Lambda2/Lambda2FunctionObject.C Peclet/Peclet.C Peclet/PecletFunctionObject.C -Q/Q.C -Q/QFunctionObject.C - -blendingFactor/blendingFactor.C -blendingFactor/blendingFactorFunctionObject.C - -dsmcFields/dsmcFields.C -dsmcFields/dsmcFieldsFunctionObject.C - pressureTools/pressureTools.C pressureTools/pressureToolsFunctionObject.C -residuals/residuals.C -residuals/residualsFunctionObject.C +Q/Q.C +Q/QFunctionObject.C scalarTransport/scalarTransport.C scalarTransport/scalarTransportFunctionObject.C diff --git a/src/postProcessing/functionObjects/utilities/Make/options b/src/postProcessing/functionObjects/utilities/Make/options index b59c6b86db480ed889122927494e68e979973061..5886ed3e42988c543635a4d6c13aea83df9dade9 100644 --- a/src/postProcessing/functionObjects/utilities/Make/options +++ b/src/postProcessing/functionObjects/utilities/Make/options @@ -11,7 +11,8 @@ EXE_INC = \ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ - -I$(LIB_SRC)/sampling/lnInclude + -I$(LIB_SRC)/sampling/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude LIB_LIBS = \ -lfvOptions \ @@ -26,4 +27,5 @@ LIB_LIBS = \ -lDSMC \ -lfiniteVolume \ -lmeshTools \ - -lsampling + -lsampling \ + -lsurfMesh diff --git a/src/postProcessing/functionObjects/utilities/Peclet/Peclet.C b/src/postProcessing/functionObjects/utilities/Peclet/Peclet.C index 18ac584332129824455c325359ab82ac51cb63fc..8785efbb32428979e54d9a36ba0df291f607c7b3 100644 --- a/src/postProcessing/functionObjects/utilities/Peclet/Peclet.C +++ b/src/postProcessing/functionObjects/utilities/Peclet/Peclet.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -53,7 +53,8 @@ Foam::Peclet::Peclet obr_(obr), active_(true), phiName_("phi"), - rhoName_("rho") + resultName_(name), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -84,7 +85,7 @@ Foam::Peclet::Peclet ( IOobject ( - type(), + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -112,8 +113,9 @@ void Foam::Peclet::read(const dictionary& dict) { if (active_) { - phiName_ = dict.lookupOrDefault<word>("phiName", "phi"); - rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho"); + log_.readIfPresent("log", dict); + dict.readIfPresent("phiName", phiName_); + dict.readIfPresent("resultName", resultName_); } } @@ -127,7 +129,10 @@ void Foam::Peclet::execute() { const fvMesh& mesh = refCast<const fvMesh>(obr_); - tmp<volScalarField> nuEff; + // Obtain nuEff of muEff. Assumes that a compressible flux is present + // when using a compressible turbulence model, and an incompressible + // flux when using an incompressible turbulence model + tmp<volScalarField> nuOrMuEff; if (mesh.foundObject<cmpTurbModel>(turbulenceModel::propertiesName)) { const cmpTurbModel& model = @@ -136,10 +141,7 @@ void Foam::Peclet::execute() turbulenceModel::propertiesName ); - const volScalarField& rho = - mesh.lookupObject<volScalarField>(rhoName_); - - nuEff = model.muEff()/rho; + nuOrMuEff = model.muEff(); } else if ( @@ -152,14 +154,14 @@ void Foam::Peclet::execute() turbulenceModel::propertiesName ); - nuEff = model.nuEff(); + nuOrMuEff = model.nuEff(); } else if (mesh.foundObject<dictionary>("transportProperties")) { const dictionary& model = mesh.lookupObject<dictionary>("transportProperties"); - nuEff = + nuOrMuEff = tmp<volScalarField> ( new volScalarField @@ -179,18 +181,20 @@ void Foam::Peclet::execute() } else { - FatalErrorIn("void Foam::Peclet::write()") + FatalErrorIn("void Foam::Peclet::execute()") << "Unable to determine the viscosity" << exit(FatalError); } + // Note: dimensions of phi will change depending on whether this is + // applied to an incompressible or compressible case const surfaceScalarField& phi = mesh.lookupObject<surfaceScalarField>(phiName_); surfaceScalarField& Peclet = const_cast<surfaceScalarField&> ( - mesh.lookupObject<surfaceScalarField>(type()) + mesh.lookupObject<surfaceScalarField>(resultName_) ); Peclet = @@ -198,7 +202,7 @@ void Foam::Peclet::execute() /( mesh.magSf() *mesh.surfaceInterpolation::deltaCoeffs() - *fvc::interpolate(nuEff) + *fvc::interpolate(nuOrMuEff) ); } } @@ -212,6 +216,7 @@ void Foam::Peclet::end() } } + void Foam::Peclet::timeSet() { // Do nothing @@ -223,9 +228,10 @@ void Foam::Peclet::write() if (active_) { const surfaceScalarField& Peclet = - obr_.lookupObject<surfaceScalarField>(type()); + obr_.lookupObject<surfaceScalarField>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << Peclet.name() << nl << endl; diff --git a/src/postProcessing/functionObjects/utilities/Peclet/Peclet.H b/src/postProcessing/functionObjects/utilities/Peclet/Peclet.H index 5becbe93e951172d1697de0d4f5c7bdb3017896d..e72129a21b1a5b5c555e790e0c3823ec39eec561 100644 --- a/src/postProcessing/functionObjects/utilities/Peclet/Peclet.H +++ b/src/postProcessing/functionObjects/utilities/Peclet/Peclet.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,6 +31,25 @@ Description This function object calculates and outputs the Peclet number as a surfaceScalarField. + Example of function object specification to calculate the Peclet number: + \verbatim + Peclet1 + { + type Peclet; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | type name: Peclet | yes | + phiName | Name of flux field | no | phi + resultName | Name of Peclet field | no | <function name> + log | Log to standard output | no | yes + \endtable + SourceFiles Peclet.C IOPeclet.H @@ -76,8 +95,11 @@ class Peclet //- Name of flux field, default is "phi" word phiName_; - //- Name of density field (compressible cases only), default is "rho" - word rhoName_; + //- Result name + word resultName_; + + //- Switch to send output to Info as well as to file + Switch log_; // Private Member Functions diff --git a/src/postProcessing/functionObjects/utilities/Q/Q.C b/src/postProcessing/functionObjects/utilities/Q/Q.C index 2dda80a88ba632a103161752fc09834aaf511aa6..243f2e92d463d43058c70b088118b2798e70481a 100644 --- a/src/postProcessing/functionObjects/utilities/Q/Q.C +++ b/src/postProcessing/functionObjects/utilities/Q/Q.C @@ -49,7 +49,9 @@ Foam::Q::Q name_(name), obr_(obr), active_(true), - UName_("U") + UName_("U"), + resultName_(name), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -80,7 +82,7 @@ Foam::Q::Q ( IOobject ( - type(), + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -108,7 +110,17 @@ void Foam::Q::read(const dictionary& dict) { if (active_) { - UName_ = dict.lookupOrDefault<word>("UName", "U"); + log_.readIfPresent("log", dict); + dict.readIfPresent("UName", UName_); + + if (!dict.readIfPresent("resultName", resultName_)) + { + resultName_ = name_; + if (UName_ != "U") + { + resultName_ = resultName_ + "(" + UName_ + ")"; + } + } } } @@ -127,7 +139,7 @@ void Foam::Q::execute() volScalarField& Q = const_cast<volScalarField&> ( - mesh.lookupObject<volScalarField>(type()) + mesh.lookupObject<volScalarField>(resultName_) ); Q = 0.5*(sqr(tr(gradU)) - tr(((gradU) & (gradU)))); @@ -155,9 +167,10 @@ void Foam::Q::write() if (active_) { const volScalarField& Q = - obr_.lookupObject<volScalarField>(type()); + obr_.lookupObject<volScalarField>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << Q.name() << nl << endl; diff --git a/src/postProcessing/functionObjects/utilities/Q/Q.H b/src/postProcessing/functionObjects/utilities/Q/Q.H index aed626228c8c61d627fa166907da83af6b0b8506..15452f71a4cb8582afb0a49d90a9f772b315194c 100644 --- a/src/postProcessing/functionObjects/utilities/Q/Q.H +++ b/src/postProcessing/functionObjects/utilities/Q/Q.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -35,6 +35,30 @@ Description Q = 0.5(sqr(tr(\nabla U)) - tr(((\nabla U) \cdot (\nabla U)))) \f] + where + \vartable + U | velocity [m/s] + \endvartable + + Example of function object specification to calculate Q: + \verbatim + Q1 + { + type Q; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | type name: Q | yes | + UName | Name of velocity field | no | U + resultName | Name of Q field | no | <function name> + log | Log to standard output | no | yes + \endtable + SourceFiles Q.C IOQ.H @@ -80,6 +104,12 @@ class Q //- Name of velocity field, default is "U" word UName_; + //- Result name + word resultName_; + + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.C b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.C index 3c98c9d86f237b13d41dadf32d9a37ed8d2d9ef6..73277fc27fb5098681057a21868fcec27a60532d 100644 --- a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.C +++ b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.C @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -34,6 +34,19 @@ namespace Foam } +// * * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * // + +void Foam::blendingFactor::writeFileHeader(Ostream& os) const +{ + writeHeader(os, "Blending factor"); + writeCommented(os, "Time"); + writeTabbed(os, "Scheme1"); + writeTabbed(os, "Scheme2"); + writeTabbed(os, "Blended"); + os << endl; +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::blendingFactor::blendingFactor @@ -44,30 +57,44 @@ Foam::blendingFactor::blendingFactor const bool loadFromFiles ) : + functionObjectState(obr, name), + functionObjectFile(obr, name, typeName, dict), name_(name), obr_(obr), - active_(true), - phiName_("unknown-phiName"), - fieldName_("unknown-fieldName") + phiName_("phi"), + fieldName_("unknown-fieldName"), + resultName_(word::null), + tolerance_(0.001), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate - if (!isA<fvMesh>(obr_)) + if (setActive<fvMesh>()) { - active_ = false; - WarningIn + read(dict); + writeFileHeader(file()); + + const fvMesh& mesh = refCast<const fvMesh>(obr_); + + volScalarField* indicatorPtr ( - "blendingFactor::blendingFactor" - "(" - "const word&, " - "const objectRegistry&, " - "const dictionary&, " - "const bool" - ")" - ) << "No fvMesh available, deactivating " << name_ << nl - << endl; + new volScalarField + ( + IOobject + ( + resultName_, + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedScalar("0", dimless, 0.0), + zeroGradientFvPatchScalarField::typeName + ) + ); + + mesh.objectRegistry::store(indicatorPtr); } - - read(dict); } @@ -83,8 +110,26 @@ void Foam::blendingFactor::read(const dictionary& dict) { if (active_) { - phiName_ = dict.lookupOrDefault<word>("phiName", "phi"); + functionObjectFile::read(dict); + + log_.readIfPresent("log", dict); + + dict.readIfPresent("phiName", phiName_); dict.lookup("fieldName") >> fieldName_; + + + if (!dict.readIfPresent("resultName", resultName_)) + { + resultName_ = name_ + ':' + fieldName_; + } + + dict.readIfPresent("tolerance", tolerance_); + if ((tolerance_ < 0) || (tolerance_ > 1)) + { + FatalErrorIn("void Foam::blendingFactor::read(const dictionary&)") + << "tolerance must be in the range 0 to 1. Supplied value: " + << tolerance_ << exit(FatalError); + } } } @@ -117,16 +162,15 @@ void Foam::blendingFactor::write() { if (active_) { - const word fieldName = "blendingFactor:" + fieldName_; - - const volScalarField& blendingFactor = - obr_.lookupObject<volScalarField>(fieldName); + const volScalarField& indicator = + obr_.lookupObject<volScalarField>(resultName_); - Info<< type() << " " << name_ << " output:" << nl - << " writing field " << blendingFactor.name() << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " writing field " << indicator.name() << nl << endl; - blendingFactor.write(); + indicator.write(); } } diff --git a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.H b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.H index 8b86a25cea60707f2cd5dc7208c6af2344f064b3..f7166470afd563e3b5874ea01211b6fd8e37d22b 100644 --- a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.H +++ b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -28,10 +28,49 @@ Group grpUtilitiesFunctionObjects Description - This function object calculates and outputs the blendingFactor as used by - the bended convection schemes. The output is a volume field (cells) whose - value is calculated via the maximum blending factor for any cell face. - + This function object provides information on the mode of operation of + blended convection schemes. + + The weight of a blended scheme is given by a function of the blending + factor, f: + + weight = f*scheme1 + (1 - f)*scheme2 + + The factor is a face-based quantity, which is converted to a cell-based + quantity by assigning the minimum blending factor for any cell face. + + An indicator (volume) field, named <functionObjectName>:<fieldName>, is + generated that is set to (1 - f), i.e. values of: + - 0 represent scheme1 as active, and + - 1 represent scheme2 as active. + - intermediate values show the contribution to scheme2 + + Additional reporting is written to the standard output, providing + statistics as to the number of cells used by each scheme. + + Example of function object specification to calculate the blending factor: + \verbatim + blendingFactor1 + { + type blendingFactor; + functionObjectLibs ("libutilityFunctionObjects.so"); + + ... + + // Name of field + fieldName U; + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: blendingFactor | yes | + phiName | Name of flux field | no | phi + fieldName | Name of field to evaluate | yes | + tolerance | Tolerance for number of blended cells | no | 0.001 + log | Log to standard output | no | yes + \endtable SourceFiles blendingFactor.C @@ -42,6 +81,8 @@ SourceFiles #ifndef blendingFactor_H #define blendingFactor_H +#include "functionObjectState.H" +#include "functionObjectFile.H" #include "volFieldsFwd.H" #include "surfaceFieldsFwd.H" #include "OFstream.H" @@ -59,28 +100,37 @@ class polyMesh; class mapPolyMesh; /*---------------------------------------------------------------------------*\ - Class blendingFactor Declaration + Class blendingFactor Declaration \*---------------------------------------------------------------------------*/ class blendingFactor +: + public functionObjectState, + public functionObjectFile { // Private data - //- Name of this set of blendingFactor objects - word name_; + //- Name + const word name_; //- Reference to the database const objectRegistry& obr_; - //- On/off switch - bool active_; - //- Name of flux field, default is "phi" word phiName_; //- Field name word fieldName_; + //- Result field name + word resultName_; + + //- Tolerance used when calculating the number of blended cells + scalar tolerance_; + + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions @@ -90,18 +140,19 @@ class blendingFactor //- Disallow default bitwise assignment void operator=(const blendingFactor&); - //- Return the blending factor field from the database - template<class Type> - volScalarField& factor - ( - const GeometricField<Type, fvPatchField, volMesh>& field - ); - //- Calculate the blending factor template<class Type> void calc(); +protected: + + // Protected Member Functions + + //- Write the file header + virtual void writeFileHeader(Ostream& os) const; + + public: //- Runtime type information diff --git a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactorTemplates.C b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactorTemplates.C index 3a284b8c731b0d83025cb989674f7c9c93662135..8dec0602fc8cf7e300de91966b9bf121a8cb25f1 100644 --- a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactorTemplates.C +++ b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactorTemplates.C @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,45 +29,6 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -template<class Type> -Foam::volScalarField& Foam::blendingFactor::factor -( - const GeometricField<Type, fvPatchField, volMesh>& field -) -{ - const word fieldName = "blendingFactor:" + field.name(); - - if (!obr_.foundObject<volScalarField>(fieldName)) - { - const fvMesh& mesh = refCast<const fvMesh>(obr_); - - volScalarField* factorPtr = - new volScalarField - ( - IOobject - ( - fieldName, - mesh.time().timeName(), - mesh, - IOobject::NO_READ, - IOobject::NO_WRITE - ), - mesh, - dimensionedScalar("0", dimless, 0.0), - zeroGradientFvPatchScalarField::typeName - ); - - obr_.store(factorPtr); - } - - return - const_cast<volScalarField&> - ( - obr_.lookupObject<volScalarField>(fieldName) - ); -} - - template<class Type> void Foam::blendingFactor::calc() { @@ -104,15 +65,60 @@ void Foam::blendingFactor::calc() << exit(FatalError); } - // retrieve the face-based blending factor + // Retrieve the face-based blending factor const blendedSchemeBase<Type>& blendedScheme = refCast<const blendedSchemeBase<Type> >(interpScheme); const surfaceScalarField factorf(blendedScheme.blendingFactor(field)); - // convert into vol field whose values represent the local face maxima - volScalarField& factor = this->factor(field); - factor = fvc::cellReduce(factorf, maxEqOp<scalar>()); - factor.correctBoundaryConditions(); + // Convert into vol field whose values represent the local face minima + // Note: factor applied to 1st scheme, and (1-factor) to 2nd scheme + volScalarField& indicator = + const_cast<volScalarField&> + ( + obr_.lookupObject<volScalarField>(resultName_) + ); + indicator = 1 - fvc::cellReduce(factorf, minEqOp<scalar>(), GREAT); + indicator.correctBoundaryConditions(); + + // Generate scheme statistics + label nCellsScheme1 = 0; + label nCellsScheme2 = 0; + label nCellsBlended = 0; + forAll(indicator, cellI) + { + scalar i = indicator[cellI]; + + if (i < tolerance_) + { + nCellsScheme1++; + } + else if (i > (1 - tolerance_)) + { + nCellsScheme2++; + } + else + { + nCellsBlended++; + } + } + + reduce(nCellsScheme1, sumOp<label>()); + reduce(nCellsScheme2, sumOp<label>()); + reduce(nCellsBlended, sumOp<label>()); + + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " scheme 1 cells : " << nCellsScheme1 << nl + << " scheme 2 cells : " << nCellsScheme2 << nl + << " blended cells : " << nCellsBlended << nl + << endl; + + file() + << obr_.time().time().value() + << token::TAB << nCellsScheme1 + << token::TAB << nCellsScheme2 + << token::TAB << nCellsBlended + << endl; } diff --git a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C index dd9400bb94fcc564fa099a6727f0b7d478590fac..348798ef783e9e2b73a4b8d6c22b12fc675476a9 100644 --- a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C +++ b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -52,7 +52,8 @@ Foam::dsmcFields::dsmcFields : name_(name), obr_(obr), - active_(true) + active_(true), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -87,7 +88,7 @@ void Foam::dsmcFields::read(const dictionary& dict) { if (active_) { - + log_.readIfPresent("log", dict); } } @@ -122,46 +123,32 @@ void Foam::dsmcFields::write() word iDofMeanName = "iDofMean"; word fDMeanName = "fDMean"; - const volScalarField& rhoNMean = obr_.lookupObject<volScalarField> - ( - rhoNMeanName - ); + const volScalarField& rhoNMean = + obr_.lookupObject<volScalarField>(rhoNMeanName); - const volScalarField& rhoMMean = obr_.lookupObject<volScalarField> - ( - rhoMMeanName - ); + const volScalarField& rhoMMean = + obr_.lookupObject<volScalarField>(rhoMMeanName); - const volVectorField& momentumMean = obr_.lookupObject<volVectorField> - ( - momentumMeanName - ); + const volVectorField& momentumMean = + obr_.lookupObject<volVectorField>(momentumMeanName); - const volScalarField& linearKEMean = obr_.lookupObject<volScalarField> - ( - linearKEMeanName - ); + const volScalarField& linearKEMean = + obr_.lookupObject<volScalarField>(linearKEMeanName); - const volScalarField& internalEMean = obr_.lookupObject<volScalarField> - ( - internalEMeanName - ); + const volScalarField& internalEMean = + obr_.lookupObject<volScalarField>(internalEMeanName); - const volScalarField& iDofMean = obr_.lookupObject<volScalarField> - ( - iDofMeanName - ); + const volScalarField& iDofMean = + obr_.lookupObject<volScalarField>(iDofMeanName); - const volVectorField& fDMean = obr_.lookupObject<volVectorField> - ( - fDMeanName - ); + const volVectorField& fDMean = + obr_.lookupObject<volVectorField>(fDMeanName); if (min(mag(rhoNMean)).value() > VSMALL) { - Info<< "Calculating dsmcFields." << endl; + if (log_) Info<< type() << " " << name_ << " output:" << endl; - Info<< " Calculating UMean field." << endl; + if (log_) Info<< " Calculating UMean field" << endl; volVectorField UMean ( IOobject @@ -174,7 +161,7 @@ void Foam::dsmcFields::write() momentumMean/rhoMMean ); - Info<< " Calculating translationalT field." << endl; + if (log_) Info<< " Calculating translationalT field" << endl; volScalarField translationalT ( IOobject @@ -189,7 +176,7 @@ void Foam::dsmcFields::write() *(linearKEMean - 0.5*rhoMMean*(UMean & UMean)) ); - Info<< " Calculating internalT field." << endl; + if (log_) Info<< " Calculating internalT field" << endl; volScalarField internalT ( IOobject @@ -202,7 +189,7 @@ void Foam::dsmcFields::write() (2.0/physicoChemical::k.value())*(internalEMean/iDofMean) ); - Info<< " Calculating overallT field." << endl; + if (log_) Info<< " Calculating overallT field" << endl; volScalarField overallT ( IOobject @@ -216,7 +203,7 @@ void Foam::dsmcFields::write() *(linearKEMean - 0.5*rhoMMean*(UMean & UMean) + internalEMean) ); - Info<< " Calculating pressure field." << endl; + if (log_) Info<< " Calculating pressure field" << endl; volScalarField p ( IOobject @@ -243,25 +230,28 @@ void Foam::dsmcFields::write() } } - Info<< " mag(UMean) max/min : " - << max(mag(UMean)).value() << " " - << min(mag(UMean)).value() << endl; + if (log_) + { + Info<< " mag(UMean) max/min: " + << max(mag(UMean)).value() << " " + << min(mag(UMean)).value() << endl; - Info<< " translationalT max/min : " - << max(translationalT).value() << " " - << min(translationalT).value() << endl; + Info<< " translationalT max/min: " + << max(translationalT).value() << " " + << min(translationalT).value() << endl; - Info<< " internalT max/min : " - << max(internalT).value() << " " - << min(internalT).value() << endl; + Info<< " internalT max/min: " + << max(internalT).value() << " " + << min(internalT).value() << endl; - Info<< " overallT max/min : " - << max(overallT).value() << " " - << min(overallT).value() << endl; + Info<< " overallT max/min: " + << max(overallT).value() << " " + << min(overallT).value() << endl; - Info<< " p max/min : " - << max(p).value() << " " - << min(p).value() << endl; + Info<< " p max/min: " + << max(p).value() << " " + << min(p).value() << endl; + } UMean.write(); @@ -273,13 +263,14 @@ void Foam::dsmcFields::write() p.write(); - Info<< "dsmcFields written." << nl << endl; + if (log_) Info<< " " << type() << " written" << nl << endl; } else { - Info<< "Small value (" << min(mag(rhoNMean)) + if (log_) Info + << "Small value (" << min(mag(rhoNMean)) << ") found in rhoNMean field. " - << "Not calculating dsmcFields to avoid division by zero." + << "Not calculating " << type() << " to avoid division by zero." << endl; } } diff --git a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.H b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.H index b6f7ae68d61dc0bd968fbfc4b8eef43cf3bd02fb..ccef65a1075a5ea52da92a9c99c36acbaf0124a4 100644 --- a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.H +++ b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -28,13 +28,32 @@ Group grpUtilitiesFunctionObjects Description - Calculate intensive fields: + This function object calculates and outputs the intensive fields: - UMean - translationalT - internalT - overallT from averaged extensive fields from a DSMC calculation. + + Example of function object specification to calculate DSMC fields: + \verbatim + dsmcFields1 + { + type dsmcFields; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: dsmcFields | yes | + log | Log to standard output | no | yes + \endtable + + SourceFiles dsmcFields.C IOdsmcFields.H @@ -45,6 +64,7 @@ SourceFiles #define dsmcFields_H #include "typeInfo.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -73,6 +93,9 @@ class dsmcFields //- on/off switch bool active_; + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/IOfluxSummary.H b/src/postProcessing/functionObjects/utilities/fluxSummary/IOfluxSummary.H new file mode 100644 index 0000000000000000000000000000000000000000..f29c2e41d17e4453bc7e4b8f92f466dea312b7e1 --- /dev/null +++ b/src/postProcessing/functionObjects/utilities/fluxSummary/IOfluxSummary.H @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedef + Foam::IOfluxSummary + +Description + Instance of the generic IOOutputFilter for fluxSummary. + +\*---------------------------------------------------------------------------*/ + +#ifndef IOfluxSummary_H +#define IOfluxSummary_H + +#include "fluxSummary.H" +#include "IOOutputFilter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + typedef IOOutputFilter<fluxSummary> IOfluxSummary; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.C b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.C new file mode 100644 index 0000000000000000000000000000000000000000..7ec070bef00cf97fb365ccc29fee1df47b6123c9 --- /dev/null +++ b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.C @@ -0,0 +1,956 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "fluxSummary.H" +#include "surfaceFields.H" +#include "dictionary.H" +#include "Time.H" +#include "syncTools.H" +#include "meshTools.H" +#include "PatchEdgeFaceWave.H" +#include "patchEdgeFaceRegion.H" +#include "globalIndex.H" +#include "OBJstream.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(fluxSummary, 0); + + template<> + const char* NamedEnum + < + fluxSummary::modeType, + 3 + >::names[] = + { + "faceZone", + "faceZoneAndDirection", + "cellZoneAndDirection" + }; +} + + +const Foam::NamedEnum<Foam::fluxSummary::modeType, 3> +Foam::fluxSummary::modeTypeNames_; + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::fluxSummary::initialiseFaceZone +( + const word& faceZoneName, + DynamicList<word>& faceZoneNames, + DynamicList<List<label> >& faceID, + DynamicList<List<label> >& facePatchID, + DynamicList<List<scalar> >& faceSign +) const +{ + const fvMesh& mesh = refCast<const fvMesh>(obr_); + + label zoneI = mesh.faceZones().findZoneID(faceZoneName); + + if (zoneI == -1) + { + FatalErrorIn + ( + "void Foam::fluxSummary::initialiseFaceZone" + "(" + "const word&, " + "DynamicList<word>&, " + "DynamicList<List<label> >&, " + "DynamicList<List<label> >&, " + "DynamicList<List<scalar> >&" + ") const" + ) + << "Unable to find faceZone " << faceZoneName + << ". Valid faceZones are: " << mesh.faceZones().names() + << exit(FatalError); + } + + faceZoneNames.append(faceZoneName); + + const faceZone& fZone = mesh.faceZones()[zoneI]; + + DynamicList<label> faceIDs(fZone.size()); + DynamicList<label> facePatchIDs(fZone.size()); + DynamicList<scalar> faceSigns(fZone.size()); + + forAll(fZone, i) + { + label faceI = fZone[i]; + + label faceID = -1; + label facePatchID = -1; + if (mesh.isInternalFace(faceI)) + { + faceID = faceI; + facePatchID = -1; + } + else + { + facePatchID = mesh.boundaryMesh().whichPatch(faceI); + const polyPatch& pp = mesh.boundaryMesh()[facePatchID]; + if (isA<coupledPolyPatch>(pp)) + { + if (refCast<const coupledPolyPatch>(pp).owner()) + { + faceID = pp.whichFace(faceI); + } + else + { + faceID = -1; + } + } + else if (!isA<emptyPolyPatch>(pp)) + { + faceID = faceI - pp.start(); + } + else + { + faceID = -1; + facePatchID = -1; + } + } + + if (faceID >= 0) + { + // orientation set by faceZone flip map + if (fZone.flipMap()[faceI]) + { + faceSigns.append(-1); + } + else + { + faceSigns.append(1); + } + + faceIDs.append(faceID); + facePatchIDs.append(facePatchID); + } + } + + faceID.append(faceIDs); + facePatchID.append(facePatchIDs); + faceSign.append(faceSigns); +} + + +void Foam::fluxSummary::initialiseFaceZoneAndDirection +( + const word& faceZoneName, + const vector& dir, + DynamicList<vector>& zoneRefDir, + DynamicList<word>& faceZoneNames, + DynamicList<List<label> >& faceID, + DynamicList<List<label> >& facePatchID, + DynamicList<List<scalar> >& faceSign +) const +{ + const fvMesh& mesh = refCast<const fvMesh>(obr_); + + vector refDir = dir/(mag(dir) + ROOTVSMALL); + + label zoneI = mesh.faceZones().findZoneID(faceZoneName); + + if (zoneI == -1) + { + FatalErrorIn + ( + "void Foam::fluxSummary::initialiseFaceZoneAndDirection" + "(" + "const word&, " + "const vector&, " + "DynamicList<vector>&, " + "DynamicList<word>&, " + "DynamicList<List<label> >&, " + "DynamicList<List<label> >&, " + "DynamicList<List<scalar> >&" + ") const" + ) + << "Unable to find faceZone " << faceZoneName + << ". Valid faceZones are: " << mesh.faceZones().names() + << exit(FatalError); + } + + faceZoneNames.append(faceZoneName); + zoneRefDir.append(refDir); + + const faceZone& fZone = mesh.faceZones()[zoneI]; + + DynamicList<label> faceIDs(fZone.size()); + DynamicList<label> facePatchIDs(fZone.size()); + DynamicList<scalar> faceSigns(fZone.size()); + + const surfaceVectorField& Sf = mesh.Sf(); + const surfaceScalarField& magSf = mesh.magSf(); + + vector n = vector::zero; + + forAll(fZone, i) + { + label faceI = fZone[i]; + + label faceID = -1; + label facePatchID = -1; + if (mesh.isInternalFace(faceI)) + { + faceID = faceI; + facePatchID = -1; + } + else + { + facePatchID = mesh.boundaryMesh().whichPatch(faceI); + const polyPatch& pp = mesh.boundaryMesh()[facePatchID]; + if (isA<coupledPolyPatch>(pp)) + { + if (refCast<const coupledPolyPatch>(pp).owner()) + { + faceID = pp.whichFace(faceI); + } + else + { + faceID = -1; + } + } + else if (!isA<emptyPolyPatch>(pp)) + { + faceID = faceI - pp.start(); + } + else + { + faceID = -1; + facePatchID = -1; + } + } + + if (faceID >= 0) + { + // orientation set by comparison with reference direction + if (facePatchID != -1) + { + n = Sf.boundaryField()[facePatchID][faceID] + /(magSf.boundaryField()[facePatchID][faceID] + ROOTVSMALL); + } + else + { + n = Sf[faceID]/(magSf[faceID] + ROOTVSMALL); + } + + if ((n & refDir) > tolerance_) + { + faceSigns.append(1); + } + else + { + faceSigns.append(-1); + } + + faceIDs.append(faceID); + facePatchIDs.append(facePatchID); + } + } + + faceID.append(faceIDs); + facePatchID.append(facePatchIDs); + faceSign.append(faceSigns); +} + + +void Foam::fluxSummary::initialiseCellZoneAndDirection +( + const word& cellZoneName, + const vector& dir, + DynamicList<vector>& zoneRefDir, + DynamicList<word>& faceZoneNames, + DynamicList<List<label> >& faceID, + DynamicList<List<label> >& facePatchID, + DynamicList<List<scalar> >& faceSign +) const +{ + const fvMesh& mesh = refCast<const fvMesh>(obr_); + + vector refDir = dir/(mag(dir) + ROOTVSMALL); + + const label cellZoneI = mesh.cellZones().findZoneID(cellZoneName); + + if (cellZoneI == -1) + { + FatalErrorIn + ( + "void Foam::fluxSummary::initialiseCellZoneAndDirection" + "(" + "const word&, " + "const vector&, " + "DynamicList<vector>&, " + "DynamicList<word>&, " + "DynamicList<List<label> >&, " + "DynamicList<List<label> >&, " + "DynamicList<List<scalar> >&" + ") const" + ) + << "Unable to find cellZone " << cellZoneName + << ". Valid zones are: " << mesh.cellZones().names() + << exit(FatalError); + } + + const label nInternalFaces = mesh.nInternalFaces(); + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + + labelList cellAddr(mesh.nCells(), -1); + const labelList& cellIDs = mesh.cellZones()[cellZoneI]; + UIndirectList<label>(cellAddr, cellIDs) = identity(cellIDs.size()); + labelList nbrFaceCellAddr(mesh.nFaces() - nInternalFaces, -1); + + forAll(pbm, patchI) + { + const polyPatch& pp = pbm[patchI]; + + if (pp.coupled()) + { + forAll(pp, i) + { + label faceI = pp.start() + i; + label nbrFaceI = faceI - nInternalFaces; + label own = mesh.faceOwner()[faceI]; + nbrFaceCellAddr[nbrFaceI] = cellAddr[own]; + } + } + } + + // correct boundary values for parallel running + syncTools::swapBoundaryFaceList(mesh, nbrFaceCellAddr); + + // collect faces + DynamicList<label> faceIDs(floor(0.1*mesh.nFaces())); + DynamicList<label> facePatchIDs(faceIDs.size()); + DynamicList<label> faceLocalPatchIDs(faceIDs.size()); + DynamicList<scalar> faceSigns(faceIDs.size()); + + // internal faces + for (label faceI = 0; faceI < nInternalFaces; faceI++) + { + const label own = cellAddr[mesh.faceOwner()[faceI]]; + const label nbr = cellAddr[mesh.faceNeighbour()[faceI]]; + + if (((own != -1) && (nbr == -1)) || ((own == -1) && (nbr != -1))) + { + vector n = mesh.faces()[faceI].normal(mesh.points()); + n /= mag(n) + ROOTVSMALL; + + if ((n & refDir) > tolerance_) + { + faceIDs.append(faceI); + faceLocalPatchIDs.append(faceI); + facePatchIDs.append(-1); + faceSigns.append(1); + } + else if ((n & -refDir) > tolerance_) + { + faceIDs.append(faceI); + faceLocalPatchIDs.append(faceI); + facePatchIDs.append(-1); + faceSigns.append(-1); + } + } + } + + // loop of boundary faces + forAll(pbm, patchI) + { + const polyPatch& pp = pbm[patchI]; + + forAll(pp, localFaceI) + { + const label faceI = pp.start() + localFaceI; + const label own = cellAddr[mesh.faceOwner()[faceI]]; + const label nbr = nbrFaceCellAddr[faceI - nInternalFaces]; + + if ((own != -1) && (nbr == -1)) + { + vector n = mesh.faces()[faceI].normal(mesh.points()); + n /= mag(n) + ROOTVSMALL; + + if ((n & refDir) > tolerance_) + { + faceIDs.append(faceI); + faceLocalPatchIDs.append(localFaceI); + facePatchIDs.append(patchI); + faceSigns.append(1); + } + else if ((n & -refDir) > tolerance_) + { + faceIDs.append(faceI); + faceLocalPatchIDs.append(localFaceI); + facePatchIDs.append(patchI); + faceSigns.append(-1); + } + } + } + } + + // convert into primitivePatch for convenience + indirectPrimitivePatch patch + ( + IndirectList<face>(mesh.faces(), faceIDs), + mesh.points() + ); + + if (debug) + { + OBJstream os(mesh.time().path()/"patch.obj"); + faceList faces(patch); + os.write(faces, mesh.points(), false); + } + + + // data on all edges and faces + List<patchEdgeFaceRegion> allEdgeInfo(patch.nEdges()); + List<patchEdgeFaceRegion> allFaceInfo(patch.size()); + + bool search = true; + + if (debug) + { + Info<< "initialiseCellZoneAndDirection: " + << "Starting walk to split patch into faceZones" + << endl; + } + + globalIndex globalFaces(patch.size()); + + label oldFaceID = 0; + label regionI = 0; + while (search) + { + DynamicList<label> changedEdges; + DynamicList<patchEdgeFaceRegion> changedInfo; + + label seedFaceI = labelMax; + for (; oldFaceID < patch.size(); oldFaceID++) + { + if (allFaceInfo[oldFaceID].region() == -1) + { + seedFaceI = globalFaces.toGlobal(oldFaceID); + break; + } + } + reduce(seedFaceI, minOp<label>()); + + if (seedFaceI == labelMax) + { + break; + } + + if (globalFaces.isLocal(seedFaceI)) + { + label localFaceI = globalFaces.toLocal(seedFaceI); + const labelList& fEdges = patch.faceEdges()[localFaceI]; + + forAll(fEdges, i) + { + if (allEdgeInfo[fEdges[i]].region() != -1) + { + WarningIn + ( + "void Foam::fluxSummary::initialiseCellZoneAndDirection" + "(" + "const word&, " + "const vector&, " + "DynamicList<vector>&, " + "DynamicList<word>&, " + "DynamicList<List<label> >&, " + "DynamicList<List<label> >&, " + "DynamicList<List<scalar> >&" + ") const" + ) << "Problem in edge face wave: attempted to assign a " + << "value to an edge that has already been visited. " + << "Edge info: " << allEdgeInfo[fEdges[i]] + << endl; + } + + changedEdges.append(fEdges[i]); + changedInfo.append(regionI); + } + } + + + PatchEdgeFaceWave + < + indirectPrimitivePatch, + patchEdgeFaceRegion + > calc + ( + mesh, + patch, + changedEdges, + changedInfo, + allEdgeInfo, + allFaceInfo, + returnReduce(patch.nEdges(), sumOp<label>()) + ); + + label nCells = 0; + forAll(allFaceInfo, faceI) + { + if (allFaceInfo[faceI].region() == regionI) + { + nCells++; + } + } + + if (debug) + { + Info<< "*** region:" << regionI + << " found:" << returnReduce(nCells, sumOp<label>()) + << " faces" << endl; + } + + regionI++; + } + + // collect the data per region + label nRegion = regionI; + + List<DynamicList<label> > regionFaceIDs(nRegion); + List<DynamicList<label> > regionFacePatchIDs(nRegion); + List<DynamicList<scalar> > regionFaceSigns(nRegion); + + forAll(allFaceInfo, faceI) + { + regionI = allFaceInfo[faceI].region(); + + regionFaceIDs[regionI].append(faceLocalPatchIDs[faceI]); + regionFacePatchIDs[regionI].append(facePatchIDs[faceI]); + regionFaceSigns[regionI].append(faceSigns[faceI]); + } + + // transfer to persistent storage + forAll(regionFaceIDs, regionI) + { + const word zoneName = cellZoneName + ":faceZone" + Foam::name(regionI); + faceZoneNames.append(zoneName); + zoneRefDir.append(refDir); + faceID.append(regionFaceIDs[regionI]); + facePatchID.append(regionFacePatchIDs[regionI]); + faceSign.append(regionFaceSigns[regionI]); + + // write OBJ of faces to file + if (debug) + { + OBJstream os(mesh.time().path()/zoneName + ".obj"); + faceList faces(mesh.faces(), regionFaceIDs[regionI]); + os.write(faces, mesh.points(), false); + } + } + + if (log_) + { + Info<< type() << " " << name_ << " output:" << nl + << " Created " << faceID.size() + << " separate face zones from cell zone " << cellZoneName << nl; + + forAll(faceZoneNames, i) + { + label nFaces = returnReduce(faceID[i].size(), sumOp<label>()); + Info<< " " << faceZoneNames[i] << ": " + << nFaces << " faces" << nl; + } + + Info<< endl; + } +} + + +void Foam::fluxSummary::initialiseFaceArea() +{ + faceArea_.setSize(faceID_.size(), 0); + + const fvMesh& mesh = refCast<const fvMesh>(obr_); + const surfaceScalarField& magSf = mesh.magSf(); + + forAll(faceID_, zoneI) + { + const labelList& faceIDs = faceID_[zoneI]; + const labelList& facePatchIDs = facePatchID_[zoneI]; + + scalar sumMagSf = 0; + + forAll(faceIDs, i) + { + label faceI = faceIDs[i]; + + if (facePatchIDs[i] == -1) + { + sumMagSf += magSf[faceI]; + } + else + { + label patchI = facePatchIDs[i]; + sumMagSf += magSf.boundaryField()[patchI][faceI]; + } + } + + faceArea_[zoneI] = returnReduce(sumMagSf, sumOp<scalar>()); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::fluxSummary::fluxSummary +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + const bool loadFromFiles +) +: + functionObjectFile(obr, name), + name_(name), + obr_(obr), + active_(true), + log_(true), + mode_(mdFaceZone), + scaleFactor_(1), + phiName_("phi"), + faceZoneName_(), + refDir_(), + faceID_(), + facePatchID_(), + faceSign_(), + faceArea_(), + filePtrs_(), + tolerance_(0.8) +{ + // Check if the available mesh is an fvMesh otherise deactivate + if (!isA<fvMesh>(obr_)) + { + active_ = false; + WarningIn + ( + "fluxSummary::fluxSummary" + "(" + "const word&, " + "const objectRegistry&, " + "const dictionary&, " + "const bool" + ")" + ) << "No fvMesh available, deactivating " << name_ + << endl; + } + + read(dict); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::fluxSummary::~fluxSummary() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::fluxSummary::read(const dictionary& dict) +{ + if (active_) + { + functionObjectFile::read(dict); + + log_ = dict.lookupOrDefault<Switch>("log", true); + + mode_ = modeTypeNames_.read(dict.lookup("mode")); + phiName_= dict.lookupOrDefault<word>("phiName", "phi"); + dict.readIfPresent("scaleFactor", scaleFactor_); + dict.readIfPresent("tolerance", tolerance_); + + // initialise with capacity of 10 faceZones + DynamicList<vector> refDir(10); + DynamicList<word> faceZoneName(refDir.size()); + DynamicList<List<label> > faceID(refDir.size()); + DynamicList<List<label> > facePatchID(refDir.size()); + DynamicList<List<scalar> > faceSign(refDir.size()); + + switch (mode_) + { + case mdFaceZone: + { + List<word> zones(dict.lookup("faceZones")); + + forAll(zones, i) + { + initialiseFaceZone + ( + zones[i], + faceZoneName, + faceID, + facePatchID, + faceSign + ); + } + break; + } + case mdFaceZoneAndDirection: + { + List<Tuple2<word, vector> > + zoneAndDirection(dict.lookup("faceZoneAndDirection")); + + forAll(zoneAndDirection, i) + { + initialiseFaceZoneAndDirection + ( + zoneAndDirection[i].first(), + zoneAndDirection[i].second(), + refDir, + faceZoneName, + faceID, + facePatchID, + faceSign + ); + } + break; + } + case mdCellZoneAndDirection: + { + List<Tuple2<word, vector> > + zoneAndDirection(dict.lookup("cellZoneAndDirection")); + + forAll(zoneAndDirection, i) + { + initialiseCellZoneAndDirection + ( + zoneAndDirection[i].first(), + zoneAndDirection[i].second(), + refDir, + faceZoneName, + faceID, + facePatchID, + faceSign + ); + } + break; + } + default: + { + FatalIOErrorIn + ( + "void Foam::fluxSummary::read(const dictionary&)", + dict + ) + << "unhandled enumeration " << modeTypeNames_[mode_] + << abort(FatalIOError); + } + } + + faceZoneName_.transfer(faceZoneName); + refDir_.transfer(refDir); + faceID_.transfer(faceID); + facePatchID_.transfer(facePatchID); + faceSign_.transfer(faceSign); + + initialiseFaceArea(); + + if (writeToFile()) + { + filePtrs_.setSize(faceZoneName_.size()); + + forAll(filePtrs_, fileI) + { + const word& fzName = faceZoneName_[fileI]; + filePtrs_.set(fileI, createFile(fzName)); + writeFileHeader + ( + fzName, + faceArea_[fileI], + refDir_[fileI], + filePtrs_[fileI] + ); + } + } + } +} + + +void Foam::fluxSummary::writeFileHeader +( + const word& fzName, + const scalar area, + const vector& refDir, + Ostream& os +) const +{ + writeHeader(os, "Flux summary"); + writeHeaderValue(os, "Face zone", fzName); + writeHeaderValue(os, "Total area", area); + + switch (mode_) + { + case mdFaceZoneAndDirection: + case mdCellZoneAndDirection: + { + writeHeaderValue(os, "Reference direction", refDir); + break; + } + default: + {} + } + + writeHeaderValue(os, "Scale factor", scaleFactor_); + + writeCommented(os, "Time"); + os << tab << "positive" + << tab << "negative" + << tab << "net" + << tab << "absolute" + << endl; +} + + +void Foam::fluxSummary::execute() +{ + // Do nothing - only valid on write +} + + +void Foam::fluxSummary::end() +{ + // Do nothing - only valid on write +} + + +void Foam::fluxSummary::timeSet() +{ + // Do nothing - only valid on write +} + + +void Foam::fluxSummary::write() +{ + if (!active_) + { + return; + } + + const surfaceScalarField& phi = + obr_.lookupObject<surfaceScalarField>(phiName_); + + word flowType = ""; + if (phi.dimensions() == dimVolume/dimTime) + { + flowType = "volumetric"; + } + else if (phi.dimensions() == dimMass/dimTime) + { + flowType = "mass"; + } + else + { + FatalErrorIn("void Foam::fluxSummary::write()") + << "Unsupported flux field " << phi.name() << " with dimensions " + << phi.dimensions() << ". Expected eithe mass flow or volumetric " + << "flow rate" << abort(FatalError); + } + + if (log_) + { + Info<< type() << " " << name_ << ' ' << flowType << " flux output:" + << nl; + } + + forAll(faceZoneName_, zoneI) + { + const labelList& faceID = faceID_[zoneI]; + const labelList& facePatchID = facePatchID_[zoneI]; + const scalarList& faceSign = faceSign_[zoneI]; + + scalar phiPos = scalar(0); + scalar phiNeg = scalar(0); + scalar phif = scalar(0); + + forAll(faceID, i) + { + label faceI = faceID[i]; + label patchI = facePatchID[i]; + + if (patchI != -1) + { + phif = phi.boundaryField()[patchI][faceI]; + } + else + { + phif = phi[faceI]; + } + + phif *= faceSign[i]; + + if (phif > 0) + { + phiPos += phif; + } + else + { + phiNeg += phif; + } + } + + reduce(phiPos, sumOp<scalar>()); + reduce(phiNeg, sumOp<scalar>()); + + phiPos *= scaleFactor_; + phiNeg *= scaleFactor_; + + scalar netFlux = phiPos + phiNeg; + scalar absoluteFlux = phiPos - phiNeg; + + if (log_) + { + Info<< " faceZone " << faceZoneName_[zoneI] << ':' << nl + << " positive : " << phiPos << nl + << " negative : " << phiNeg << nl + << " net : " << netFlux << nl + << " absolute : " << absoluteFlux + << nl << endl; + } + + if (writeToFile()) + { + filePtrs_[zoneI] + << obr_.time().value() << token::TAB + << phiPos << token::TAB + << phiNeg << token::TAB + << netFlux << token::TAB + << absoluteFlux + << endl; + } + } + + if (log_) Info<< endl; +} + + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.H b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.H new file mode 100644 index 0000000000000000000000000000000000000000..777167b171ffc4b3a575d2f3df735010ab3ea313 --- /dev/null +++ b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.H @@ -0,0 +1,302 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::fluxSummary + +Group + grpUtilityFunctionObjects + +Description + This function object calculates the flux across selections of faces. + + Output comprises, per set of faces, the: + - positive + - negative + - net + - absolute + fluxes + + Example of function object specification: + \verbatim + fluxSummary1 + { + type fluxSummary; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + write yes; + log yes; + mode cellZoneAndDirection; + cellZoneAndDirection + ( + (porosity (1 0 0)) + ); + scaleFactor 1.2; + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | type name: fluxSummary | yes | + write | write flux data to file | no | yes + log | write flux data to standard output | no | yes + mode | mode to generate faces to test | yes | + scaleFactor | optional factor to scale result | no | 1 + \endtable + + The mode is one of: + - faceZone + - faceZoneAndDirection + - cellZoneAndDirection + + Output data is written to files of the form \<timeDir\>/<faceZoneName>.dat + +SeeAlso + Foam::functionObject + Foam::OutputFilterFunctionObject + +SourceFiles + fluxSummary.C + IOfluxSummary.H + +\*---------------------------------------------------------------------------*/ + +#ifndef fluxSummary_H +#define fluxSummary_H + +#include "functionObjectFile.H" +#include "Switch.H" +#include "vector.H" +#include "DynamicList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class objectRegistry; +class dictionary; +class polyMesh; +class mapPolyMesh; + +/*---------------------------------------------------------------------------*\ + Class fluxSummary Declaration +\*---------------------------------------------------------------------------*/ + +class fluxSummary +: + public functionObjectFile +{ +public: + + // Public enumerations + + //- Face mode type + enum modeType + { + mdFaceZone, + mdFaceZoneAndDirection, + mdCellZoneAndDirection + }; + + //- Mode type names + static const NamedEnum<modeType, 3> modeTypeNames_; + + +protected: + + // Protected data + + //- Name of function object + // Also used as the name of the output directory + word name_; + + //- Reference to the database + const objectRegistry& obr_; + + //- on/off switch + bool active_; + + //- Switch to send output to Info as well + Switch log_; + + //- Mode for face determination + modeType mode_; + + //- Scale factor + scalar scaleFactor_; + + //- Name of flux field, default = phi + word phiName_; + + + // Per-faceZone information + + //- Region names + List<word> faceZoneName_; + + //- Reference direction + List<vector> refDir_; + + //- Face IDs + List<List<label> > faceID_; + + //- Face patch IDs + List<List<label> > facePatchID_; + + //- Face flip map signs + List<List<scalar> > faceSign_; + + //- Sum of face areas + List<scalar> faceArea_; + + //- Output file per face zone + PtrList<OFstream> filePtrs_; + + + //- Tolerance applied when matching face normals + scalar tolerance_; + + + // Private Member Functions + + //- Initialise face set from face zone + void initialiseFaceZone + ( + const word& faceZoneName, + DynamicList<word>& faceZoneNames, + DynamicList<List<label> >& faceID, + DynamicList<List<label> >& facePatchID, + DynamicList<List<scalar> >& faceSign + ) const; + + //- Initialise face set from face zone and direction + void initialiseFaceZoneAndDirection + ( + const word& faceZoneName, + const vector& refDir, + DynamicList<vector>& dir, + DynamicList<word>& faceZoneNames, + DynamicList<List<label> >& faceID, + DynamicList<List<label> >& facePatchID, + DynamicList<List<scalar> >& faceSign + ) const; + + //- Initialise face set from cell zone and direction + void initialiseCellZoneAndDirection + ( + const word& cellZoneName, + const vector& refDir, + DynamicList<vector>& dir, + DynamicList<word>& faceZoneNames, + DynamicList<List<label> >& faceID, + DynamicList<List<label> >& facePatchID, + DynamicList<List<scalar> >& faceSign + ) const; + + //- Initialise the total area per derived faceZone + void initialiseFaceArea(); + + //- Output file header information + virtual void writeFileHeader + ( + const word& fzName, + const scalar area, + const vector& refDir, + Ostream& os + ) const; + + //- Disallow default bitwise copy construct + fluxSummary(const fluxSummary&); + + //- Disallow default bitwise assignment + void operator=(const fluxSummary&); + + +public: + + //- Runtime type information + TypeName("fluxSummary"); + + + // Constructors + + //- Construct for given objectRegistry and dictionary. + // Allow the possibility to load fields from files + fluxSummary + ( + const word& name, + const objectRegistry&, + const dictionary&, + const bool loadFromFiles = false + ); + + + //- Destructor + virtual ~fluxSummary(); + + + // Member Functions + + //- Return name of the set of field min/max + virtual const word& name() const + { + return name_; + } + + //- Read the field min/max data + virtual void read(const dictionary&); + + //- Execute, currently does nothing + virtual void execute(); + + //- Execute at the final time-loop, currently does nothing + virtual void end(); + + //- Called when time was set at the end of the Time::operator++ + virtual void timeSet(); + + //- Write the fluxSummary + virtual void write(); + + //- Update for changes of mesh + virtual void updateMesh(const mapPolyMesh&) + {} + + //- Update for changes of mesh + virtual void movePoints(const polyMesh&) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.C b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.C new file mode 100644 index 0000000000000000000000000000000000000000..32c61e2df39a96767deba45878275a98ad5912c8 --- /dev/null +++ b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.C @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "fluxSummaryFunctionObject.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineNamedTemplateTypeNameAndDebug(fluxSummaryFunctionObject, 0); + + addToRunTimeSelectionTable + ( + functionObject, + fluxSummaryFunctionObject, + dictionary + ); +} + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.H b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.H new file mode 100644 index 0000000000000000000000000000000000000000..b0b4380bff5da4a9eca0e98cc67342cd7eaa9178 --- /dev/null +++ b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.H @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedef + Foam::fluxSummaryFunctionObject + +Description + FunctionObject wrapper around fluxSummary to allow them to be created + via the functions entry within controlDict. + +SourceFiles + fluxSummaryFunctionObject.C + +\*---------------------------------------------------------------------------*/ + +#ifndef fluxSummaryFunctionObject_H +#define fluxSummaryFunctionObject_H + +#include "fluxSummary.H" +#include "OutputFilterFunctionObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + typedef OutputFilterFunctionObject<fluxSummary> fluxSummaryFunctionObject; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C index e760f43107bd3fa39c218e80bd7e7b69d125109a..7d26627af68a43aa4d63dc6265df3e1e06f1aad7 100644 --- a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C +++ b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,28 +37,6 @@ namespace Foam // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -Foam::word Foam::pressureTools::pName() const -{ - word fieldName = pName_; - - if (calcTotal_) - { - fieldName = "total(" + fieldName + ")"; - } - else - { - fieldName = "static(" + fieldName + ")"; - } - - if (calcCoeff_) - { - fieldName = fieldName + "_coeff"; - } - - return fieldName; -} - - Foam::dimensionedScalar Foam::pressureTools::rhoScale ( const volScalarField& p @@ -86,7 +64,23 @@ Foam::tmp<Foam::volScalarField> Foam::pressureTools::rho } else { - return + if (!rhoInfInitialised_) + { + FatalErrorIn + ( + "Foam::tmp<Foam::volScalarField> Foam::pressureTools::rho" + "(" + " const volScalarField&" + ") const" + ) + << type() << " " << name_ << ": " + << "pressure identified as incompressible, but reference " + << "density is not set. Please set rhoName to rhoInf, and " + << "set an appropriate value for rhoInf" + << exit(FatalError); + } + + return tmp<volScalarField> ( new volScalarField @@ -193,12 +187,15 @@ Foam::pressureTools::pressureTools pName_("p"), UName_("U"), rhoName_("rho"), + resultName_(word::null), + log_(true), calcTotal_(false), pRef_(0.0), calcCoeff_(false), pInf_(0.0), UInf_(vector::zero), - rhoInf_(0.0) + rhoInf_(0.0), + rhoInfInitialised_(false) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -236,7 +233,7 @@ Foam::pressureTools::pressureTools ( IOobject ( - pName(), + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -264,13 +261,18 @@ void Foam::pressureTools::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); + dict.readIfPresent("pName", pName_); dict.readIfPresent("UName", UName_); dict.readIfPresent("rhoName", rhoName_); + rhoInfInitialised_ = false; + if (rhoName_ == "rhoInf") { dict.lookup("rhoInf") >> rhoInf_; + rhoInfInitialised_ = true; } dict.lookup("calcTotal") >> calcTotal_; @@ -296,6 +298,27 @@ void Foam::pressureTools::read(const dictionary& dict) << "pressure level is zero. Please check the supplied " << "values of pInf, UInf and rhoInf" << endl; } + + rhoInfInitialised_ = true; + } + + if (!dict.readIfPresent("resultName", resultName_)) + { + resultName_ = pName_; + + if (calcTotal_) + { + resultName_ = "total(" + resultName_ + ")"; + } + else + { + resultName_ = "static(" + resultName_ + ")"; + } + + if (calcCoeff_) + { + resultName_ = resultName_ + "_coeff"; + } } } } @@ -310,7 +333,7 @@ void Foam::pressureTools::execute() volScalarField& pResult = const_cast<volScalarField&> ( - obr_.lookupObject<volScalarField>(pName()) + obr_.lookupObject<volScalarField>(resultName_) ); pResult == convertToCoeff(rhoScale(p)*p + pDyn(p) + pRef()); @@ -338,9 +361,10 @@ void Foam::pressureTools::write() if (active_) { const volScalarField& pResult = - obr_.lookupObject<volScalarField>(pName()); + obr_.lookupObject<volScalarField>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << pResult.name() << nl << endl; diff --git a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H index 6f7607e6e0f76afdc3d518f288c3a95c4532180d..aa5623ebd5416d196d27ef3bbe01c360bf51e284 100644 --- a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H +++ b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H @@ -101,6 +101,8 @@ Description pInf | Freestream pressure for coefficient calculation | no | UInf | Freestream velocity for coefficient calculation | no | rhoInf | Freestream density for coefficient calculation | no | + resultName | Name of derived pressure field | no | auto generated + log | log to standard output | no | yes \endtable SourceFiles @@ -114,6 +116,7 @@ SourceFiles #include "volFieldsFwd.H" #include "dimensionedScalar.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -152,6 +155,12 @@ class pressureTools //- Name of density field, default is "rho" word rhoName_; + //- Result name + word resultName_; + + //- Switch to send output to Info as well as to file + Switch log_; + // Total pressure calculation @@ -176,13 +185,13 @@ class pressureTools //- Freestream density scalar rhoInf_; + //- Flag to show whether rhoInf has been initialised + bool rhoInfInitialised_; - // Private Member Functions - //- Return the name of the derived pressure field - word pName() const; + // Private Member Functions - //- Return the density scaling if supplied with kinematic pressure + //- Return the density scale dimensionedScalar rhoScale(const volScalarField& p) const; //- Return the density field diff --git a/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.C b/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.C index d38cc9d14d1554930e9c40a8ef87b227c7c4f4b8..2b9c1eb5875e7fe356b3077ba58a54b915bdb60f 100644 --- a/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.C +++ b/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.C @@ -186,7 +186,8 @@ Foam::scalarTransport::scalarTransport resetOnStartUp_(false), nCorr_(0), autoSchemes_(false), - fvOptions_(mesh_) + fvOptions_(mesh_), + log_(true) { read(dict); @@ -209,11 +210,13 @@ void Foam::scalarTransport::read(const dictionary& dict) { if (active_) { - Info<< type() << ":" << nl; + log_.readIfPresent("log", dict); - phiName_ = dict.lookupOrDefault<word>("phiName", "phi"); - UName_ = dict.lookupOrDefault<word>("UName", "U"); - rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho"); + if (log_) Info<< type() << " " << name_ << " output:" << nl; + + dict.readIfPresent("phiName", phiName_); + dict.readIfPresent("UName", UName_); + dict.readIfPresent("rhoName", rhoName_); userDT_ = false; if (dict.readIfPresent("DT", DT_)) @@ -221,10 +224,8 @@ void Foam::scalarTransport::read(const dictionary& dict) userDT_ = true; } - dict.lookup("resetOnStartUp") >> resetOnStartUp_; - dict.readIfPresent("nCorr", nCorr_); - + dict.lookup("resetOnStartUp") >> resetOnStartUp_; dict.lookup("autoSchemes") >> autoSchemes_; fvOptions_.reset(dict.subDict("fvOptions")); @@ -236,7 +237,7 @@ void Foam::scalarTransport::execute() { if (active_) { - Info<< type() << " output:" << endl; + if (log_) Info<< type() << " " << name_ << " output:" << nl; const surfaceScalarField& phi = mesh_.lookupObject<surfaceScalarField>(phiName_); @@ -316,7 +317,7 @@ void Foam::scalarTransport::execute() << dimVolume/dimTime << endl; } - Info<< endl; + if (log_) Info<< endl; } } diff --git a/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.H b/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.H index c2ffbcec2cd838b4b64b5952235f42b526fd8061..c541c925a31a6d5aadb9c26a193d14baed8ba165 100644 --- a/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.H +++ b/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License @@ -29,9 +29,10 @@ Group Description This function object evolves a passive scalar transport equation. The - field in ininitially zero, to which sources are added. The field name + field is initially zero, to which sources are added. The field name is assigned the name of the function object. Boundary conditions are - automatically applied, based on the velocity boundary conditions. + read from file if the field file is available, or automatically applied + based on the velocity boundary conditions. - the field can be zeroed on start-up using the resetOnStartUp flag - to employ the same numerical schemes as the flow velocity, use the @@ -39,10 +40,51 @@ Description - the diffusivity can be set manually using the DT entry, or retrieved from the turbulence model (if applicable) + Example of function object specification to solve a scalar transport + equation: + \verbatim + functions + { + scalar1 // <--- NOTE: SCALAR NAME + { + type scalarTransport; + functionObjectLibs ("libutilityFunctionObjects.so"); + resetOnStartUp no; + + autoSchemes yes; + + fvOptions + { + ... + } + } + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: scalarTransport | yes | + phiName | Name of flux field | no | phi + UName | Name of velocity field | no | U + rhoName | Name of density field | no | rho + nCorr | Number of correctors | no | 0 + DT | Diffision coefficient | no | auto generated + resetOnStartUp | Reset source to zero on start-up | no | no + autoSchemes | Use U schemes to evolve scalar | no | yes + fvOptions | List of scalar sources | yes | + log | Log to standard output | no | yes + \endtable + +SeeAlso + fvOption.H + fvOptionList.H + SourceFiles scalarTransport.C IOscalarTransport.H + \*---------------------------------------------------------------------------*/ #ifndef scalarTransport_H @@ -108,6 +150,9 @@ class scalarTransport //- Run-time selectable finite volume options, e.g. sources, constraints fv::optionList fvOptions_; + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.C b/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.C index a8d540771b3afb5d9e4c14a01845af0b55fd514e..1720091977b265df27a190dd2e5bf5ca7c2b4820 100644 --- a/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.C +++ b/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -116,7 +116,7 @@ bool Foam::setTimeStepFunctionObject::adjustTimeStep() bool Foam::setTimeStepFunctionObject::read(const dictionary& dict) { - enabled_ = dict.lookupOrDefault("enabled", true); + enabled_.readIfPresent("enabled", dict); if (enabled_) { @@ -133,7 +133,7 @@ bool Foam::setTimeStepFunctionObject::read(const dictionary& dict) ) { FatalIOErrorIn("setTimeStep::read(const dictionary&)", dict) - << "Need to have 'adjustTimeStep' true to enable external" + << "'adjustTimeStep' must be set to true to enable external" << " timestep control" << exit(FatalIOError); } } diff --git a/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.H b/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.H index 3f03f3ddcccc351283a0df367c76ea34923a21be..10bd6fec3cadd3123d4347f155de9ff90b7e544d 100644 --- a/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.H +++ b/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -28,12 +28,30 @@ Group grpUtilitiesFunctionObjects Description - Overrides the timeStep. Can only be used with - solvers with adjustTimeStep control (e.g. pimpleFoam). Makes no attempt - to cooperate with other timeStep 'controllers' (maxCo, other - functionObjects). Supports 'enabled' flag but none of othe other ones + This function object overrides the calculation time step. Can only be used + with solvers with adjustTimeStep control (e.g. pimpleFoam). It makes no + attempt to co-operate with other time step 'controllers', e.g. maxCo, other + functionObjects. Supports 'enabled' flag but none of the other options 'timeStart', 'timeEnd', 'outputControl' etc. + + Example of function object specification to manipulate the time step: + \verbatim + setTimeStep1 + { + type setTimeStep; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: setTimeStep | yes | + enabled | On/off switch | no | yes + \endtable + SourceFiles setTimeStepFunctionObject.C @@ -45,6 +63,7 @@ SourceFiles #include "functionObject.H" #include "dictionary.H" #include "DataEntry.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -68,7 +87,7 @@ class setTimeStepFunctionObject // Optional user inputs //- Switch for the execution - defaults to 'yes/on' - bool enabled_; + Switch enabled_; //- Time step autoPtr<DataEntry<scalar> > timeStepPtr_; @@ -82,6 +101,7 @@ class setTimeStepFunctionObject public: + //- Runtime type information TypeName("setTimeStep"); @@ -121,7 +141,6 @@ public: //- Switch the function object off virtual void off(); - //- Called at the start of the time-loop virtual bool start(); @@ -145,7 +164,6 @@ public: //- Update for changes of mesh virtual void movePoints(const polyMesh& mesh); - }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C b/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C index 91d5f381f601279637dd2025d04dfc28c17921ef..68c09980cc270a735a7fb611fc14dfd5a8b75509 100644 --- a/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C +++ b/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -52,7 +52,8 @@ void Foam::timeActivatedFileUpdate::updateFile() if (i > lastIndex_) { - Info<< nl << type() << ": copying file" << nl << timeVsFile_[i].second() + if (log_) Info + << nl << type() << ": copying file" << nl << timeVsFile_[i].second() << nl << "to:" << nl << fileToUpdate_ << nl << endl; cp(timeVsFile_[i].second(), fileToUpdate_); @@ -74,9 +75,10 @@ Foam::timeActivatedFileUpdate::timeActivatedFileUpdate name_(name), obr_(obr), active_(true), - fileToUpdate_(dict.lookup("fileToUpdate")), + fileToUpdate_("unknown-fileToUpdate"), timeVsFile_(), - lastIndex_(-1) + lastIndex_(-1), + log_(true) { read(dict); } @@ -94,13 +96,18 @@ void Foam::timeActivatedFileUpdate::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); + dict.lookup("fileToUpdate") >> fileToUpdate_; dict.lookup("timeVsFile") >> timeVsFile_; lastIndex_ = -1; fileToUpdate_.expand(); - Info<< type() << ": time vs file list:" << nl; + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " time vs file list:" << endl; + forAll(timeVsFile_, i) { timeVsFile_[i].second() = timeVsFile_[i].second().expand(); @@ -111,10 +118,11 @@ void Foam::timeActivatedFileUpdate::read(const dictionary& dict) << nl << exit(FatalError); } - Info<< " " << timeVsFile_[i].first() << tab + if (log_) Info + << " " << timeVsFile_[i].first() << tab << timeVsFile_[i].second() << endl; } - Info<< endl; + if (log_) Info<< endl; updateFile(); } diff --git a/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.H b/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.H index e2f168eaf2dcabfa39c6a5cedbee9760944d49cd..927f88a609fa31bbf1d8029258ff04d54f13b6fe 100644 --- a/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.H +++ b/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -28,18 +28,16 @@ Group grpUtilitiesFunctionObjects Description - Performs a file copy/replacement once a specified time has been reached. + This function object performs a file copy/replacement once a specified + time has been reached. Example usage to update the fvSolution dictionary at various times throughout the calculation: - \verbatim fileUpdate1 { type timeActivatedFileUpdate; functionObjectLibs ("libutilityFunctionObjects.so"); - outputControl timeStep; - outputInterval 1; fileToUpdate "$FOAM_CASE/system/fvSolution"; timeVsFile ( @@ -48,9 +46,20 @@ Description (0.20 "$FOAM_CASE/system/fvSolution.20") (0.35 "$FOAM_CASE/system/fvSolution.35") ); + ... } \endverbatim + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: timeActivatedFileUpdate | yes | + fileToUpdate | Name of file to update | yes | + timeVsFile | List of time vs file | yes | + log | Log to standard output | no | yes + \endtable + + SourceFiles timeActivatedFileUpdate.C IOtimeActivatedFileUpdate.H @@ -61,6 +70,7 @@ SourceFiles #define timeActivatedFileUpdate_H #include "Tuple2.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -99,6 +109,9 @@ class timeActivatedFileUpdate //- Index of last file copied label lastIndex_; + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions diff --git a/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.C b/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.C index 6a16f35c1379cffe6a322bccd50466ba2d0a2762..7e7d1aff8cb5de2961cd5b4457b5ad33e082bc89 100644 --- a/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.C +++ b/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.C @@ -102,7 +102,8 @@ Foam::turbulenceFields::turbulenceFields name_(name), obr_(obr), active_(true), - fieldSet_() + fieldSet_(), + log_(true) { // Check if the available mesh is an fvMesh otherise deactivate if (isA<fvMesh>(obr_)) @@ -139,21 +140,26 @@ void Foam::turbulenceFields::read(const dictionary& dict) { if (active_) { + log_.readIfPresent("log", dict); fieldSet_.insert(wordList(dict.lookup("fields"))); Info<< type() << " " << name_ << ": "; - if (fieldSet_.size()) + if (log_) { - Info<< "storing fields:" << nl; - forAllConstIter(wordHashSet, fieldSet_, iter) + Info<< type() << " " << name_ << " output:" << nl; + if (fieldSet_.size()) { - Info<< " " << modelName << ':' << iter.key() << nl; + Info<< "storing fields:" << nl; + forAllConstIter(wordHashSet, fieldSet_, iter) + { + Info<< " " << modelName << ':' << iter.key() << nl; + } + Info<< endl; + } + else + { + Info<< "no fields requested to be stored" << nl << endl; } - Info<< endl; - } - else - { - Info<< "no fields requested to be stored" << nl << endl; } } } diff --git a/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.H b/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.H index af412a9711273b09e2ef96e01f19c71cfdd36d36..7903afa246b3e4a6a4e0d6304069873f1483136d 100644 --- a/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.H +++ b/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.H @@ -25,7 +25,7 @@ Class Foam::turbulenceFields Group - grpFieldFunctionObjects + grpUtilitiesFunctionObjects Description This function object stores turbulence fields on the mesh database for @@ -89,6 +89,7 @@ SourceFiles #include "IOobject.H" #include "NamedEnum.H" #include "volFieldsFwd.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -151,6 +152,9 @@ protected: //- Fields to load wordHashSet fieldSet_; + //- Switch to send output to Info as well as to file + Switch log_; + // Protected Member Functions diff --git a/src/postProcessing/functionObjects/utilities/vorticity/vorticity.C b/src/postProcessing/functionObjects/utilities/vorticity/vorticity.C index ac9c5e392c6fb52aaefa81b6ae0e8cfb0437028c..f59b8a4c204a7f5f74aca9e8f80a7cc16cf686b9 100644 --- a/src/postProcessing/functionObjects/utilities/vorticity/vorticity.C +++ b/src/postProcessing/functionObjects/utilities/vorticity/vorticity.C @@ -50,7 +50,8 @@ Foam::vorticity::vorticity obr_(obr), active_(true), UName_("U"), - outputName_(typeName) + resultName_(name), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -81,7 +82,7 @@ Foam::vorticity::vorticity ( IOobject ( - outputName_, + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -109,10 +110,16 @@ void Foam::vorticity::read(const dictionary& dict) { if (active_) { - UName_ = dict.lookupOrDefault<word>("UName", "U"); - if (UName_ != "U") + log_.readIfPresent("log", dict); + dict.readIfPresent("UName", UName_); + + if (!dict.readIfPresent("resultName", resultName_)) { - outputName_ = typeName + "(" + UName_ + ")"; + resultName_ = name_; + if (UName_ != "U") + { + resultName_ = resultName_ + "(" + UName_ + ")"; + } } } } @@ -127,7 +134,7 @@ void Foam::vorticity::execute() volVectorField& vorticity = const_cast<volVectorField&> ( - obr_.lookupObject<volVectorField>(outputName_) + obr_.lookupObject<volVectorField>(resultName_) ); vorticity = fvc::curl(U); @@ -155,9 +162,10 @@ void Foam::vorticity::write() if (active_) { const volVectorField& vorticity = - obr_.lookupObject<volVectorField>(outputName_); + obr_.lookupObject<volVectorField>(resultName_); - Info<< type() << " " << name_ << " output:" << nl + if (log_) Info + << type() << " " << name_ << " output:" << nl << " writing field " << vorticity.name() << nl << endl; diff --git a/src/postProcessing/functionObjects/utilities/vorticity/vorticity.H b/src/postProcessing/functionObjects/utilities/vorticity/vorticity.H index bce5d943ebc1a1390cda05422b706c5565f80419..87209915cf6da5a42ba86c8e77bebfe29b5f05d6 100644 --- a/src/postProcessing/functionObjects/utilities/vorticity/vorticity.H +++ b/src/postProcessing/functionObjects/utilities/vorticity/vorticity.H @@ -28,7 +28,29 @@ Group grpUtilitiesFunctionObjects Description - This function object calculates the vorticity, the curl of the velocity. + This function object calculates and outputs the vorticity, the curl of + the velocity as a volvectorField. The field is stored on the mesh + database so that it can be retrieved and used for other applications. + + Example of function object specification to calculate the vorticity: + \verbatim + vorticity1 + { + type vorticity; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: vorticity | yes | + UName | Name of velocity field | no | U + resultName | Name of Courant number field | no | \<function name\> + log | Log to standard output | no | yes + \endtable + SourceFiles vorticity.C @@ -40,6 +62,7 @@ SourceFiles #define vorticity_H #include "volFieldsFwd.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -73,7 +96,10 @@ class vorticity word UName_; //- Name of vorticity field - word outputName_; + word resultName_; + + //- Switch to send output to Info as well as to file + Switch log_; // Private Member Functions diff --git a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C index 0f5be2bbb04ead5b8941a1f3045b95fbca2be0e4..c0885773e3fca5389344cb109e7948715a49c354 100644 --- a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C +++ b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C @@ -80,11 +80,9 @@ void Foam::wallShearStress::calcShearStress << token::TAB << maxSsp << endl; - if (log_) - { - Info<< " min/max(" << pp.name() << ") = " - << minSsp << ", " << maxSsp << endl; - } + if (log_) Info + << " min/max(" << pp.name() << ") = " + << minSsp << ", " << maxSsp << endl; } } @@ -296,12 +294,10 @@ void Foam::wallShearStress::write() const volVectorField& wallShearStress = obr_.lookupObject<volVectorField>(resultName_); - if (log_) - { - Info<< type() << " " << name_ << " output:" << nl - << " writing field " << wallShearStress.name() << nl - << endl; - } + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " writing field " << wallShearStress.name() << nl + << endl; wallShearStress.write(); } diff --git a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H index 7d51167335bbae37cf86370e6b7e6460d48aa513..83bafbab532e306df8fbd8bca43270771407210d 100644 --- a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H +++ b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H @@ -61,7 +61,7 @@ Description \table Property | Description | Required | Default value type | type name: wallShearStress | yes | - resultName | Name of wall shear stress field | no | <function name> + resultName | Name of wall shear stress field | no | \<function name\> patches | list of patches to process | no | all wall patches log | Log to standard output | no | yes \endtable diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C index 01630313c846a1ef83dd5c988dee74a7c9dc3a95..a88623b1cece97fd54516ac6b62ad06a2f77c77a 100644 --- a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C +++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C @@ -229,13 +229,10 @@ void Foam::yPlus::write() const volScalarField& yPlus = obr_.lookupObject<volScalarField>(resultName_); - if (log_) - { - Info - << type() << " " << name_ << " output:" << nl - << " writing field " << yPlus.name() << nl - << endl; - } + if (log_) Info + << type() << " " << name_ << " output:" << nl + << " writing field " << yPlus.name() << nl + << endl; yPlus.write(); } diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H index 80ce1abb8d82d13b638124cececcc32451a3b7d3..7c1461ae4e52b187a775a37eabfb23a2a0a7b133 100644 --- a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H +++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H @@ -47,7 +47,7 @@ Description Property | Description | Required | Default value type | Type name: yPlus | yes | phiName | Name of flux field | no | phi - resultName | Name of y+ field | no | <function name> + resultName | Name of y+ field | no | \<function name\> log | Log to standard output | no | yes \endtable diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C b/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C index 0e7a625879d55ec79979543847a02cb154c35033..0358fa760b56cff87117683dc019e384b1942554 100644 --- a/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C +++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C @@ -69,12 +69,9 @@ void Foam::yPlus::calcYPlus const scalar maxYplus = gMax(yPlusp); const scalar avgYplus = gAverage(yPlusp); - if (log_) - { - Info<< " patch " << patch.name() - << " y+ : min = " << minYplus << ", max = " << maxYplus - << ", average = " << avgYplus << nl; - } + if (log_) Info<< " patch " << patch.name() + << " y+ : min = " << minYplus << ", max = " << maxYplus + << ", average = " << avgYplus << nl; file() << obr_.time().value() << token::TAB << patch.name() diff --git a/src/sampling/probes/patchProbes.C b/src/sampling/probes/patchProbes.C index b6792ea08cd35ba9befff7b07b9f6ead6c9c5508..3c6d2329b38215138874c1da2e040b8ecc502d61 100644 --- a/src/sampling/probes/patchProbes.C +++ b/src/sampling/probes/patchProbes.C @@ -46,32 +46,41 @@ void Foam::patchProbes::findElements(const fvMesh& mesh) const polyBoundaryMesh& bm = mesh.boundaryMesh(); - label patchI = bm.findPatchID(patchName_); + // All the info for nearest. Construct to miss + List<mappedPatchBase::nearInfo> nearest(this->size()); - if (patchI == -1) - { - FatalErrorIn - ( - " Foam::patchProbes::findElements(const fvMesh&)" - ) << " Unknown patch name " - << patchName_ << endl - << exit(FatalError); - } - // All the info for nearest. Construct to miss - List<mappedPatchBase::nearInfo> nearest(this->size()); + const labelList patchIDs(bm.patchSet(patchNames_).sortedToc()); - const polyPatch& pp = bm[patchI]; + label nFaces = 0; + forAll(patchIDs, i) + { + nFaces += bm[patchIDs[i]].size(); + } - if (pp.size() > 0) + if (nFaces > 0) { - labelList bndFaces(pp.size()); - forAll(bndFaces, i) + // Collect mesh faces and bounding box + labelList bndFaces(nFaces); + treeBoundBox overallBb(treeBoundBox::invertedBox); + + nFaces = 0; + forAll(patchIDs, i) { - bndFaces[i] = pp.start() + i; + const polyPatch& pp = bm[patchIDs[i]]; + forAll(pp, i) + { + bndFaces[nFaces++] = pp.start()+i; + const face& f = pp[i]; + forAll(f, fp) + { + const point& pt = pp.points()[f[fp]]; + overallBb.min() = min(overallBb.min(), pt); + overallBb.max() = max(overallBb.max(), pt); + } + } } - treeBoundBox overallBb(pp.points()); Random rndGen(123456); overallBb = overallBb.extend(rndGen, 1e-4); overallBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); @@ -106,11 +115,7 @@ void Foam::patchProbes::findElements(const fvMesh& mesh) if (!info.hit()) { - info = boundaryTree.findNearest - ( - sample, - Foam::sqr(GREAT) - ); + info = boundaryTree.findNearest(sample, Foam::sqr(GREAT)); } label faceI = boundaryTree.shapes().faceLabels()[info.index()]; @@ -129,20 +134,26 @@ void Foam::patchProbes::findElements(const fvMesh& mesh) << " This sample will not be included " << endl; } - else + else if (info.hit()) { - const point& fc = mesh.faceCentres()[faceI]; + // Note: do we store the face centre or the actual nearest? + // We interpolate using the faceI only though (no + // interpolation) so it does not actually matter much, just for + // the location written to the header. + + //const point& facePt = mesh.faceCentres()[faceI]; + const point& facePt = info.hitPoint(); mappedPatchBase::nearInfo sampleInfo; sampleInfo.first() = pointIndexHit ( true, - fc, + facePt, faceI ); - sampleInfo.second().first() = magSqr(fc-sample); + sampleInfo.second().first() = magSqr(facePt-sample); sampleInfo.second().second() = Pstream::myProcNo(); nearest[probeI]= sampleInfo; @@ -155,6 +166,14 @@ void Foam::patchProbes::findElements(const fvMesh& mesh) Pstream::listCombineGather(nearest, mappedPatchBase::nearestEqOp()); Pstream::listCombineScatter(nearest); + + // Update actual probe locations + forAll(nearest, sampleI) + { + operator[](sampleI) = nearest[sampleI].first().rawPoint(); + } + + if (debug) { Info<< "patchProbes::findElements" << " : " << endl; @@ -165,26 +184,41 @@ void Foam::patchProbes::findElements(const fvMesh& mesh) Info<< " " << sampleI << " coord:"<< operator[](sampleI) << " found on processor:" << procI - << " in local cell/face:" << localI - << " with fc:" << nearest[sampleI].first().rawPoint() << endl; + << " in local face:" << localI + << " with location:" << nearest[sampleI].first().rawPoint() + << endl; } } // Extract any local faces to sample - elementList_.setSize(nearest.size(), -1); + elementList_.setSize(nearest.size()); + elementList_ = -1; + faceList_.setSize(nearest.size()); + faceList_ = -1; forAll(nearest, sampleI) { if (nearest[sampleI].second().second() == Pstream::myProcNo()) { // Store the face to sample - elementList_[sampleI] = nearest[sampleI].first().index(); + faceList_[sampleI] = nearest[sampleI].first().index(); } } } +void Foam::patchProbes::readDict(const dictionary& dict) +{ + if (!dict.readIfPresent("patches", patchNames_)) + { + word patchName(dict.lookup("patchName")); + patchNames_ = wordReList(1, wordRe(patchName)); + } + probes::readDict(dict); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::patchProbes::patchProbes @@ -192,19 +226,22 @@ Foam::patchProbes::patchProbes const word& name, const objectRegistry& obr, const dictionary& dict, - const bool loadFromFiles + const bool loadFromFiles, + const bool doFindElements ) : - probes(name, obr, dict, loadFromFiles) + probes(name, obr, dict, loadFromFiles, false) { - // When constructing probes above it will have called the - // probes::findElements (since the virtual mechanism not yet operating). - // Not easy to workaround (apart from feeding through flag into constructor) - // so clear out any cells found for now. - elementList_.clear(); - faceList_.clear(); - - read(dict); + readDict(dict); + + if (doFindElements) + { + // Find the elements + findElements(mesh_); + + // Open the probe streams + prepare(); + } } @@ -232,10 +269,16 @@ void Foam::patchProbes::write() } } + void Foam::patchProbes::read(const dictionary& dict) { - dict.lookup("patchName") >> patchName_; - probes::read(dict); + readDict(dict); + + // Find the elements + findElements(mesh_); + + // Open the probe streams + prepare(); } diff --git a/src/sampling/probes/patchProbes.H b/src/sampling/probes/patchProbes.H index 2425b67f776bff4d4bc5464b42a9acea84d55fb9..e24b05efcec3f5ad4d9a621af52f3ac3369d450a 100644 --- a/src/sampling/probes/patchProbes.H +++ b/src/sampling/probes/patchProbes.H @@ -25,9 +25,45 @@ Class Foam::patchProbes Description - Set of locations to sample.at patches + Set of locations to sample at patches Call write() to sample and write files. + - find nearest location on nearest face + - update *this with location (so header contains 'snapped' locations + - use *this as the sampling location + + Example of function object specification: + \verbatim + patchProbes + { + type patchProbes; + functionObjectLibs ( "libsampling.so" ); + + // Name of the directory for probe data + name patchProbes; + + // Patches to sample (wildcards allowed) + patches (".*inl.*"); + + // Write at same frequency as fields + outputControl outputTime; + outputInterval 1; + + // Fields to be probed + fields + ( + p U + ); + + // Locations to probe. These get snapped onto the nearest point + // on the selected patches + probeLocations + ( + ( -100 0 0.01 ) // at inlet + ); + } + \endverbatim + SourceFiles patchProbes.C @@ -58,13 +94,15 @@ class patchProbes : public probes { - // Private data +protected: + + // Protected data - //- Patch name - word patchName_; + //- Patches to sample + wordReList patchNames_; - // Private Member Functions + // Protected Member Functions //- Sample and write a particular volume field template<class Type> @@ -73,7 +111,6 @@ class patchProbes const GeometricField<Type, fvPatchField, volMesh>& ); - //- Sample and write a particular surface field template<class Type> void sampleAndWrite @@ -81,17 +118,14 @@ class patchProbes const GeometricField<Type, fvsPatchField, surfaceMesh>& ); - //- Sample and write all the fields of the given type template<class Type> void sampleAndWrite(const fieldGroup<Type>&); - //- Sample and write all the surface fields of the given type template<class Type> void sampleAndWriteSurfaceFields(const fieldGroup<Type>&); - //- Sample a volume field at all locations template<class Type> tmp<Field<Type> > sample @@ -99,7 +133,6 @@ class patchProbes const GeometricField<Type, fvPatchField, volMesh>& ) const; - //- Sample a surface field at all locations template<class Type> tmp<Field<Type> > sample @@ -107,11 +140,18 @@ class patchProbes const GeometricField<Type, fvsPatchField, surfaceMesh>& ) const; - //- Sample a single field on all sample locations template<class Type> tmp<Field<Type> > sample(const word& fieldName) const; + //- Find elements containing patchProbes + virtual void findElements(const fvMesh&); + + //- Read dictionary settings + void readDict(const dictionary& dict); + + +private: //- Disallow default bitwise copy construct patchProbes(const patchProbes&); @@ -135,7 +175,8 @@ public: const word& name, const objectRegistry&, const dictionary&, - const bool loadFromFiles = false + const bool loadFromFiles = false, + const bool findElements = true ); @@ -149,9 +190,6 @@ public: //- Read virtual void read(const dictionary&); - - //- Find elements containing patchProbes - virtual void findElements(const fvMesh&); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/sampling/probes/patchProbesTemplates.C b/src/sampling/probes/patchProbesTemplates.C index 7e8ddd74b427bfcdaddc957e16f053a768c6b1d5..e0ff2206e74b893c498f5ebf2529efb1ef9d92bf 100644 --- a/src/sampling/probes/patchProbesTemplates.C +++ b/src/sampling/probes/patchProbesTemplates.C @@ -208,7 +208,7 @@ Foam::patchProbes::sample forAll(*this, probeI) { - label faceI = elementList_[probeI]; + label faceI = faceList_[probeI]; if (faceI >= 0) { @@ -259,7 +259,7 @@ Foam::patchProbes::sample forAll(*this, probeI) { - label faceI = elementList_[probeI]; + label faceI = faceList_[probeI]; if (faceI >= 0) { @@ -274,4 +274,6 @@ Foam::patchProbes::sample return tValues; } + + // ************************************************************************* // diff --git a/src/sampling/probes/probes.C b/src/sampling/probes/probes.C index 38ef3a63b47cca6388358bd289e320a3842d8f51..fd13764fab37c3e3725d1b462a9b51ddec0ef67d 100644 --- a/src/sampling/probes/probes.C +++ b/src/sampling/probes/probes.C @@ -265,6 +265,25 @@ Foam::label Foam::probes::prepare() } +void Foam::probes::readDict(const dictionary& dict) +{ + dict.lookup("probeLocations") >> *this; + dict.lookup("fields") >> fieldSelection_; + + dict.readIfPresent("fixedLocations", fixedLocations_); + if (dict.readIfPresent("interpolationScheme", interpolationScheme_)) + { + if (!fixedLocations_ && interpolationScheme_ != "cell") + { + WarningIn("void Foam::probes::read(const dictionary&)") + << "Only cell interpolation can be applied when " + << "not using fixedLocations. InterpolationScheme " + << "entry will be ignored"; + } + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::probes::probes @@ -272,7 +291,8 @@ Foam::probes::probes const word& name, const objectRegistry& obr, const dictionary& dict, - const bool loadFromFiles + const bool loadFromFiles, + const bool doFindElements ) : pointField(0), @@ -283,7 +303,18 @@ Foam::probes::probes fixedLocations_(true), interpolationScheme_("cell") { - read(dict); + // Read dictionary (but do not search for elements) + readDict(dict); + + // Optionally find elements in constructor + if (doFindElements) + { + // Find the elements + findElements(mesh_); + + // Open the probe streams + prepare(); + } } @@ -334,24 +365,12 @@ void Foam::probes::write() void Foam::probes::read(const dictionary& dict) { - dict.lookup("probeLocations") >> *this; - dict.lookup("fields") >> fieldSelection_; + readDict(dict); - dict.readIfPresent("fixedLocations", fixedLocations_); - if (dict.readIfPresent("interpolationScheme", interpolationScheme_)) - { - if (!fixedLocations_ && interpolationScheme_ != "cell") - { - WarningIn("void Foam::probes::read(const dictionary&)") - << "Only cell interpolation can be applied when " - << "not using fixedLocations. InterpolationScheme " - << "entry will be ignored"; - } - } - - // Initialise cells to sample from supplied locations + // Find the elements findElements(mesh_); + // Open the probe streams prepare(); } @@ -382,20 +401,28 @@ void Foam::probes::updateMesh(const mapPolyMesh& mpm) forAll(elementList_, i) { label cellI = elementList_[i]; - label newCellI = reverseMap[cellI]; - if (newCellI == -1) + if (cellI != -1) { - // cell removed - } - else if (newCellI < -1) - { - // cell merged - elems.append(-newCellI - 2); + label newCellI = reverseMap[cellI]; + if (newCellI == -1) + { + // cell removed + } + else if (newCellI < -1) + { + // cell merged + elems.append(-newCellI - 2); + } + else + { + // valid new cell + elems.append(newCellI); + } } else { - // valid new cell - elems.append(newCellI); + // Keep -1 elements so the size stays the same + elems.append(-1); } } @@ -410,20 +437,28 @@ void Foam::probes::updateMesh(const mapPolyMesh& mpm) forAll(faceList_, i) { label faceI = faceList_[i]; - label newFaceI = reverseMap[faceI]; - if (newFaceI == -1) - { - // face removed - } - else if (newFaceI < -1) + if (faceI != -1) { - // face merged - elems.append(-newFaceI - 2); + label newFaceI = reverseMap[faceI]; + if (newFaceI == -1) + { + // face removed + } + else if (newFaceI < -1) + { + // face merged + elems.append(-newFaceI - 2); + } + else + { + // valid new face + elems.append(newFaceI); + } } else { - // valid new face - elems.append(newFaceI); + // Keep -1 elements + elems.append(-1); } } diff --git a/src/sampling/probes/probes.H b/src/sampling/probes/probes.H index 5cc8c9f50c0ec9a050f5b857b56c9f9ffbfad830..ec759f11139df2fc067fad5accba6a2cbc185796 100644 --- a/src/sampling/probes/probes.H +++ b/src/sampling/probes/probes.H @@ -32,6 +32,42 @@ Description Call write() to sample and write files. + Example of function object specification: + \verbatim + probes + { + type probes; + functionObjectLibs ( "libsampling.so" ); + + // Name of the directory for probe data + name probes; + + // Write at same frequency as fields + outputControl outputTime; + outputInterval 1; + + // Fields to be probed + fields + ( + p U + ); + + // Optional: do not recalculate cells if mesh moves + fixedLocations false; + + // Optional: interpolation scheme to use (default is cell) + interpolationScheme cellPoint; + + probeLocations + ( + ( 1e-06 0 0.01 ) // at inlet + (0.21 -0.20999 0.01) // at outlet1 + (0.21 0.20999 0.01) // at outlet2 + (0.21 0 0.01) // at central block + ); + } + \endverbatim + SourceFiles probes.C @@ -91,13 +127,13 @@ protected: //- Name of this set of probes, // Also used as the name of the probes directory. - word name_; + const word name_; //- Const reference to fvMesh const fvMesh& mesh_; //- Load fields from files (not from objectRegistry) - bool loadFromFiles_; + const bool loadFromFiles_; // Read from dictonary @@ -106,7 +142,7 @@ protected: wordReList fieldSelection_; //- Fixed locations, default = yes - // Note: set to false for moving mesh calations where locations + // Note: set to false for moving mesh calculations where locations // should move with the mesh bool fixedLocations_; @@ -141,7 +177,7 @@ protected: HashPtrTable<OFstream> probeFilePtrs_; - // Private Member Functions + // Protected Member Functions //- Clear old field groups void clearFieldGroups(); @@ -159,6 +195,8 @@ protected: // returns number of fields to sample label prepare(); + //- Read dictionary settings + void readDict(const dictionary& dict); private: @@ -207,7 +245,8 @@ public: const word& name, const objectRegistry&, const dictionary&, - const bool loadFromFiles = false + const bool loadFromFiles = false, + const bool findElements = true ); diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H index 27433a57dac4af59d7ecc625be326b5070bdd003..b70b4d47c5b0be71102b019f25baa1baf7d4eea6 100644 --- a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H @@ -27,30 +27,32 @@ Class Description A surfaceWriter for outputting to a form useable for the timeVaryingMapped boundary condition. This reads the data from - constant/boundaryData/<patch> + constant/boundaryData/\<patch\> directory Typical way of working: - use a sampledSurface of type 'patch' (to sample a patch): + \verbatim + surfaces + { + type surfaces; + surfaceFormat boundaryData; + fields ( p ); surfaces - { - type surfaces; - surfaceFormat boundaryData; - fields ( p ); - surfaces - ( - outlet - { - type patch; - patches (outlet); - interpolate false; - } - ); - } + ( + outlet + { + type patch; + patches (outlet); + interpolate false; + } + ); + } + \endverbatim - write using this writer. - move postProcessing/surfaces/outlet to constant/boundaryData/outlet in your destination case. - - use a timeVaryingMappedFixedValue bc to read&interpolate + - use a timeVaryingMappedFixedValue condition to read and interpolate the profile: type timeVaryingMappedFixedValue; setAverage false; // do not use read average diff --git a/src/thermophysicalModels/radiation/derivedFvPatchFields/radiationCoupledBase/radiationCoupledBase.H b/src/thermophysicalModels/radiation/derivedFvPatchFields/radiationCoupledBase/radiationCoupledBase.H index 54902fa26105b483c25c9709a7d53bd042136a17..910371fb4abc30131a4ac7c0df848e80c2d97be5 100644 --- a/src/thermophysicalModels/radiation/derivedFvPatchFields/radiationCoupledBase/radiationCoupledBase.H +++ b/src/thermophysicalModels/radiation/derivedFvPatchFields/radiationCoupledBase/radiationCoupledBase.H @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - radiationCoupledBase + Foam::radiationCoupledBase Description Common functions to emissivity. It gets supplied from lookup into a