Merge branch 'feature-functionObjects' into 'develop'

Feature function objects

Lots of code migrated from internal development line, code tidying and a few fixes

Updated objects
- corrected Peclet number for compressible cases
- propagated log flag and resultName across objects

New function objects
- new fluxSummary:
  - calculates positive, negative, absolute and net flux across face
    zones
- new runTimeControl
  - abort the calculation when a user-defined metric is achieved.
    Available options include:
    - average value remains unchanged wrt a given threshold
    - equation initial residual exceeds a threshold - useful to abort
      diverging cases
    - equation max iterations exceeds a threshold - useful to abort
      diverging cases
    - min/max of a function object value
    - min time step exceeds a threshold - useful to abort diverging
      cases
- new valueAverage:
  - average singular values from other function objects, e.g. Cd, Cl and
    Cm from the forceCoeffs function object


See merge request !12
This commit is contained in:
Mattijs Janssens
2015-11-25 19:46:41 +00:00
132 changed files with 9284 additions and 3577 deletions

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

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

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

@ -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,11 +111,12 @@ 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();
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

@ -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,18 +66,41 @@ Foam::partialWrite::~partialWrite()
void Foam::partialWrite::read(const dictionary& dict)
{
log_.readIfPresent("log", dict);
dict.lookup("objectNames") >> objectNames_;
dict.lookup("writeInterval") >> writeInterval_;
writeInstance_ = 0;
if (log_)
{
Info<< type() << " " << name() << ":" << nl
<< " dumping every " << writeInterval_
<< " th outputTime : " << nl << endl ;
<< " 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)
{
FatalIOErrorIn("partialWrite::read(const dictionary&)", dict)

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

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.
@ -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,9 +172,8 @@ void Foam::cloudInfo::write()
<< endl;
}
if (log_)
{
Info<< type() << " " << name_ << " output:" << nl
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " number of parcels : " << nParcels << nl
<< " mass in system : " << massInSystem << nl
<< " maximum diameter : " << Dmax << nl
@ -184,7 +183,6 @@ void Foam::cloudInfo::write()
}
}
}
}
// ************************************************************************* //

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

@ -34,16 +34,19 @@ 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
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " Calculating averages" << nl;
}
addMeanSqrToPrime2Mean<scalar, scalar>();
addMeanSqrToPrime2Mean<vector, symmTensor>();
@ -204,25 +202,21 @@ void Foam::fieldAverage::readAveragingProperties()
totalIter_[fieldI] = readLabel(fieldDict.lookup("totalIter"));
totalTime_[fieldI] = readScalar(fieldDict.lookup("totalTime"));
if (log_)
{
Info<< " " << fieldName
if (log_) Info
<< " " << fieldName
<< " iters = " << totalIter_[fieldI]
<< " time = " << totalTime_[fieldI] << nl;
}
}
else
{
if (log_)
{
Info<< " " << fieldName
if (log_) Info
<< " " << fieldName
<< ": starting averaging at time "
<< obr_.time().timeName() << endl;
}
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -315,11 +309,9 @@ void Foam::fieldAverage::write()
if (resetOnOutput_)
{
if (log_)
{
Info<< " Restarting averaging at time " << obr_.time().timeName()
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
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
if (log_) Info
<< " Cannot allocate average field " << prime2MeanFieldName
<< " since an object with that name already exists."
<< " Disabling averaging for field." << nl;
}
<< " 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_ << ":"
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_]
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_]
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()
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,14 +392,12 @@ void Foam::regionSizeDistribution::read(const dictionary& dict)
{
coordSysPtr_.reset(new coordinateSystem(obr_, dict));
if (log_)
{
Info<< "Transforming all vectorFields with coordinate system "
if (log_) Info
<< "Transforming all vectorFields with coordinate system "
<< coordSysPtr_().name() << endl;
}
}
}
}
void Foam::regionSizeDistribution::execute()
@ -467,24 +459,20 @@ void Foam::regionSizeDistribution::write()
: obr_.lookupObject<volScalarField>(alphaName_)
);
if (log_)
{
Info<< " Volume of alpha = "
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
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()
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"
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,29 +607,25 @@ void Foam::regionSizeDistribution::write()
++vIter, ++aIter, ++numIter
)
{
if (log_)
{
Info<< " " << token::TAB << vIter.key()
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:"
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
if (log_) Info
<< "Transforming vector field " << fldName
<< " with coordinate system "
<< coordSysPtr_().name()
<< endl;
}
<< 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());
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
initInterpolations
(
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]
nSeeds,
UIndex,
vsFlds,
vsInterp,
vvFlds,
vvInterp
);
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
if (log_) Info
<< " automatic track length specified through"
<< " number of sub cycles : " << nSubCycle_ << nl
<< endl;
// Massage into form suitable for writers
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (Pstream::master() && allTracks_.size())
{
// Make output directory
fileName vtkPath
(
Pstream::parRun()
? runTime.path()/".."/"postProcessing"/"sets"/name()
: runTime.path()/"postProcessing"/"sets"/name()
);
if (mesh.name() != fvMesh::defaultRegion)
{
vtkPath = vtkPath/mesh.name();
}
vtkPath = vtkPath/mesh.time().timeName();
mkDir(vtkPath);
// Convert track positions
PtrList<coordSet> tracks(allTracks_.size());
forAll(allTracks_, trackI)
{
tracks.set
(
trackI,
new coordSet
(
"track" + Foam::name(trackI),
sampledSetAxis_ //"xyz"
)
);
tracks[trackI].transfer(allTracks_[trackI]);
}
// Convert scalar values
if (allScalars_.size() > 0)
{
List<List<scalarField> > scalarValues(allScalars_.size());
forAll(allScalars_, scalarI)
{
DynamicList<scalarList>& allTrackVals =
allScalars_[scalarI];
scalarValues[scalarI].setSize(allTrackVals.size());
forAll(allTrackVals, trackI)
{
scalarList& trackVals = allTrackVals[trackI];
scalarValues[scalarI][trackI].transfer(trackVals);
}
}
fileName vtkFile
(
vtkPath
/ scalarFormatterPtr_().getFileName
(
tracks[0],
scalarNames_
)
);
Info<< " Writing data to " << vtkFile.path() << endl;
scalarFormatterPtr_().write
(
true, // writeTracks
tracks,
scalarNames_,
scalarValues,
OFstream(vtkFile)()
);
}
// Convert vector values
if (allVectors_.size() > 0)
{
List<List<vectorField> > vectorValues(allVectors_.size());
forAll(allVectors_, vectorI)
{
DynamicList<vectorList>& allTrackVals =
allVectors_[vectorI];
vectorValues[vectorI].setSize(allTrackVals.size());
forAll(allTrackVals, trackI)
{
vectorList& trackVals = allTrackVals[trackI];
vectorValues[vectorI][trackI].transfer(trackVals);
}
}
fileName vtkFile
(
vtkPath
/ vectorFormatterPtr_().getFileName
(
tracks[0],
vectorNames_
)
);
//Info<< " Writing vector data to " << vtkFile << endl;
vectorFormatterPtr_().write
(
true, // writeTracks
tracks,
vectorNames_,
vectorValues,
OFstream(vtkFile)()
);
}
}
}
}
void Foam::streamLine::updateMesh(const mapPolyMesh&)
{
read(dict_);
}
void Foam::streamLine::movePoints(const polyMesh&)
{
// Moving mesh affects the search tree
read(dict_);
}
//void Foam::streamLine::readUpdate(const polyMesh::readUpdateState state)
//{
// if (state != UNCHANGED)
// {
// read(dict_);
// }
//}
// ************************************************************************* //

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,976 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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_
)
);
Info(log_)<< " 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

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::IOvalueAverage
Description
Instance of the generic IOOutputFilter for valueAverage.
\*---------------------------------------------------------------------------*/
#ifndef IOvalueAverage_H
#define IOvalueAverage_H
#include "valueAverage.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<valueAverage> IOvalueAverage;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#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,8 +257,6 @@ bool Foam::wallBoundedParticle::isTriAlongTrack
const triFace triVerts(currentTetIndices().faceTriIs(mesh_));
const edge currentE = currentEdge();
//if (debug)
{
if
(
currentE[0] == currentE[1]
@ -276,7 +272,6 @@ bool Foam::wallBoundedParticle::isTriAlongTrack
<< info()
<< abort(FatalError);
}
}
const vector dir = endPosition-position();
@ -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,19 +23,10 @@ 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 * * * * * * * * * * * * * //
@ -48,57 +39,6 @@ defineTypeNameAndDebug(wallBoundedStreamLine, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::autoPtr<Foam::indirectPrimitivePatch>
Foam::wallBoundedStreamLine::wallPatch() const
{
const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
const polyBoundaryMesh& patches = mesh.boundaryMesh();
label nFaces = 0;
forAll(patches, patchI)
{
//if (!polyPatch::constraintType(patches[patchI].type()))
if (isA<wallPolyPatch>(patches[patchI]))
{
nFaces += patches[patchI].size();
}
}
labelList addressing(nFaces);
nFaces = 0;
forAll(patches, patchI)
{
//if (!polyPatch::constraintType(patches[patchI].type()))
if (isA<wallPolyPatch>(patches[patchI]))
{
const polyPatch& pp = patches[patchI];
forAll(pp, i)
{
addressing[nFaces++] = pp.start()+i;
}
}
}
return autoPtr<indirectPrimitivePatch>
(
new indirectPrimitivePatch
(
IndirectList<face>
(
mesh.faces(),
addressing
),
mesh.points()
)
);
}
Foam::tetIndices Foam::wallBoundedStreamLine::findNearestTet
(
const PackedBoolList& isWallPatch,
@ -158,7 +98,7 @@ Foam::tetIndices Foam::wallBoundedStreamLine::findNearestTet
void Foam::wallBoundedStreamLine::track()
{
const Time& runTime = obr_.time();
//const Time& runTime = obr_.time();
const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
@ -227,14 +167,14 @@ void Foam::wallBoundedStreamLine::track()
else
{
Pout<< type() << " : ignoring seed " << seedPt
<< " since not in wall cell." << endl;
<< " since not in wall cell" << endl;
}
}
}
label nSeeds = returnReduce(particles.size(), sumOp<label>());
Info<< type() << " : seeded " << nSeeds << " particles." << endl;
if (log_) Info<< type() << " : seeded " << nSeeds << " particles" << endl;
@ -243,168 +183,19 @@ void Foam::wallBoundedStreamLine::track()
PtrList<interpolation<scalar> > vsInterp;
PtrList<volVectorField> vvFlds;
PtrList<interpolation<vector> > vvInterp;
label UIndex = -1;
if (loadFromFiles_)
{
IOobjectList allObjects(mesh, runTime.timeName());
IOobjectList objects(2*fields_.size());
forAll(fields_, i)
{
objects.add(*allObjects[fields_[i]]);
}
ReadFields(mesh, objects, vsFlds);
vsInterp.setSize(vsFlds.size());
forAll(vsFlds, i)
{
vsInterp.set
initInterpolations
(
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]
nSeeds,
UIndex,
vsFlds,
vsInterp,
vvFlds,
vvInterp
);
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
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
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

View File

@ -0,0 +1,947 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "externalCoupledFunctionObject.H"
#include "addToRunTimeSelectionTable.H"
#include "OSspecific.H"
#include "IFstream.H"
#include "OFstream.H"
#include "volFields.H"
#include "globalIndex.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(externalCoupledFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
externalCoupledFunctionObject,
dictionary
);
}
Foam::word Foam::externalCoupledFunctionObject::lockName = "OpenFOAM";
Foam::string Foam::externalCoupledFunctionObject::patchKey = "# Patch: ";
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::fileName Foam::externalCoupledFunctionObject::baseDir() const
{
fileName result(commsDir_);
result.clean();
return result;
}
Foam::fileName Foam::externalCoupledFunctionObject::groupDir
(
const fileName& commsDir,
const word& regionName,
const wordRe& groupName
)
{
fileName result(commsDir/regionName/string::validate<fileName>(groupName));
result.clean();
return result;
}
Foam::fileName Foam::externalCoupledFunctionObject::lockFile() const
{
return fileName(baseDir()/(lockName + ".lock"));
}
void Foam::externalCoupledFunctionObject::createLockFile() const
{
if (!Pstream::master())
{
return;
}
const fileName fName(lockFile());
IFstream is(fName);
// Only create lock file if it doesn't already exist
if (!is.good())
{
if (log_) Info<< type() << ": creating lock file" << endl;
OFstream os(fName);
os << "lock file";
os.flush();
}
}
void Foam::externalCoupledFunctionObject::removeLockFile() const
{
if (!Pstream::master())
{
return;
}
if (log_) Info<< type() << ": removing lock file" << endl;
rm(lockFile());
}
void Foam::externalCoupledFunctionObject::removeReadFiles() const
{
if (!Pstream::master())
{
return;
}
if (log_) Info<< type() << ": removing all read files" << endl;
forAll(regionNames_, regionI)
{
const word& regionName = regionNames_[regionI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
const labelList& groups = regionToGroups_[regionName];
forAll(groups, i)
{
label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI];
forAll(groupReadFields_[groupI], fieldI)
{
const word& fieldName = groupReadFields_[groupI][fieldI];
rm
(
groupDir(commsDir_, mesh.dbDir(), groupName)
/ fieldName + ".in"
);
}
}
}
}
void Foam::externalCoupledFunctionObject::removeWriteFiles() const
{
if (!Pstream::master())
{
return;
}
if (log_) Info<< type() << ": removing all write files" << endl;
forAll(regionNames_, regionI)
{
const word& regionName = regionNames_[regionI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
const labelList& groups = regionToGroups_[regionName];
forAll(groups, i)
{
label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI];
forAll(groupWriteFields_[groupI], fieldI)
{
const word& fieldName = groupWriteFields_[groupI][fieldI];
rm
(
groupDir(commsDir_, mesh.dbDir(), groupName)
/ fieldName + ".out"
);
}
}
}
}
void Foam::externalCoupledFunctionObject::wait() const
{
const fileName fName(lockFile());
label found = 0;
label totalTime = 0;
if (log_) Info<< type() << ": beginning wait for lock file " << fName << nl;
while (found == 0)
{
if (Pstream::master())
{
if (totalTime > timeOut_)
{
FatalErrorIn
(
"void "
"Foam::externalCoupledFunctionObject::wait() "
"const"
)
<< "Wait time exceeded time out time of " << timeOut_
<< " s" << abort(FatalError);
}
IFstream is(fName);
if (is.good())
{
found++;
if (log_)
{
Info<< type() << ": found lock file " << fName << endl;
}
}
else
{
sleep(waitInterval_);
totalTime += waitInterval_;
if (log_)
{
Info<< type() << ": wait time = " << totalTime << endl;
}
}
}
// prevent other procs from racing ahead
reduce(found, sumOp<label>());
}
}
void Foam::externalCoupledFunctionObject::readColumns
(
const label nRows,
const label nColumns,
autoPtr<IFstream>& masterFilePtr,
List<scalarField>& data
) const
{
// Get sizes for all processors
const globalIndex globalFaces(nRows);
PstreamBuffers pBufs(Pstream::nonBlocking);
if (Pstream::master())
{
string line;
// Read data from file and send to destination processor
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
// Temporary storage
List<scalarField> values(nColumns);
// Number of rows to read for processor procI
label procNRows = globalFaces.localSize(procI);
forAll(values, columnI)
{
values[columnI].setSize(procNRows);
}
for (label rowI = 0; rowI < procNRows; rowI++)
{
// Get a line
do
{
if (!masterFilePtr().good())
{
FatalIOErrorIn
(
"externalCoupledFunctionObject::readColumns()",
masterFilePtr()
) << "Trying to read data for processor " << procI
<< " row " << rowI
<< ". Does your file have as many rows as there are"
<< " patch faces (" << globalFaces.size()
<< ") ?" << exit(FatalIOError);
}
masterFilePtr().getLine(line);
} while (line.empty() || line[0] == '#');
IStringStream lineStr(line);
for (label columnI = 0; columnI < nColumns; columnI++)
{
lineStr >> values[columnI][rowI];
}
}
// Send to procI
UOPstream str(procI, pBufs);
str << values;
}
}
pBufs.finishedSends();
// Read from PstreamBuffers
UIPstream str(Pstream::masterNo(), pBufs);
str >> data;
}
void Foam::externalCoupledFunctionObject::readLines
(
const label nRows,
autoPtr<IFstream>& masterFilePtr,
OStringStream& lines
) const
{
// Get sizes for all processors
const globalIndex globalFaces(nRows);
PstreamBuffers pBufs(Pstream::nonBlocking);
if (Pstream::master())
{
string line;
// Read line from file and send to destination processor
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
// Number of rows to read for processor procI
label procNRows = globalFaces.localSize(procI);
UOPstream toProc(procI, pBufs);
for (label rowI = 0; rowI < procNRows; rowI++)
{
// Get a line
do
{
if (!masterFilePtr().good())
{
FatalIOErrorIn
(
"externalCoupledFunctionObject::readColumns()",
masterFilePtr()
) << "Trying to read data for processor " << procI
<< " row " << rowI
<< ". Does your file have as many rows as there are"
<< " patch faces (" << globalFaces.size()
<< ") ?" << exit(FatalIOError);
}
masterFilePtr().getLine(line);
} while (line.empty() || line[0] == '#');
// Send line to the destination processor
toProc << line;
}
}
}
pBufs.finishedSends();
// Read lines from PstreamBuffers
UIPstream str(Pstream::masterNo(), pBufs);
for (label rowI = 0; rowI < nRows; rowI++)
{
string line(str);
lines << line.c_str() << nl;
}
}
void Foam::externalCoupledFunctionObject::writeGeometry
(
const fvMesh& mesh,
const fileName& commsDir,
const wordRe& groupName
)
{
fileName dir(groupDir(commsDir, mesh.dbDir(), groupName));
//if (log_)
{
Info<< typeName << ": writing geometry to " << dir << endl;
}
autoPtr<OFstream> osPointsPtr;
autoPtr<OFstream> osFacesPtr;
if (Pstream::master())
{
mkDir(dir);
osPointsPtr.reset(new OFstream(dir/"patchPoints"));
osFacesPtr.reset(new OFstream(dir/"patchFaces"));
}
const labelList patchIDs
(
mesh.boundaryMesh().patchSet
(
List<wordRe>(1, groupName)
).sortedToc()
);
forAll(patchIDs, i)
{
label patchI = patchIDs[i];
const polyPatch& p = mesh.boundaryMesh()[patchI];
labelList pointToGlobal;
labelList uniquePointIDs;
mesh.globalData().mergePoints
(
p.meshPoints(),
p.meshPointMap(),
pointToGlobal,
uniquePointIDs
);
label procI = Pstream::myProcNo();
List<pointField> allPoints(Pstream::nProcs());
allPoints[procI] = pointField(mesh.points(), uniquePointIDs);
Pstream::gatherList(allPoints);
List<faceList> allFaces(Pstream::nProcs());
faceList& patchFaces = allFaces[procI];
patchFaces = p.localFaces();
forAll(patchFaces, faceI)
{
inplaceRenumber(pointToGlobal, patchFaces[faceI]);
}
Pstream::gatherList(allFaces);
if (Pstream::master())
{
pointField pts
(
ListListOps::combine<pointField>
(
allPoints,
accessOp<pointField>()
)
);
//if (log_)
{
Info<< typeName << ": for patch " << p.name()
<< " writing " << pts.size() << " points to "
<< osPointsPtr().name() << endl;
}
// Write points
osPointsPtr() << patchKey.c_str() << p.name() << pts << endl;
faceList fcs
(
ListListOps::combine<faceList>(allFaces, accessOp<faceList>())
);
//if (log_)
{
Info<< typeName << ": for patch " << p.name()
<< " writing " << fcs.size() << " faces to "
<< osFacesPtr().name() << endl;
}
// Write faces
osFacesPtr() << patchKey.c_str() << p.name() << fcs << endl;
}
}
}
void Foam::externalCoupledFunctionObject::readData()
{
forAll(regionNames_, regionI)
{
const word& regionName = regionNames_[regionI];
const labelList& groups = regionToGroups_[regionName];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
forAll(groups, i)
{
label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI];
const labelList& patchIDs = groupPatchIDs_[groupI];
const wordList& fieldNames = groupReadFields_[groupI];
forAll(fieldNames, fieldI)
{
const word& fieldName = fieldNames[fieldI];
bool ok = readData<scalar>
(
mesh,
groupName,
patchIDs,
fieldName
);
ok = ok || readData<vector>
(
mesh,
groupName,
patchIDs,
fieldName
);
ok = ok || readData<sphericalTensor>
(
mesh,
groupName,
patchIDs,
fieldName
);
ok = ok || readData<symmTensor>
(
mesh,
groupName,
patchIDs,
fieldName
);
ok = ok || readData<tensor>
(
mesh,
groupName,
patchIDs,
fieldName
);
if (!ok)
{
WarningIn
(
"void Foam::externalCoupledFunctionObject::readData()"
)
<< "Field " << fieldName << " in region " << mesh.name()
<< " was not found." << endl;
}
}
}
}
}
void Foam::externalCoupledFunctionObject::writeData() const
{
forAll(regionNames_, regionI)
{
const word& regionName = regionNames_[regionI];
const labelList& groups = regionToGroups_[regionName];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
forAll(groups, i)
{
label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI];
const labelList& patchIDs = groupPatchIDs_[groupI];
const wordList& fieldNames = groupWriteFields_[groupI];
forAll(fieldNames, fieldI)
{
const word& fieldName = fieldNames[fieldI];
bool ok = writeData<scalar>
(
mesh,
groupName,
patchIDs,
fieldName
);
ok = ok || writeData<vector>
(
mesh,
groupName,
patchIDs,
fieldName
);
ok = ok || writeData<sphericalTensor>
(
mesh,
groupName,
patchIDs,
fieldName
);
ok = ok || writeData<symmTensor>
(
mesh,
groupName,
patchIDs,
fieldName
);
ok = ok || writeData<tensor>
(
mesh,
groupName,
patchIDs,
fieldName
);
if (!ok)
{
WarningIn
(
"void Foam::externalCoupledFunctionObject::writeData()"
)
<< "Field " << fieldName << " in region " << mesh.name()
<< " was not found." << endl;
}
}
}
}
}
void Foam::externalCoupledFunctionObject::initialise()
{
if (initialised_)
{
return;
}
// Write the geometry if not already there
forAll(regionNames_, regionI)
{
const word& regionName = regionNames_[regionI];
const labelList& groups = regionToGroups_[regionName];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
forAll(groups, i)
{
label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI];
bool exists = false;
if (Pstream::master())
{
fileName dir(groupDir(commsDir_, mesh.dbDir(), groupName));
exists = isFile(dir/"patchPoints") || isFile(dir/"patchFaces");
}
if (!returnReduce(exists, orOp<bool>()))
{
writeGeometry(mesh, commsDir_, groupName);
}
}
}
if (initByExternal_)
{
// Wait for initial data to be made available
wait();
// Eead data passed back from external source
readData();
}
initialised_ = true;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::externalCoupledFunctionObject::externalCoupledFunctionObject
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
functionObject(name),
time_(runTime),
enabled_(true),
initialised_(false)
{
read(dict);
if (Pstream::master())
{
mkDir(baseDir());
}
if (!initByExternal_)
{
createLockFile();
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::externalCoupledFunctionObject::~externalCoupledFunctionObject()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::externalCoupledFunctionObject::on()
{
enabled_ = true;
}
void Foam::externalCoupledFunctionObject::off()
{
enabled_ = false;
}
bool Foam::externalCoupledFunctionObject::start()
{
return true;
}
bool Foam::externalCoupledFunctionObject::execute(const bool forceWrite)
{
if
(
enabled()
&& (!initialised_ || time_.timeIndex() % calcFrequency_ == 0)
)
{
// Initialise the coupling
initialise();
// Write data for external source
writeData();
// remove lock file, signalling external source to execute
removeLockFile();
// Wait for response
wait();
// Remove old data files from OpenFOAM
removeWriteFiles();
// Read data passed back from external source
readData();
// create lock file for external source
createLockFile();
return true;
}
else
{
return false;
}
}
bool Foam::externalCoupledFunctionObject::end()
{
if (enabled())
{
// Remove old data files
removeReadFiles();
removeWriteFiles();
removeLockFile();
}
return true;
}
bool Foam::externalCoupledFunctionObject::timeSet()
{
// Do nothing - only valid on execute
return true;
}
bool Foam::externalCoupledFunctionObject::adjustTimeStep()
{
return true;
}
bool Foam::externalCoupledFunctionObject::read(const dictionary& dict)
{
dict.readIfPresent("enabled", enabled_);
if (!enabled_)
{
return true;
}
dict.lookup("commsDir") >> commsDir_;
commsDir_.expand();
waitInterval_ = dict.lookupOrDefault("waitInterval", 1);
timeOut_ = dict.lookupOrDefault("timeOut", 100*waitInterval_);
calcFrequency_ = dict.lookupOrDefault("calcFrequency", 1);
initByExternal_ = readBool(dict.lookup("initByExternal"));
log_ = dict.lookupOrDefault("log", false);
const dictionary& allRegionsDict = dict.subDict("regions");
forAllConstIter(dictionary, allRegionsDict, iter)
{
if (!iter().isDict())
{
FatalIOErrorIn
(
"void Foam::externalCoupledFunctionObject::read"
"(const dictionary&)",
allRegionsDict
)
<< "Regions must be specified in dictionary format"
<< exit(FatalIOError);
}
const word& regionName = iter().keyword();
const dictionary& regionDict = iter().dict();
regionNames_.append(regionName);
forAllConstIter(dictionary, regionDict, regionIter)
{
if (!regionIter().isDict())
{
FatalIOErrorIn
(
"void Foam::externalCoupledFunctionObject::read"
"(const dictionary&)",
regionDict
)
<< "Regions must be specified in dictionary format"
<< exit(FatalIOError);
}
const wordRe groupName(regionIter().keyword());
const dictionary& groupDict = regionIter().dict();
label nGroups = groupNames_.size();
const wordList readFields(groupDict.lookup("readFields"));
const wordList writeFields(groupDict.lookup("writeFields"));
HashTable<labelList>::iterator fnd = regionToGroups_.find
(
regionName
);
if (fnd != regionToGroups_.end())
{
fnd().append(nGroups);
}
else
{
regionToGroups_.insert(regionName, labelList(1, nGroups));
}
groupNames_.append(groupName);
groupReadFields_.append(readFields);
groupWriteFields_.append(writeFields);
// Pre-calculate the patchIDs
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
groupPatchIDs_.append
(
mesh.boundaryMesh().patchSet
(
List<wordRe>(1, groupName)
).sortedToc()
);
}
}
// Print a bit
if (log_)
{
Info<< type() << ": Communicating with regions:" << endl;
forAll(regionNames_, regionI)
{
const word& regionName = regionNames_[regionI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
Info<< "Region: " << mesh.name() << endl << incrIndent;
const labelList& groups = regionToGroups_[regionName];
forAll(groups, i)
{
label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI];
const labelList& patchIDs = groupPatchIDs_[groupI];
Info<< indent << "Group: " << groupName << "\t"
<< " patches: " << patchIDs << endl
<< incrIndent
<< indent << "Reading fields: " << groupReadFields_[groupI]
<< endl
<< indent << "Writing fields: " << groupWriteFields_[groupI]
<< endl
<< decrIndent;
}
Info<< decrIndent;
}
Info<< endl;
}
// Note: we should not have to make directories since the geometry
// should already be written - but just make sure
if (Pstream::master())
{
forAll(regionNames_, regionI)
{
const word& regionName = regionNames_[regionI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
const labelList& groups = regionToGroups_[regionName];
forAll(groups, i)
{
label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI];
fileName dir(groupDir(commsDir_, mesh.dbDir(), groupName));
if (!isDir(dir))
{
if (log_)
{
Info<< type() << ": creating communications directory "
<< dir << endl;
}
mkDir(dir);
}
}
}
}
return true;
}
void Foam::externalCoupledFunctionObject::updateMesh(const mapPolyMesh& mpm)
{}
void Foam::externalCoupledFunctionObject::movePoints(const polyMesh& mesh)
{}
// ************************************************************************* //

View File

@ -0,0 +1,383 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify i
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::externalCoupledFunctionObject
Group
grpJobControlFunctionObjects
Description
This functionObject provides a simple interface for explicit coupling with
an external application. The coupling is through plain text files
where OpenFOAM boundary data is read/written as one line per face
(data from all processors collated):
# Patch: <patch name>
<fld1> <fld2> .. <fldn> //face0
<fld1> <fld2> .. <fldn> //face1
..
<fld1> <fld2> .. <fldn> //faceN
where the actual entries depend on the bc type:
- mixed: value, snGrad, refValue, refGrad, valueFraction
- externalCoupledMixed: output of writeData
- other: value, snGrad
These text files are located in a user specified communications directory
which gets read/written on the master processor only. In the
communications directory the structure will be
<regionName>/<patchGroup>/<fieldName>.[in|out]
At start-up, the boundary creates a lock file, i.e..
OpenFOAM.lock
... to signal the external source to wait. During the functionObject
execution the boundary values are written to files (one per region,
per patch(group), per field), e.g.
<regionName>/<patchGroup>/<fieldName>.out
The lock file is then removed, instructing the external source to take
control of the program execution. When ready, the external program
should create the return values, e.g. to files
<regionName>/<patchGroup>/<fieldName>.in
... and then re-instate the lock file. The functionObject will then
read these values, apply them to the boundary conditions and pass
program execution back to OpenFOAM.
Example of function object specification:
\verbatim
externalCoupled
{
type externalCoupled;
...
log yes;
commsDir "${FOAM_CASE}/comms";
initByExternal yes;
regions
{
region0
{
TPatchGroup // Name of patch(group)
{
readFields (p); // List of fields to read
writeFields (T); // List of fields to write
}
}
}
}
\endverbatim
This reads/writes (on the master processor) the directory:
comms/region0/TPatchGroup/
with contents:
patchPoints (collected points)
patchFaces (collected faces)
p.in (input file of p, written by external application)
T.out (output file of T, written by OpenFOAM)
The patchPoints/patchFaces files denote the (collated) geometry
which will be written if it does not exist yet or can be written as
a preprocessing step using the createExternalCoupledPatchGeometry
application.
SourceFiles
externalCoupledFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef externalCoupledFunctionObject_H
#define externalCoupledFunctionObject_H
#include "functionObject.H"
#include "DynamicList.H"
#include "wordReList.H"
#include "scalarField.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class dictionary;
class polyMesh;
class mapPolyMesh;
class IFstream;
class fvMesh;
/*---------------------------------------------------------------------------*\
Class externalCoupledFunctionObject Declaration
\*---------------------------------------------------------------------------*/
class externalCoupledFunctionObject
:
public functionObject
{
// Private data
//- Reference to the time database
const Time& time_;
//- Switch for the execution - defaults to 'yes/on'
Switch enabled_;
//- Path to communications directory
fileName commsDir_;
//- Interval time between checking for return data [s]
label waitInterval_;
//- Time out time [s]
label timeOut_;
//- Calculation frequency
label calcFrequency_;
//- Flag to indicate values are initialised by external application
bool initByExternal_;
//- Log flag
bool log_;
//- Names of regions
DynamicList<word> regionNames_;
// Per region the indices of the group information
HashTable<labelList> regionToGroups_;
// Per group the names of the patches/patchGroups
DynamicList<wordRe> groupNames_;
// Per group the indices of the patches
DynamicList<labelList> groupPatchIDs_;
// Per group the names of the fields to read
DynamicList<wordList> groupReadFields_;
// Per group the names of the fields to write
DynamicList<wordList> groupWriteFields_;
//- Initialised flag
bool initialised_;
// Private Member Functions
//- Return the file path to the communications directory for the region
static fileName groupDir
(
const fileName& commsDir,
const word& regionName,
const wordRe& groupName
);
//- Return the file path to the base communications directory
fileName baseDir() const;
//- Return the file path to the lock file
fileName lockFile() const;
//- Create lock file
void createLockFile() const;
//- Remove lock file
void removeLockFile() const;
//- Remove files written by OpenFOAM
void removeWriteFiles() const;
//- Remove files written by external code
void removeReadFiles() const;
//- Wait for response from external source
void wait() const;
//- Read data for a single region, single field
template<class Type>
bool readData
(
const fvMesh& mesh,
const wordRe& groupName,
const labelList& patchIDs,
const word& fieldName
);
//- Read data for all regions, all fields
void readData();
//- Write data for a single region, single field
template<class Type>
bool writeData
(
const fvMesh& mesh,
const wordRe& groupName,
const labelList& patchIDs,
const word& fieldName
) const;
//- Write data for all regions, all fields
void writeData() const;
void initialise();
//- Read (and distribute) scalar columns from stream. Every processor
// gets nRows (= patch size) of these. Note: could make its argument
// ISstream& but then would need additional logic to construct valid
// stream on all processors.
void readColumns
(
const label nRows,
const label nColumns,
autoPtr<IFstream>& masterFilePtr,
List<scalarField>& data
) const;
//- Read (and distribute) lines from stream. Every processor
// gets nRows (= patch size) of these. Data kept as stream (instead
// of strings) for ease of interfacing to readData routines that take
// an Istream.
void readLines
(
const label nRows,
autoPtr<IFstream>& masterFilePtr,
OStringStream& data
) const;
//- Helper: append data from all processors onto master
template<class Type>
static tmp<Field<Type> > gatherAndCombine(const Field<Type>& fld);
//- Disallow default bitwise copy construc
externalCoupledFunctionObject(const externalCoupledFunctionObject&);
//- Disallow default bitwise assignmen
void operator=(const externalCoupledFunctionObject&);
public:
//- Runtime type information
TypeName("externalCoupled");
//- Name of lock file
static word lockName;
//- Name of patch key, e.g. '# Patch:' when looking for start of patch data
static string patchKey;
// Constructors
//- Construct given time and dictionary
externalCoupledFunctionObject
(
const word& name,
const Time& runTime,
const dictionary& dict
);
//- Destructor
virtual ~externalCoupledFunctionObject();
// Member Functions
// Access
//- Return the enabled flag
virtual bool enabled() const
{
return enabled_;
}
// Function object control
//- Switch the function object on
virtual void on();
//- Switch the function object off
virtual void off();
//- Called at the start of the time-loop
virtual bool start();
//- Called at each ++ or += of the time-loop
virtual bool execute(const bool forceWrite);
//- Called when Time::run() determines that the time-loop exits
virtual bool end();
//- Called when time was set at the end of the Time::operator++
virtual bool timeSet();
//- Called at the end of Time::adjustDeltaT() if adjustTime is true
virtual bool adjustTimeStep();
//- Read and set the function object if its data have changed
virtual bool read(const dictionary&);
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh& mpm);
//- Update for changes of mesh
virtual void movePoints(const polyMesh& mesh);
// Other
//- Write geometry for the group/patch
static void writeGeometry
(
const fvMesh& mesh,
const fileName& commsDir,
const wordRe& groupName
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "externalCoupledFunctionObjectTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,459 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify i
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "externalCoupledFunctionObject.H"
#include "OSspecific.H"
#include "IFstream.H"
#include "OFstream.H"
#include "volFields.H"
#include "externalCoupledMixedFvPatchFields.H"
#include "mixedFvPatchFields.H"
#include "fixedGradientFvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "OStringStream.H"
#include "globalIndex.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
bool Foam::externalCoupledFunctionObject::readData
(
const fvMesh& mesh,
const wordRe& groupName,
const labelList& patchIDs,
const word& fieldName
)
{
typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
typedef externalCoupledMixedFvPatchField<Type> patchFieldType;
if (!mesh.foundObject<volFieldType>(fieldName))
{
return false;
}
const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
const typename volFieldType::GeometricBoundaryField& bf =
cvf.boundaryField();
// File only opened on master; contains data for all processors, for all
// patchIDs.
autoPtr<IFstream> masterFilePtr;
if (Pstream::master())
{
const fileName transferFile
(
groupDir(commsDir_, mesh.dbDir(), groupName)
/ fieldName + ".in"
);
if (log_)
{
Info<< type() << ": reading data from " << transferFile << endl;
}
masterFilePtr.reset(new IFstream(transferFile));
if (!masterFilePtr().good())
{
FatalIOErrorIn
(
"void externalCoupledFunctionObject::readData"
"("
"const fvMesh&, "
"const wordRe&, "
"const labelList&, "
"const word&"
")",
masterFilePtr()
) << "Cannot open file for region " << mesh.name()
<< ", field " << fieldName << ", patches " << patchIDs
<< exit(FatalIOError);
}
}
// Handle column-wise reading of patch data. Supports most easy types
forAll(patchIDs, i)
{
label patchI = patchIDs[i];
if (isA<patchFieldType>(bf[patchI]))
{
// Explicit handling of externalCoupledObjectMixed bcs - they have
// specialised reading routines.
patchFieldType& pf = const_cast<patchFieldType&>
(
refCast<const patchFieldType>
(
bf[patchI]
)
);
// Read from master into local stream
OStringStream os;
readLines
(
bf[patchI].size(), // number of lines to read
masterFilePtr,
os
);
// Pass responsability for all reading over to bc
pf.readData(IStringStream(os.str())());
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.patchFieldType::evaluate();
}
else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
{
// Read columns from file for
// value, snGrad, refValue, refGrad, valueFraction
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
4*pTraits<Type>::nComponents+1, // nColumns: 4*Type + 1*scalar
masterFilePtr,
data
);
mixedFvPatchField<Type>& pf = const_cast<mixedFvPatchField<Type>&>
(
refCast<const mixedFvPatchField<Type> >
(
bf[patchI]
)
);
// Transfer read data to bc.
// Skip value, snGrad
direction columnI = 2*pTraits<Type>::nComponents;
Field<Type>& refValue = pf.refValue();
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
refValue.replace(cmpt, data[columnI++]);
}
Field<Type>& refGrad = pf.refGrad();
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
refGrad.replace(cmpt, data[columnI++]);
}
pf.valueFraction() = data[columnI];
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.mixedFvPatchField<Type>::evaluate();
}
else if (isA<fixedGradientFvPatchField<Type> >(bf[patchI]))
{
// Read columns for value and gradient
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
2*pTraits<Type>::nComponents, // nColumns: Type
masterFilePtr,
data
);
fixedGradientFvPatchField<Type>& pf =
const_cast<fixedGradientFvPatchField<Type>&>
(
refCast<const fixedGradientFvPatchField<Type> >
(
bf[patchI]
)
);
// Transfer gradient to bc
Field<Type>& gradient = pf.gradient();
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
gradient.replace(cmpt, data[pTraits<Type>::nComponents+cmpt]);
}
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.fixedGradientFvPatchField<Type>::evaluate();
}
else if (isA<fixedValueFvPatchField<Type> >(bf[patchI]))
{
// Read columns for value only
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
pTraits<Type>::nComponents, // number of columns to read
masterFilePtr,
data
);
// Transfer read value to bc
Field<Type> value(bf[patchI].size());
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
value.replace(cmpt, data[cmpt]);
}
fixedValueFvPatchField<Type>& pf =
const_cast<fixedValueFvPatchField<Type>&>
(
refCast<const fixedValueFvPatchField<Type> >
(
bf[patchI]
)
);
pf == value;
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.fixedValueFvPatchField<Type>::evaluate();
}
else
{
FatalErrorIn
(
"void externalCoupledFunctionObject::readData"
"("
"const fvMesh&, "
"const wordRe&, "
"const labelList&, "
"const word&"
")"
)
<< "Unsupported boundary condition " << bf[patchI].type()
<< " for patch " << bf[patchI].patch().name()
<< " in region " << mesh.name()
<< exit(FatalError);
}
initialised_ = true;
}
return true;
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::externalCoupledFunctionObject::gatherAndCombine
(
const Field<Type>& fld
)
{
// Collect values from all processors
List<Field<Type> > gatheredValues(Pstream::nProcs());
gatheredValues[Pstream::myProcNo()] = fld;
Pstream::gatherList(gatheredValues);
tmp<Field<Type> > tresult(new Field<Type>(0));
Field<Type>& result = tresult();
if (Pstream::master())
{
// Combine values into single field
label globalElemI = 0;
forAll(gatheredValues, lstI)
{
globalElemI += gatheredValues[lstI].size();
}
result.setSize(globalElemI);
globalElemI = 0;
forAll(gatheredValues, lstI)
{
const Field<Type>& sub = gatheredValues[lstI];
forAll(sub, elemI)
{
result[globalElemI++] = sub[elemI];
}
}
}
return tresult;
}
template<class Type>
bool Foam::externalCoupledFunctionObject::writeData
(
const fvMesh& mesh,
const wordRe& groupName,
const labelList& patchIDs,
const word& fieldName
) const
{
typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
typedef externalCoupledMixedFvPatchField<Type> patchFieldType;
if (!mesh.foundObject<volFieldType>(fieldName))
{
return false;
}
const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
const typename volFieldType::GeometricBoundaryField& bf =
cvf.boundaryField();
// File only opened on master; contains data for all processors, for all
// patchIDs
autoPtr<OFstream> masterFilePtr;
if (Pstream::master())
{
const fileName transferFile
(
groupDir(commsDir_, mesh.dbDir(), groupName)
/ fieldName + ".out"
);
if (log_)
{
Info<< type() << ": writing data to " << transferFile << endl;
}
masterFilePtr.reset(new OFstream(transferFile));
if (!masterFilePtr().good())
{
FatalIOErrorIn
(
"externalCoupledFunctionObject::writeData"
"("
"const fvMesh&, "
"const wordRe&, "
"const labelList&, "
"const word&"
") const",
masterFilePtr()
) << "Cannot open file for region " << mesh.name()
<< ", field " << fieldName << ", patches " << patchIDs
<< exit(FatalIOError);
}
}
bool headerDone = false;
// Handle column-wise writing of patch data. Supports most easy types
forAll(patchIDs, i)
{
label patchI = patchIDs[i];
const globalIndex globalFaces(bf[patchI].size());
if (isA<patchFieldType>(bf[patchI]))
{
// Explicit handling of externalCoupledObjectMixed bcs - they have
// specialised writing routines
const patchFieldType& pf = refCast<const patchFieldType>
(
bf[patchI]
);
OStringStream os;
// Pass responsibility for all writing over to bc
pf.writeData(os);
// Collect contributions from all processors and output them on
// master
if (Pstream::master())
{
// Output master data first
if (!headerDone)
{
pf.writeHeader(masterFilePtr());
headerDone = true;
}
masterFilePtr() << os.str().c_str();
for (label procI = 1; procI < Pstream::nProcs(); procI++)
{
IPstream fromSlave(Pstream::scheduled, procI);
string str(fromSlave);
masterFilePtr() << str.c_str();
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster << os.str();
}
}
else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
{
const mixedFvPatchField<Type>& pf =
refCast<const mixedFvPatchField<Type> >(bf[patchI]);
Field<Type> value(gatherAndCombine(pf));
Field<Type> snGrad(gatherAndCombine(pf.snGrad()()));
Field<Type> refValue(gatherAndCombine(pf.refValue()));
Field<Type> refGrad(gatherAndCombine(pf.refGrad()));
scalarField valueFraction(gatherAndCombine(pf.valueFraction()));
if (Pstream::master())
{
forAll(refValue, faceI)
{
masterFilePtr()
<< value[faceI] << token::SPACE
<< snGrad[faceI] << token::SPACE
<< refValue[faceI] << token::SPACE
<< refGrad[faceI] << token::SPACE
<< valueFraction[faceI] << nl;
}
}
}
else
{
// Output the value and snGrad
Field<Type> value(gatherAndCombine(bf[patchI]));
Field<Type> snGrad(gatherAndCombine(bf[patchI].snGrad()()));
if (Pstream::master())
{
forAll(value, faceI)
{
masterFilePtr()
<< value[faceI] << token::SPACE
<< snGrad[faceI] << nl;
}
}
}
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,168 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "externalCoupledMixedFvPatchField.H"
#include "fvPatchFieldMapper.H"
#include "ISstream.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::externalCoupledMixedFvPatchField<Type>::
externalCoupledMixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(p, iF)
{
this->refValue() = pTraits<Type>::zero;
this->refGrad() = pTraits<Type>::zero;
this->valueFraction() = 0.0;
}
template<class Type>
Foam::externalCoupledMixedFvPatchField<Type>::
externalCoupledMixedFvPatchField
(
const externalCoupledMixedFvPatchField& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchField<Type>(ptf, p, iF, mapper)
{}
template<class Type>
Foam::externalCoupledMixedFvPatchField<Type>::
externalCoupledMixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchField<Type>(p, iF, dict)
{}
template<class Type>
Foam::externalCoupledMixedFvPatchField<Type>::
externalCoupledMixedFvPatchField
(
const externalCoupledMixedFvPatchField& ecmpf
)
:
mixedFvPatchField<Type>(ecmpf)
{}
template<class Type>
Foam::externalCoupledMixedFvPatchField<Type>::
externalCoupledMixedFvPatchField
(
const externalCoupledMixedFvPatchField& ecmpf,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(ecmpf, iF)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Type>
Foam::externalCoupledMixedFvPatchField<Type>::
~externalCoupledMixedFvPatchField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::externalCoupledMixedFvPatchField<Type>::writeHeader
(
Ostream& os
) const
{
os << "# Values: value snGrad refValue refGrad valueFraction" << endl;
}
template<class Type>
void Foam::externalCoupledMixedFvPatchField<Type>::writeData
(
Ostream& os
) const
{
const Field<Type> snGrad(this->snGrad());
const Field<Type>& refValue(this->refValue());
const Field<Type>& refGrad(this->refGrad());
const scalarField& valueFraction(this->valueFraction());
forAll(refValue, faceI)
{
os << this->operator[](faceI) << token::SPACE
<< snGrad[faceI] << token::SPACE
<< refValue[faceI] << token::SPACE
<< refGrad[faceI] << token::SPACE
<< valueFraction[faceI] << nl;
}
}
template<class Type>
void Foam::externalCoupledMixedFvPatchField<Type>::readData(Istream& is)
{
// Assume generic input stream so we can do line-based format and skip
// unused columns
ISstream& iss = dynamic_cast<ISstream&>(is);
string line;
forAll(*this, faceI)
{
iss.getLine(line);
IStringStream lineStr(line);
// For symmetry with writing ignore value, snGrad columns
Type value, snGrad;
lineStr
>> value
>> snGrad
>> this->refValue()[faceI]
>> this->refGrad()[faceI]
>> this->valueFraction()[faceI];
}
}
// ************************************************************************* //

View File

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::externalCoupledMixedFvPatchField
Group
grpGenericBoundaryConditions grpCoupledBoundaryConditions
Description
This boundary condition extends the mixed boundary condition with
serialisation through
- writeHeader
- writeData
- readData
functions. It is used for coupling to external applications in combination
with the externalCoupled functionObject. The default output is one
line per face, with columns
<value> <snGrad> <refValue> <refGrad> <valueFraction>
Notes
readData,writeData are not callbacks for regIOobject (since fvPatchField
not derived from it). They do however do exactly the same - streaming of
data.
SeeAlso
mixedFvPatchField
externalCoupledFunctionObject
SourceFiles
externalCoupledMixedFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef externalCoupledMixedFvPatchField_H
#define externalCoupledMixedFvPatchField_H
#include "mixedFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class externalCoupledMixedFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class externalCoupledMixedFvPatchField
:
public mixedFvPatchField<Type>
{
public:
//- Runtime type information
TypeName("externalCoupled");
// Constructors
//- Construct from patch and internal field
externalCoupledMixedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
externalCoupledMixedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given externalCoupledMixedFvPatchField
// onto a new patch
externalCoupledMixedFvPatchField
(
const externalCoupledMixedFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
externalCoupledMixedFvPatchField
(
const externalCoupledMixedFvPatchField&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type> > clone() const
{
return tmp<fvPatchField<Type> >
(
new externalCoupledMixedFvPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
externalCoupledMixedFvPatchField
(
const externalCoupledMixedFvPatchField&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type> > clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type> >
(
new externalCoupledMixedFvPatchField<Type>(*this, iF)
);
}
//- Destructor
virtual ~externalCoupledMixedFvPatchField();
// Member functions
//- Write header
virtual void writeHeader(Ostream&) const;
//- Write data
virtual void writeData(Ostream&) const;
//- Read data
virtual void readData(Istream&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "externalCoupledMixedFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

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

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

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

View File

@ -28,16 +28,15 @@ License
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "OFstream.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::externalCoupledTemperatureMixedFvPatchScalarField::writeHeader
(
OFstream& os
Ostream& os
) const
{
os << "# Values: magSf value qDot htc" << endl;
os << "# Values: magSf T qDot htc" << endl;
}
@ -75,8 +74,40 @@ externalCoupledTemperatureMixedFvPatchScalarField
const dictionary& dict
)
:
externalCoupledMixedFvPatchField<scalar>(p, iF, dict)
{}
//externalCoupledMixedFvPatchField<scalar>(p, iF, dict)
externalCoupledMixedFvPatchField<scalar>(p, iF)
{
if (dict.found("refValue"))
{
// Initialise same way as mixed
this->refValue() = scalarField("refValue", dict, p.size());
this->refGrad() = scalarField("refGradient", dict, p.size());
this->valueFraction() = scalarField("valueFraction", dict, p.size());
evaluate();
}
else
{
// For convenience: initialise as fixedValue with either read value
// or extrapolated value
if (dict.found("value"))
{
fvPatchField<scalar>::operator=
(
scalarField("value", dict, p.size())
);
}
else
{
fvPatchField<scalar>::operator=(this->patchInternalField());
}
// Initialise as a fixed value
this->refValue() = *this;
this->refGrad() = pTraits<scalar>::zero;
this->valueFraction() = 1.0;
}
}
Foam::externalCoupledTemperatureMixedFvPatchScalarField::
@ -109,21 +140,14 @@ Foam::externalCoupledTemperatureMixedFvPatchScalarField::
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData
void Foam::externalCoupledTemperatureMixedFvPatchScalarField::writeData
(
OFstream& os
Ostream& os
) const
{
if (log())
{
Info<< type() << ": " << this->patch().name()
<< ": writing data to " << os.name()
<< endl;
}
const label patchI = patch().index();
// heat flux [W/m2]
// Heat flux [W/m2]
scalarField qDot(this->patch().size(), 0.0);
typedef compressible::turbulenceModel cmpTurbModelType;
@ -137,7 +161,7 @@ void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData
)
);
static word thermoName(basicThermo::dictName);
static word thermoName("thermophysicalProperties");
if (db().foundObject<cmpTurbModelType>(turbName))
{
@ -165,69 +189,21 @@ void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData
"void Foam::externalCoupledTemperatureMixedFvPatchScalarField::"
"transferData"
"("
"OFstream&"
"Ostream&"
") const"
) << "Condition requires either compressible turbulence and/or "
<< "thermo model to be available" << exit(FatalError);
}
// patch temperature [K]
const scalarField Tp(*this);
// Patch temperature [K]
const scalarField& Tp(*this);
// near wall cell temperature [K]
// Near wall cell temperature [K]
const scalarField Tc(patchInternalField());
// heat transfer coefficient [W/m2/K]
// Heat transfer coefficient [W/m2/K]
const scalarField htc(qDot/(Tp - Tc + ROOTVSMALL));
if (Pstream::parRun())
{
int tag = Pstream::msgType() + 1;
List<Field<scalar> > magSfs(Pstream::nProcs());
magSfs[Pstream::myProcNo()].setSize(this->patch().size());
magSfs[Pstream::myProcNo()] = this->patch().magSf();
Pstream::gatherList(magSfs, tag);
List<Field<scalar> > values(Pstream::nProcs());
values[Pstream::myProcNo()].setSize(this->patch().size());
values[Pstream::myProcNo()] = Tp;
Pstream::gatherList(values, tag);
List<Field<scalar> > qDots(Pstream::nProcs());
qDots[Pstream::myProcNo()].setSize(this->patch().size());
qDots[Pstream::myProcNo()] = qDot;
Pstream::gatherList(qDots, tag);
List<Field<scalar> > htcs(Pstream::nProcs());
htcs[Pstream::myProcNo()].setSize(this->patch().size());
htcs[Pstream::myProcNo()] = htc;
Pstream::gatherList(htcs, tag);
if (Pstream::master())
{
forAll(values, procI)
{
const Field<scalar>& magSf = magSfs[procI];
const Field<scalar>& value = values[procI];
const Field<scalar>& qDot = qDots[procI];
const Field<scalar>& htc = htcs[procI];
forAll(magSf, faceI)
{
os << magSf[faceI] << token::SPACE
<< value[faceI] << token::SPACE
<< qDot[faceI] << token::SPACE
<< htc[faceI] << token::SPACE
<< nl;
}
}
os.flush();
}
}
else
{
const Field<scalar>& magSf(this->patch().magSf());
forAll(patch(), faceI)
@ -238,27 +214,30 @@ void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData
<< htc[faceI] << token::SPACE
<< nl;
}
os.flush();
}
}
void Foam::externalCoupledTemperatureMixedFvPatchScalarField::evaluate
void Foam::externalCoupledTemperatureMixedFvPatchScalarField::readData
(
const Pstream::commsTypes comms
Istream& is
)
{
externalCoupledMixedFvPatchField<scalar>::evaluate(comms);
}
// Assume generic input stream so we can do line-based format and skip
// unused columns
ISstream& iss = dynamic_cast<ISstream&>(is);
string line;
void Foam::externalCoupledTemperatureMixedFvPatchScalarField::write
(
Ostream& os
) const
forAll(*this, faceI)
{
externalCoupledMixedFvPatchField<scalar>::write(os);
iss.getLine(line);
IStringStream lineStr(line);
lineStr
>> this->refValue()[faceI]
>> this->refGrad()[faceI]
>> this->valueFraction()[faceI];
}
}

View File

@ -42,59 +42,16 @@ Description
and received as the constituent pieces of the `mixed' condition, i.e.
# Patch: <patch name>
<value1> <gradient1> <valueFracion1>
<value2> <gradient2> <valueFracion2>
<value3> <gradient3> <valueFracion3>
<refValue1> <refGrad1> <valueFraction1>
<refValue2> <refGrad2> <valueFraction2>
<refValue3> <refGrad3> <valueFraction3>
...
<valueN> <gradientN> <valueFracionN>
<refValueN> <refGradN> <valueFractionN>
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
log | log program control | no | no
\endtable
Example of the boundary condition specification:
\verbatim
myPatch
{
type externalCoupledTemperature;
commsDir "$FOAM_CASE/comms";
fileName data;
calcFrequency 1;
}
\endverbatim
To be used in combination with the externalCoupled functionObject.
SeeAlso
externalCoupledFunctionObject
mixedFvPatchField
externalCoupledMixedFvPatchField
@ -113,8 +70,6 @@ SourceFiles
namespace Foam
{
class IFstream;
/*---------------------------------------------------------------------------*\
Class externalCoupledTemperatureMixedFvPatchScalarField Declaration
\*---------------------------------------------------------------------------*/
@ -124,14 +79,6 @@ class externalCoupledTemperatureMixedFvPatchScalarField
public externalCoupledMixedFvPatchField<scalar>
{
protected:
// Protected Member Functions
//- Write header to transfer file
virtual void writeHeader(OFstream& os) const;
public:
//- Runtime type information
@ -210,20 +157,14 @@ public:
// Member functions
// Evaluation functions
//- Write header
virtual void writeHeader(Ostream&) const;
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
);
//- Write data
virtual void writeData(Ostream&) const;
//- Transfer data for external source
virtual void transferData(OFstream& os) const;
//- Write
virtual void write(Ostream&) const;
//- Read data
virtual void readData(Istream&);
};

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::IOrunTimeControl
Description
Instance of the generic IOOutputFilter for runTimeControl.
\*---------------------------------------------------------------------------*/
#ifndef IOrunTimeControl_H
#define IOrunTimeControl_H
#include "runTimeControl.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<runTimeControl> IOrunTimeControl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "averageCondition.H"
#include "addToRunTimeSelectionTable.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(averageCondition, 0);
addToRunTimeSelectionTable(runTimeCondition, averageCondition, dictionary);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::averageCondition::averageCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
)
:
runTimeCondition(name, obr, dict, state),
functionObjectName_(dict.lookup("functionObjectName")),
fieldNames_(dict.lookup("fields")),
tolerance_(readScalar(dict.lookup("tolerance"))),
window_(dict.lookupOrDefault<scalar>("window", -1)),
totalTime_(fieldNames_.size(), obr_.time().deltaTValue()),
resetOnRestart_(false)
{
if (resetOnRestart_)
{
const dictionary& dict = conditionDict();
forAll(fieldNames_, fieldI)
{
const word& fieldName = fieldNames_[fieldI];
if (dict.found(fieldName))
{
const dictionary& valueDict = dict.subDict(fieldName);
totalTime_[fieldI] = readScalar(valueDict.lookup("totalTime"));
}
}
}
}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
Foam::averageCondition::~averageCondition()
{}
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
bool Foam::averageCondition::apply()
{
bool satisfied = true;
if (!active_)
{
return satisfied;
}
scalar dt = obr_.time().deltaTValue();
if (log_) Info<< " " << type() << ": " << name_ << " averages:" << nl;
DynamicList<label> unprocessedFields(fieldNames_.size());
forAll(fieldNames_, fieldI)
{
const word& fieldName(fieldNames_[fieldI]);
scalar Dt = totalTime_[fieldI];
scalar alpha = (Dt - dt)/Dt;
scalar beta = dt/Dt;
if (window_ > 0)
{
if (Dt - dt >= window_)
{
alpha = (window_ - dt)/window_;
beta = dt/window_;
}
else
{
// Ensure that averaging is performed over window time
// before condition can be satisfied
satisfied = false;
}
}
bool processed = false;
calc<scalar>(fieldName, alpha, beta, satisfied, processed);
calc<vector>(fieldName, alpha, beta, satisfied, processed);
calc<sphericalTensor>(fieldName, alpha, beta, satisfied, processed);
calc<symmTensor>(fieldName, alpha, beta, satisfied, processed);
calc<tensor>(fieldName, alpha, beta, satisfied, processed);
if (!processed)
{
unprocessedFields.append(fieldI);
}
totalTime_[fieldI] += dt;
}
if (unprocessedFields.size())
{
WarningIn("bool Foam::averageCondition::apply()")
<< "From function object: " << functionObjectName_ << nl
<< "Unprocessed fields:" << nl;
forAll(unprocessedFields, i)
{
label fieldI = unprocessedFields[i];
Info<< " " << fieldNames_[fieldI] << nl;
}
}
if (log_) Info<< endl;
return satisfied;
}
void Foam::averageCondition::write()
{
dictionary& conditionDict = this->conditionDict();
forAll(fieldNames_, fieldI)
{
const word& fieldName = fieldNames_[fieldI];
// value dictionary should be present - mean values are written there
if (conditionDict.found(fieldName))
{
dictionary& valueDict = conditionDict.subDict(fieldName);
valueDict.add("totalTime", totalTime_[fieldI], true);
}
else
{
dictionary valueDict;
valueDict.add("totalTime", totalTime_[fieldI], true);
conditionDict.add(fieldName, valueDict);
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,136 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::averageCondition
Description
Average run time condition - satisfied when average does not change by
more than a given value.
SourceFiles
averageCondition.H
averageCondition.C
\*---------------------------------------------------------------------------*/
#ifndef averageCondition_H
#define averageCondition_H
#include "runTimeCondition.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class averageCondition Declaration
\*---------------------------------------------------------------------------*/
class averageCondition
:
public runTimeCondition
{
protected:
// Protected data
//- Name of function object to retrueve data from
word functionObjectName_;
//- List of fields on which to operate
wordList fieldNames_;
//- Satisfied when difference in mean values is less than this value
const scalar tolerance_;
//- Averaging window
const scalar window_;
//- Average time per field
List<scalar> totalTime_;
//- Reset the averaging process on restart flag
Switch resetOnRestart_;
// Protected Member Functions
//- Templated function to calculate the average
template<class Type>
void calc
(
const word& fieldName,
const scalar alpha,
const scalar beta,
bool& satisfied,
bool& processed
);
public:
//- Runtime type information
TypeName("average");
//- Constructor
averageCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
);
//- Destructor
virtual ~averageCondition();
// Public Member Functions
//- Apply the condition
virtual bool apply();
//- Write
virtual void write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "averageConditionTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
template<class Type>
void Foam::averageCondition::calc
(
const word& fieldName,
const scalar alpha,
const scalar beta,
bool& satisfied,
bool& processed
)
{
const word valueType =
state_.objectResultType(functionObjectName_, fieldName);
if (pTraits<Type>::typeName != valueType)
{
return;
}
Type currentValue =
state_.getObjectResult<Type>(functionObjectName_, fieldName);
const word meanName(fieldName + "Mean");
Type meanValue = state_.getResult<Type>(meanName);
meanValue = alpha*meanValue + beta*currentValue;
scalar delta = mag(meanValue - currentValue);
if (log_)
{
Info<< " " << meanName << ": " << meanValue
<< ", delta: " << delta << nl;
}
state_.setResult(meanName, meanValue);
if (delta > tolerance_)
{
satisfied = false;
}
processed = true;
}
// ************************************************************************* //

View File

@ -0,0 +1,222 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "equationInitialResidualCondition.H"
#include "addToRunTimeSelectionTable.H"
#include "fvMesh.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(equationInitialResidualCondition, 0);
addToRunTimeSelectionTable
(
runTimeCondition,
equationInitialResidualCondition,
dictionary
);
template<>
const char* Foam::NamedEnum
<
equationInitialResidualCondition::operatingMode,
2
>::names[] =
{
"minimum",
"maximum"
};
const NamedEnum<Foam::equationInitialResidualCondition::operatingMode, 2>
Foam::equationInitialResidualCondition::operatingModeNames;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::equationInitialResidualCondition::equationInitialResidualCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
)
:
runTimeCondition(name, obr, dict, state),
fieldNames_(dict.lookup("fields")),
value_(readScalar(dict.lookup("value"))),
timeStart_(dict.lookupOrDefault("timeStart", -GREAT)),
mode_(operatingModeNames.read(dict.lookup("mode")))
{
if (!fieldNames_.size())
{
WarningIn
(
"Foam::equationInitialResidualCondition::"
"equationInitialResidualCondition"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"functionObjectState&"
")"
)
<< "No fields supplied: deactivating" << endl;
active_ = false;
}
}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
Foam::equationInitialResidualCondition::
~equationInitialResidualCondition()
{}
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
bool Foam::equationInitialResidualCondition::apply()
{
bool satisfied = false;
if (!active_)
{
return true;
}
if ((obr_.time().timeIndex() < 3) || (obr_.time().value() < timeStart_))
{
// Do not start checking until reached start time
return false;
}
const fvMesh& mesh = refCast<const fvMesh>(obr_);
const dictionary& solverDict = mesh.solverPerformanceDict();
List<scalar> result(fieldNames_.size(), -VGREAT);
forAll(fieldNames_, fieldI)
{
const word& fieldName = fieldNames_[fieldI];
if (solverDict.found(fieldName))
{
const List<solverPerformance> sp(solverDict.lookup(fieldName));
const scalar residual = sp.first().initialResidual();
result[fieldI] = residual;
switch (mode_)
{
case omMin:
{
if (residual < value_)
{
satisfied = true;
}
break;
}
case omMax:
{
if (residual > value_)
{
satisfied = true;
}
break;
}
default:
{
FatalErrorIn
(
"bool Foam::equationInitialResidualCondition::apply()"
)
<< "Unhandled enumeration "
<< operatingModeNames[mode_]
<< abort(FatalError);
}
}
}
}
bool valid = false;
forAll(result, i)
{
if (result[i] < 0)
{
WarningIn("bool Foam::equationInitialResidualCondition::apply()")
<< "Initial residual data not found for field "
<< fieldNames_[i] << endl;
}
else
{
valid = true;
}
}
if (!valid)
{
WarningIn("bool Foam::equationInitialResidualCondition::apply()")
<< "Initial residual data not found for any fields: "
<< "deactivating" << endl;
active_ = false;
}
if (satisfied && valid)
{
if (log_)
{
Info<< type() << ": " << name_
<< ": satisfied using threshold value: " << value_ << nl;
}
forAll(result, resultI)
{
if (result[resultI] > 0)
{
if (log_)
{
Info<< " field: " << fieldNames_[resultI]
<< ", residual: " << result[resultI] << nl;
}
}
}
if (log_) Info<< endl;
}
return satisfied;
}
void Foam::equationInitialResidualCondition::write()
{
// do nothing
}
// ************************************************************************* //

View File

@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::equationInitialResidualCondition
Description
Minimum or maximum initial residual run time condition
SourceFiles
equationInitialResidualCondition.H
equationInitialResidualCondition.C
\*---------------------------------------------------------------------------*/
#ifndef equationInitialResidualCondition_H
#define equationInitialResidualCondition_H
#include "runTimeCondition.H"
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class equationInitialResidualCondition Declaration
\*---------------------------------------------------------------------------*/
class equationInitialResidualCondition
:
public runTimeCondition
{
public:
enum operatingMode
{
omMin,
omMax
};
static const NamedEnum<operatingMode, 2> operatingModeNames;
protected:
// Protected data
//- Field name
const wordList fieldNames_;
//- Value to compare
const scalar value_;
//- Start checking from time - always skips first iteration
scalar timeStart_;
//- Operating mode
operatingMode mode_;
public:
//- Runtime type information
TypeName("equationInitialResidual");
//- Constructor
equationInitialResidualCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
);
//- Destructor
virtual ~equationInitialResidualCondition();
// Public Member Functions
//- Apply the condition
virtual bool apply();
//- Write
virtual void write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,183 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "equationMaxIterCondition.H"
#include "addToRunTimeSelectionTable.H"
#include "fvMesh.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(equationMaxIterCondition, 0);
addToRunTimeSelectionTable
(
runTimeCondition,
equationMaxIterCondition,
dictionary
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::equationMaxIterCondition::equationMaxIterCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
)
:
runTimeCondition(name, obr, dict, state),
fieldNames_(dict.lookup("fields")),
threshold_(readLabel(dict.lookup("threshold"))),
startIter_(dict.lookupOrDefault("startIter", 2))
{
if (!fieldNames_.size())
{
WarningIn
(
"Foam::equationMaxIterCondition::"
"equationMaxIterCondition"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"functionObjectState&"
")"
)
<< "No fields supplied: deactivating" << endl;
active_ = false;
}
startIter_ = max(startIter_, 2);
}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
Foam::equationMaxIterCondition::~equationMaxIterCondition()
{}
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
bool Foam::equationMaxIterCondition::apply()
{
bool satisfied = false;
if (!active_)
{
return true;
}
if (obr_.time().timeIndex() < startIter_)
{
// Do not start checking until start iter
return false;
}
const fvMesh& mesh = refCast<const fvMesh>(obr_);
const dictionary& solverDict = mesh.solverPerformanceDict();
List<label> result(fieldNames_.size(), -1);
forAll(fieldNames_, fieldI)
{
const word& fieldName = fieldNames_[fieldI];
if (solverDict.found(fieldName))
{
const List<solverPerformance> sp(solverDict.lookup(fieldName));
const label nIterations = sp.first().nIterations();
result[fieldI] = nIterations;
if (nIterations > threshold_)
{
satisfied = true;
}
}
}
bool valid = false;
forAll(result, i)
{
if (result[i] < 0)
{
WarningIn("bool Foam::equationMaxIterCondition::apply()")
<< "Number of iterations data not found for field "
<< fieldNames_[i] << endl;
}
else
{
valid = true;
}
}
if (!valid)
{
WarningIn("bool Foam::equationMaxIterCondition::apply()")
<< "Number of iterations data not found for any fields: "
<< "deactivating" << endl;
active_ = false;
}
if (satisfied && valid)
{
if (log_)
{
Info<< type() << ": " << name_
<< ": satisfied using threshold value: " << threshold_ << nl;
}
forAll(result, resultI)
{
if (result[resultI] != -1)
{
if (log_)
{
Info<< " field: " << fieldNames_[resultI]
<< ", iterations: " << result[resultI] << nl;
}
}
}
if (log_) Info<< endl;
}
return satisfied;
}
void Foam::equationMaxIterCondition::write()
{
// do nothing
}
// ************************************************************************* //

View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::equationMaxIterCondition
Description
Maximum number of equation iterations run time condition
SourceFiles
equationMaxIterCondition.H
equationMaxIterCondition.C
\*---------------------------------------------------------------------------*/
#ifndef equationMaxIterCondition_H
#define equationMaxIterCondition_H
#include "runTimeCondition.H"
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class equationMaxIterCondition Declaration
\*---------------------------------------------------------------------------*/
class equationMaxIterCondition
:
public runTimeCondition
{
protected:
// Protected data
//- Field name
const wordList fieldNames_;
//- Threshold for maximum number of iterations
const label threshold_;
//- Start checking from iteration - always skips first iteration
label startIter_;
public:
//- Runtime type information
TypeName("equationMaxIter");
//- Constructor
equationMaxIterCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
);
//- Destructor
virtual ~equationMaxIterCondition();
// Public Member Functions
//- Apply the condition
virtual bool apply();
//- Write
virtual void write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "minMaxCondition.H"
#include "addToRunTimeSelectionTable.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
template<>
void Foam::minMaxCondition::setValue<Foam::scalar>
(
const word& valueType,
const word& fieldName,
scalar& value
) const
{
state_.getObjectResult(functionObjectName_, fieldName, value);
}
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(minMaxCondition, 0);
addToRunTimeSelectionTable(runTimeCondition, minMaxCondition, dictionary);
template<>
const char* NamedEnum<minMaxCondition::modeType, 2>::names[] =
{
"minimum",
"maximum"
};
}
const Foam::NamedEnum<Foam::minMaxCondition::modeType, 2>
Foam::minMaxCondition::modeTypeNames_;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::minMaxCondition::minMaxCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
)
:
runTimeCondition(name, obr, dict, state),
functionObjectName_(dict.lookup("functionObjectName")),
mode_(modeTypeNames_.read(dict.lookup("mode"))),
fieldNames_(dict.lookup("fields")),
value_(readScalar(dict.lookup("value")))
{}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
Foam::minMaxCondition::~minMaxCondition()
{}
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
bool Foam::minMaxCondition::apply()
{
bool satisfied = true;
if (!active_)
{
return satisfied;
}
forAll(fieldNames_, fieldI)
{
const word& fieldName = fieldNames_[fieldI];
const word valueType =
state_.objectResultType(functionObjectName_, fieldName);
if (valueType == word::null)
{
WarningIn("bool Foam::minMaxCondition::apply()")
<< "Unable to find entry " << fieldName
<< " for function object " << functionObjectName_
<< ". Condition will not be applied."
<< endl;
continue;
}
scalar v = 0;
setValue<scalar>(valueType, fieldName, v);
setValue<vector>(valueType, fieldName, v);
setValue<sphericalTensor>(valueType, fieldName, v);
setValue<symmTensor>(valueType, fieldName, v);
setValue<tensor>(valueType, fieldName, v);
Switch ok = false;
switch (mode_)
{
case mdMin:
{
if (v < value_)
{
ok = true;
}
break;
}
case mdMax:
{
if (v > value_)
{
ok = true;
}
break;
}
}
if (log_)
{
Info<< " " << type() << ": " << modeTypeNames_[mode_] << " "
<< fieldName << ": value = " << v
<< ", threshold value = " << value_
<< ", satisfied = " << ok << endl;
}
satisfied = satisfied && ok;
}
return satisfied;
}
void Foam::minMaxCondition::write()
{
// do nothing
}
// ************************************************************************* //

View File

@ -0,0 +1,145 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::minMaxCondition
Description
Minimum/maximum run time conditions. If the value type is not scalar,
the magnitude of the value is used in the evaluation.
SourceFiles
minMaxCondition.H
minMaxCondition.C
\*---------------------------------------------------------------------------*/
#ifndef minMaxCondition_H
#define minMaxCondition_H
#include "runTimeCondition.H"
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class minMaxCondition Declaration
\*---------------------------------------------------------------------------*/
class minMaxCondition
:
public runTimeCondition
{
public:
// Public enumerations
// Mode type
enum modeType
{
mdMin,
mdMax
};
static const NamedEnum<modeType, 2> modeTypeNames_;
protected:
// Protected data
//- Name of function object to retrueve data from
word functionObjectName_;
//- Mode
modeType mode_;
//- Field names
const wordList fieldNames_;
//- Value to compare
const scalar value_;
//- Helper function to retrieve the value from the state dictionary
template<class Type>
void setValue
(
const word& valueType,
const word& fieldName,
scalar& value
) const;
public:
//- Runtime type information
TypeName("minMax");
//- Constructor
minMaxCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
);
//- Destructor
virtual ~minMaxCondition();
// Public Member Functions
//- Apply the condition
virtual bool apply();
//- Write
virtual void write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<>
void minMaxCondition::setValue<Foam::scalar>
(
const word& valueType,
const word& fieldName,
scalar& value
) const;
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "minMaxConditionTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
template<class Type>
void Foam::minMaxCondition::setValue
(
const word& valueType,
const word& fieldName,
scalar& value
) const
{
if (pTraits<Type>::typeName != valueType)
{
return;
}
Type v = state_.getObjectResult<Type>(functionObjectName_, fieldName);
value = mag(v);
}
// ************************************************************************* //

View File

@ -0,0 +1,91 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "minTimeStepCondition.H"
#include "addToRunTimeSelectionTable.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(minTimeStepCondition, 0);
addToRunTimeSelectionTable
(
runTimeCondition,
minTimeStepCondition,
dictionary
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::minTimeStepCondition::minTimeStepCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
)
:
runTimeCondition(name, obr, dict, state),
minValue_(readScalar(dict.lookup("minValue")))
{}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
Foam::minTimeStepCondition::~minTimeStepCondition()
{}
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
bool Foam::minTimeStepCondition::apply()
{
bool satisfied = false;
if (!active_)
{
return true;
}
if (obr_.time().deltaTValue() < minValue_)
{
satisfied = true;
}
return satisfied;
}
void Foam::minTimeStepCondition::write()
{
// do nothing
}
// ************************************************************************* //

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::minTimeStepCondition
Description
Initial residual run time condition
SourceFiles
minTimeStepCondition.H
minTimeStepCondition.C
\*---------------------------------------------------------------------------*/
#ifndef minTimeStepCondition_H
#define minTimeStepCondition_H
#include "runTimeCondition.H"
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class minTimeStepCondition Declaration
\*---------------------------------------------------------------------------*/
class minTimeStepCondition
:
public runTimeCondition
{
protected:
// Protected data
//- Minumim time step value to compare
const scalar minValue_;
public:
//- Runtime type information
TypeName("minTimeStep");
//- Constructor
minTimeStepCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
);
//- Destructor
virtual ~minTimeStepCondition();
// Public Member Functions
//- Apply the condition
virtual bool apply();
//- Write
virtual void write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "runTimeCondition.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(runTimeCondition, 0);
defineRunTimeSelectionTable(runTimeCondition, dictionary);
}
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
Foam::dictionary& Foam::runTimeCondition::setConditionDict()
{
dictionary& propertyDict = state_.propertyDict();
if (!propertyDict.found(name_))
{
propertyDict.add(name_, dictionary());
}
return propertyDict.subDict(name_);
}
const Foam::dictionary& Foam::runTimeCondition::conditionDict() const
{
return conditionDict_;
}
Foam::dictionary& Foam::runTimeCondition::conditionDict()
{
return conditionDict_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::runTimeCondition::runTimeCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
)
:
name_(name),
obr_(obr),
state_(state),
active_(dict.lookupOrDefault<bool>("active", true)),
conditionDict_(setConditionDict()),
log_(dict.lookupOrDefault("log", true)),
groupID_(dict.lookupOrDefault("groupID", -1))
{}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
Foam::runTimeCondition::~runTimeCondition()
{}
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
const Foam::word& Foam::runTimeCondition::name() const
{
return name_;
}
bool Foam::runTimeCondition::active() const
{
return active_;
}
Foam::label Foam::runTimeCondition::groupID() const
{
return groupID_;
}
// ************************************************************************* //

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::runTimeCondition
Description
Base class for run time conditions
SourceFiles
runTimeCondition.C
runTimeConditionNew.C
runTimeCondition.H
\*---------------------------------------------------------------------------*/
#ifndef runTimeCondition_H
#define runTimeCondition_H
#include "functionObjectState.H"
#include "dictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class runTimeCondition Declaration
\*---------------------------------------------------------------------------*/
class runTimeCondition
{
protected:
// Protected data
//- Condition name
word name_;
//- Reference to the object registry
const objectRegistry& obr_;
//- State
functionObjectState& state_;
//- On/off switch
bool active_;
//- Reference to the condition dictionary
dictionary& conditionDict_;
//- Switch to send output to Info
Switch log_;
//- Group index - if applied, all conditions in a group must be
// satisfield before condition is met
label groupID_;
// Protected Member Functions
//- Set the condition dictionary (create if necessary)
dictionary& setConditionDict();
//- Return const access to the conditions dictionary
const dictionary& conditionDict() const;
//- Return non-const access to the conditions dictionary
dictionary& conditionDict();
public:
//- Runtime type information
TypeName("runTimeCondition");
//- Declare runtime constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
runTimeCondition,
dictionary,
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
),
(name, obr, dict, state)
);
//- Constructor
runTimeCondition
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
);
//- Destructor
virtual ~runTimeCondition();
//- Selector
static autoPtr<runTimeCondition> New
(
const word& conditionName,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
);
// Public Member Functions
//- Return the condition name
virtual const word& name() const;
//- Return the active flag
virtual bool active() const;
//- Return the group index
virtual label groupID() const;
//- Apply the condition
virtual bool apply() = 0;
//- Write
virtual void write() = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "runTimeCondition.H"
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::runTimeCondition> Foam::runTimeCondition::New
(
const word& conditionName,
const objectRegistry& obr,
const dictionary& dict,
functionObjectState& state
)
{
word conditionType(dict.lookup("type"));
Info<< "Selecting runTimeCondition " << conditionType << endl;
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(conditionType);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"runTimeCondition::New"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"functionObjectState&"
")"
) << "Unknown runTimeCondition type "
<< conditionType << nl << nl
<< "Valid runTimeCondition types are:" << nl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<runTimeCondition>
(
cstrIter()(conditionName, obr, dict, state)
);
}
// ************************************************************************* //

View File

@ -0,0 +1,264 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "runTimeControl.H"
#include "dictionary.H"
#include "runTimeCondition.H"
#include "fvMesh.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(runTimeControl, 0);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::runTimeControl::runTimeControl
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
functionObjectState(obr, name),
obr_(obr),
conditions_(),
groupMap_(),
nWriteStep_(0),
writeStepI_(0)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (setActive<fvMesh>())
{
read(dict);
// Check that some conditions are set
if (conditions_.empty())
{
Info<< type() << " " << name_ << " output:" << nl
<< " No conditions present - deactivating" << nl
<< endl;
active_ = false;
}
else
{
// Check that at least one condition is active
active_ = false;
forAll(conditions_, conditionI)
{
if (conditions_[conditionI].active())
{
active_ = true;
break;
}
}
if (!active_)
{
Info<< type() << " " << name_ << " output:" << nl
<< " All conditions inactive - deactivating" << nl
<< endl;
}
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::runTimeControl::~runTimeControl()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::runTimeControl::read(const dictionary& dict)
{
if (active_)
{
const dictionary& conditionsDict = dict.subDict("conditions");
const wordList conditionNames(conditionsDict.toc());
conditions_.setSize(conditionNames.size());
label uniqueGroupI = 0;
forAll(conditionNames, conditionI)
{
const word& conditionName = conditionNames[conditionI];
const dictionary& dict = conditionsDict.subDict(conditionName);
conditions_.set
(
conditionI,
runTimeCondition::New(conditionName, obr_, dict, *this)
);
label groupI = conditions_[conditionI].groupID();
if (groupMap_.insert(groupI, uniqueGroupI))
{
uniqueGroupI++;
}
}
dict.readIfPresent("nWriteStep", nWriteStep_);
}
}
void Foam::runTimeControl::execute()
{
if (!active_)
{
return;
}
Info<< type() << " " << name_ << " output:" << nl;
// IDs of satisfied conditions
DynamicList<label> IDs(conditions_.size());
// Run stops only if all conditions within a group are satisfied
List<bool> groupSatisfied(groupMap_.size(), true);
List<bool> groupActive(groupMap_.size(), false);
forAll(conditions_, conditionI)
{
runTimeCondition& condition = conditions_[conditionI];
if (condition.active())
{
bool conditionSatisfied = condition.apply();
label groupI = condition.groupID();
Map<label>::const_iterator conditionIter = groupMap_.find(groupI);
if (conditionIter == groupMap_.end())
{
FatalErrorIn("void Foam::runTimeControl::execute()")
<< "group " << groupI << " not found in map"
<< abort(FatalError);
}
if (conditionSatisfied)
{
IDs.append(conditionI);
groupActive[conditionIter()] = true;
if (groupI == -1)
{
// Condition not part of a group - only requires this to be
// satisfied for completion flag to be set
groupSatisfied[conditionIter()] = true;
break;
}
}
else
{
groupSatisfied[conditionIter()] = false;
}
}
}
bool done = false;
forAll(groupSatisfied, groupI)
{
if (groupSatisfied[groupI] && groupActive[groupI])
{
done = true;
break;
}
}
if (done)
{
forAll(IDs, conditionI)
{
Info<< " " << conditions_[conditionI].type() << ": "
<< conditions_[conditionI].name()
<< " condition satisfied" << nl;
}
// Set to write a data dump or finalise the calculation
Time& time = const_cast<Time&>(obr_.time());
if (writeStepI_ < nWriteStep_ - 1)
{
writeStepI_++;
Info<< " Writing fields - step " << writeStepI_ << nl;
time.writeNow();
}
else
{
Info<< " Stopping calculation" << nl
<< " Writing fields - final step" << nl;
time.writeAndEnd();
}
}
else
{
Info<< " Conditions not met - calculations proceeding" << nl;
}
Info<< endl;
}
void Foam::runTimeControl::end()
{
if (active_)
{
execute();
}
}
void Foam::runTimeControl::timeSet()
{
// Do nothing
}
void Foam::runTimeControl::write()
{
if (active_)
{
forAll(conditions_, conditionI)
{
conditions_[conditionI].write();
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::runTimeControl
Group
grpJobControlFunctionObjects
Description
This function object controls when the calculation is terminated based on
satisfying user-specified conditions.
Optionally specify a number of write steps before the calculation is
terminated. Here, a write is performed each time that all conditons are
satisfied.
SourceFiles
runTimeControl.C
IOrunTimeControl.H
\*---------------------------------------------------------------------------*/
#ifndef runTimeControl_H
#define runTimeControl_H
#include "functionObjectState.H"
#include "Map.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
class dictionary;
class polyMesh;
class mapPolyMesh;
class runTimeCondition;
/*---------------------------------------------------------------------------*\
Class runTimeControl Declaration
\*---------------------------------------------------------------------------*/
class runTimeControl
:
public functionObjectState
{
// Private data
//- Reference to the database
const objectRegistry& obr_;
//- List of conditions to satisfy
PtrList<runTimeCondition> conditions_;
//- Map to define group IDs
Map<label> groupMap_;
//- Number of write steps before exiting
label nWriteStep_;
//- Current number of steps written
label writeStepI_;
// Private Member Functions
//- Disallow default bitwise copy construct
runTimeControl(const runTimeControl&);
//- Disallow default bitwise assignment
void operator=(const runTimeControl&);
public:
//- Runtime type information
TypeName("runTimeControl");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
runTimeControl
(
const word& name,
const objectRegistry&,
const dictionary&,
const bool loadFromFiles = false
);
//- Destructor
virtual ~runTimeControl();
// Member Functions
//- Return name of the set of runTimeControl
virtual const word& name() const
{
return name_;
}
//- Read the runTimeControl data
virtual void read(const dictionary&);
//- Execute, currently does nothing
virtual void execute();
//- Execute at the final time-loop, currently does nothing
virtual void end();
//- Called when time was set at the end of the Time::operator++
virtual void timeSet();
//- Calculate the runTimeControl and write
virtual void write();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&)
{}
//- Update for changes of mesh
virtual void movePoints(const polyMesh&)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

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 "runTimeControlFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(runTimeControlFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
runTimeControlFunctionObject,
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::runTimeControlFunctionObject
Description
FunctionObject wrapper around runTimeControl to allow it to be created
via the functions entry within controlDict.
SourceFiles
runTimeControlFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef runTimeControlFunctionObject_H
#define runTimeControlFunctionObject_H
#include "runTimeControl.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<runTimeControl>
runTimeControlFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -68,7 +68,9 @@ Foam::CourantNo::CourantNo
obr_(obr),
active_(true),
phiName_("phi"),
rhoName_("rho")
rhoName_("rho"),
resultName_(name),
log_(true)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -99,7 +101,7 @@ Foam::CourantNo::CourantNo
(
IOobject
(
type(),
resultName_,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
@ -128,8 +130,11 @@ void Foam::CourantNo::read(const dictionary& dict)
{
if (active_)
{
phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho");
log_.readIfPresent("log", dict);
dict.readIfPresent("phiName", phiName_);
dict.readIfPresent("rhoName", rhoName_);
dict.readIfPresent("resultName", resultName_);
}
}
@ -146,7 +151,7 @@ void Foam::CourantNo::execute()
volScalarField& Co =
const_cast<volScalarField&>
(
mesh.lookupObject<volScalarField>(type())
mesh.lookupObject<volScalarField>(resultName_)
);
Co.dimensionedInternalField() = byRho
@ -178,9 +183,10 @@ void Foam::CourantNo::write()
if (active_)
{
const volScalarField& CourantNo =
obr_.lookupObject<volScalarField>(type());
obr_.lookupObject<volScalarField>(resultName_);
Info<< type() << " " << name_ << " output:" << nl
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << CourantNo.name() << nl
<< endl;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,6 +32,27 @@ Description
volScalarField. The field is stored on the mesh database so that it can
be retrieved and used for other applications.
Example of function object specification to calculate the Courant number:
\verbatim
CourantNo1
{
type CourantNo;
functionObjectLibs ("libutilityFunctionObjects.so");
...
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: CourantNo | yes |
rhoName | Name of density field | no | rho
phiName | Name of flux field | no | phi
resultName | Name of Courant number field | no | <function name>
log | Log to standard output | no | yes
\endtable
SourceFiles
CourantNo.C
IOCourantNo.H
@ -77,6 +98,12 @@ class CourantNo
//- Name of density field (optional)
word rhoName_;
//- Result name
word resultName_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions

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,9 @@ Foam::Lambda2::Lambda2
name_(name),
obr_(obr),
active_(true),
UName_("U")
UName_("U"),
resultName_(name),
log_(true)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -81,7 +83,7 @@ Foam::Lambda2::Lambda2
(
IOobject
(
type(),
resultName_,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
@ -109,7 +111,17 @@ void Foam::Lambda2::read(const dictionary& dict)
{
if (active_)
{
UName_ = dict.lookupOrDefault<word>("UName", "U");
log_.readIfPresent("log", dict);
dict.readIfPresent("UName", UName_);
if (!dict.readIfPresent("resultName", resultName_))
{
resultName_ = name_;
if (UName_ != "U")
{
resultName_ = resultName_ + "(" + UName_ + ")";
}
}
}
}
@ -134,7 +146,7 @@ void Foam::Lambda2::execute()
volScalarField& Lambda2 =
const_cast<volScalarField&>
(
mesh.lookupObject<volScalarField>(type())
mesh.lookupObject<volScalarField>(resultName_)
);
Lambda2 = -eigenValues(SSplusWW)().component(vector::Y);
@ -162,9 +174,10 @@ void Foam::Lambda2::write()
if (active_)
{
const volScalarField& Lambda2 =
obr_.lookupObject<volScalarField>(type());
obr_.lookupObject<volScalarField>(resultName_);
Info<< type() << " " << name_ << " output:" << nl
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << Lambda2.name() << nl
<< endl;

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
@ -32,6 +32,25 @@ Description
of the sum of the square of the symmetrical and anti-symmetrical parts of
the velocity gradient tensor.
Example of function object specification to calculate Lambda2:
\verbatim
Lambda2_1
{
type Lambda2;
functionObjectLibs ("libutilityFunctionObjects.so");
...
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: Lambda2 | yes |
UName | Name of velocity field | no | U
resultName | Name of Lambda2 field | no | <function name>
log | Log to standard output | no | yes
\endtable
SourceFiles
Lambda2.C
IOLambda2.H
@ -77,6 +96,12 @@ class Lambda2
//- Name of velocity field, default is "U"
word UName_;
//- Result name
word resultName_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions

View File

@ -1,28 +1,28 @@
blendingFactor/blendingFactor.C
blendingFactor/blendingFactorFunctionObject.C
codedFunctionObject/codedFunctionObject.C
CourantNo/CourantNo.C
CourantNo/CourantNoFunctionObject.C
dsmcFields/dsmcFields.C
dsmcFields/dsmcFieldsFunctionObject.C
fluxSummary/fluxSummary.C
fluxSummary/fluxSummaryFunctionObject.C
Lambda2/Lambda2.C
Lambda2/Lambda2FunctionObject.C
Peclet/Peclet.C
Peclet/PecletFunctionObject.C
Q/Q.C
Q/QFunctionObject.C
blendingFactor/blendingFactor.C
blendingFactor/blendingFactorFunctionObject.C
dsmcFields/dsmcFields.C
dsmcFields/dsmcFieldsFunctionObject.C
pressureTools/pressureTools.C
pressureTools/pressureToolsFunctionObject.C
residuals/residuals.C
residuals/residualsFunctionObject.C
Q/Q.C
Q/QFunctionObject.C
scalarTransport/scalarTransport.C
scalarTransport/scalarTransportFunctionObject.C

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