/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2017 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 .
\*---------------------------------------------------------------------------*/
#include "scalarTransport.H"
#include "surfaceFields.H"
#include "fvmDdt.H"
#include "fvmDiv.H"
#include "fvmLaplacian.H"
#include "fvmSup.H"
#include "turbulentTransportModel.H"
#include "turbulentFluidThermoModel.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(scalarTransport, 0);
addToRunTimeSelectionTable
(
functionObject,
scalarTransport,
dictionary
);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::tmp Foam::functionObjects::scalarTransport::D
(
const surfaceScalarField& phi
) const
{
typedef incompressible::turbulenceModel icoModel;
typedef compressible::turbulenceModel cmpModel;
word Dname("D" + s_.name());
if (constantD_)
{
return tmp
(
new volScalarField
(
IOobject
(
Dname,
mesh_.time().timeName(),
mesh_.time(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedScalar(Dname, phi.dimensions()/dimLength, D_)
)
);
}
else if (mesh_.foundObject(turbulenceModel::propertiesName))
{
const icoModel& model = mesh_.lookupObject
(
turbulenceModel::propertiesName
);
return alphaD_*model.nu() + alphaDt_*model.nut();
}
else if (mesh_.foundObject(turbulenceModel::propertiesName))
{
const cmpModel& model = mesh_.lookupObject
(
turbulenceModel::propertiesName
);
return alphaD_*model.mu() + alphaDt_*model.mut();
}
else
{
return tmp
(
new volScalarField
(
IOobject
(
Dname,
mesh_.time().timeName(),
mesh_.time(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedScalar(Dname, phi.dimensions()/dimLength, 0.0)
)
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::scalarTransport::scalarTransport
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
fieldName_(dict.lookupOrDefault("field", "s")),
D_(0),
nCorr_(0),
fvOptions_(mesh_),
s_
(
IOobject
(
fieldName_,
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh_
)
{
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::scalarTransport::~scalarTransport()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::scalarTransport::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
phiName_ = dict.lookupOrDefault("phi", "phi");
rhoName_ = dict.lookupOrDefault("rho", "rho");
schemesField_ = dict.lookupOrDefault("schemesField", fieldName_);
constantD_ = dict.readIfPresent("D", D_);
alphaD_ = dict.lookupOrDefault("alphaD", 1.0);
alphaDt_ = dict.lookupOrDefault("alphaDt", 1.0);
dict.readIfPresent("nCorr", nCorr_);
if (dict.found("fvOptions"))
{
fvOptions_.reset(dict.subDict("fvOptions"));
}
return true;
}
bool Foam::functionObjects::scalarTransport::execute()
{
Info<< type() << " write:" << endl;
const surfaceScalarField& phi =
mesh_.lookupObject(phiName_);
// Calculate the diffusivity
volScalarField D(this->D(phi));
word divScheme("div(phi," + schemesField_ + ")");
word laplacianScheme("laplacian(" + D.name() + "," + schemesField_ + ")");
// Set under-relaxation coeff
scalar relaxCoeff = 0.0;
if (mesh_.relaxEquation(schemesField_))
{
relaxCoeff = mesh_.equationRelaxationFactor(schemesField_);
}
if (phi.dimensions() == dimMass/dimTime)
{
const volScalarField& rho =
mesh_.lookupObject(rhoName_);
for (label i = 0; i <= nCorr_; i++)
{
fvScalarMatrix sEqn
(
fvm::ddt(rho, s_)
+ fvm::div(phi, s_, divScheme)
- fvm::laplacian(D, s_, laplacianScheme)
==
fvOptions_(rho, s_)
);
sEqn.relax(relaxCoeff);
fvOptions_.constrain(sEqn);
sEqn.solve(mesh_.solverDict(schemesField_));
}
}
else if (phi.dimensions() == dimVolume/dimTime)
{
for (label i = 0; i <= nCorr_; i++)
{
fvScalarMatrix sEqn
(
fvm::ddt(s_)
+ fvm::div(phi, s_, divScheme)
- fvm::laplacian(D, s_, laplacianScheme)
==
fvOptions_(s_)
);
sEqn.relax(relaxCoeff);
fvOptions_.constrain(sEqn);
sEqn.solve(mesh_.solverDict(schemesField_));
}
}
else
{
FatalErrorInFunction
<< "Incompatible dimensions for phi: " << phi.dimensions() << nl
<< "Dimensions should be " << dimMass/dimTime << " or "
<< dimVolume/dimTime << exit(FatalError);
}
Info<< endl;
return true;
}
bool Foam::functionObjects::scalarTransport::write()
{
return true;
}
// ************************************************************************* //