/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 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 .
Application
execFlowFunctionObjects
Description
Execute the set of functionObjects specified in the selected dictionary
(which defaults to system/controlDict) for the selected set of times.
Alternative dictionaries should be placed in the system/ directory.
The flow (p-U) and optionally turbulence fields are available for the
function objects to operate on allowing forces and other related properties
to be calculated in addition to cutting planes etc.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "timeSelector.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "pointFields.H"
#include "uniformDimensionedFields.H"
#include "ReadFields.H"
#include "fvOptions.H"
#include "singlePhaseTransportModel.H"
#include "turbulentTransportModel.H"
#include "turbulentFluidThermoModel.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Read all fields of type. Returns names of fields read. Guarantees all
// processors to read fields in same order.
template
wordList ReadUniformFields
(
const IOobjectList& objects,
PtrList& fields,
const bool syncPar
)
{
// Search list of objects for wanted type
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
wordList masterNames(fieldObjects.names());
if (syncPar && Pstream::parRun())
{
// Check that I have the same fields as the master
const wordList localNames(masterNames);
Pstream::scatter(masterNames);
HashSet localNamesSet(localNames);
forAll(masterNames, i)
{
const word& masterFld = masterNames[i];
HashSet::iterator iter = localNamesSet.find(masterFld);
if (iter == localNamesSet.end())
{
FatalErrorInFunction
<< "Fields not synchronised across processors." << endl
<< "Master has fields " << masterNames
<< " processor " << Pstream::myProcNo()
<< " has fields " << localNames << exit(FatalError);
}
else
{
localNamesSet.erase(iter);
}
}
forAllConstIter(HashSet, localNamesSet, iter)
{
FatalErrorInFunction
<< "Fields not synchronised across processors." << endl
<< "Master has fields " << masterNames
<< " processor " << Pstream::myProcNo()
<< " has fields " << localNames << exit(FatalError);
}
}
fields.setSize(masterNames.size());
// Make sure to read in masterNames order.
forAll(masterNames, i)
{
Info<< "Reading " << GeoField::typeName << ' ' << masterNames[i]
<< endl;
const IOobject& io = *fieldObjects[masterNames[i]];
fields.set
(
i,
new GeoField
(
IOobject
(
io.name(),
io.instance(),
io.local(),
io.db(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE,
io.registerObject()
)
)
);
}
return masterNames;
}
void calc
(
const argList& args,
const Time& runTime,
const fvMesh& mesh,
functionObjectList& fol
)
{
if (args.optionFound("noFlow"))
{
Info<< " Operating in no-flow mode; no models will be loaded."
<< " All vol, surface and point fields will be loaded." << endl;
// Read objects in time directory
IOobjectList objects(mesh, runTime.timeName());
// Read vol fields.
PtrList vsFlds;
ReadFields(mesh, objects, vsFlds);
PtrList vvFlds;
ReadFields(mesh, objects, vvFlds);
PtrList vstFlds;
ReadFields(mesh, objects, vstFlds);
PtrList vsymtFlds;
ReadFields(mesh, objects, vsymtFlds);
PtrList vtFlds;
ReadFields(mesh, objects, vtFlds);
// Read vol-internal fields.
PtrList vsiFlds;
ReadFields(mesh, objects, vsiFlds);
PtrList vviFlds;
ReadFields(mesh, objects, vviFlds);
PtrList vstiFlds;
ReadFields(mesh, objects, vstiFlds);
PtrList vsymtiFlds;
ReadFields(mesh, objects, vsymtiFlds);
PtrList vtiFlds;
ReadFields(mesh, objects, vtiFlds);
// Read surface fields.
PtrList ssFlds;
ReadFields(mesh, objects, ssFlds);
PtrList svFlds;
ReadFields(mesh, objects, svFlds);
PtrList sstFlds;
ReadFields(mesh, objects, sstFlds);
PtrList ssymtFlds;
ReadFields(mesh, objects, ssymtFlds);
PtrList stFlds;
ReadFields(mesh, objects, stFlds);
// Read point fields.
const pointMesh& pMesh = pointMesh::New(mesh);
PtrList psFlds;
ReadFields(pMesh, objects, psFlds);
PtrList pvFlds;
ReadFields(pMesh, objects, pvFlds);
PtrList pstFlds;
ReadFields(pMesh, objects, pstFlds);
PtrList psymtFlds;
ReadFields(pMesh, objects, psymtFlds);
PtrList ptFlds;
ReadFields(pMesh, objects, ptFlds);
// Read uniform dimensioned fields
IOobjectList constantObjects(mesh, runTime.constant());
PtrList usFlds;
ReadUniformFields(constantObjects, usFlds, true);
PtrList uvFlds;
ReadUniformFields(constantObjects, uvFlds, true);
PtrList ustFlds;
ReadUniformFields(constantObjects, ustFlds, true);
PtrList usymmtFlds;
ReadUniformFields(constantObjects, usymmtFlds, true);
PtrList utFlds;
ReadUniformFields(constantObjects, utFlds, true);
fol.execute(true);
}
else
{
Info<< " Reading phi" << endl;
surfaceScalarField phi
(
IOobject
(
"phi",
runTime.timeName(),
mesh,
IOobject::MUST_READ
),
mesh
);
Info<< " Reading U" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ
),
mesh
);
Info<< " Reading p" << endl;
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::MUST_READ
),
mesh
);
if (phi.dimensions() == dimVolume/dimTime)
{
IOobject turbulencePropertiesHeader
(
"turbulenceProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
);
if (turbulencePropertiesHeader.headerOk())
{
singlePhaseTransportModel laminarTransport(U, phi);
autoPtr turbulenceModel
(
incompressible::turbulenceModel::New
(
U,
phi,
laminarTransport
)
);
fol.execute(true);
}
else
{
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
fol.execute(true);
}
}
else if (phi.dimensions() == dimMass/dimTime)
{
autoPtr thermo(fluidThermo::New(mesh));
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh
),
thermo->rho()
);
IOobject turbulencePropertiesHeader
(
"turbulenceProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
);
if (turbulencePropertiesHeader.headerOk())
{
autoPtr turbulenceModel
(
compressible::turbulenceModel::New
(
rho,
U,
phi,
thermo()
)
);
fol.execute(true);
}
else
{
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
fol.execute(true);
}
}
else
{
FatalErrorInFunction
<< "Incorrect dimensions of phi: " << phi.dimensions()
<< nl << exit(FatalError);
}
}
}
autoPtr readFunctionObjects
(
const argList& args,
const Time& runTime,
dictionary& folDict
)
{
autoPtr folPtr;
if (args.optionFound("dict"))
{
folDict = IOdictionary
(
IOobject
(
args["dict"],
runTime,
IOobject::MUST_READ_IF_MODIFIED
)
);
folPtr.reset(new functionObjectList(runTime, folDict));
}
else
{
folPtr.reset(new functionObjectList(runTime));
}
folPtr->start();
return folPtr;
}
int main(int argc, char *argv[])
{
Foam::timeSelector::addOptions();
#include "addRegionOption.H"
Foam::argList::addBoolOption
(
"noFlow",
"suppress creating flow models"
);
#include "addDictOption.H"
#include "setRootCase.H"
#include "createTime.H"
Foam::instantList timeDirs = Foam::timeSelector::select0(runTime, args);
#include "createNamedMesh.H"
// Externally stored dictionary for functionObjectList
// if not constructed from runTime
dictionary folDict;
// Construct functionObjectList
autoPtr folPtr
(
readFunctionObjects(args, runTime, folDict)
);
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
Info<< "Time = " << runTime.timeName() << endl;
if (mesh.readUpdate() != polyMesh::UNCHANGED)
{
// Update functionObjectList if mesh changes
folPtr = readFunctionObjects(args, runTime, folDict);
}
FatalIOError.throwExceptions();
try
{
calc(args, runTime, mesh, folPtr());
}
catch (IOerror& err)
{
Warning<< err << endl;
}
Info<< endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //