fvOptions: Added massSource option

This fvOption applies a mass source to the continuity equation and to
all field equations.

Example usage:

    massSource
    {
        type            massSource;

        selectionMode   cellSet;
        cellSet         massSource;

        massFlowRate    1e-4;

        fieldValues
        {
            U               (10 0 0);
            T               350;
            k               0.375;
            epsilon         14.855;
        }
    }

Values should be provided for all solved for fields. Warnings will be
issued if values are not provided for fields for which transport equations
are solved. Warnings will also be issued if values are provided for fields
which are not solved for.
This commit is contained in:
Will Bainbridge
2021-02-05 13:47:07 +00:00
parent 07f5080f2e
commit 69e98dc28d
6 changed files with 785 additions and 50 deletions

View File

@ -37,6 +37,7 @@ $(derivedSources)/phaseLimitStabilization/phaseLimitStabilization.C
$(derivedSources)/accelerationSource/accelerationSource.C
$(derivedSources)/volumeFractionSource/volumeFractionSource.C
$(derivedSources)/solidEquilibriumEnergySource/solidEquilibriumEnergySource.C
$(derivedSources)/massSource/massSource.C
interRegion = sources/interRegion
$(interRegion)/interRegionHeatTransfer/interRegionHeatTransferModel/interRegionHeatTransferModel.C

View File

@ -0,0 +1,445 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021 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 "massSource.H"
#include "fvMatrices.H"
#include "basicThermo.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
defineTypeNameAndDebug(massSource, 0);
addToRunTimeSelectionTable(option, massSource, dictionary);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fv::massSource::readCoeffs()
{
phaseName_ = coeffs_.lookupOrDefault<word>("phase", word::null);
rhoName_ =
coeffs_.lookupOrDefault<word>
(
"rho",
IOobject::groupName("rho", phaseName_)
);
if
(
mesh_.foundObject<basicThermo>
(
IOobject::groupName(basicThermo::dictName, phaseName_)
)
)
{
const basicThermo& thermo =
mesh_.lookupObject<basicThermo>
(
IOobject::groupName(basicThermo::dictName, phaseName_)
);
heName_ = thermo.he().name();
TName_ = thermo.T().name();
}
fieldValues_.clear();
const dictionary& fieldCoeffs = coeffs_.subDict("fieldValues");
forAllConstIter(dictionary, fieldCoeffs, iter)
{
fieldValues_.set(iter().keyword(), nullptr);
}
readFieldValuesType<scalar>();
readFieldValuesType<vector>();
readFieldValuesType<sphericalTensor>();
readFieldValuesType<symmTensor>();
readFieldValuesType<tensor>();
massFlowRate_.reset(Function1<scalar>::New("massFlowRate", coeffs_).ptr());
}
template<class Type>
void Foam::fv::massSource::readFieldValuesType()
{
const dictionary& fieldCoeffs = coeffs_.subDict("fieldValues");
forAllConstIter(dictionary, fieldCoeffs, iter)
{
const word& fieldName = iter().keyword();
if (mesh_.foundObject<VolField<Type>>(fieldName))
{
fieldValues_.set
(
fieldName,
objectFunction1::New<VolField>
(
fieldName,
fieldCoeffs,
fieldName,
mesh_
).ptr()
);
}
}
}
void Foam::fv::massSource::addRhoSup
(
fvMatrix<scalar>& eqn,
const word& fieldName
) const
{
const scalar t = mesh_.time().value();
const scalar massFlowRate = massFlowRate_->value(t);
forAll(cells(), i)
{
eqn.source()[cells()[i]] -= mesh_.V()[cells()[i]]/V()*massFlowRate;
}
}
void Foam::fv::massSource::addHeSupT
(
fvMatrix<scalar>& eqn,
const word& fieldName
) const
{
if (fieldValues_.found(heName_))
{
WarningInFunction
<< "Source " << name() << " defined for both field " << heName_
<< " and " << TName_ << ". Only one of these should be present."
<< endl;
}
const scalar t = mesh_.time().value();
const scalar massFlowRate = massFlowRate_->value(t);
const scalar T = fieldValues_[TName_]->value<scalar>(t);
const basicThermo& thermo =
mesh_.lookupObject<basicThermo>
(
IOobject::groupName(basicThermo::dictName, phaseName_)
);
const scalarField hs(thermo.hs(scalarField(cells().size(), T), cells()));
forAll(cells(), i)
{
eqn.source()[cells()[i]] -=
mesh_.V()[cells()[i]]/V()*massFlowRate*hs[i];
}
}
template<class Type>
void Foam::fv::massSource::addSupType
(
fvMatrix<Type>& eqn,
const word& fieldName
) const
{
const scalar t = mesh_.time().value();
const scalar massFlowRate = massFlowRate_->value(t);
const Type value = fieldValues_[fieldName]->value<Type>(t);
forAll(cells(), i)
{
eqn.source()[cells()[i]] -=
mesh_.V()[cells()[i]]/V()*massFlowRate*value;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::massSource::massSource
(
const word& name,
const word& modelType,
const dictionary& dict,
const fvMesh& mesh
)
:
cellSetOption(name, modelType, dict, mesh),
phaseName_(),
rhoName_(),
heName_(),
TName_(),
massFlowRate_(),
fieldValues_()
{
readCoeffs();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::fv::massSource::addsToField(const word& fieldName) const
{
const bool isThisPhase = IOobject::group(fieldName) == phaseName_;
if
(
isThisPhase
&& !(fieldName == rhoName_)
&& !(fieldName == heName_ && fieldValues_.found(TName_))
&& !fieldValues_.found(fieldName)
)
{
WarningInFunction
<< "No value supplied for field " << fieldName << " in "
<< type() << " fvOption " << name() << endl;
return false;
}
return isThisPhase;
}
Foam::wordList Foam::fv::massSource::addedToFields() const
{
wordList fieldNames = fieldValues_.toc();
if (fieldValues_.found(TName_))
{
fieldNames[findIndex(fieldNames, TName_)] = heName_;
}
return fieldNames;
}
void Foam::fv::massSource::addSup
(
fvMatrix<scalar>& eqn,
const word& fieldName
) const
{
if (fieldName == rhoName_)
{
addRhoSup(eqn, fieldName);
}
else if (fieldName == heName_ && fieldValues_.found(TName_))
{
addHeSupT(eqn, fieldName);
}
else
{
addSupType(eqn, fieldName);
}
}
void Foam::fv::massSource::addSup
(
fvMatrix<vector>& eqn,
const word& fieldName
) const
{
addSupType(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
fvMatrix<sphericalTensor>& eqn,
const word& fieldName
) const
{
addSupType(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
fvMatrix<symmTensor>& eqn,
const word& fieldName
) const
{
addSupType(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
fvMatrix<tensor>& eqn,
const word& fieldName
) const
{
addSupType(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
const volScalarField& rho,
fvMatrix<scalar>& eqn,
const word& fieldName
) const
{
if (fieldName == heName_ && fieldValues_.found(TName_))
{
addHeSupT(eqn, fieldName);
}
else
{
addSup(eqn, fieldName);
}
}
void Foam::fv::massSource::addSup
(
const volScalarField& rho,
fvMatrix<vector>& eqn,
const word& fieldName
) const
{
addSup(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
const volScalarField& rho,
fvMatrix<sphericalTensor>& eqn,
const word& fieldName
) const
{
addSup(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
const volScalarField& rho,
fvMatrix<symmTensor>& eqn,
const word& fieldName
) const
{
addSup(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
const volScalarField& rho,
fvMatrix<tensor>& eqn,
const word& fieldName
) const
{
addSup(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<scalar>& eqn,
const word& fieldName
) const
{
if (fieldName == heName_ && fieldValues_.found(TName_))
{
addHeSupT(eqn, fieldName);
}
else
{
addSup(eqn, fieldName);
}
}
void Foam::fv::massSource::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<vector>& eqn,
const word& fieldName
) const
{
addSup(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<sphericalTensor>& eqn,
const word& fieldName
) const
{
addSup(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<symmTensor>& eqn,
const word& fieldName
) const
{
addSup(eqn, fieldName);
}
void Foam::fv::massSource::addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<tensor>& eqn,
const word& fieldName
) const
{
addSup(eqn, fieldName);
}
bool Foam::fv::massSource::read(const dictionary& dict)
{
if (cellSetOption::read(dict))
{
readCoeffs();
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,300 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021 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::fv::massSource
Description
This fvOption applies a mass source to the continuity equation and to all
field equations.
Usage
Example usage:
\verbatim
massSource
{
type massSource;
selectionMode cellSet;
cellSet massSource;
massFlowRate 1e-4;
fieldValues
{
U (10 0 0);
e 10;
k 0.375;
epsilon 14.855;
}
}
\endverbatim
Values should be provided for all solved for fields. Warnings will be
issued if values are not provided for fields for which transport equations
are solved. Warnings will also be issued if values are provided for fields
which are not solved for.
SourceFiles
massSource.C
\*---------------------------------------------------------------------------*/
#ifndef massSource_H
#define massSource_H
#include "cellSetOption.H"
#include "HashPtrTable.H"
#include "objectFunction1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
/*---------------------------------------------------------------------------*\
Class massSource Declaration
\*---------------------------------------------------------------------------*/
class massSource
:
public cellSetOption
{
// Private Data
//- Name of the phase
word phaseName_;
//- Name of the density field
word rhoName_;
//- Name of the energy field
word heName_;
//- Name of the temperature field
word TName_;
//- Mass source
autoPtr<Function1<scalar>> massFlowRate_;
//- Field values
HashPtrTable<objectFunction1> fieldValues_;
// Private Member Functions
//- Non-virtual read
void readCoeffs();
//- Read field values for a given primitive type
template<class Type>
void readFieldValuesType();
//- Add the mass source term to the continuity equation
void addRhoSup(fvMatrix<scalar>& eqn, const word& fieldName) const;
//- Add the mass source term to the energy equation, given a value of
// temperature
void addHeSupT(fvMatrix<scalar>& eqn, const word& fieldName) const;
//- Add the mass source term to an equation
template<class Type>
void addSupType(fvMatrix<Type>& eqn, const word& fieldName) const;
public:
//- Runtime type information
TypeName("massSource");
// Constructors
//- Construct from explicit source name and mesh
massSource
(
const word& sourceName,
const word& modelType,
const dictionary& dict,
const fvMesh& mesh
);
//- Disallow default bitwise copy construction
massSource(const massSource&) = delete;
// Member Functions
// Access
//- Return the name of the density field
const word& rhoName() const
{
return rhoName_;
}
// Checks
//- Return true if the option adds a source term to the given
// field's transport equation
virtual bool addsToField(const word& fieldName) const;
//- Return the list of fields for which the option adds source term
// to the transport equation
virtual wordList addedToFields() const;
// Evaluate
virtual void addSup
(
fvMatrix<scalar>& eqn,
const word& fieldName
) const;
virtual void addSup
(
fvMatrix<vector>& eqn,
const word& fieldName
) const;
virtual void addSup
(
fvMatrix<sphericalTensor>& eqn,
const word& fieldName
) const;
virtual void addSup
(
fvMatrix<symmTensor>& eqn,
const word& fieldName
) const;
virtual void addSup
(
fvMatrix<tensor>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& rho,
fvMatrix<scalar>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& rho,
fvMatrix<vector>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& rho,
fvMatrix<sphericalTensor>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& rho,
fvMatrix<symmTensor>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& rho,
fvMatrix<tensor>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<scalar>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<vector>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<sphericalTensor>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<symmTensor>& eqn,
const word& fieldName
) const;
virtual void addSup
(
const volScalarField& alpha,
const volScalarField& rho,
fvMatrix<tensor>& eqn,
const word& fieldName
) const;
// IO
//- Read source dictionary
virtual bool read(const dictionary& dict);
// Member Operators
//- Disallow default bitwise assignment
void operator=(const massSource&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -19,26 +19,21 @@ options
{
massSource
{
type semiImplicitSource;
timeStart 0;
duration 1e6;
type massSource;
selectionMode points;
points
(
(0.075 0.925 0.05)
);
points ((0.075 0.925 0.05));
volumeMode absolute;
sources
massFlowRate 1;
phase water;
rho thermo:rho.water;
fieldValues
{
thermo:rho.water
{
explicit 1; // kg/s
implicit 0;
}
U.water (0 0 0);
}
}
}

View File

@ -19,7 +19,7 @@ options
{
massSource
{
type semiImplicitSource;
type massSource;
timeStart 0.1;
duration 5;
@ -32,25 +32,22 @@ options
volumeMode absolute;
sources
phase air;
rho thermo:rho.air;
massFlowRate
{
thermo:rho.air
{
explicit 1e-3; // kg/s
implicit 0;
type scale;
scale squarePulse;
start 0.1;
duration 5;
value 1e-3;
}
U.air
fieldValues
{
explicit (0 -1e-2 0); // kg*m/s^2
implicit 0;
}
e.air
{
explicit 500; // kg*m^2/s^3
implicit 0;
}
U.air (0 -10 0);
T.air 300;
}
}
}

View File

@ -19,7 +19,7 @@ options
{
massSource
{
type semiImplicitSource;
type massSource;
timeStart 1;
duration 500;
@ -32,25 +32,22 @@ options
volumeMode absolute;
sources
phase steam;
rho thermo:rho.steam;
massFlowRate
{
thermo:rho.steam
{
explicit 1.0e-3; // kg/s
implicit 0;
type scale;
scale squarePulse;
start 1;
duration 1e6;
value 1e-3;
}
U.steam
fieldValues
{
explicit (0 1e-1 0); // kg*m/s^2
implicit 0;
}
h.steam
{
explicit 3700; // kg*m^2/s^3
implicit 0;
}
U.steam (0 10 0);
h.steam 3700000;
}
}