Merge branch 'develop' of develop.openfoam.com:Development/OpenFOAM-dev-OpenCFD into develop

This commit is contained in:
mattijs
2015-11-26 10:44:01 +00:00
175 changed files with 10821 additions and 4016 deletions

View File

@ -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;

View File

@ -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 \

View File

@ -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(),

View File

@ -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;
};

View File

@ -57,11 +57,4 @@ const Foam::labelList& Foam::backgroundMeshDecomposition::pointLevel() const
}
const Foam::decompositionMethod&
Foam::backgroundMeshDecomposition::decomposer() const
{
return decomposerPtr_();
}
// ************************************************************************* //

View File

@ -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)
"sizes",
runTime.timeName(),
meshSubDir,
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
);
triadIOField alignments
(
IOobject
(
"alignments",
mesh.time().timeName(),
meshSubDir,
mesh.time(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_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

View File

@ -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
),

View File

@ -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 = ""
);

View File

@ -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
(

View File

@ -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

View File

@ -30,7 +30,8 @@ EXE_LIBS = \
-lconformalVoronoiMesh \
-lmeshTools \
-ldecompositionMethods \
-L$(FOAM_LIBBIN)/dummy -lptscotchDecomp \
-ldecompose \
-L$(FOAM_LIBBIN)/dummy -lptscotchDecomp -lscotchDecomp \
-ledgeMesh \
-lfileFormats \
-ltriSurface \

View File

@ -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;
}

View File

@ -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;

View File

@ -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 \

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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
)
);
}

View File

@ -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",

View File

@ -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

View File

@ -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];
const wordRe patchGroup(args[1]);
IOobjectList objects(IOobjectList(mesh, mesh.time().timeName()));
fileName commsDir(runTime.path()/"comms");
args.optionReadIfPresent("commsDir", commsDir);
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);
if (processed == -1)
{
Info<< "Field " << fieldName << " not found" << endl;
}
externalCoupledFunctionObject::writeGeometry(mesh, commsDir, patchGroup);
Info<< "\nEnd\n" << endl;

View File

@ -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;
}
}
}
// ************************************************************************* //

View File

@ -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

View File

@ -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
int nProcsTarget = readNumProcs
(
readInt(decompositionDictSource.lookup("numberOfSubdomains"))
);
IOdictionary decompositionDictTarget
(
IOobject
(
"decomposeParDict",
runTimeTarget.system(),
runTimeTarget,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
int nProcsTarget
(
readInt(decompositionDictTarget.lookup("numberOfSubdomains"))
args,
"targetDecomposeParDict",
runTimeTarget
);
List<boundBox> bbsTarget(nProcsTarget);

View File

@ -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

View File

@ -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;

View File

@ -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)
{

View File

@ -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

View File

@ -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;

View File

@ -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_;

View File

@ -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

View File

@ -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.
@}

View File

@ -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.
@}

View File

@ -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

View File

@ -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);
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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
);
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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;
}

View File

@ -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
);
}

View File

@ -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

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude
LIB_LIBS = \

View File

@ -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
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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)

View File

@ -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_;

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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();
}

View File

@ -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_))
{

View File

@ -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_];

View File

@ -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_];

View File

@ -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_;

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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:

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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());
initInterpolations
(
nSeeds,
UIndex,
vsFlds,
vsInterp,
vvFlds,
vvInterp
);
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);
}
// 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;
}
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)()
);
}
if (log_) Info
<< " automatic track length specified through"
<< " number of sub cycles : " << nSubCycle_ << nl
<< endl;
}
}
}
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_);
// }
//}
// ************************************************************************* //

View File

@ -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();
};

View File

@ -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_);
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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)

View File

@ -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_;

View File

@ -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;
}
}

View File

@ -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
// ************************************************************************* //

View File

@ -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
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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
);
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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;
}
// ************************************************************************* //

View File

@ -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;

View File

@ -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_);
}
}

View File

@ -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);

View File

@ -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());
initInterpolations
(
nSeeds,
UIndex,
vsFlds,
vsInterp,
vvFlds,
vvInterp
);
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);
}
// 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_);
// }
//}
// ************************************************************************* //

View File

@ -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();
};

View File

@ -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())
{

View File

@ -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_)
{
dict.lookup("fieldName") >> fieldName_;
dict.lookup("resultName") >> resultName_;
log_.readIfPresent("log", dict);
if (resultName_ == "none")
dict.lookup("fieldName") >> fieldName_;
dict.readIfPresent("resultName", resultName_);
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();

View File

@ -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

View File

@ -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_)
{
dict.lookup("fieldName") >> fieldName_;
dict.lookup("resultName") >> resultName_;
log_.readIfPresent("log", dict);
if (resultName_ == "none")
dict.lookup("fieldName") >> fieldName_;
dict.readIfPresent("resultName", resultName_);
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();

View File

@ -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

View File

@ -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_)
{
dict.lookup("fieldName") >> fieldName_;
dict.lookup("resultName") >> resultName_;
log_.readIfPresent("log", dict);
if (resultName_ == "none")
dict.lookup("fieldName") >> fieldName_;
dict.readIfPresent("resultName", resultName_);
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();

View File

@ -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

View File

@ -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
@}
\*---------------------------------------------------------------------------*/

View File

@ -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.

View File

@ -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

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More