/*---------------------------------------------------------------------------*\ ========= | \\ / 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; } // ************************************************************************* //