ENH: Multiple updates to function objects

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
This commit is contained in:
Andrew Heather
2015-11-25 17:19:06 +00:00
parent f4de5d17e4
commit 6838df9cd2
129 changed files with 9233 additions and 3546 deletions

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

View File

@ -11,7 +11,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude
LIB_LIBS = \
-lfvOptions \
@ -26,4 +27,5 @@ LIB_LIBS = \
-lDSMC \
-lfiniteVolume \
-lmeshTools \
-lsampling
-lsampling \
-lsurfMesh

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.
@ -53,7 +53,8 @@ Foam::Peclet::Peclet
obr_(obr),
active_(true),
phiName_("phi"),
rhoName_("rho")
resultName_(name),
log_(true)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -84,7 +85,7 @@ Foam::Peclet::Peclet
(
IOobject
(
type(),
resultName_,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
@ -112,8 +113,9 @@ void Foam::Peclet::read(const dictionary& dict)
{
if (active_)
{
phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho");
log_.readIfPresent("log", dict);
dict.readIfPresent("phiName", phiName_);
dict.readIfPresent("resultName", resultName_);
}
}
@ -127,7 +129,10 @@ void Foam::Peclet::execute()
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
tmp<volScalarField> nuEff;
// Obtain nuEff of muEff. Assumes that a compressible flux is present
// when using a compressible turbulence model, and an incompressible
// flux when using an incompressible turbulence model
tmp<volScalarField> nuOrMuEff;
if (mesh.foundObject<cmpTurbModel>(turbulenceModel::propertiesName))
{
const cmpTurbModel& model =
@ -136,10 +141,7 @@ void Foam::Peclet::execute()
turbulenceModel::propertiesName
);
const volScalarField& rho =
mesh.lookupObject<volScalarField>(rhoName_);
nuEff = model.muEff()/rho;
nuOrMuEff = model.muEff();
}
else if
(
@ -152,14 +154,14 @@ void Foam::Peclet::execute()
turbulenceModel::propertiesName
);
nuEff = model.nuEff();
nuOrMuEff = model.nuEff();
}
else if (mesh.foundObject<dictionary>("transportProperties"))
{
const dictionary& model =
mesh.lookupObject<dictionary>("transportProperties");
nuEff =
nuOrMuEff =
tmp<volScalarField>
(
new volScalarField
@ -179,18 +181,20 @@ void Foam::Peclet::execute()
}
else
{
FatalErrorIn("void Foam::Peclet::write()")
FatalErrorIn("void Foam::Peclet::execute()")
<< "Unable to determine the viscosity"
<< exit(FatalError);
}
// Note: dimensions of phi will change depending on whether this is
// applied to an incompressible or compressible case
const surfaceScalarField& phi =
mesh.lookupObject<surfaceScalarField>(phiName_);
surfaceScalarField& Peclet =
const_cast<surfaceScalarField&>
(
mesh.lookupObject<surfaceScalarField>(type())
mesh.lookupObject<surfaceScalarField>(resultName_)
);
Peclet =
@ -198,7 +202,7 @@ void Foam::Peclet::execute()
/(
mesh.magSf()
*mesh.surfaceInterpolation::deltaCoeffs()
*fvc::interpolate(nuEff)
*fvc::interpolate(nuOrMuEff)
);
}
}
@ -212,6 +216,7 @@ void Foam::Peclet::end()
}
}
void Foam::Peclet::timeSet()
{
// Do nothing
@ -223,9 +228,10 @@ void Foam::Peclet::write()
if (active_)
{
const surfaceScalarField& Peclet =
obr_.lookupObject<surfaceScalarField>(type());
obr_.lookupObject<surfaceScalarField>(resultName_);
Info<< type() << " " << name_ << " output:" << nl
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << Peclet.name() << nl
<< endl;

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,6 +31,25 @@ Description
This function object calculates and outputs the Peclet number as a
surfaceScalarField.
Example of function object specification to calculate the Peclet number:
\verbatim
Peclet1
{
type Peclet;
functionObjectLibs ("libutilityFunctionObjects.so");
...
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | type name: Peclet | yes |
phiName | Name of flux field | no | phi
resultName | Name of Peclet field | no | <function name>
log | Log to standard output | no | yes
\endtable
SourceFiles
Peclet.C
IOPeclet.H
@ -76,8 +95,11 @@ class Peclet
//- Name of flux field, default is "phi"
word phiName_;
//- Name of density field (compressible cases only), default is "rho"
word rhoName_;
//- Result name
word resultName_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions

View File

@ -49,7 +49,9 @@ Foam::Q::Q
name_(name),
obr_(obr),
active_(true),
UName_("U")
UName_("U"),
resultName_(name),
log_(true)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -80,7 +82,7 @@ Foam::Q::Q
(
IOobject
(
type(),
resultName_,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
@ -108,7 +110,17 @@ void Foam::Q::read(const dictionary& dict)
{
if (active_)
{
UName_ = dict.lookupOrDefault<word>("UName", "U");
log_.readIfPresent("log", dict);
dict.readIfPresent("UName", UName_);
if (!dict.readIfPresent("resultName", resultName_))
{
resultName_ = name_;
if (UName_ != "U")
{
resultName_ = resultName_ + "(" + UName_ + ")";
}
}
}
}
@ -127,7 +139,7 @@ void Foam::Q::execute()
volScalarField& Q =
const_cast<volScalarField&>
(
mesh.lookupObject<volScalarField>(type())
mesh.lookupObject<volScalarField>(resultName_)
);
Q = 0.5*(sqr(tr(gradU)) - tr(((gradU) & (gradU))));
@ -155,9 +167,10 @@ void Foam::Q::write()
if (active_)
{
const volScalarField& Q =
obr_.lookupObject<volScalarField>(type());
obr_.lookupObject<volScalarField>(resultName_);
Info<< type() << " " << name_ << " output:" << nl
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << Q.name() << nl
<< endl;

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
@ -35,6 +35,30 @@ Description
Q = 0.5(sqr(tr(\nabla U)) - tr(((\nabla U) \cdot (\nabla U))))
\f]
where
\vartable
U | velocity [m/s]
\endvartable
Example of function object specification to calculate Q:
\verbatim
Q1
{
type Q;
functionObjectLibs ("libutilityFunctionObjects.so");
...
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | type name: Q | yes |
UName | Name of velocity field | no | U
resultName | Name of Q field | no | <function name>
log | Log to standard output | no | yes
\endtable
SourceFiles
Q.C
IOQ.H
@ -80,6 +104,12 @@ class Q
//- Name of velocity field, default is "U"
word UName_;
//- Result name
word resultName_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,6 +34,19 @@ namespace Foam
}
// * * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * //
void Foam::blendingFactor::writeFileHeader(Ostream& os) const
{
writeHeader(os, "Blending factor");
writeCommented(os, "Time");
writeTabbed(os, "Scheme1");
writeTabbed(os, "Scheme2");
writeTabbed(os, "Blended");
os << endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::blendingFactor::blendingFactor
@ -44,30 +57,44 @@ Foam::blendingFactor::blendingFactor
const bool loadFromFiles
)
:
functionObjectState(obr, name),
functionObjectFile(obr, name, typeName, dict),
name_(name),
obr_(obr),
active_(true),
phiName_("unknown-phiName"),
fieldName_("unknown-fieldName")
phiName_("phi"),
fieldName_("unknown-fieldName"),
resultName_(word::null),
tolerance_(0.001),
log_(true)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
if (setActive<fvMesh>())
{
active_ = false;
WarningIn
(
"blendingFactor::blendingFactor"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"const bool"
")"
) << "No fvMesh available, deactivating " << name_ << nl
<< endl;
}
read(dict);
writeFileHeader(file());
read(dict);
const fvMesh& mesh = refCast<const fvMesh>(obr_);
volScalarField* indicatorPtr
(
new volScalarField
(
IOobject
(
resultName_,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("0", dimless, 0.0),
zeroGradientFvPatchScalarField::typeName
)
);
mesh.objectRegistry::store(indicatorPtr);
}
}
@ -83,8 +110,26 @@ void Foam::blendingFactor::read(const dictionary& dict)
{
if (active_)
{
phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
functionObjectFile::read(dict);
log_.readIfPresent("log", dict);
dict.readIfPresent("phiName", phiName_);
dict.lookup("fieldName") >> fieldName_;
if (!dict.readIfPresent("resultName", resultName_))
{
resultName_ = name_ + ':' + fieldName_;
}
dict.readIfPresent("tolerance", tolerance_);
if ((tolerance_ < 0) || (tolerance_ > 1))
{
FatalErrorIn("void Foam::blendingFactor::read(const dictionary&)")
<< "tolerance must be in the range 0 to 1. Supplied value: "
<< tolerance_ << exit(FatalError);
}
}
}
@ -117,16 +162,15 @@ void Foam::blendingFactor::write()
{
if (active_)
{
const word fieldName = "blendingFactor:" + fieldName_;
const volScalarField& indicator =
obr_.lookupObject<volScalarField>(resultName_);
const volScalarField& blendingFactor =
obr_.lookupObject<volScalarField>(fieldName);
Info<< type() << " " << name_ << " output:" << nl
<< " writing field " << blendingFactor.name() << nl
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << indicator.name() << nl
<< endl;
blendingFactor.write();
indicator.write();
}
}

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
@ -28,10 +28,49 @@ Group
grpUtilitiesFunctionObjects
Description
This function object calculates and outputs the blendingFactor as used by
the bended convection schemes. The output is a volume field (cells) whose
value is calculated via the maximum blending factor for any cell face.
This function object provides information on the mode of operation of
blended convection schemes.
The weight of a blended scheme is given by a function of the blending
factor, f:
weight = f*scheme1 + (1 - f)*scheme2
The factor is a face-based quantity, which is converted to a cell-based
quantity by assigning the minimum blending factor for any cell face.
An indicator (volume) field, named <functionObjectName>:<fieldName>, is
generated that is set to (1 - f), i.e. values of:
- 0 represent scheme1 as active, and
- 1 represent scheme2 as active.
- intermediate values show the contribution to scheme2
Additional reporting is written to the standard output, providing
statistics as to the number of cells used by each scheme.
Example of function object specification to calculate the blending factor:
\verbatim
blendingFactor1
{
type blendingFactor;
functionObjectLibs ("libutilityFunctionObjects.so");
...
// Name of field
fieldName U;
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: blendingFactor | yes |
phiName | Name of flux field | no | phi
fieldName | Name of field to evaluate | yes |
tolerance | Tolerance for number of blended cells | no | 0.001
log | Log to standard output | no | yes
\endtable
SourceFiles
blendingFactor.C
@ -42,6 +81,8 @@ SourceFiles
#ifndef blendingFactor_H
#define blendingFactor_H
#include "functionObjectState.H"
#include "functionObjectFile.H"
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "OFstream.H"
@ -59,28 +100,37 @@ class polyMesh;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class blendingFactor Declaration
Class blendingFactor Declaration
\*---------------------------------------------------------------------------*/
class blendingFactor
:
public functionObjectState,
public functionObjectFile
{
// Private data
//- Name of this set of blendingFactor objects
word name_;
//- Name
const word name_;
//- Reference to the database
const objectRegistry& obr_;
//- On/off switch
bool active_;
//- Name of flux field, default is "phi"
word phiName_;
//- Field name
word fieldName_;
//- Result field name
word resultName_;
//- Tolerance used when calculating the number of blended cells
scalar tolerance_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions
@ -90,18 +140,19 @@ class blendingFactor
//- Disallow default bitwise assignment
void operator=(const blendingFactor&);
//- Return the blending factor field from the database
template<class Type>
volScalarField& factor
(
const GeometricField<Type, fvPatchField, volMesh>& field
);
//- Calculate the blending factor
template<class Type>
void calc();
protected:
// Protected Member Functions
//- Write the file header
virtual void writeFileHeader(Ostream& os) const;
public:
//- Runtime type information

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,45 +29,6 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::volScalarField& Foam::blendingFactor::factor
(
const GeometricField<Type, fvPatchField, volMesh>& field
)
{
const word fieldName = "blendingFactor:" + field.name();
if (!obr_.foundObject<volScalarField>(fieldName))
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
volScalarField* factorPtr =
new volScalarField
(
IOobject
(
fieldName,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("0", dimless, 0.0),
zeroGradientFvPatchScalarField::typeName
);
obr_.store(factorPtr);
}
return
const_cast<volScalarField&>
(
obr_.lookupObject<volScalarField>(fieldName)
);
}
template<class Type>
void Foam::blendingFactor::calc()
{
@ -104,15 +65,60 @@ void Foam::blendingFactor::calc()
<< exit(FatalError);
}
// retrieve the face-based blending factor
// Retrieve the face-based blending factor
const blendedSchemeBase<Type>& blendedScheme =
refCast<const blendedSchemeBase<Type> >(interpScheme);
const surfaceScalarField factorf(blendedScheme.blendingFactor(field));
// convert into vol field whose values represent the local face maxima
volScalarField& factor = this->factor(field);
factor = fvc::cellReduce(factorf, maxEqOp<scalar>());
factor.correctBoundaryConditions();
// Convert into vol field whose values represent the local face minima
// Note: factor applied to 1st scheme, and (1-factor) to 2nd scheme
volScalarField& indicator =
const_cast<volScalarField&>
(
obr_.lookupObject<volScalarField>(resultName_)
);
indicator = 1 - fvc::cellReduce(factorf, minEqOp<scalar>(), GREAT);
indicator.correctBoundaryConditions();
// Generate scheme statistics
label nCellsScheme1 = 0;
label nCellsScheme2 = 0;
label nCellsBlended = 0;
forAll(indicator, cellI)
{
scalar i = indicator[cellI];
if (i < tolerance_)
{
nCellsScheme1++;
}
else if (i > (1 - tolerance_))
{
nCellsScheme2++;
}
else
{
nCellsBlended++;
}
}
reduce(nCellsScheme1, sumOp<label>());
reduce(nCellsScheme2, sumOp<label>());
reduce(nCellsBlended, sumOp<label>());
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " scheme 1 cells : " << nCellsScheme1 << nl
<< " scheme 2 cells : " << nCellsScheme2 << nl
<< " blended cells : " << nCellsBlended << nl
<< endl;
file()
<< obr_.time().time().value()
<< token::TAB << nCellsScheme1
<< token::TAB << nCellsScheme2
<< token::TAB << nCellsBlended
<< endl;
}

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
@ -52,7 +52,8 @@ Foam::dsmcFields::dsmcFields
:
name_(name),
obr_(obr),
active_(true)
active_(true),
log_(true)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -87,7 +88,7 @@ void Foam::dsmcFields::read(const dictionary& dict)
{
if (active_)
{
log_.readIfPresent("log", dict);
}
}
@ -122,46 +123,32 @@ void Foam::dsmcFields::write()
word iDofMeanName = "iDofMean";
word fDMeanName = "fDMean";
const volScalarField& rhoNMean = obr_.lookupObject<volScalarField>
(
rhoNMeanName
);
const volScalarField& rhoNMean =
obr_.lookupObject<volScalarField>(rhoNMeanName);
const volScalarField& rhoMMean = obr_.lookupObject<volScalarField>
(
rhoMMeanName
);
const volScalarField& rhoMMean =
obr_.lookupObject<volScalarField>(rhoMMeanName);
const volVectorField& momentumMean = obr_.lookupObject<volVectorField>
(
momentumMeanName
);
const volVectorField& momentumMean =
obr_.lookupObject<volVectorField>(momentumMeanName);
const volScalarField& linearKEMean = obr_.lookupObject<volScalarField>
(
linearKEMeanName
);
const volScalarField& linearKEMean =
obr_.lookupObject<volScalarField>(linearKEMeanName);
const volScalarField& internalEMean = obr_.lookupObject<volScalarField>
(
internalEMeanName
);
const volScalarField& internalEMean =
obr_.lookupObject<volScalarField>(internalEMeanName);
const volScalarField& iDofMean = obr_.lookupObject<volScalarField>
(
iDofMeanName
);
const volScalarField& iDofMean =
obr_.lookupObject<volScalarField>(iDofMeanName);
const volVectorField& fDMean = obr_.lookupObject<volVectorField>
(
fDMeanName
);
const volVectorField& fDMean =
obr_.lookupObject<volVectorField>(fDMeanName);
if (min(mag(rhoNMean)).value() > VSMALL)
{
Info<< "Calculating dsmcFields." << endl;
if (log_) Info<< type() << " " << name_ << " output:" << endl;
Info<< " Calculating UMean field." << endl;
if (log_) Info<< " Calculating UMean field" << endl;
volVectorField UMean
(
IOobject
@ -174,7 +161,7 @@ void Foam::dsmcFields::write()
momentumMean/rhoMMean
);
Info<< " Calculating translationalT field." << endl;
if (log_) Info<< " Calculating translationalT field" << endl;
volScalarField translationalT
(
IOobject
@ -189,7 +176,7 @@ void Foam::dsmcFields::write()
*(linearKEMean - 0.5*rhoMMean*(UMean & UMean))
);
Info<< " Calculating internalT field." << endl;
if (log_) Info<< " Calculating internalT field" << endl;
volScalarField internalT
(
IOobject
@ -202,7 +189,7 @@ void Foam::dsmcFields::write()
(2.0/physicoChemical::k.value())*(internalEMean/iDofMean)
);
Info<< " Calculating overallT field." << endl;
if (log_) Info<< " Calculating overallT field" << endl;
volScalarField overallT
(
IOobject
@ -216,7 +203,7 @@ void Foam::dsmcFields::write()
*(linearKEMean - 0.5*rhoMMean*(UMean & UMean) + internalEMean)
);
Info<< " Calculating pressure field." << endl;
if (log_) Info<< " Calculating pressure field" << endl;
volScalarField p
(
IOobject
@ -243,25 +230,28 @@ void Foam::dsmcFields::write()
}
}
Info<< " mag(UMean) max/min : "
<< max(mag(UMean)).value() << " "
<< min(mag(UMean)).value() << endl;
if (log_)
{
Info<< " mag(UMean) max/min: "
<< max(mag(UMean)).value() << " "
<< min(mag(UMean)).value() << endl;
Info<< " translationalT max/min : "
<< max(translationalT).value() << " "
<< min(translationalT).value() << endl;
Info<< " translationalT max/min: "
<< max(translationalT).value() << " "
<< min(translationalT).value() << endl;
Info<< " internalT max/min : "
<< max(internalT).value() << " "
<< min(internalT).value() << endl;
Info<< " internalT max/min: "
<< max(internalT).value() << " "
<< min(internalT).value() << endl;
Info<< " overallT max/min : "
<< max(overallT).value() << " "
<< min(overallT).value() << endl;
Info<< " overallT max/min: "
<< max(overallT).value() << " "
<< min(overallT).value() << endl;
Info<< " p max/min : "
<< max(p).value() << " "
<< min(p).value() << endl;
Info<< " p max/min: "
<< max(p).value() << " "
<< min(p).value() << endl;
}
UMean.write();
@ -273,13 +263,14 @@ void Foam::dsmcFields::write()
p.write();
Info<< "dsmcFields written." << nl << endl;
if (log_) Info<< " " << type() << " written" << nl << endl;
}
else
{
Info<< "Small value (" << min(mag(rhoNMean))
if (log_) Info
<< "Small value (" << min(mag(rhoNMean))
<< ") found in rhoNMean field. "
<< "Not calculating dsmcFields to avoid division by zero."
<< "Not calculating " << type() << " to avoid division by zero."
<< endl;
}
}

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
@ -28,13 +28,32 @@ Group
grpUtilitiesFunctionObjects
Description
Calculate intensive fields:
This function object calculates and outputs the intensive fields:
- UMean
- translationalT
- internalT
- overallT
from averaged extensive fields from a DSMC calculation.
Example of function object specification to calculate DSMC fields:
\verbatim
dsmcFields1
{
type dsmcFields;
functionObjectLibs ("libutilityFunctionObjects.so");
...
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: dsmcFields | yes |
log | Log to standard output | no | yes
\endtable
SourceFiles
dsmcFields.C
IOdsmcFields.H
@ -45,6 +64,7 @@ SourceFiles
#define dsmcFields_H
#include "typeInfo.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -73,6 +93,9 @@ class dsmcFields
//- on/off switch
bool active_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions

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::IOfluxSummary
Description
Instance of the generic IOOutputFilter for fluxSummary.
\*---------------------------------------------------------------------------*/
#ifndef IOfluxSummary_H
#define IOfluxSummary_H
#include "fluxSummary.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<fluxSummary> IOfluxSummary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,956 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "fluxSummary.H"
#include "surfaceFields.H"
#include "dictionary.H"
#include "Time.H"
#include "syncTools.H"
#include "meshTools.H"
#include "PatchEdgeFaceWave.H"
#include "patchEdgeFaceRegion.H"
#include "globalIndex.H"
#include "OBJstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(fluxSummary, 0);
template<>
const char* NamedEnum
<
fluxSummary::modeType,
3
>::names[] =
{
"faceZone",
"faceZoneAndDirection",
"cellZoneAndDirection"
};
}
const Foam::NamedEnum<Foam::fluxSummary::modeType, 3>
Foam::fluxSummary::modeTypeNames_;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fluxSummary::initialiseFaceZone
(
const word& faceZoneName,
DynamicList<word>& faceZoneNames,
DynamicList<List<label> >& faceID,
DynamicList<List<label> >& facePatchID,
DynamicList<List<scalar> >& faceSign
) const
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
label zoneI = mesh.faceZones().findZoneID(faceZoneName);
if (zoneI == -1)
{
FatalErrorIn
(
"void Foam::fluxSummary::initialiseFaceZone"
"("
"const word&, "
"DynamicList<word>&, "
"DynamicList<List<label> >&, "
"DynamicList<List<label> >&, "
"DynamicList<List<scalar> >&"
") const"
)
<< "Unable to find faceZone " << faceZoneName
<< ". Valid faceZones are: " << mesh.faceZones().names()
<< exit(FatalError);
}
faceZoneNames.append(faceZoneName);
const faceZone& fZone = mesh.faceZones()[zoneI];
DynamicList<label> faceIDs(fZone.size());
DynamicList<label> facePatchIDs(fZone.size());
DynamicList<scalar> faceSigns(fZone.size());
forAll(fZone, i)
{
label faceI = fZone[i];
label faceID = -1;
label facePatchID = -1;
if (mesh.isInternalFace(faceI))
{
faceID = faceI;
facePatchID = -1;
}
else
{
facePatchID = mesh.boundaryMesh().whichPatch(faceI);
const polyPatch& pp = mesh.boundaryMesh()[facePatchID];
if (isA<coupledPolyPatch>(pp))
{
if (refCast<const coupledPolyPatch>(pp).owner())
{
faceID = pp.whichFace(faceI);
}
else
{
faceID = -1;
}
}
else if (!isA<emptyPolyPatch>(pp))
{
faceID = faceI - pp.start();
}
else
{
faceID = -1;
facePatchID = -1;
}
}
if (faceID >= 0)
{
// orientation set by faceZone flip map
if (fZone.flipMap()[faceI])
{
faceSigns.append(-1);
}
else
{
faceSigns.append(1);
}
faceIDs.append(faceID);
facePatchIDs.append(facePatchID);
}
}
faceID.append(faceIDs);
facePatchID.append(facePatchIDs);
faceSign.append(faceSigns);
}
void Foam::fluxSummary::initialiseFaceZoneAndDirection
(
const word& faceZoneName,
const vector& dir,
DynamicList<vector>& zoneRefDir,
DynamicList<word>& faceZoneNames,
DynamicList<List<label> >& faceID,
DynamicList<List<label> >& facePatchID,
DynamicList<List<scalar> >& faceSign
) const
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
vector refDir = dir/(mag(dir) + ROOTVSMALL);
label zoneI = mesh.faceZones().findZoneID(faceZoneName);
if (zoneI == -1)
{
FatalErrorIn
(
"void Foam::fluxSummary::initialiseFaceZoneAndDirection"
"("
"const word&, "
"const vector&, "
"DynamicList<vector>&, "
"DynamicList<word>&, "
"DynamicList<List<label> >&, "
"DynamicList<List<label> >&, "
"DynamicList<List<scalar> >&"
") const"
)
<< "Unable to find faceZone " << faceZoneName
<< ". Valid faceZones are: " << mesh.faceZones().names()
<< exit(FatalError);
}
faceZoneNames.append(faceZoneName);
zoneRefDir.append(refDir);
const faceZone& fZone = mesh.faceZones()[zoneI];
DynamicList<label> faceIDs(fZone.size());
DynamicList<label> facePatchIDs(fZone.size());
DynamicList<scalar> faceSigns(fZone.size());
const surfaceVectorField& Sf = mesh.Sf();
const surfaceScalarField& magSf = mesh.magSf();
vector n = vector::zero;
forAll(fZone, i)
{
label faceI = fZone[i];
label faceID = -1;
label facePatchID = -1;
if (mesh.isInternalFace(faceI))
{
faceID = faceI;
facePatchID = -1;
}
else
{
facePatchID = mesh.boundaryMesh().whichPatch(faceI);
const polyPatch& pp = mesh.boundaryMesh()[facePatchID];
if (isA<coupledPolyPatch>(pp))
{
if (refCast<const coupledPolyPatch>(pp).owner())
{
faceID = pp.whichFace(faceI);
}
else
{
faceID = -1;
}
}
else if (!isA<emptyPolyPatch>(pp))
{
faceID = faceI - pp.start();
}
else
{
faceID = -1;
facePatchID = -1;
}
}
if (faceID >= 0)
{
// orientation set by comparison with reference direction
if (facePatchID != -1)
{
n = Sf.boundaryField()[facePatchID][faceID]
/(magSf.boundaryField()[facePatchID][faceID] + ROOTVSMALL);
}
else
{
n = Sf[faceID]/(magSf[faceID] + ROOTVSMALL);
}
if ((n & refDir) > tolerance_)
{
faceSigns.append(1);
}
else
{
faceSigns.append(-1);
}
faceIDs.append(faceID);
facePatchIDs.append(facePatchID);
}
}
faceID.append(faceIDs);
facePatchID.append(facePatchIDs);
faceSign.append(faceSigns);
}
void Foam::fluxSummary::initialiseCellZoneAndDirection
(
const word& cellZoneName,
const vector& dir,
DynamicList<vector>& zoneRefDir,
DynamicList<word>& faceZoneNames,
DynamicList<List<label> >& faceID,
DynamicList<List<label> >& facePatchID,
DynamicList<List<scalar> >& faceSign
) const
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
vector refDir = dir/(mag(dir) + ROOTVSMALL);
const label cellZoneI = mesh.cellZones().findZoneID(cellZoneName);
if (cellZoneI == -1)
{
FatalErrorIn
(
"void Foam::fluxSummary::initialiseCellZoneAndDirection"
"("
"const word&, "
"const vector&, "
"DynamicList<vector>&, "
"DynamicList<word>&, "
"DynamicList<List<label> >&, "
"DynamicList<List<label> >&, "
"DynamicList<List<scalar> >&"
") const"
)
<< "Unable to find cellZone " << cellZoneName
<< ". Valid zones are: " << mesh.cellZones().names()
<< exit(FatalError);
}
const label nInternalFaces = mesh.nInternalFaces();
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
labelList cellAddr(mesh.nCells(), -1);
const labelList& cellIDs = mesh.cellZones()[cellZoneI];
UIndirectList<label>(cellAddr, cellIDs) = identity(cellIDs.size());
labelList nbrFaceCellAddr(mesh.nFaces() - nInternalFaces, -1);
forAll(pbm, patchI)
{
const polyPatch& pp = pbm[patchI];
if (pp.coupled())
{
forAll(pp, i)
{
label faceI = pp.start() + i;
label nbrFaceI = faceI - nInternalFaces;
label own = mesh.faceOwner()[faceI];
nbrFaceCellAddr[nbrFaceI] = cellAddr[own];
}
}
}
// correct boundary values for parallel running
syncTools::swapBoundaryFaceList(mesh, nbrFaceCellAddr);
// collect faces
DynamicList<label> faceIDs(floor(0.1*mesh.nFaces()));
DynamicList<label> facePatchIDs(faceIDs.size());
DynamicList<label> faceLocalPatchIDs(faceIDs.size());
DynamicList<scalar> faceSigns(faceIDs.size());
// internal faces
for (label faceI = 0; faceI < nInternalFaces; faceI++)
{
const label own = cellAddr[mesh.faceOwner()[faceI]];
const label nbr = cellAddr[mesh.faceNeighbour()[faceI]];
if (((own != -1) && (nbr == -1)) || ((own == -1) && (nbr != -1)))
{
vector n = mesh.faces()[faceI].normal(mesh.points());
n /= mag(n) + ROOTVSMALL;
if ((n & refDir) > tolerance_)
{
faceIDs.append(faceI);
faceLocalPatchIDs.append(faceI);
facePatchIDs.append(-1);
faceSigns.append(1);
}
else if ((n & -refDir) > tolerance_)
{
faceIDs.append(faceI);
faceLocalPatchIDs.append(faceI);
facePatchIDs.append(-1);
faceSigns.append(-1);
}
}
}
// loop of boundary faces
forAll(pbm, patchI)
{
const polyPatch& pp = pbm[patchI];
forAll(pp, localFaceI)
{
const label faceI = pp.start() + localFaceI;
const label own = cellAddr[mesh.faceOwner()[faceI]];
const label nbr = nbrFaceCellAddr[faceI - nInternalFaces];
if ((own != -1) && (nbr == -1))
{
vector n = mesh.faces()[faceI].normal(mesh.points());
n /= mag(n) + ROOTVSMALL;
if ((n & refDir) > tolerance_)
{
faceIDs.append(faceI);
faceLocalPatchIDs.append(localFaceI);
facePatchIDs.append(patchI);
faceSigns.append(1);
}
else if ((n & -refDir) > tolerance_)
{
faceIDs.append(faceI);
faceLocalPatchIDs.append(localFaceI);
facePatchIDs.append(patchI);
faceSigns.append(-1);
}
}
}
}
// convert into primitivePatch for convenience
indirectPrimitivePatch patch
(
IndirectList<face>(mesh.faces(), faceIDs),
mesh.points()
);
if (debug)
{
OBJstream os(mesh.time().path()/"patch.obj");
faceList faces(patch);
os.write(faces, mesh.points(), false);
}
// data on all edges and faces
List<patchEdgeFaceRegion> allEdgeInfo(patch.nEdges());
List<patchEdgeFaceRegion> allFaceInfo(patch.size());
bool search = true;
if (debug)
{
Info<< "initialiseCellZoneAndDirection: "
<< "Starting walk to split patch into faceZones"
<< endl;
}
globalIndex globalFaces(patch.size());
label oldFaceID = 0;
label regionI = 0;
while (search)
{
DynamicList<label> changedEdges;
DynamicList<patchEdgeFaceRegion> changedInfo;
label seedFaceI = labelMax;
for (; oldFaceID < patch.size(); oldFaceID++)
{
if (allFaceInfo[oldFaceID].region() == -1)
{
seedFaceI = globalFaces.toGlobal(oldFaceID);
break;
}
}
reduce(seedFaceI, minOp<label>());
if (seedFaceI == labelMax)
{
break;
}
if (globalFaces.isLocal(seedFaceI))
{
label localFaceI = globalFaces.toLocal(seedFaceI);
const labelList& fEdges = patch.faceEdges()[localFaceI];
forAll(fEdges, i)
{
if (allEdgeInfo[fEdges[i]].region() != -1)
{
WarningIn
(
"void Foam::fluxSummary::initialiseCellZoneAndDirection"
"("
"const word&, "
"const vector&, "
"DynamicList<vector>&, "
"DynamicList<word>&, "
"DynamicList<List<label> >&, "
"DynamicList<List<label> >&, "
"DynamicList<List<scalar> >&"
") const"
) << "Problem in edge face wave: attempted to assign a "
<< "value to an edge that has already been visited. "
<< "Edge info: " << allEdgeInfo[fEdges[i]]
<< endl;
}
changedEdges.append(fEdges[i]);
changedInfo.append(regionI);
}
}
PatchEdgeFaceWave
<
indirectPrimitivePatch,
patchEdgeFaceRegion
> calc
(
mesh,
patch,
changedEdges,
changedInfo,
allEdgeInfo,
allFaceInfo,
returnReduce(patch.nEdges(), sumOp<label>())
);
label nCells = 0;
forAll(allFaceInfo, faceI)
{
if (allFaceInfo[faceI].region() == regionI)
{
nCells++;
}
}
if (debug)
{
Info<< "*** region:" << regionI
<< " found:" << returnReduce(nCells, sumOp<label>())
<< " faces" << endl;
}
regionI++;
}
// collect the data per region
label nRegion = regionI;
List<DynamicList<label> > regionFaceIDs(nRegion);
List<DynamicList<label> > regionFacePatchIDs(nRegion);
List<DynamicList<scalar> > regionFaceSigns(nRegion);
forAll(allFaceInfo, faceI)
{
regionI = allFaceInfo[faceI].region();
regionFaceIDs[regionI].append(faceLocalPatchIDs[faceI]);
regionFacePatchIDs[regionI].append(facePatchIDs[faceI]);
regionFaceSigns[regionI].append(faceSigns[faceI]);
}
// transfer to persistent storage
forAll(regionFaceIDs, regionI)
{
const word zoneName = cellZoneName + ":faceZone" + Foam::name(regionI);
faceZoneNames.append(zoneName);
zoneRefDir.append(refDir);
faceID.append(regionFaceIDs[regionI]);
facePatchID.append(regionFacePatchIDs[regionI]);
faceSign.append(regionFaceSigns[regionI]);
// write OBJ of faces to file
if (debug)
{
OBJstream os(mesh.time().path()/zoneName + ".obj");
faceList faces(mesh.faces(), regionFaceIDs[regionI]);
os.write(faces, mesh.points(), false);
}
}
if (log_)
{
Info<< type() << " " << name_ << " output:" << nl
<< " Created " << faceID.size()
<< " separate face zones from cell zone " << cellZoneName << nl;
forAll(faceZoneNames, i)
{
label nFaces = returnReduce(faceID[i].size(), sumOp<label>());
Info<< " " << faceZoneNames[i] << ": "
<< nFaces << " faces" << nl;
}
Info<< endl;
}
}
void Foam::fluxSummary::initialiseFaceArea()
{
faceArea_.setSize(faceID_.size(), 0);
const fvMesh& mesh = refCast<const fvMesh>(obr_);
const surfaceScalarField& magSf = mesh.magSf();
forAll(faceID_, zoneI)
{
const labelList& faceIDs = faceID_[zoneI];
const labelList& facePatchIDs = facePatchID_[zoneI];
scalar sumMagSf = 0;
forAll(faceIDs, i)
{
label faceI = faceIDs[i];
if (facePatchIDs[i] == -1)
{
sumMagSf += magSf[faceI];
}
else
{
label patchI = facePatchIDs[i];
sumMagSf += magSf.boundaryField()[patchI][faceI];
}
}
faceArea_[zoneI] = returnReduce(sumMagSf, sumOp<scalar>());
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fluxSummary::fluxSummary
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
functionObjectFile(obr, name),
name_(name),
obr_(obr),
active_(true),
log_(true),
mode_(mdFaceZone),
scaleFactor_(1),
phiName_("phi"),
faceZoneName_(),
refDir_(),
faceID_(),
facePatchID_(),
faceSign_(),
faceArea_(),
filePtrs_(),
tolerance_(0.8)
{
// Check if the available mesh is an fvMesh otherise deactivate
if (!isA<fvMesh>(obr_))
{
active_ = false;
WarningIn
(
"fluxSummary::fluxSummary"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"const bool"
")"
) << "No fvMesh available, deactivating " << name_
<< endl;
}
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fluxSummary::~fluxSummary()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fluxSummary::read(const dictionary& dict)
{
if (active_)
{
functionObjectFile::read(dict);
log_ = dict.lookupOrDefault<Switch>("log", true);
mode_ = modeTypeNames_.read(dict.lookup("mode"));
phiName_= dict.lookupOrDefault<word>("phiName", "phi");
dict.readIfPresent("scaleFactor", scaleFactor_);
dict.readIfPresent("tolerance", tolerance_);
// initialise with capacity of 10 faceZones
DynamicList<vector> refDir(10);
DynamicList<word> faceZoneName(refDir.size());
DynamicList<List<label> > faceID(refDir.size());
DynamicList<List<label> > facePatchID(refDir.size());
DynamicList<List<scalar> > faceSign(refDir.size());
switch (mode_)
{
case mdFaceZone:
{
List<word> zones(dict.lookup("faceZones"));
forAll(zones, i)
{
initialiseFaceZone
(
zones[i],
faceZoneName,
faceID,
facePatchID,
faceSign
);
}
break;
}
case mdFaceZoneAndDirection:
{
List<Tuple2<word, vector> >
zoneAndDirection(dict.lookup("faceZoneAndDirection"));
forAll(zoneAndDirection, i)
{
initialiseFaceZoneAndDirection
(
zoneAndDirection[i].first(),
zoneAndDirection[i].second(),
refDir,
faceZoneName,
faceID,
facePatchID,
faceSign
);
}
break;
}
case mdCellZoneAndDirection:
{
List<Tuple2<word, vector> >
zoneAndDirection(dict.lookup("cellZoneAndDirection"));
forAll(zoneAndDirection, i)
{
initialiseCellZoneAndDirection
(
zoneAndDirection[i].first(),
zoneAndDirection[i].second(),
refDir,
faceZoneName,
faceID,
facePatchID,
faceSign
);
}
break;
}
default:
{
FatalIOErrorIn
(
"void Foam::fluxSummary::read(const dictionary&)",
dict
)
<< "unhandled enumeration " << modeTypeNames_[mode_]
<< abort(FatalIOError);
}
}
faceZoneName_.transfer(faceZoneName);
refDir_.transfer(refDir);
faceID_.transfer(faceID);
facePatchID_.transfer(facePatchID);
faceSign_.transfer(faceSign);
initialiseFaceArea();
if (writeToFile())
{
filePtrs_.setSize(faceZoneName_.size());
forAll(filePtrs_, fileI)
{
const word& fzName = faceZoneName_[fileI];
filePtrs_.set(fileI, createFile(fzName));
writeFileHeader
(
fzName,
faceArea_[fileI],
refDir_[fileI],
filePtrs_[fileI]
);
}
}
}
}
void Foam::fluxSummary::writeFileHeader
(
const word& fzName,
const scalar area,
const vector& refDir,
Ostream& os
) const
{
writeHeader(os, "Flux summary");
writeHeaderValue(os, "Face zone", fzName);
writeHeaderValue(os, "Total area", area);
switch (mode_)
{
case mdFaceZoneAndDirection:
case mdCellZoneAndDirection:
{
writeHeaderValue(os, "Reference direction", refDir);
break;
}
default:
{}
}
writeHeaderValue(os, "Scale factor", scaleFactor_);
writeCommented(os, "Time");
os << tab << "positive"
<< tab << "negative"
<< tab << "net"
<< tab << "absolute"
<< endl;
}
void Foam::fluxSummary::execute()
{
// Do nothing - only valid on write
}
void Foam::fluxSummary::end()
{
// Do nothing - only valid on write
}
void Foam::fluxSummary::timeSet()
{
// Do nothing - only valid on write
}
void Foam::fluxSummary::write()
{
if (!active_)
{
return;
}
const surfaceScalarField& phi =
obr_.lookupObject<surfaceScalarField>(phiName_);
word flowType = "";
if (phi.dimensions() == dimVolume/dimTime)
{
flowType = "volumetric";
}
else if (phi.dimensions() == dimMass/dimTime)
{
flowType = "mass";
}
else
{
FatalErrorIn("void Foam::fluxSummary::write()")
<< "Unsupported flux field " << phi.name() << " with dimensions "
<< phi.dimensions() << ". Expected eithe mass flow or volumetric "
<< "flow rate" << abort(FatalError);
}
if (log_)
{
Info<< type() << " " << name_ << ' ' << flowType << " flux output:"
<< nl;
}
forAll(faceZoneName_, zoneI)
{
const labelList& faceID = faceID_[zoneI];
const labelList& facePatchID = facePatchID_[zoneI];
const scalarList& faceSign = faceSign_[zoneI];
scalar phiPos = scalar(0);
scalar phiNeg = scalar(0);
scalar phif = scalar(0);
forAll(faceID, i)
{
label faceI = faceID[i];
label patchI = facePatchID[i];
if (patchI != -1)
{
phif = phi.boundaryField()[patchI][faceI];
}
else
{
phif = phi[faceI];
}
phif *= faceSign[i];
if (phif > 0)
{
phiPos += phif;
}
else
{
phiNeg += phif;
}
}
reduce(phiPos, sumOp<scalar>());
reduce(phiNeg, sumOp<scalar>());
phiPos *= scaleFactor_;
phiNeg *= scaleFactor_;
scalar netFlux = phiPos + phiNeg;
scalar absoluteFlux = phiPos - phiNeg;
if (log_)
{
Info<< " faceZone " << faceZoneName_[zoneI] << ':' << nl
<< " positive : " << phiPos << nl
<< " negative : " << phiNeg << nl
<< " net : " << netFlux << nl
<< " absolute : " << absoluteFlux
<< nl << endl;
}
if (writeToFile())
{
filePtrs_[zoneI]
<< obr_.time().value() << token::TAB
<< phiPos << token::TAB
<< phiNeg << token::TAB
<< netFlux << token::TAB
<< absoluteFlux
<< endl;
}
}
if (log_) Info<< endl;
}
// ************************************************************************* //

View File

@ -0,0 +1,302 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::fluxSummary
Group
grpUtilityFunctionObjects
Description
This function object calculates the flux across selections of faces.
Output comprises, per set of faces, the:
- positive
- negative
- net
- absolute
fluxes
Example of function object specification:
\verbatim
fluxSummary1
{
type fluxSummary;
functionObjectLibs ("libutilityFunctionObjects.so");
...
write yes;
log yes;
mode cellZoneAndDirection;
cellZoneAndDirection
(
(porosity (1 0 0))
);
scaleFactor 1.2;
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | type name: fluxSummary | yes |
write | write flux data to file | no | yes
log | write flux data to standard output | no | yes
mode | mode to generate faces to test | yes |
scaleFactor | optional factor to scale result | no | 1
\endtable
The mode is one of:
- faceZone
- faceZoneAndDirection
- cellZoneAndDirection
Output data is written to files of the form \<timeDir\>/<faceZoneName>.dat
SeeAlso
Foam::functionObject
Foam::OutputFilterFunctionObject
SourceFiles
fluxSummary.C
IOfluxSummary.H
\*---------------------------------------------------------------------------*/
#ifndef fluxSummary_H
#define fluxSummary_H
#include "functionObjectFile.H"
#include "Switch.H"
#include "vector.H"
#include "DynamicList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
class dictionary;
class polyMesh;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class fluxSummary Declaration
\*---------------------------------------------------------------------------*/
class fluxSummary
:
public functionObjectFile
{
public:
// Public enumerations
//- Face mode type
enum modeType
{
mdFaceZone,
mdFaceZoneAndDirection,
mdCellZoneAndDirection
};
//- Mode type names
static const NamedEnum<modeType, 3> modeTypeNames_;
protected:
// Protected data
//- Name of function object
// Also used as the name of the output directory
word name_;
//- Reference to the database
const objectRegistry& obr_;
//- on/off switch
bool active_;
//- Switch to send output to Info as well
Switch log_;
//- Mode for face determination
modeType mode_;
//- Scale factor
scalar scaleFactor_;
//- Name of flux field, default = phi
word phiName_;
// Per-faceZone information
//- Region names
List<word> faceZoneName_;
//- Reference direction
List<vector> refDir_;
//- Face IDs
List<List<label> > faceID_;
//- Face patch IDs
List<List<label> > facePatchID_;
//- Face flip map signs
List<List<scalar> > faceSign_;
//- Sum of face areas
List<scalar> faceArea_;
//- Output file per face zone
PtrList<OFstream> filePtrs_;
//- Tolerance applied when matching face normals
scalar tolerance_;
// Private Member Functions
//- Initialise face set from face zone
void initialiseFaceZone
(
const word& faceZoneName,
DynamicList<word>& faceZoneNames,
DynamicList<List<label> >& faceID,
DynamicList<List<label> >& facePatchID,
DynamicList<List<scalar> >& faceSign
) const;
//- Initialise face set from face zone and direction
void initialiseFaceZoneAndDirection
(
const word& faceZoneName,
const vector& refDir,
DynamicList<vector>& dir,
DynamicList<word>& faceZoneNames,
DynamicList<List<label> >& faceID,
DynamicList<List<label> >& facePatchID,
DynamicList<List<scalar> >& faceSign
) const;
//- Initialise face set from cell zone and direction
void initialiseCellZoneAndDirection
(
const word& cellZoneName,
const vector& refDir,
DynamicList<vector>& dir,
DynamicList<word>& faceZoneNames,
DynamicList<List<label> >& faceID,
DynamicList<List<label> >& facePatchID,
DynamicList<List<scalar> >& faceSign
) const;
//- Initialise the total area per derived faceZone
void initialiseFaceArea();
//- Output file header information
virtual void writeFileHeader
(
const word& fzName,
const scalar area,
const vector& refDir,
Ostream& os
) const;
//- Disallow default bitwise copy construct
fluxSummary(const fluxSummary&);
//- Disallow default bitwise assignment
void operator=(const fluxSummary&);
public:
//- Runtime type information
TypeName("fluxSummary");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
fluxSummary
(
const word& name,
const objectRegistry&,
const dictionary&,
const bool loadFromFiles = false
);
//- Destructor
virtual ~fluxSummary();
// Member Functions
//- Return name of the set of field min/max
virtual const word& name() const
{
return name_;
}
//- Read the field min/max data
virtual void read(const dictionary&);
//- Execute, currently does nothing
virtual void execute();
//- Execute at the final time-loop, currently does nothing
virtual void end();
//- Called when time was set at the end of the Time::operator++
virtual void timeSet();
//- Write the fluxSummary
virtual void write();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&)
{}
//- Update for changes of mesh
virtual void movePoints(const polyMesh&)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

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 "fluxSummaryFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(fluxSummaryFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
fluxSummaryFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

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

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,28 +37,6 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::word Foam::pressureTools::pName() const
{
word fieldName = pName_;
if (calcTotal_)
{
fieldName = "total(" + fieldName + ")";
}
else
{
fieldName = "static(" + fieldName + ")";
}
if (calcCoeff_)
{
fieldName = fieldName + "_coeff";
}
return fieldName;
}
Foam::dimensionedScalar Foam::pressureTools::rhoScale
(
const volScalarField& p
@ -86,7 +64,23 @@ Foam::tmp<Foam::volScalarField> Foam::pressureTools::rho
}
else
{
return
if (!rhoInfInitialised_)
{
FatalErrorIn
(
"Foam::tmp<Foam::volScalarField> Foam::pressureTools::rho"
"("
" const volScalarField&"
") const"
)
<< type() << " " << name_ << ": "
<< "pressure identified as incompressible, but reference "
<< "density is not set. Please set rhoName to rhoInf, and "
<< "set an appropriate value for rhoInf"
<< exit(FatalError);
}
return
tmp<volScalarField>
(
new volScalarField
@ -193,12 +187,15 @@ Foam::pressureTools::pressureTools
pName_("p"),
UName_("U"),
rhoName_("rho"),
resultName_(word::null),
log_(true),
calcTotal_(false),
pRef_(0.0),
calcCoeff_(false),
pInf_(0.0),
UInf_(vector::zero),
rhoInf_(0.0)
rhoInf_(0.0),
rhoInfInitialised_(false)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -236,7 +233,7 @@ Foam::pressureTools::pressureTools
(
IOobject
(
pName(),
resultName_,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
@ -264,13 +261,18 @@ void Foam::pressureTools::read(const dictionary& dict)
{
if (active_)
{
log_.readIfPresent("log", dict);
dict.readIfPresent("pName", pName_);
dict.readIfPresent("UName", UName_);
dict.readIfPresent("rhoName", rhoName_);
rhoInfInitialised_ = false;
if (rhoName_ == "rhoInf")
{
dict.lookup("rhoInf") >> rhoInf_;
rhoInfInitialised_ = true;
}
dict.lookup("calcTotal") >> calcTotal_;
@ -296,6 +298,27 @@ void Foam::pressureTools::read(const dictionary& dict)
<< "pressure level is zero. Please check the supplied "
<< "values of pInf, UInf and rhoInf" << endl;
}
rhoInfInitialised_ = true;
}
if (!dict.readIfPresent("resultName", resultName_))
{
resultName_ = pName_;
if (calcTotal_)
{
resultName_ = "total(" + resultName_ + ")";
}
else
{
resultName_ = "static(" + resultName_ + ")";
}
if (calcCoeff_)
{
resultName_ = resultName_ + "_coeff";
}
}
}
}
@ -310,7 +333,7 @@ void Foam::pressureTools::execute()
volScalarField& pResult =
const_cast<volScalarField&>
(
obr_.lookupObject<volScalarField>(pName())
obr_.lookupObject<volScalarField>(resultName_)
);
pResult == convertToCoeff(rhoScale(p)*p + pDyn(p) + pRef());
@ -338,9 +361,10 @@ void Foam::pressureTools::write()
if (active_)
{
const volScalarField& pResult =
obr_.lookupObject<volScalarField>(pName());
obr_.lookupObject<volScalarField>(resultName_);
Info<< type() << " " << name_ << " output:" << nl
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << pResult.name() << nl
<< endl;

View File

@ -101,6 +101,8 @@ Description
pInf | Freestream pressure for coefficient calculation | no |
UInf | Freestream velocity for coefficient calculation | no |
rhoInf | Freestream density for coefficient calculation | no |
resultName | Name of derived pressure field | no | auto generated
log | log to standard output | no | yes
\endtable
SourceFiles
@ -114,6 +116,7 @@ SourceFiles
#include "volFieldsFwd.H"
#include "dimensionedScalar.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -152,6 +155,12 @@ class pressureTools
//- Name of density field, default is "rho"
word rhoName_;
//- Result name
word resultName_;
//- Switch to send output to Info as well as to file
Switch log_;
// Total pressure calculation
@ -176,13 +185,13 @@ class pressureTools
//- Freestream density
scalar rhoInf_;
//- Flag to show whether rhoInf has been initialised
bool rhoInfInitialised_;
// Private Member Functions
//- Return the name of the derived pressure field
word pName() const;
//- Return the density scaling if supplied with kinematic pressure
//- Return the density scale
dimensionedScalar rhoScale(const volScalarField& p) const;
//- Return the density field

View File

@ -186,7 +186,8 @@ Foam::scalarTransport::scalarTransport
resetOnStartUp_(false),
nCorr_(0),
autoSchemes_(false),
fvOptions_(mesh_)
fvOptions_(mesh_),
log_(true)
{
read(dict);
@ -209,11 +210,13 @@ void Foam::scalarTransport::read(const dictionary& dict)
{
if (active_)
{
Info<< type() << ":" << nl;
log_.readIfPresent("log", dict);
phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
UName_ = dict.lookupOrDefault<word>("UName", "U");
rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho");
if (log_) Info<< type() << " " << name_ << " output:" << nl;
dict.readIfPresent("phiName", phiName_);
dict.readIfPresent("UName", UName_);
dict.readIfPresent("rhoName", rhoName_);
userDT_ = false;
if (dict.readIfPresent("DT", DT_))
@ -221,10 +224,8 @@ void Foam::scalarTransport::read(const dictionary& dict)
userDT_ = true;
}
dict.lookup("resetOnStartUp") >> resetOnStartUp_;
dict.readIfPresent("nCorr", nCorr_);
dict.lookup("resetOnStartUp") >> resetOnStartUp_;
dict.lookup("autoSchemes") >> autoSchemes_;
fvOptions_.reset(dict.subDict("fvOptions"));
@ -236,7 +237,7 @@ void Foam::scalarTransport::execute()
{
if (active_)
{
Info<< type() << " output:" << endl;
if (log_) Info<< type() << " " << name_ << " output:" << nl;
const surfaceScalarField& phi =
mesh_.lookupObject<surfaceScalarField>(phiName_);
@ -316,7 +317,7 @@ void Foam::scalarTransport::execute()
<< dimVolume/dimTime << endl;
}
Info<< endl;
if (log_) Info<< endl;
}
}

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 | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -29,9 +29,10 @@ Group
Description
This function object evolves a passive scalar transport equation. The
field in ininitially zero, to which sources are added. The field name
field is initially zero, to which sources are added. The field name
is assigned the name of the function object. Boundary conditions are
automatically applied, based on the velocity boundary conditions.
read from file if the field file is available, or automatically applied
based on the velocity boundary conditions.
- the field can be zeroed on start-up using the resetOnStartUp flag
- to employ the same numerical schemes as the flow velocity, use the
@ -39,10 +40,51 @@ Description
- the diffusivity can be set manually using the DT entry, or retrieved
from the turbulence model (if applicable)
Example of function object specification to solve a scalar transport
equation:
\verbatim
functions
{
scalar1 // <--- NOTE: SCALAR NAME
{
type scalarTransport;
functionObjectLibs ("libutilityFunctionObjects.so");
resetOnStartUp no;
autoSchemes yes;
fvOptions
{
...
}
}
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: scalarTransport | yes |
phiName | Name of flux field | no | phi
UName | Name of velocity field | no | U
rhoName | Name of density field | no | rho
nCorr | Number of correctors | no | 0
DT | Diffision coefficient | no | auto generated
resetOnStartUp | Reset source to zero on start-up | no | no
autoSchemes | Use U schemes to evolve scalar | no | yes
fvOptions | List of scalar sources | yes |
log | Log to standard output | no | yes
\endtable
SeeAlso
fvOption.H
fvOptionList.H
SourceFiles
scalarTransport.C
IOscalarTransport.H
\*---------------------------------------------------------------------------*/
#ifndef scalarTransport_H
@ -108,6 +150,9 @@ class scalarTransport
//- Run-time selectable finite volume options, e.g. sources, constraints
fv::optionList fvOptions_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions

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
@ -116,7 +116,7 @@ bool Foam::setTimeStepFunctionObject::adjustTimeStep()
bool Foam::setTimeStepFunctionObject::read(const dictionary& dict)
{
enabled_ = dict.lookupOrDefault("enabled", true);
enabled_.readIfPresent("enabled", dict);
if (enabled_)
{
@ -133,7 +133,7 @@ bool Foam::setTimeStepFunctionObject::read(const dictionary& dict)
)
{
FatalIOErrorIn("setTimeStep::read(const dictionary&)", dict)
<< "Need to have 'adjustTimeStep' true to enable external"
<< "'adjustTimeStep' must be set to true to enable external"
<< " timestep control" << exit(FatalIOError);
}
}

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
@ -28,12 +28,30 @@ Group
grpUtilitiesFunctionObjects
Description
Overrides the timeStep. Can only be used with
solvers with adjustTimeStep control (e.g. pimpleFoam). Makes no attempt
to cooperate with other timeStep 'controllers' (maxCo, other
functionObjects). Supports 'enabled' flag but none of othe other ones
This function object overrides the calculation time step. Can only be used
with solvers with adjustTimeStep control (e.g. pimpleFoam). It makes no
attempt to co-operate with other time step 'controllers', e.g. maxCo, other
functionObjects. Supports 'enabled' flag but none of the other options
'timeStart', 'timeEnd', 'outputControl' etc.
Example of function object specification to manipulate the time step:
\verbatim
setTimeStep1
{
type setTimeStep;
functionObjectLibs ("libutilityFunctionObjects.so");
...
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: setTimeStep | yes |
enabled | On/off switch | no | yes
\endtable
SourceFiles
setTimeStepFunctionObject.C
@ -45,6 +63,7 @@ SourceFiles
#include "functionObject.H"
#include "dictionary.H"
#include "DataEntry.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -68,7 +87,7 @@ class setTimeStepFunctionObject
// Optional user inputs
//- Switch for the execution - defaults to 'yes/on'
bool enabled_;
Switch enabled_;
//- Time step
autoPtr<DataEntry<scalar> > timeStepPtr_;
@ -82,6 +101,7 @@ class setTimeStepFunctionObject
public:
//- Runtime type information
TypeName("setTimeStep");
@ -121,7 +141,6 @@ public:
//- Switch the function object off
virtual void off();
//- Called at the start of the time-loop
virtual bool start();
@ -145,7 +164,6 @@ public:
//- Update for changes of mesh
virtual void movePoints(const polyMesh& mesh);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

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.
@ -52,7 +52,8 @@ void Foam::timeActivatedFileUpdate::updateFile()
if (i > lastIndex_)
{
Info<< nl << type() << ": copying file" << nl << timeVsFile_[i].second()
if (log_) Info
<< nl << type() << ": copying file" << nl << timeVsFile_[i].second()
<< nl << "to:" << nl << fileToUpdate_ << nl << endl;
cp(timeVsFile_[i].second(), fileToUpdate_);
@ -74,9 +75,10 @@ Foam::timeActivatedFileUpdate::timeActivatedFileUpdate
name_(name),
obr_(obr),
active_(true),
fileToUpdate_(dict.lookup("fileToUpdate")),
fileToUpdate_("unknown-fileToUpdate"),
timeVsFile_(),
lastIndex_(-1)
lastIndex_(-1),
log_(true)
{
read(dict);
}
@ -94,13 +96,18 @@ void Foam::timeActivatedFileUpdate::read(const dictionary& dict)
{
if (active_)
{
log_.readIfPresent("log", dict);
dict.lookup("fileToUpdate") >> fileToUpdate_;
dict.lookup("timeVsFile") >> timeVsFile_;
lastIndex_ = -1;
fileToUpdate_.expand();
Info<< type() << ": time vs file list:" << nl;
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " time vs file list:" << endl;
forAll(timeVsFile_, i)
{
timeVsFile_[i].second() = timeVsFile_[i].second().expand();
@ -111,10 +118,11 @@ void Foam::timeActivatedFileUpdate::read(const dictionary& dict)
<< nl << exit(FatalError);
}
Info<< " " << timeVsFile_[i].first() << tab
if (log_) Info
<< " " << timeVsFile_[i].first() << tab
<< timeVsFile_[i].second() << endl;
}
Info<< endl;
if (log_) Info<< endl;
updateFile();
}

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
@ -28,18 +28,16 @@ Group
grpUtilitiesFunctionObjects
Description
Performs a file copy/replacement once a specified time has been reached.
This function object performs a file copy/replacement once a specified
time has been reached.
Example usage to update the fvSolution dictionary at various times
throughout the calculation:
\verbatim
fileUpdate1
{
type timeActivatedFileUpdate;
functionObjectLibs ("libutilityFunctionObjects.so");
outputControl timeStep;
outputInterval 1;
fileToUpdate "$FOAM_CASE/system/fvSolution";
timeVsFile
(
@ -48,9 +46,20 @@ Description
(0.20 "$FOAM_CASE/system/fvSolution.20")
(0.35 "$FOAM_CASE/system/fvSolution.35")
);
...
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: timeActivatedFileUpdate | yes |
fileToUpdate | Name of file to update | yes |
timeVsFile | List of time vs file | yes |
log | Log to standard output | no | yes
\endtable
SourceFiles
timeActivatedFileUpdate.C
IOtimeActivatedFileUpdate.H
@ -61,6 +70,7 @@ SourceFiles
#define timeActivatedFileUpdate_H
#include "Tuple2.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -99,6 +109,9 @@ class timeActivatedFileUpdate
//- Index of last file copied
label lastIndex_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions

View File

@ -102,7 +102,8 @@ Foam::turbulenceFields::turbulenceFields
name_(name),
obr_(obr),
active_(true),
fieldSet_()
fieldSet_(),
log_(true)
{
// Check if the available mesh is an fvMesh otherise deactivate
if (isA<fvMesh>(obr_))
@ -139,21 +140,26 @@ void Foam::turbulenceFields::read(const dictionary& dict)
{
if (active_)
{
log_.readIfPresent("log", dict);
fieldSet_.insert(wordList(dict.lookup("fields")));
Info<< type() << " " << name_ << ": ";
if (fieldSet_.size())
if (log_)
{
Info<< "storing fields:" << nl;
forAllConstIter(wordHashSet, fieldSet_, iter)
Info<< type() << " " << name_ << " output:" << nl;
if (fieldSet_.size())
{
Info<< " " << modelName << ':' << iter.key() << nl;
Info<< "storing fields:" << nl;
forAllConstIter(wordHashSet, fieldSet_, iter)
{
Info<< " " << modelName << ':' << iter.key() << nl;
}
Info<< endl;
}
else
{
Info<< "no fields requested to be stored" << nl << endl;
}
Info<< endl;
}
else
{
Info<< "no fields requested to be stored" << nl << endl;
}
}
}

View File

@ -25,7 +25,7 @@ Class
Foam::turbulenceFields
Group
grpFieldFunctionObjects
grpUtilitiesFunctionObjects
Description
This function object stores turbulence fields on the mesh database for
@ -89,6 +89,7 @@ SourceFiles
#include "IOobject.H"
#include "NamedEnum.H"
#include "volFieldsFwd.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -151,6 +152,9 @@ protected:
//- Fields to load
wordHashSet fieldSet_;
//- Switch to send output to Info as well as to file
Switch log_;
// Protected Member Functions

View File

@ -50,7 +50,8 @@ Foam::vorticity::vorticity
obr_(obr),
active_(true),
UName_("U"),
outputName_(typeName)
resultName_(name),
log_(true)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -81,7 +82,7 @@ Foam::vorticity::vorticity
(
IOobject
(
outputName_,
resultName_,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
@ -109,10 +110,16 @@ void Foam::vorticity::read(const dictionary& dict)
{
if (active_)
{
UName_ = dict.lookupOrDefault<word>("UName", "U");
if (UName_ != "U")
log_.readIfPresent("log", dict);
dict.readIfPresent("UName", UName_);
if (!dict.readIfPresent("resultName", resultName_))
{
outputName_ = typeName + "(" + UName_ + ")";
resultName_ = name_;
if (UName_ != "U")
{
resultName_ = resultName_ + "(" + UName_ + ")";
}
}
}
}
@ -127,7 +134,7 @@ void Foam::vorticity::execute()
volVectorField& vorticity =
const_cast<volVectorField&>
(
obr_.lookupObject<volVectorField>(outputName_)
obr_.lookupObject<volVectorField>(resultName_)
);
vorticity = fvc::curl(U);
@ -155,9 +162,10 @@ void Foam::vorticity::write()
if (active_)
{
const volVectorField& vorticity =
obr_.lookupObject<volVectorField>(outputName_);
obr_.lookupObject<volVectorField>(resultName_);
Info<< type() << " " << name_ << " output:" << nl
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << vorticity.name() << nl
<< endl;

View File

@ -28,7 +28,29 @@ Group
grpUtilitiesFunctionObjects
Description
This function object calculates the vorticity, the curl of the velocity.
This function object calculates and outputs the vorticity, the curl of
the velocity as a volvectorField. The field is stored on the mesh
database so that it can be retrieved and used for other applications.
Example of function object specification to calculate the vorticity:
\verbatim
vorticity1
{
type vorticity;
functionObjectLibs ("libutilityFunctionObjects.so");
...
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: vorticity | yes |
UName | Name of velocity field | no | U
resultName | Name of Courant number field | no | \<function name\>
log | Log to standard output | no | yes
\endtable
SourceFiles
vorticity.C
@ -40,6 +62,7 @@ SourceFiles
#define vorticity_H
#include "volFieldsFwd.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -73,7 +96,10 @@ class vorticity
word UName_;
//- Name of vorticity field
word outputName_;
word resultName_;
//- Switch to send output to Info as well as to file
Switch log_;
// Private Member Functions

View File

@ -80,11 +80,9 @@ void Foam::wallShearStress::calcShearStress
<< token::TAB << maxSsp
<< endl;
if (log_)
{
Info<< " min/max(" << pp.name() << ") = "
<< minSsp << ", " << maxSsp << endl;
}
if (log_) Info
<< " min/max(" << pp.name() << ") = "
<< minSsp << ", " << maxSsp << endl;
}
}
@ -296,12 +294,10 @@ void Foam::wallShearStress::write()
const volVectorField& wallShearStress =
obr_.lookupObject<volVectorField>(resultName_);
if (log_)
{
Info<< type() << " " << name_ << " output:" << nl
<< " writing field " << wallShearStress.name() << nl
<< endl;
}
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << wallShearStress.name() << nl
<< endl;
wallShearStress.write();
}

View File

@ -61,7 +61,7 @@ Description
\table
Property | Description | Required | Default value
type | type name: wallShearStress | yes |
resultName | Name of wall shear stress field | no | <function name>
resultName | Name of wall shear stress field | no | \<function name\>
patches | list of patches to process | no | all wall patches
log | Log to standard output | no | yes
\endtable

View File

@ -229,13 +229,10 @@ void Foam::yPlus::write()
const volScalarField& yPlus =
obr_.lookupObject<volScalarField>(resultName_);
if (log_)
{
Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << yPlus.name() << nl
<< endl;
}
if (log_) Info
<< type() << " " << name_ << " output:" << nl
<< " writing field " << yPlus.name() << nl
<< endl;
yPlus.write();
}

View File

@ -69,12 +69,9 @@ void Foam::yPlus::calcYPlus
const scalar maxYplus = gMax(yPlusp);
const scalar avgYplus = gAverage(yPlusp);
if (log_)
{
Info<< " patch " << patch.name()
<< " y+ : min = " << minYplus << ", max = " << maxYplus
<< ", average = " << avgYplus << nl;
}
if (log_) Info<< " patch " << patch.name()
<< " y+ : min = " << minYplus << ", max = " << maxYplus
<< ", average = " << avgYplus << nl;
file() << obr_.time().value()
<< token::TAB << patch.name()