GIT: conflict resolution

This commit is contained in:
andy
2012-09-26 12:13:44 +01:00
636 changed files with 20768 additions and 5580 deletions

View File

@ -4,6 +4,9 @@ partialWrite/partialWriteFunctionObject.C
removeRegisteredObject/removeRegisteredObject.C
removeRegisteredObject/removeRegisteredObjectFunctionObject.C
writeDictionary/writeDictionary.C
writeDictionary/writeDictionaryFunctionObject.C
writeRegisteredObject/writeRegisteredObject.C
writeRegisteredObject/writeRegisteredObjectFunctionObject.C

View File

@ -22,24 +22,24 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::IOpressureCoefficient
Foam::IOwriteDictionary
Description
Instance of the generic IOOutputFilter for pressureCoefficient.
Instance of the generic IOOutputFilter for writeDictionary.
\*---------------------------------------------------------------------------*/
#ifndef IOpressureCoefficient_H
#define IOpressureCoefficient_H
#ifndef IOwriteDictionary_H
#define IOwriteDictionary_H
#include "pressureCoefficient.H"
#include "writeDictionary.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<pressureCoefficient> IOpressureCoefficient;
typedef IOOutputFilter<writeDictionary> IOwriteDictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,199 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "writeDictionary.H"
#include "dictionary.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::writeDictionary, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::writeDictionary::tryFolder
(
const label dictI,
const word& location,
bool& firstDict
)
{
IOobject dictIO
(
dictNames_[dictI],
location,
obr_,
IOobject::MUST_READ
);
if (dictIO.headerOk())
{
IOdictionary dict(dictIO);
if (dict.digest() != digests_[dictI])
{
if (firstDict)
{
Info<< type() << " output:" << nl << endl;
IOobject::writeDivider(Info);
Info<< endl;
firstDict = false;
}
Info<< dict.dictName() << dict << nl;
IOobject::writeDivider(Info);
digests_[dictI] = dict.digest();
}
return true;
}
return false;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::writeDictionary::writeDictionary
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
name_(name),
obr_(obr),
dictNames_(),
digests_()
{
read(dict);
execute();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::writeDictionary::~writeDictionary()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::writeDictionary::read(const dictionary& dict)
{
dict.lookup("dictNames") >> dictNames_;
digests_.setSize(dictNames_.size(), SHA1Digest());
Info<< type() << ": monitoring dictionaries:" << nl;
if (dictNames_.size())
{
forAll(dictNames_, i)
{
Info<< " " << dictNames_[i] << endl;
}
}
else
{
Info<< " none" << nl;
}
Info<< endl;
}
void Foam::writeDictionary::execute()
{
bool firstDict = true;
forAll(dictNames_, i)
{
if (obr_.foundObject<dictionary>(dictNames_[i]))
{
const dictionary& dict =
obr_.lookupObject<dictionary>(dictNames_[i]);
if (dict.digest() != digests_[i])
{
if (firstDict)
{
Info<< type() << " output:" << nl << endl;
IOobject::writeDivider(Info);
Info<< endl;
firstDict = false;
}
digests_[i] = dict.digest();
Info<< dict.dictName() << dict << nl;
IOobject::writeDivider(Info);
Info<< endl;
}
}
else
{
bool processed = tryFolder(i, obr_.time().timeName(), firstDict);
if (!processed)
{
processed = tryFolder(i, obr_.time().constant(), firstDict);
}
if (!processed)
{
processed = tryFolder(i, obr_.time().system(), firstDict);
}
if (!processed)
{
Info<< " Unable to locate dictionary " << dictNames_[i]
<< nl << endl;
}
else
{
Info<< endl;
}
}
}
}
void Foam::writeDictionary::end()
{
// do nothing
}
void Foam::writeDictionary::write()
{
// do nothing
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,27 +22,27 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::staticPressure
Foam::writeDictionary
Group
grpUtilitiesFunctionObjects
Description
Converts kinematic pressure to static pressure, from the name of the
pressure field, and density, i.e.
p_static = density*p_kinematic
This function object writes dictionaries on start-up, and on change
SourceFiles
staticPressure.C
IOstaticPressure.H
writeDictionary.C
IOwriteDictionary.H
\*---------------------------------------------------------------------------*/
#ifndef staticPressure_H
#define staticPressure_H
#ifndef writeDictionary_H
#define writeDictionary_H
#include "pointFieldFwd.H"
#include "wordList.H"
#include "runTimeSelectionTables.H"
#include "SHA1Digest.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -55,51 +55,56 @@ class dictionary;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class staticPressure Declaration
Class writeDictionary Declaration
\*---------------------------------------------------------------------------*/
class staticPressure
class writeDictionary
{
protected:
// Private data
//- Name of this set of staticPressure objects
//- Name of this set of writeDictionary
word name_;
//- Reference to the database
const objectRegistry& obr_;
//- on/off switch
bool active_;
//- Names of dictionaries to monitor
wordList dictNames_;
//- Name of pressure field, default is "p"
word pName_;
//- Density value
scalar rho_;
//- List of changed dictionaries (only those registered to database)
List<SHA1Digest> digests_;
// Private Member Functions
//- Return true if the pressure field corresponds to kinematic pressure
bool isKinematicPressure();
//- Helper function to write the dictionary if found at location
bool tryFolder
(
const label dictI,
const word& location,
bool& firstDict
);
//- Disallow default bitwise copy construct
staticPressure(const staticPressure&);
writeDictionary(const writeDictionary&);
//- Disallow default bitwise assignment
void operator=(const staticPressure&);
void operator=(const writeDictionary&);
public:
//- Runtime type information
TypeName("staticPressure");
TypeName("writeDictionary");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
staticPressure
writeDictionary
(
const word& name,
const objectRegistry&,
@ -109,18 +114,18 @@ public:
//- Destructor
virtual ~staticPressure();
virtual ~writeDictionary();
// Member Functions
//- Return name of the set of staticPressure
//- Return name of the writeDictionary
virtual const word& name() const
{
return name_;
}
//- Read the staticPressure data
//- Read the writeDictionary data
virtual void read(const dictionary&);
//- Execute, currently does nothing
@ -129,7 +134,7 @@ public:
//- Execute at the final time-loop, currently does nothing
virtual void end();
//- Calculate the staticPressure and write
//- Write the writeDictionary
virtual void write();
//- Update for changes of mesh

View File

@ -23,18 +23,18 @@ License
\*---------------------------------------------------------------------------*/
#include "pressureCoefficientFunctionObject.H"
#include "writeDictionaryFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(pressureCoefficientFunctionObject, 0);
defineNamedTemplateTypeNameAndDebug(writeDictionaryFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
pressureCoefficientFunctionObject,
writeDictionaryFunctionObject,
dictionary
);
}

View File

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::writeDictionaryFunctionObject
Description
FunctionObject wrapper around writeDictionary to allow them to be
created via the functions entry within controlDict.
SourceFiles
writeDictionaryFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef writeDictionaryFunctionObject_H
#define writeDictionaryFunctionObject_H
#include "writeDictionary.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<writeDictionary>
writeDictionaryFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -96,7 +96,7 @@ void Foam::fieldMinMax::calcMinMaxFields
}
fieldMinMaxFilePtr_()
<< token::TAB << maxValue << token::TAB << maxC;
<< token::TAB << maxValue << token::TAB << maxC;
if (Pstream::parRun())
{

View File

@ -29,6 +29,8 @@ License
#include "emptyPolyPatch.H"
#include "coupledPolyPatch.H"
#include "sampledSurface.H"
#include "mergePoints.H"
#include "indirectPrimitivePatch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -222,6 +224,127 @@ void Foam::fieldValues::faceSource::sampledSurfaceFaces(const dictionary& dict)
}
void Foam::fieldValues::faceSource::combineSurfaceGeometry
(
faceList& faces,
pointField& points
) const
{
List<faceList> allFaces(Pstream::nProcs());
List<pointField> allPoints(Pstream::nProcs());
labelList globalFacesIs(faceId_);
forAll(globalFacesIs, i)
{
if (facePatchId_[i] != -1)
{
label patchI = facePatchId_[i];
globalFacesIs[i] += mesh().boundaryMesh()[patchI].start();
}
}
// Add local faces and points to the all* lists
indirectPrimitivePatch pp
(
IndirectList<face>(mesh().faces(), globalFacesIs),
mesh().points()
);
allFaces[Pstream::myProcNo()] = pp.localFaces();
allPoints[Pstream::myProcNo()] = pp.localPoints();
Pstream::gatherList(allFaces);
Pstream::gatherList(allPoints);
// Renumber and flatten
label nFaces = 0;
label nPoints = 0;
forAll(allFaces, procI)
{
nFaces += allFaces[procI].size();
nPoints += allPoints[procI].size();
}
faces.setSize(nFaces);
points.setSize(nPoints);
nFaces = 0;
nPoints = 0;
// My own data first
{
const faceList& fcs = allFaces[Pstream::myProcNo()];
forAll(fcs, i)
{
const face& f = fcs[i];
face& newF = faces[nFaces++];
newF.setSize(f.size());
forAll(f, fp)
{
newF[fp] = f[fp] + nPoints;
}
}
const pointField& pts = allPoints[Pstream::myProcNo()];
forAll(pts, i)
{
points[nPoints++] = pts[i];
}
}
// Other proc data follows
forAll(allFaces, procI)
{
if (procI != Pstream::myProcNo())
{
const faceList& fcs = allFaces[procI];
forAll(fcs, i)
{
const face& f = fcs[i];
face& newF = faces[nFaces++];
newF.setSize(f.size());
forAll(f, fp)
{
newF[fp] = f[fp] + nPoints;
}
}
const pointField& pts = allPoints[procI];
forAll(pts, i)
{
points[nPoints++] = pts[i];
}
}
}
// Merge
labelList oldToNew;
pointField newPoints;
bool hasMerged = mergePoints
(
points,
SMALL,
false,
oldToNew,
newPoints
);
if (hasMerged)
{
if (debug)
{
Pout<< "Merged from " << points.size()
<< " down to " << newPoints.size() << " points" << endl;
}
points.transfer(newPoints);
forAll(faces, i)
{
inplaceRenumber(oldToNew, faces[i]);
}
}
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
@ -291,6 +414,14 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
}
Info<< nl << endl;
if (valueOutput_)
{
surfaceWriterPtr_.reset
(
surfaceWriter::New(dict.lookup("surfaceFormat")).ptr()
);
}
}
@ -355,6 +486,7 @@ Foam::fieldValues::faceSource::faceSource
)
:
fieldValue(name, obr, dict, loadFromFiles),
surfaceWriterPtr_(NULL),
source_(sourceTypeNames_.read(dict.lookup("source"))),
operation_(operationTypeNames_.read(dict.lookup("operation"))),
weightFieldName_("none"),

View File

@ -45,7 +45,8 @@ Description
functionObjectLibs ("libfieldFunctionObjects.so");
...
log yes;
valueOutput yes;
valueOutput true;
surfaceFormat none;
source faceZone;
sourceName f0;
operation sum;
@ -64,7 +65,8 @@ Description
Property | Description | Required | Default value
type | type name: faceSource | yes |
log | write data to standard output | no | no
valueOutput | write the raw output values | yes |
valueOutput | write the output values | yes |
surfaceFormat | output value format | no |
source | face source: see below | yes |
sourceName | name of face source if required | no |
operation | operation to perform | yes |
@ -132,6 +134,7 @@ SourceFiles
#include "fieldValue.H"
#include "surfaceFieldsFwd.H"
#include "volFieldsFwd.H"
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -201,11 +204,21 @@ private:
//- Set faces according to sampledSurface
void sampledSurfaceFaces(const dictionary&);
//- Combine faces and points from multiple processors
void combineSurfaceGeometry
(
faceList& faces,
pointField& points
) const;
protected:
// Protected data
//- Surface writer
autoPtr<surfaceWriter> surfaceWriterPtr_;
//- Source type
sourceType source_;
@ -219,7 +232,7 @@ protected:
label nFaces_;
// If operating on mesh faces (faceZone,patch)
// If operating on mesh faces (faceZone, patch)
//- Local list of face IDs
labelList faceId_;
@ -231,6 +244,7 @@ protected:
// (1 use as is, -1 negate)
labelList faceSign_;
// If operating on sampledSurface
//- underlying sampledSurface

View File

@ -254,31 +254,46 @@ bool Foam::fieldValues::faceSource::writeValues(const word& fieldName)
combineFields(Sf);
combineFields(weightField);
// Write raw values on surface if specified
if (surfaceWriterPtr_.valid())
{
faceList faces;
pointField points;
combineSurfaceGeometry(faces, points);
fileName outputDir;
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
outputDir = obr_.time().path()/".."/name_;
}
else
{
outputDir = obr_.time().path()/name_;
}
outputDir = outputDir/"surface"/obr_.time().timeName();
surfaceWriterPtr_->write
(
outputDir,
word(sourceTypeNames_[source_]) + "_" + sourceName_,
points,
faces,
fieldName,
values,
false
);
}
// apply weight field
values *= weightField;
if (Pstream::master())
{
Type result = processValues(values, Sf, weightField);
if (valueOutput_)
{
IOField<Type>
(
IOobject
(
fieldName + "_" + sourceTypeNames_[source_] + "-"
+ sourceName_,
obr_.time().timeName(),
obr_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
values
).write();
}
outputFilePtr_()<< tab << result;
if (log_)

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -27,6 +27,7 @@ License
#include "dictionary.H"
#include "Time.H"
#include "Pstream.H"
#include "IOmanip.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -89,7 +90,8 @@ void Foam::forceCoeffs::writeFileHeader()
if (forcesFilePtr_.valid())
{
forcesFilePtr_()
<< "# Time" << tab << "Cd" << tab << "Cl" << tab << "Cm" << endl;
<< "# Time" << tab << "Cm" << tab << "Cd" << tab << "Cl" << tab
<< "Cl(f)" << "Cl(r)" << endl;
}
}
@ -112,37 +114,77 @@ void Foam::forceCoeffs::write()
{
// Create the forces file if not already created
makeFile();
forcesMoments fm = forces::calcForcesMoment();
scalar pDyn = 0.5*rhoRef_*magUInf_*magUInf_;
vector totForce = fm.first().first() + fm.first().second();
vector totMoment = fm.second().first() + fm.second().second();
scalar liftForce = totForce & liftDir_;
scalar dragForce = totForce & dragDir_;
scalar pitchMoment = totMoment & pitchAxis_;
scalar Cl = liftForce/(Aref_*pDyn);
scalar Cd = dragForce/(Aref_*pDyn);
scalar Cm = pitchMoment/(Aref_*lRef_*pDyn);
forces::calcForcesMoment();
if (Pstream::master())
{
scalar pDyn = 0.5*rhoRef_*magUInf_*magUInf_;
Field<vector> totForce(force_[0] + force_[1]);
Field<vector> totMoment(moment_[0] + moment_[1]);
List<Field<scalar> > coeffs(3);
coeffs[0].setSize(nBin_);
coeffs[1].setSize(nBin_);
coeffs[2].setSize(nBin_);
// lift, drag and moment
coeffs[0] = (totForce & liftDir_)/(Aref_*pDyn);
coeffs[1] = (totForce & dragDir_)/(Aref_*pDyn);
coeffs[2] = (totMoment & pitchAxis_)/(Aref_*lRef_*pDyn);
scalar Cl = sum(coeffs[0]);
scalar Cd = sum(coeffs[1]);
scalar Cm = sum(coeffs[2]);
scalar Clf = Cl/2.0 - Cm;
scalar Clr = Cl/2.0 + Cm;
forcesFilePtr_()
<< obr_.time().value() << tab
<< Cd << tab << Cl << tab << Cm << endl;
<< Cm << tab << Cd << tab << Cl << tab << Clf << tab << Clr
<< endl;
if (log_)
{
Info<< "forceCoeffs output:" << nl
Info<< type() << " output:" << nl
<< " Cm = " << Cm << nl
<< " Cd = " << Cd << nl
<< " Cl = " << Cl << nl
<< " Cl(f) = " << Cl/2.0 - Cm << nl
<< " Cl(r) = " << Cl/2.0 + Cm << nl
<< endl;
<< " Cl(f) = " << Clf << nl
<< " Cl(r) = " << Clr << endl;
}
if (nBin_ > 1)
{
autoPtr<writer<scalar> >
binWriterPtr(writer<scalar>::New(binFormat_));
wordList fieldNames(IStringStream("(lift drag moment)")());
coordSet axis
(
"forceCoeffs",
"distance",
binPoints_,
mag(binPoints_)
);
fileName forcesDir =
baseFileDir()/"bins"/obr_.time().timeName();
mkDir(forcesDir);
if (log_)
{
Info<< " Writing bins to " << forcesDir << endl;
}
OFstream osCoeffs(forcesDir/"forceCoeffs");
binWriterPtr->write(axis, fieldNames, coeffs, osCoeffs);
}
if (log_)
{
Info<< endl;
}
}
}

View File

@ -29,7 +29,8 @@ Group
Description
This function object extends the Foam::forces function object by providing
lift, drag and moment coefficients.
lift, drag and moment coefficients. The data can optionally be output into
bins, defined in a given direction.
Example of function object specification:
\verbatim
@ -46,6 +47,9 @@ Description
magUInf 100;
lRef 3.5;
ARef 2.2;
nBin 20;
binDir (1 0 0);
binFormat gnuplot;
}
\endverbatim
@ -61,6 +65,9 @@ Description
magUInf | free stream velocity magnitude | yes |
lRef | reference length scale for moment calculations | yes |
ARef | reference area | yes |
nBin | number of data bins | no |
binDir | direction along which bins are defined | no |
binFormat | output format for bin data | no |
\endtable
SeeAlso
@ -121,6 +128,12 @@ class forceCoeffs
scalar Aref_;
// Bin information
//- Writer for bin data
autoPtr<writer<scalar> > binWriterPtr_;
// Private Member Functions
//- Disallow default bitwise copy construct

View File

@ -43,7 +43,78 @@ License
defineTypeNameAndDebug(Foam::forces, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::fileName Foam::forces::baseFileDir() const
{
fileName baseDir;
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
baseDir = obr_.time().path()/".."/name_;
}
else
{
baseDir = obr_.time().path()/name_;
}
return baseDir;
}
void Foam::forces::makeFile()
{
// Create the forces file if not already created
if (forcesFilePtr_.empty())
{
if (debug)
{
Info<< "Creating forces file" << endl;
}
// File update
if (Pstream::master())
{
word startTimeName =
obr_.time().timeName(obr_.time().startTime().value());
fileName forcesDir = baseFileDir()/startTimeName;
// Create directory if does not exist.
mkDir(forcesDir);
// Open new file at start up
forcesFilePtr_.reset(new OFstream(forcesDir/(type() + ".dat")));
// Add headers to output data
writeFileHeader();
}
}
}
void Foam::forces::writeFileHeader()
{
if (forcesFilePtr_.valid())
{
forcesFilePtr_()
<< "# Time" << tab
<< "forces(pressure, viscous) moment(pressure, viscous)";
if (localSystem_)
{
forcesFilePtr_()
<< tab
<< "local forces(pressure, viscous) "
<< "local moment(pressure, viscous)";
}
forcesFilePtr_()<< endl;
}
}
Foam::tmp<Foam::volSymmTensorField> Foam::forces::devRhoReff() const
{
@ -167,6 +238,85 @@ Foam::scalar Foam::forces::rho(const volScalarField& p) const
}
void Foam::forces::applyBins
(
const label patchI,
const vectorField fN,
const vectorField Md,
const vectorField fT
)
{
if (nBin_ == 1)
{
force_[0][0] = sum(fN);
force_[1][0] = sum(fT);
moment_[0][0] = sum(Md ^ fN);
moment_[1][0] = sum(Md ^ fT);
}
else
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
const vectorField& Cf = mesh.C().boundaryField()[patchI];
scalarField d((Cf & binDir_) - binMin_);
forAll(d, i)
{
label binI = floor(d[i]/binDx_);
force_[0][binI] += fN[i];
force_[1][binI] += fT[i];
moment_[0][binI] += Md[i]^fN[i];
moment_[1][binI] += Md[i]^fT[i];
}
}
}
void Foam::forces::writeBins() const
{
if (nBin_ == 1)
{
return;
}
autoPtr<writer<vector> > binWriterPtr(writer<vector>::New(binFormat_));
coordSet axis("forces", "distance", binPoints_, mag(binPoints_));
fileName forcesDir = baseFileDir()/"bins"/obr_.time().timeName();
mkDir(forcesDir);
if (log_)
{
Info<< " Writing bins to " << forcesDir << endl;
}
wordList fieldNames(IStringStream("(pressure viscous)")());
OFstream osForce(forcesDir/"force");
binWriterPtr->write(axis, fieldNames, force_, osForce);
OFstream osMoment(forcesDir/"moment");
binWriterPtr->write(axis, fieldNames, moment_, osMoment);
if (localSystem_)
{
List<Field<vector> > localForce(2);
List<Field<vector> > localMoment(2);
localForce[0] = coordSys_.localVector(force_[0]);
localForce[1] = coordSys_.localVector(force_[1]);
localMoment[0] = coordSys_.localVector(moment_[0]);
localMoment[1] = coordSys_.localVector(moment_[1]);
OFstream osLocalForce(forcesDir/"force_local");
binWriterPtr->write(axis, fieldNames, localForce, osLocalForce);
OFstream osLocalMoment(forcesDir/"moment_local");
binWriterPtr->write(axis, fieldNames, localMoment, osLocalMoment);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::forces::forces
@ -181,6 +331,8 @@ Foam::forces::forces
obr_(obr),
active_(true),
log_(false),
force_(2),
moment_(2),
patchSet_(),
pName_(word::null),
UName_(word::null),
@ -191,6 +343,12 @@ Foam::forces::forces
pRef_(0),
coordSys_(),
localSystem_(false),
nBin_(1),
binDir_(vector::zero),
binDx_(0.0),
binMin_(GREAT),
binPoints_(),
binFormat_("undefined"),
forcesFilePtr_(NULL)
{
// Check if the available mesh is an fvMesh otherise deactivate
@ -231,6 +389,8 @@ Foam::forces::forces
obr_(obr),
active_(true),
log_(false),
force_(2),
moment_(2),
patchSet_(patchSet),
pName_(pName),
UName_(UName),
@ -241,6 +401,12 @@ Foam::forces::forces
pRef_(pRef),
coordSys_(coordSys),
localSystem_(false),
nBin_(1),
binDir_(vector::zero),
binDx_(0.0),
binMin_(GREAT),
binPoints_(),
binFormat_("undefined"),
forcesFilePtr_(NULL)
{}
@ -261,11 +427,9 @@ void Foam::forces::read(const dictionary& dict)
directForceDensity_ = dict.lookupOrDefault("directForceDensity", false);
const fvMesh& mesh = refCast<const fvMesh>(obr_);
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
patchSet_ = mesh.boundaryMesh().patchSet
(
wordReList(dict.lookup("patches"))
);
patchSet_ = pbm.patchSet(wordReList(dict.lookup("patches")));
if (directForceDensity_)
{
@ -334,68 +498,77 @@ void Foam::forces::read(const dictionary& dict)
coordSys_ = coordinateSystem(dict, obr_);
localSystem_ = true;
}
}
}
void Foam::forces::makeFile()
{
// Create the forces file if not already created
if (forcesFilePtr_.empty())
{
if (debug)
// read bin information if present
if (dict.readIfPresent<label>("nBin", nBin_))
{
Info<< "Creating forces file." << endl;
}
// File update
if (Pstream::master())
{
fileName forcesDir;
word startTimeName =
obr_.time().timeName(obr_.time().startTime().value());
if (Pstream::parRun())
if (nBin_ < 0)
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
forcesDir = obr_.time().path()/".."/name_/startTimeName;
FatalIOErrorIn
(
"void Foam::forces::read(const dictionary&)", dict
) << "Number of bins (nBin) must be zero or greater"
<< exit(FatalIOError);
}
else
else if ((nBin_ == 0) || (nBin_ == 1))
{
forcesDir = obr_.time().path()/name_/startTimeName;
nBin_ = 1;
force_[0].setSize(1);
force_[1].setSize(1);
moment_[0].setSize(1);
moment_[1].setSize(1);
}
// Create directory if does not exist.
mkDir(forcesDir);
if (nBin_ > 1)
{
dict.lookup("binDir") >> binDir_;
binDir_ /= mag(binDir_);
// Open new file at start up
forcesFilePtr_.reset(new OFstream(forcesDir/(type() + ".dat")));
binMin_ = GREAT;
scalar binMax = -GREAT;
forAllConstIter(labelHashSet, patchSet_, iter)
{
label patchI = iter.key();
const polyPatch& pp = pbm[patchI];
scalarField d(pp.faceCentres() & binDir_);
binMin_ = min(min(d), binMin_);
binMax = max(max(d), binMax);
}
reduce(binMin_, minOp<scalar>());
reduce(binMax, maxOp<scalar>());
// Add headers to output data
writeFileHeader();
// slightly boost binMax so that region of interest is fully
// within bounds
binMax = 1.0001*(binMax - binMin_) + binMin_;
binDx_ = (binMax - binMin_)/scalar(nBin_);
// create the bin points used for writing
binPoints_.setSize(nBin_);
forAll(binPoints_, i)
{
binPoints_[i] = (i + 0.5)*binDir_*binDx_;
}
dict.lookup("binFormat") >> binFormat_;
// allocate storage for forces and moments
forAll(force_, i)
{
force_[i].setSize(nBin_);
moment_[i].setSize(nBin_);
}
}
}
}
}
void Foam::forces::writeFileHeader()
{
if (forcesFilePtr_.valid())
{
forcesFilePtr_()
<< "# Time" << tab
<< "forces(pressure, viscous) moment(pressure, viscous)";
if (localSystem_)
if (nBin_ == 1)
{
forcesFilePtr_()
<< tab
<< "local forces(pressure, viscous) "
<< "local moment(pressure, viscous)";
// allocate storage for forces and moments
force_[0].setSize(1);
force_[1].setSize(1);
moment_[0].setSize(1);
moment_[1].setSize(1);
}
forcesFilePtr_()<< endl;
}
}
@ -414,71 +587,65 @@ void Foam::forces::end()
void Foam::forces::write()
{
if (active_)
if (!active_)
{
// Create the forces file if not already created
makeFile();
return;
}
forcesMoments fm = calcForcesMoment();
// Create the forces file if not already created
makeFile();
if (Pstream::master())
calcForcesMoment();
if (Pstream::master())
{
if (log_)
{
if (log_)
{
Info<< "forces output:" << nl
<< " forces(pressure, viscous)" << fm.first() << nl
<< " moment(pressure, viscous)" << fm.second() << nl;
}
forcesFilePtr_() << obr_.time().value() << tab << fm;
if (localSystem_)
{
forcesMoments fmLocal;
fmLocal.first().first() =
coordSys_.localVector(fm.first().first());
fmLocal.first().second() =
coordSys_.localVector(fm.first().second());
fmLocal.second().first() =
coordSys_.localVector(fm.second().first());
fmLocal.second().second() =
coordSys_.localVector(fm.second().second());
forcesFilePtr_() << tab << fmLocal;
if (log_)
{
Info<< " local:" << nl
<< " forces(pressure, viscous)" << fmLocal.first()
<< nl
<< " moment(pressure, viscous)" << fmLocal.second()
<< nl;
}
}
forcesFilePtr_() << endl;
if (log_)
{
Info<< endl;
}
Info<< type() << " output:" << nl
<< " forces(pressure,viscous)"
<< "(" << sum(force_[0]) << "," << sum(force_[1]) << ")" << nl
<< " moment(pressure,viscous)"
<< "(" << sum(moment_[0]) << "," << sum(moment_[1]) << ")"
<< nl;
}
forcesFilePtr_() << obr_.time().value() << tab
<< "(" << sum(force_[0]) << "," << sum(force_[1]) << ") "
<< "(" << sum(moment_[0]) << "," << sum(moment_[1]) << ")"
<< endl;
if (localSystem_)
{
vectorField localForceP(coordSys_.localVector(force_[0]));
vectorField localForceV(coordSys_.localVector(force_[1]));
vectorField localMomentP(coordSys_.localVector(moment_[0]));
vectorField localMomentV(coordSys_.localVector(moment_[1]));
forcesFilePtr_() << obr_.time().value() << tab
<< "(" << sum(localForceP) << "," << sum(localForceV) << ") "
<< "(" << sum(localMomentP) << "," << sum(localMomentV) << ")"
<< endl;
}
writeBins();
if (log_)
{
Info<< endl;
}
forcesFilePtr_() << endl;
}
}
Foam::forces::forcesMoments Foam::forces::calcForcesMoment() const
void Foam::forces::calcForcesMoment()
{
forcesMoments fm
(
pressureViscous(vector::zero, vector::zero),
pressureViscous(vector::zero, vector::zero)
);
force_[0] = vector::zero;
force_[1] = vector::zero;
moment_[0] = vector::zero;
moment_[1] = vector::zero;
if (directForceDensity_)
{
@ -491,32 +658,28 @@ Foam::forces::forcesMoments Foam::forces::calcForcesMoment() const
forAllConstIter(labelHashSet, patchSet_, iter)
{
label patchi = iter.key();
label patchI = iter.key();
vectorField Md
(
mesh.C().boundaryField()[patchi] - coordSys_.origin()
mesh.C().boundaryField()[patchI] - coordSys_.origin()
);
scalarField sA(mag(Sfb[patchi]));
scalarField sA(mag(Sfb[patchI]));
// Normal force = surfaceUnitNormal * (surfaceNormal & forceDensity)
// Normal force = surfaceUnitNormal*(surfaceNormal & forceDensity)
vectorField fN
(
Sfb[patchi]/sA
Sfb[patchI]/sA
*(
Sfb[patchi] & fD.boundaryField()[patchi]
Sfb[patchI] & fD.boundaryField()[patchI]
)
);
fm.first().first() += sum(fN);
fm.second().first() += sum(Md ^ fN);
// Tangential force (total force minus normal fN)
vectorField fT(sA*fD.boundaryField()[patchi] - fN);
vectorField fT(sA*fD.boundaryField()[patchI] - fN);
fm.first().second() += sum(fT);
fm.second().second() += sum(Md ^ fT);
applyBins(patchI, fN, Md, fT);
}
}
else
@ -538,28 +701,38 @@ Foam::forces::forcesMoments Foam::forces::calcForcesMoment() const
forAllConstIter(labelHashSet, patchSet_, iter)
{
label patchi = iter.key();
label patchI = iter.key();
vectorField Md
(
mesh.C().boundaryField()[patchi] - coordSys_.origin()
mesh.C().boundaryField()[patchI] - coordSys_.origin()
);
vectorField pf(Sfb[patchi]*(p.boundaryField()[patchi] - pRef));
vectorField pf
(
rho(p)*Sfb[patchI]*(p.boundaryField()[patchI] - pRef)
);
fm.first().first() += rho(p)*sum(pf);
fm.second().first() += rho(p)*sum(Md ^ pf);
vectorField vf(Sfb[patchI] & devRhoReffb[patchI]);
vectorField vf(Sfb[patchi] & devRhoReffb[patchi]);
fm.first().second() += sum(vf);
fm.second().second() += sum(Md ^ vf);
applyBins(patchI, pf, Md, vf);
}
}
reduce(fm, sumOp());
Pstream::listCombineGather(force_, plusEqOp<vectorField>());
Pstream::listCombineGather(moment_, plusEqOp<vectorField>());
}
return fm;
Foam::vector Foam::forces::forceEff() const
{
return sum(force_[0]) + sum(force_[1]);
}
Foam::vector Foam::forces::momentEff() const
{
return sum(moment_[0]) + sum(moment_[1]);
}

View File

@ -43,6 +43,9 @@ Description
...
log yes;
patches (walls);
nBin 20;
binDir (1 0 0);
binFormat gnuplot;
}
\endverbatim
@ -52,6 +55,9 @@ Description
type | type name: forces | yes |
log | write force data to standard output | no | no
patches | patches included in the forces calculation | yes |
nBin | number of data bins | no |
binDir | direction along which bins are defined | no |
binFormat | output format for bin data | no |
pName | pressure field name | no | p
UName | velocity field name | no | U
rhoName | density field name (see below) | no | rho
@ -106,6 +112,7 @@ SourceFiles
#include "OFstream.H"
#include "Switch.H"
#include "pointFieldFwd.H"
#include "writer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -123,46 +130,9 @@ class mapPolyMesh;
class forces
{
public:
// Tuple for pressure (.first()) and viscous (.second()) forces
typedef Tuple2<vector, vector> pressureViscous;
// Tuple for forces (.first()) and moment (.second())
// pressure/viscous forces Tuples.
typedef Tuple2<pressureViscous, pressureViscous> forcesMoments;
//- Sum operation class to accumulate pressure/viscous forces and moments
class sumOp
{
public:
forcesMoments operator()
(
const forcesMoments& fm1,
const forcesMoments& fm2
) const
{
return forcesMoments
(
pressureViscous
(
fm1.first().first() + fm2.first().first(),
fm1.first().second() + fm2.first().second()
),
pressureViscous
(
fm1.second().first() + fm2.second().first(),
fm1.second().second() + fm2.second().second()
)
);
}
};
protected:
// Private data
// Protected data
//- Name of this set of forces,
// Also used as the name of the probes directory.
@ -170,12 +140,19 @@ protected:
const objectRegistry& obr_;
//- on/off switch
//- On/off switch
bool active_;
//- Switch to send output to Info as well as to file
Switch log_;
//- Pressure and viscous force per bin
List<Field<vector> > force_;
//- Pressure and viscous pressure per bin
List<Field<vector> > moment_;
// Read from dictionary
//- Patches to integrate forces over
@ -209,11 +186,35 @@ protected:
bool localSystem_;
// Bin information
//- Number of bins
label nBin_;
//- Direction used to determine bin orientation
vector binDir_;
//- Distance between bin divisions
scalar binDx_;
//- Minimum bin bounds
scalar binMin_;
//- Bin positions along binDir
List<point> binPoints_;
//- Write format for bin data
word binFormat_;
//- Forces/moment file ptr
autoPtr<OFstream> forcesFilePtr_;
// Private Member Functions
// Protected Member Functions
//- Return the base file directory for output
fileName baseFileDir() const;
//- If the forces file has not been created create it
void makeFile();
@ -231,6 +232,18 @@ protected:
// otherwise return 1
scalar rho(const volScalarField& p) const;
//- Accumulate bin data
void applyBins
(
const label patchI,
const vectorField fN,
const vectorField Md,
const vectorField fT
);
//- Helper function to write bin data
void writeBins() const;
//- Disallow default bitwise copy construct
forces(const forces&);
@ -296,8 +309,14 @@ public:
//- Write the forces
virtual void write();
//- Calculate and return forces and moment
virtual forcesMoments calcForcesMoment() const;
//- Calculate the forces and moments
virtual void calcForcesMoment();
//- Return the total force
virtual vector forceEff() const;
//- Return the total moment
virtual vector momentEff() const;
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&)

View File

@ -218,7 +218,7 @@ void sixDoFRigidBodyDisplacementPointPatchVectorField::updateCoeffs()
forces f("forces", db(), forcesDict);
forces::forcesMoments fm = f.calcForcesMoment();
f.calcForcesMoment();
// Get the forces on the patch faces at the current positions
@ -232,8 +232,8 @@ void sixDoFRigidBodyDisplacementPointPatchVectorField::updateCoeffs()
motion_.updateForce
(
fm.first().first() + fm.first().second() + g_*motion_.mass(),
fm.second().first() + fm.second().second(),
f.forceEff() + g_*motion_.mass(),
f.momentEff(),
t.deltaTValue()
);

View File

@ -23,25 +23,28 @@ License
\*---------------------------------------------------------------------------*/
#include "pressureCoefficient.H"
#include "CourantNo.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "dictionary.H"
#include "zeroGradientFvPatchFields.H"
#include "fvcSurfaceIntegrate.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::pressureCoefficient, 0);
defineTypeNameAndDebug(Foam::CourantNo, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::pressureCoefficient::rho
Foam::tmp<Foam::volScalarField> Foam::CourantNo::rho
(
const volScalarField& p
const surfaceScalarField& phi
) const
{
if (p.dimensions() == dimPressure)
if (phi.dimensions() == dimMass/dimTime)
{
return(obr_.lookupObject<volScalarField>(rhoName_));
return (obr_.lookupObject<volScalarField>(rhoName_));
}
else
{
@ -67,7 +70,7 @@ Foam::tmp<Foam::volScalarField> Foam::pressureCoefficient::rho
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::pressureCoefficient::pressureCoefficient
Foam::CourantNo::CourantNo
(
const word& name,
const objectRegistry& obr,
@ -78,9 +81,8 @@ Foam::pressureCoefficient::pressureCoefficient
name_(name),
obr_(obr),
active_(true),
pName_("p"),
rhoName_("rho"),
magUinf_(0.0)
phiName_("phi"),
rhoName_("rho")
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -88,7 +90,7 @@ Foam::pressureCoefficient::pressureCoefficient
active_ = false;
WarningIn
(
"pressureCoefficient::pressureCoefficient"
"CourantNo::CourantNo"
"("
"const word&, "
"const objectRegistry&, "
@ -100,60 +102,94 @@ Foam::pressureCoefficient::pressureCoefficient
}
read(dict);
if (active_)
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
volScalarField* CourantNoPtr
(
new volScalarField
(
IOobject
(
type(),
mesh.time().timeName(),
mesh,
IOobject::NO_READ
),
mesh,
dimensionedScalar("0", dimless, 0.0),
zeroGradientFvPatchScalarField::typeName
)
);
mesh.objectRegistry::store(CourantNoPtr);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::pressureCoefficient::~pressureCoefficient()
Foam::CourantNo::~CourantNo()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::pressureCoefficient::read(const dictionary& dict)
void Foam::CourantNo::read(const dictionary& dict)
{
if (active_)
{
pName_ = dict.lookupOrDefault<word>("pName", "p");
phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho");
dict.lookup("magUinf") >> magUinf_;
}
}
void Foam::pressureCoefficient::execute()
void Foam::CourantNo::execute()
{
// Do nothing - only valid on write
}
void Foam::pressureCoefficient::end()
void Foam::CourantNo::end()
{
// Do nothing - only valid on write
}
void Foam::pressureCoefficient::write()
void Foam::CourantNo::write()
{
if (active_)
{
const volScalarField& p = obr_.lookupObject<volScalarField>(pName_);
const fvMesh& mesh = refCast<const fvMesh>(obr_);
volScalarField pressureCoefficient
(
IOobject
const surfaceScalarField& phi =
mesh.lookupObject<surfaceScalarField>(phiName_);
volScalarField& CourantNo =
const_cast<volScalarField&>
(
"pressureCoefficient",
obr_.time().timeName(),
obr_,
IOobject::NO_READ
),
p/(0.5*rho(p)*sqr(magUinf_))
mesh.lookupObject<volScalarField>(type())
);
scalarField& iField = CourantNo.internalField();
const scalarField sumPhi
(
fvc::surfaceSum(mag(phi))().internalField()
/rho(phi)().internalField()
);
pressureCoefficient.write();
iField = 0.5*sumPhi/mesh.V().field()*mesh.time().deltaTValue();
CourantNo.correctBoundaryConditions();
CourantNo.write();
Info<< type() << " output:" << nl
<< " writing " << CourantNo.name() << "field" << nl << endl;
}
}

View File

@ -22,42 +22,27 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::pressureCoefficient
Group
grpUtilitiesFunctionObjects
Foam::CourantNo
Description
Calculates pressure coefficient, \f$c_p\f$
\f[
c_p = \frac{p}{p_{dyn,\infty}}
\f]
where:
\f[
p_{dyn,\infty} = 0.5 \rho |U_{\infty}|^2
\f]
where
\vartable
c_p | pressure coefficient
p | pressure [bar]
\rho | density [kg/m3]
U | velocity [m/s]
\endvartable
This function object calculates and outputs the Courant number as a
volScalarField. The field is stored on the mesh database so that it can
be retrieved and used for other applications.
SourceFiles
pressureCoefficient.C
IOpressureCoefficient.H
CourantNo.C
IOCourantNo.H
\*---------------------------------------------------------------------------*/
#ifndef pressureCoefficient_H
#define pressureCoefficient_H
#ifndef CourantNo_H
#define CourantNo_H
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "pointFieldFwd.H"
#include "OFstream.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -70,55 +55,53 @@ class dictionary;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class pressureCoefficient Declaration
Class CourantNo Declaration
\*---------------------------------------------------------------------------*/
class pressureCoefficient
class CourantNo
{
// Private data
//- Name of this set of pressureCoefficient objects
//- Name of this set of CourantNo objects
word name_;
//- Reference to the database
const objectRegistry& obr_;
//- on/off switch
//- On/off switch
bool active_;
//- Name of pressure field, default is "p"
word pName_;
//- Name of flux field, default is "phi"
word phiName_;
//- Name of density field (optional)
word rhoName_;
//- Free stream velocity magnitude [m/s]
scalar magUinf_;
// Private Member Functions
//- Return 1 if the pressure field is kinematic, i.e. p/rho
// otherwise return rho from database
tmp<volScalarField> rho(const volScalarField& p) const;
//- Return 1 if the flux field is volumetric, otherwise return rho
// from the database
tmp<volScalarField> rho(const surfaceScalarField& p) const;
//- Disallow default bitwise copy construct
pressureCoefficient(const pressureCoefficient&);
CourantNo(const CourantNo&);
//- Disallow default bitwise assignment
void operator=(const pressureCoefficient&);
void operator=(const CourantNo&);
public:
//- Runtime type information
TypeName("pressureCoefficient");
TypeName("CourantNo");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
pressureCoefficient
CourantNo
(
const word& name,
const objectRegistry&,
@ -128,18 +111,18 @@ public:
//- Destructor
virtual ~pressureCoefficient();
virtual ~CourantNo();
// Member Functions
//- Return name of the set of pressureCoefficient
//- Return name of the set of CourantNo
virtual const word& name() const
{
return name_;
}
//- Read the pressureCoefficient data
//- Read the CourantNo data
virtual void read(const dictionary&);
//- Execute, currently does nothing
@ -148,7 +131,7 @@ public:
//- Execute at the final time-loop, currently does nothing
virtual void end();
//- Calculate the pressureCoefficient and write
//- Calculate the CourantNo and write
virtual void write();
//- Update for changes of mesh

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,18 +23,18 @@ License
\*---------------------------------------------------------------------------*/
#include "staticPressureFunctionObject.H"
#include "CourantNoFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(staticPressureFunctionObject, 0);
defineNamedTemplateTypeNameAndDebug(CourantNoFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
staticPressureFunctionObject,
CourantNoFunctionObject,
dictionary
);
}

View File

@ -22,29 +22,28 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::pressureCoefficientFunctionObject
Foam::CourantNoFunctionObject
Description
FunctionObject wrapper around pressureCoefficient to allow it to be created
FunctionObject wrapper around CourantNo to allow it to be created
via the functions entry within controlDict.
SourceFiles
pressureCoefficientFunctionObject.C
CourantNoFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef pressureCoefficientFunctionObject_H
#define pressureCoefficientFunctionObject_H
#ifndef CourantNoFunctionObject_H
#define CourantNoFunctionObject_H
#include "pressureCoefficient.H"
#include "CourantNo.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<pressureCoefficient>
pressureCoefficientFunctionObject;
typedef OutputFilterFunctionObject<CourantNo> CourantNoFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,24 +22,24 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::IOstaticPressure
Foam::IOCourantNo
Description
Instance of the generic IOOutputFilter for staticPressure.
Instance of the generic IOOutputFilter for CourantNo.
\*---------------------------------------------------------------------------*/
#ifndef IOstaticPressure_H
#define IOstaticPressure_H
#ifndef IOCourantNo_H
#define IOCourantNo_H
#include "staticPressure.H"
#include "CourantNo.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<staticPressure> IOstaticPressure;
typedef IOOutputFilter<CourantNo> IOCourantNo;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -1,17 +1,23 @@
codedFunctionObject/codedFunctionObject.C
CourantNo/CourantNo.C
CourantNo/CourantNoFunctionObject.C
dsmcFields/dsmcFields.C
dsmcFields/dsmcFieldsFunctionObject.C
pressureCoefficient/pressureCoefficient.C
pressureCoefficient/pressureCoefficientFunctionObject.C
pressureTools/pressureTools.C
pressureTools/pressureToolsFunctionObject.C
staticPressure/staticPressure.C
staticPressure/staticPressureFunctionObject.C
scalarTransport/scalarTransport.C
scalarTransport/scalarTransportFunctionObject.C
timeActivatedFileUpdate/timeActivatedFileUpdate.C
timeActivatedFileUpdate/timeActivatedFileUpdateFunctionObject.C
wallShearStress/wallShearStress.C
wallShearStress/wallShearStressFunctionObject.C
yPlusLES/yPlusLES.C
yPlusLES/yPlusLESFunctionObject.C

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fieldSources/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/dsmc/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
@ -13,6 +14,7 @@ EXE_INC = \
LIB_LIBS = \
-lfiniteVolume \
-lfieldSources \
-lmeshTools \
-lsampling \
-llagrangian \

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::IOpressureTools
Description
Instance of the generic IOOutputFilter for pressureTools.
\*---------------------------------------------------------------------------*/
#ifndef IOpressureTools_H
#define IOpressureTools_H
#include "pressureTools.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<pressureTools> IOpressureTools;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,28 +23,119 @@ License
\*---------------------------------------------------------------------------*/
#include "staticPressure.H"
#include "pressureTools.H"
#include "volFields.H"
#include "dictionary.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::staticPressure, 0);
defineTypeNameAndDebug(Foam::pressureTools, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::staticPressure::isKinematicPressure()
Foam::word Foam::pressureTools::pName() const
{
const volScalarField& p = obr_.lookupObject<volScalarField>(pName_);
word fieldName = "p";
return p.dimensions() == sqr(dimLength)/sqr(dimTime);
if (calcTotal_)
{
fieldName = "total(" + fieldName + ")";
}
else
{
fieldName = "static(" + fieldName + ")";
}
if (calcCoeff_)
{
fieldName = fieldName + "_coeff";
}
return fieldName;
}
Foam::dimensionedScalar Foam::pressureTools::rho
(
const volScalarField& p
) const
{
if (p.dimensions() == dimPressure)
{
return dimensionedScalar("1", dimless, 1.0);
}
else
{
return dimensionedScalar("rhoRef", dimDensity, rhoRef_);
}
}
Foam::dimensionedScalar Foam::pressureTools::pRef() const
{
dimensionedScalar value("pRef", dimPressure, 0.0);
if (calcTotal_)
{
value.value() += pRef_;
}
return pRef();
}
Foam::tmp<Foam::volScalarField> Foam::pressureTools::pDyn() const
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
tmp<volScalarField> tpDyn
(
new volScalarField
(
IOobject
(
"pDyn",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("zero", dimPressure, 0.0)
)
);
if (calcTotal_)
{
const volVectorField& U = obr_.lookupObject<volVectorField>(UName_);
tpDyn() == 0.5*magSqr(U);
}
return tpDyn;
}
Foam::tmp<Foam::volScalarField> Foam::pressureTools::convertToCoeff
(
const volScalarField& p
) const
{
tmp<volScalarField> tCoeff(p);
if (calcCoeff_)
{
tCoeff() /= pDyn();
}
return tCoeff;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::staticPressure::staticPressure
Foam::pressureTools::pressureTools
(
const word& name,
const objectRegistry& obr,
@ -55,8 +146,12 @@ Foam::staticPressure::staticPressure
name_(name),
obr_(obr),
active_(true),
pName_(dict.lookupOrDefault<word>("p", "p")),
rho_(readScalar(dict.lookup("rho")))
calcTotal_(false),
calcCoeff_(false),
pName_("p"),
UName_("U"),
pRef_(0.0),
rhoRef_(1.0)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
@ -64,7 +159,7 @@ Foam::staticPressure::staticPressure
active_ = false;
WarningIn
(
"staticPressure::staticPressure"
"pressureTools::pressureTools"
"("
"const word&, "
"const objectRegistry&, "
@ -74,25 +169,6 @@ Foam::staticPressure::staticPressure
) << "No fvMesh available, deactivating." << nl
<< endl;
}
else
{
// Check if the pressure is kinematic pressure, otherwise deactivate
if (!isKinematicPressure())
{
active_ = false;
WarningIn
(
"staticPressure::staticPressure"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"const bool"
")"
) << "Pressure is not kinematic pressure, deactivating." << nl
<< endl;
}
}
read(dict);
}
@ -100,53 +176,68 @@ Foam::staticPressure::staticPressure
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::staticPressure::~staticPressure()
Foam::pressureTools::~pressureTools()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::staticPressure::read(const dictionary& dict)
void Foam::pressureTools::read(const dictionary& dict)
{
if (active_)
{
dict.readIfPresent("p", pName_);
dict.lookup("rho") >> rho_;
dict.readIfPresent("pName", pName_);
dict.readIfPresent("UName", UName_);
const volScalarField& p = obr_.lookupObject<volScalarField>(pName_);
if (p.dimensions() != p.dimensions())
{
dict.lookup("rhoRef") >> rhoRef_;
}
dict.lookup("calcTotal") >> calcTotal_;
if (calcTotal_)
{
dict.lookup("pRef") >> pRef_;
}
dict.lookup("calcCoeff") >> calcCoeff_;
}
}
void Foam::staticPressure::execute()
void Foam::pressureTools::execute()
{
// Do nothing - only valid on write
}
void Foam::staticPressure::end()
void Foam::pressureTools::end()
{
// Do nothing - only valid on write
}
void Foam::staticPressure::write()
void Foam::pressureTools::write()
{
if (active_)
{
const volScalarField& p = obr_.lookupObject<volScalarField>(pName_);
volScalarField pStatic
volScalarField pResult
(
IOobject
(
"pStatic",
pName(),
obr_.time().timeName(),
obr_,
IOobject::NO_READ
),
dimensionedScalar("rho", dimDensity, rho_)*p
convertToCoeff(rho(p)*(p + pDyn()) + pRef())
);
pStatic.write();
pResult.write();
}
}

View File

@ -0,0 +1,194 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::pressureTools
Description
This function object includes tools to manipulate the pressure into
different forms. These currently include:
- static pressure
p_s = rho*p_k
- total pressure
p_T = pRef + p_s + 0.5 rho |U|^2
- static pressure coefficient
Cp_s = p_s / (0.5 rho |U|^2)
- total pressure coefficient
Cp_T = p_T / (0.5 rho |U|^2)
The function object will operate on both kinematic (p_k) and static
pressure (p_s) fields, and the result is written as a volScalarField.
SourceFiles
pressureTools.C
IOpressureTools.H
\*---------------------------------------------------------------------------*/
#ifndef pressureTools_H
#define pressureTools_H
#include "volFieldsFwd.H"
#include "pointFieldFwd.H"
#include "dimensionedScalar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
class dictionary;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class pressureTools Declaration
\*---------------------------------------------------------------------------*/
class pressureTools
{
// Private data
//- Name of this set of pressureTools objects
word name_;
//- Reference to the database
const objectRegistry& obr_;
//- On/off switch
bool active_;
//- Flag to calculate total pressure
bool calcTotal_;
//- Flag to calculate pressure coefficient
bool calcCoeff_;
//- Name of pressure field, default is "p"
word pName_;
//- Name of velocity field, default is "U"
word UName_;
//- Reference pressure level (used for total pressure)
scalar pRef_;
//- Reference density value
scalar rhoRef_;
// Private Member Functions
//- Return the name of the derived pressure field
word pName() const;
//- Return the density scaling if supplied with kinematic pressure
dimensionedScalar rho(const volScalarField& p) const;
//- Return the reference pressure
dimensionedScalar pRef() const;
//- Calculate and return the (kinematic) dynamic pressure
tmp<volScalarField> pDyn() const;
//- Convert to coeff data by applying the pDyn scaling
tmp<volScalarField> convertToCoeff(const volScalarField& p) const;
//- Disallow default bitwise copy construct
pressureTools(const pressureTools&);
//- Disallow default bitwise assignment
void operator=(const pressureTools&);
public:
//- Runtime type information
TypeName("pressureTools");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
pressureTools
(
const word& name,
const objectRegistry&,
const dictionary&,
const bool loadFromFiles = false
);
//- Destructor
virtual ~pressureTools();
// Member Functions
//- Return name of the set of pressureTools
virtual const word& name() const
{
return name_;
}
//- Read the pressureTools 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();
//- Calculate the pressureTools and write
virtual void write();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&)
{}
//- Update for changes of mesh
virtual void movePoints(const pointField&)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "pressureToolsFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(pressureToolsFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
pressureToolsFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,29 +22,29 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::staticPressureFunctionObject
Foam::pressureToolsFunctionObject
Description
FunctionObject wrapper around staticPressure to allow it to be created via
FunctionObject wrapper around pressureTools to allow it to be created via
the functions entry within controlDict.
SourceFiles
staticPressureFunctionObject.C
pressureToolsFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef staticPressureFunctionObject_H
#define staticPressureFunctionObject_H
#ifndef pressureToolsFunctionObject_H
#define pressureToolsFunctionObject_H
#include "staticPressure.H"
#include "pressureTools.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<staticPressure>
staticPressureFunctionObject;
typedef OutputFilterFunctionObject<pressureTools>
pressureToolsFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::IOscalarTransport
Description
Instance of the generic IOOutputFilter for scalarTransport.
\*---------------------------------------------------------------------------*/
#ifndef IOscalarTransport_H
#define IOscalarTransport_H
#include "scalarTransport.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<scalarTransport> IOscalarTransport;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,271 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "scalarTransport.H"
#include "surfaceFields.H"
#include "dictionary.H"
#include "fixedValueFvPatchFields.H"
#include "zeroGradientFvPatchFields.H"
#include "fvScalarMatrix.H"
#include "fvmDdt.H"
#include "fvmDiv.H"
#include "fvcDiv.H"
#include "fvmLaplacian.H"
#include "fvmSup.H"
#include "incompressible/turbulenceModel/turbulenceModel.H"
#include "compressible/turbulenceModel/turbulenceModel.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::scalarTransport, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::wordList Foam::scalarTransport::boundaryTypes() const
{
const volVectorField& U = mesh_.lookupObject<volVectorField>(UName_);
wordList bTypes(U.boundaryField().size());
forAll(bTypes, patchI)
{
const fvPatchField<vector>& pf = U.boundaryField()[patchI];
if (isA<fixedValueFvPatchVectorField>(pf))
{
bTypes[patchI] = fixedValueFvPatchScalarField::typeName;
}
else
{
bTypes[patchI] = zeroGradientFvPatchScalarField::typeName;
}
}
return bTypes;
}
Foam::tmp<Foam::volScalarField> Foam::scalarTransport::DT
(
const surfaceScalarField& phi
) const
{
typedef incompressible::turbulenceModel icoModel;
typedef compressible::turbulenceModel cmpModel;
if (userDT_)
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"DT",
mesh_.time().timeName(),
mesh_.time(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedScalar("DT", phi.dimensions()/dimLength, DT_)
)
);
}
else if (mesh_.foundObject<icoModel>("turbulenceModel"))
{
const icoModel& model = mesh_.lookupObject<icoModel>("turbulenceModel");
return model.nuEff();
}
else if (mesh_.foundObject<cmpModel>("turbulenceModel"))
{
const cmpModel& model = mesh_.lookupObject<cmpModel>("turbulenceModel");
return model.muEff();
}
else
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"DT",
mesh_.time().timeName(),
mesh_.time(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedScalar("DT", phi.dimensions()/dimLength, 0.0)
)
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::scalarTransport::scalarTransport
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
name_(name),
mesh_(refCast<const fvMesh>(obr)),
active_(true),
phiName_("phi"),
UName_("U"),
DT_(0.0),
userDT_(false),
resetOnStartUp_(false),
nCorr_(0),
autoSchemes_(false),
sources_(mesh_),
T_
(
IOobject
(
name,
mesh_.time().timeName(),
mesh_,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh_,
dimensionedScalar("zero", dimless, 0.0),
boundaryTypes()
)
{
read(dict);
if (resetOnStartUp_)
{
T_ == dimensionedScalar("zero", dimless, 0.0);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::scalarTransport::~scalarTransport()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::scalarTransport::read(const dictionary& dict)
{
if (active_)
{
Info<< type() << ":" << nl;
phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
UName_ = dict.lookupOrDefault<word>("UName", "U");
userDT_ = false;
if (dict.readIfPresent("DT", DT_))
{
userDT_ = true;
}
dict.lookup("resetOnStartUp") >> resetOnStartUp_;
dict.readIfPresent("nCorr", nCorr_);
dict.lookup("autoSchemes") >> autoSchemes_;
sources_.reset(dict.subDict("sources"));
}
}
void Foam::scalarTransport::execute()
{
Info<< type() << " output:" << endl;
const surfaceScalarField& phi =
mesh_.lookupObject<surfaceScalarField>(phiName_);
// calculate the diffusivity
volScalarField DT(this->DT(phi));
// set schemes
word schemeVar = T_.name();
if (autoSchemes_)
{
schemeVar = UName_;
}
word divScheme("div(phi," + schemeVar + ")");
word laplacianScheme("laplacian(" + DT.name() + "," + schemeVar + ")");
// set under-relaxation coeff
scalar relaxCoeff = 0.0;
if (mesh_.relaxEquation(schemeVar))
{
relaxCoeff = mesh_.equationRelaxationFactor(schemeVar);
}
// solve
for (label i = 0; i <= nCorr_; i++)
{
fvScalarMatrix TEqn
(
fvm::ddt(T_)
+ fvm::div(phi, T_, divScheme)
- fvm::laplacian(DT, T_, laplacianScheme)
==
sources_(T_)
);
TEqn.relax(relaxCoeff);
sources_.constrain(TEqn);
TEqn.solve(mesh_.solverDict(UName_));
}
Info<< endl;
}
void Foam::scalarTransport::end()
{
// Do nothing
}
void Foam::scalarTransport::write()
{
// Do nothing
}
// ************************************************************************* //

View File

@ -0,0 +1,188 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::scalarTransport
Description
This function object evolves a passive scalar transport equation. The
field in ininitially 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.
- the field can be zeroed on start-up using the resetOnStartUp flag
- to employ the same numerical schemes as the flow velocity, use the
autoSchemes flag
- the diffusivity can be set manually using the DT entry, or retrieved
from the turbulence model (if applicable)
SourceFiles
scalarTransport.C
IOscalarTransport.H
SeeAlso
Foam::basicSourceList
\*---------------------------------------------------------------------------*/
#ifndef scalarTransport_H
#define scalarTransport_H
#include "volFields.H"
#include "surfaceFieldsFwd.H"
#include "pointFieldFwd.H"
#include "fvMatricesFwd.H"
#include "basicSourceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
class dictionary;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class scalarTransport Declaration
\*---------------------------------------------------------------------------*/
class scalarTransport
{
// Private data
//- Name of this set of scalarTransport objects
word name_;
//- Reference to the mesh database
const fvMesh& mesh_;
//- On/off switch
bool active_;
//- Name of flux field (optional)
word phiName_;
//- Name of velocity field (optional)
word UName_;
//- Diffusion coefficient (optional)
scalar DT_;
//- Flag to indicate whether user DT_ is used
bool userDT_;
//- Flag to reset scalar field on start-up
bool resetOnStartUp_;
//- Number of corrector iterations (optional)
label nCorr_;
//- Flag to employ schemes for velocity for scalar transport
bool autoSchemes_;
//- Run-time selectable sources
basicSourceList sources_;
//- The scalar field
volScalarField T_;
// Private Member Functions
//- Return the boundary types for the scalar field
wordList boundaryTypes() const;
//- Return the diffusivity field
tmp<volScalarField> DT(const surfaceScalarField& phi) const;
//- Disallow default bitwise copy construct
scalarTransport(const scalarTransport&);
//- Disallow default bitwise assignment
void operator=(const scalarTransport&);
public:
//- Runtime type information
TypeName("scalarTransport");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
scalarTransport
(
const word& name,
const objectRegistry&,
const dictionary&,
const bool loadFromFiles = false
);
//- Destructor
virtual ~scalarTransport();
// Member Functions
//- Return name of the set of scalarTransport
virtual const word& name() const
{
return name_;
}
//- Read the scalarTransport 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();
//- Calculate the scalarTransport and write
virtual void write();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&)
{}
//- Update for changes of mesh
virtual void movePoints(const pointField&)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "scalarTransportFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(scalarTransportFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
scalarTransportFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::scalarTransportFunctionObject
Description
FunctionObject wrapper around scalarTransport to allow it to be
created via the functions entry within controlDict.
SourceFiles
scalarTransportFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef scalarTransportFunctionObject_H
#define scalarTransportFunctionObject_H
#include "scalarTransport.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<scalarTransport>
scalarTransportFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::IOwallShearStress
Description
Instance of the generic IOOutputFilter for wallShearStress.
\*---------------------------------------------------------------------------*/
#ifndef IOwallShearStress_H
#define IOwallShearStress_H
#include "wallShearStress.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<wallShearStress> IOwallShearStress;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,251 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "wallShearStress.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "incompressible/turbulenceModel/turbulenceModel.H"
#include "compressible/turbulenceModel/turbulenceModel.H"
#include "wallPolyPatch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::wallShearStress, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::wallShearStress::makeFile()
{
// Create the output file if not already created
if (outputFilePtr_.empty())
{
if (debug)
{
Info<< "Creating output file." << endl;
}
// File update
if (Pstream::master())
{
fileName outputDir;
word startTimeName =
obr_.time().timeName(obr_.time().startTime().value());
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
outputDir =
obr_.time().path()/".."/name_/startTimeName;
}
else
{
outputDir = obr_.time().path()/name_/startTimeName;
}
// Create directory if does not exist
mkDir(outputDir);
// Open new file at start up
outputFilePtr_.reset(new OFstream(outputDir/(type() + ".dat")));
// Add headers to output data
outputFilePtr_() << "# Wall shear stress" << nl
<< "# time " << token::TAB << "patch" << token::TAB
<< "min" << token::TAB << "max" << endl;
}
}
}
void Foam::wallShearStress::calcShearStress
(
const fvMesh& mesh,
const volSymmTensorField& Reff,
volVectorField& shearStress
)
{
forAll(shearStress.boundaryField(), patchI)
{
const polyPatch& pp = mesh.boundaryMesh()[patchI];
if (isA<wallPolyPatch>(pp))
{
vectorField& ssp = shearStress.boundaryField()[patchI];
const vectorField& Sfp = mesh.Sf().boundaryField()[patchI];
const scalarField& magSfp = mesh.magSf().boundaryField()[patchI];
const symmTensorField& Reffp = Reff.boundaryField()[patchI];
ssp = (-Sfp/magSfp) & Reffp;
vector minSsp = min(ssp);
vector maxSsp = max(ssp);
outputFilePtr_() << mesh.time().timeName() << token::TAB
<< pp.name() << token::TAB << minSsp
<< token::TAB << maxSsp << endl;
if (log_)
{
Info<< " min/max(" << pp.name() << ") = "
<< minSsp << ", " << maxSsp << endl;
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::wallShearStress::wallShearStress
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
name_(name),
obr_(obr),
active_(true),
log_(false),
phiName_("phi"),
outputFilePtr_(NULL)
{
// Check if the available mesh is an fvMesh, otherwise deactivate
if (!isA<fvMesh>(obr_))
{
active_ = false;
WarningIn
(
"wallShearStress::wallShearStress"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"const bool"
")"
) << "No fvMesh available, deactivating." << nl
<< endl;
}
makeFile();
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::wallShearStress::~wallShearStress()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::wallShearStress::read(const dictionary& dict)
{
if (active_)
{
log_ = dict.lookupOrDefault<Switch>("log", false);
phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
}
}
void Foam::wallShearStress::execute()
{
// Do nothing - only valid on write
}
void Foam::wallShearStress::end()
{
// Do nothing - only valid on write
}
void Foam::wallShearStress::write()
{
typedef compressible::turbulenceModel cmpModel;
typedef incompressible::turbulenceModel icoModel;
if (active_)
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
volVectorField wallShearStress
(
IOobject
(
"wallShearStress",
mesh.time().timeName(),
mesh,
IOobject::NO_READ
),
mesh,
dimensionedVector("0", sqr(dimLength)/sqr(dimTime), vector::zero)
);
if (log_)
{
Info<< type() << " output:" << nl;
}
const surfaceScalarField& phi =
obr_.lookupObject<surfaceScalarField>(phiName_);
tmp<volSymmTensorField> Reff;
if (phi.dimensions() == dimMass/dimTime)
{
const cmpModel& model =
mesh.lookupObject<cmpModel>("turbulenceModel");
Reff = model.devRhoReff();
}
else
{
const icoModel& model =
mesh.lookupObject<icoModel>("turbulenceModel");
Reff = model.devReff();
}
calcShearStress(mesh, Reff(), wallShearStress);
if (log_)
{
Info<< endl;
}
wallShearStress.write();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,180 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::wallShearStress
Group
grpUtilitiesFunctionObjects
Description
This function object evaluates and outputs the shear stress at wall
patches. The result is written as a volVectorField to time folders as
field 'wallShearStress'
\f[
Stress = R \dot n
\f]
The shear stress (symmetrical) tensor field is retrieved from the
turbulence model.
where
\vartable
R | stress tensor
n | patch normal vector (into the domain)
\endvartable
SourceFiles
wallShearStress.C
IOwallShearStress.H
\*---------------------------------------------------------------------------*/
#ifndef wallShearStress_H
#define wallShearStress_H
#include "volFieldsFwd.H"
#include "pointFieldFwd.H"
#include "Switch.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
class dictionary;
class mapPolyMesh;
class fvMesh;
/*---------------------------------------------------------------------------*\
Class wallShearStress Declaration
\*---------------------------------------------------------------------------*/
class wallShearStress
{
// Private data
//- Name of this set of wallShearStress object
word name_;
const objectRegistry& obr_;
//- on/off switch
bool active_;
//- Switch to send output to Info as well as to file
Switch log_;
//- Name of mass/volume flux field (optional, default = phi)
word phiName_;
//- Output file pointer
autoPtr<OFstream> outputFilePtr_;
// Private Member Functions
//- Make the output file
virtual void makeFile();
//- Calculate the shear stress
void calcShearStress
(
const fvMesh& mesh,
const volSymmTensorField& Reff,
volVectorField& shearStress
);
//- Disallow default bitwise copy construct
wallShearStress(const wallShearStress&);
//- Disallow default bitwise assignment
void operator=(const wallShearStress&);
public:
//- Runtime type information
TypeName("wallShearStress");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
wallShearStress
(
const word& name,
const objectRegistry&,
const dictionary&,
const bool loadFromFiles = false
);
//- Destructor
virtual ~wallShearStress();
// Member Functions
//- Return name of the set of wallShearStress
virtual const word& name() const
{
return name_;
}
//- Read the wallShearStress 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();
//- Calculate the wallShearStress and write
virtual void write();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&)
{}
//- Update for changes of mesh
virtual void movePoints(const pointField&)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "wallShearStressFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(wallShearStressFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
wallShearStressFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::wallShearStressFunctionObject
Description
FunctionObject wrapper around wallShearStress to allow it to be created
via the functions entry within controlDict.
SourceFiles
wallShearStressFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef wallShearStressFunctionObject_H
#define wallShearStressFunctionObject_H
#include "wallShearStress.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<wallShearStress>
wallShearStressFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //