fvOptions::SemiImplicitSource: Added support for Function1 specifications of the explicit and implicit sources

This significant improvement is flexibility of SemiImplicitSource required a
generalisation of the source specification syntax and all tutorials have been
updated accordingly.

Description
    Semi-implicit source, described using an input dictionary.  The injection
    rate coefficients are specified as pairs of Su-Sp coefficients, i.e.

        \f[
            S(x) = S_u + S_p x
        \f]

    where
    \vartable
        S(x)    | net source for field 'x'
        S_u     | explicit source contribution
        S_p     | linearised implicit contribution
    \endvartable

    Example tabulated heat source specification for internal energy:
    \verbatim
    volumeMode      absolute; // specific
    sources
    {
        e
        {
            explicit table ((0 0) (1.5 $power));
            implicit 0;
        }
    }
    \endverbatim

    Example coded heat source specification for enthalpy:
    \verbatim
    volumeMode      absolute; // specific
    sources
    {
        h
        {
            explicit
            {
                type coded;
                name heatInjection;
                code
                #{
                    // Power amplitude
                    const scalar powerAmplitude = 1000;

                    // x is the current time
                    return mag(powerAmplitude*sin(x));
                #};
            }
            implicit 0;
        }
    }
    \endverbatim
This commit is contained in:
Jakub Knir
2020-04-01 18:53:09 +01:00
parent c1587d5fc6
commit 95b5ef4458
15 changed files with 203 additions and 264 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -83,8 +83,9 @@ Foam::word Foam::fv::SemiImplicitSource<Type>::volumeModeTypeToWord
template<class Type>
void Foam::fv::SemiImplicitSource<Type>::setFieldData(const dictionary& dict)
{
fieldNames_.setSize(dict.toc().size());
injectionRate_.setSize(fieldNames_.size());
fieldNames_.setSize(dict.size());
Su_.setSize(fieldNames_.size());
Sp_.setSize(fieldNames_.size());
applied_.setSize(fieldNames_.size(), false);
@ -92,7 +93,9 @@ void Foam::fv::SemiImplicitSource<Type>::setFieldData(const dictionary& dict)
forAllConstIter(dictionary, dict, iter)
{
fieldNames_[i] = iter().keyword();
dict.lookup(iter().keyword()) >> injectionRate_[i];
const dictionary& fieldSubDict(iter().dict());
Su_.set(i, Function1<Type>::New("explicit", fieldSubDict));
Sp_.set(i, Function1<scalar>::New("implicit", fieldSubDict));
i++;
}
@ -117,8 +120,7 @@ Foam::fv::SemiImplicitSource<Type>::SemiImplicitSource
:
cellSetOption(name, modelType, dict, mesh),
volumeMode_(vmAbsolute),
VDash_(1.0),
injectionRate_()
VDash_(1)
{
read(dict);
}
@ -139,6 +141,8 @@ void Foam::fv::SemiImplicitSource<Type>::addSup
<< ">::addSup for source " << name_ << endl;
}
const scalar t = mesh_.time().value();
const GeometricField<Type, fvPatchField, volMesh>& psi = eqn.psi();
typename GeometricField<Type, fvPatchField, volMesh>::Internal Su
@ -161,7 +165,7 @@ void Foam::fv::SemiImplicitSource<Type>::addSup
false
);
UIndirectList<Type>(Su, cells_) = injectionRate_[fieldi].first()/VDash_;
UIndirectList<Type>(Su, cells_) = Su_[fieldi].value(t)/VDash_;
volScalarField::Internal Sp
(
@ -178,12 +182,12 @@ void Foam::fv::SemiImplicitSource<Type>::addSup
(
"zero",
Su.dimensions()/psi.dimensions(),
0.0
0
),
false
);
UIndirectList<scalar>(Sp, cells_) = injectionRate_[fieldi].second()/VDash_;
UIndirectList<scalar>(Sp, cells_) = Sp_[fieldi].value(t)/VDash_;
eqn += Su + fvm::SuSp(Sp, psi);
}
@ -207,4 +211,21 @@ void Foam::fv::SemiImplicitSource<Type>::addSup
}
template<class Type>
bool Foam::fv::SemiImplicitSource<Type>::read(const dictionary& dict)
{
if (cellSetOption::read(dict))
{
volumeMode_ = wordToVolumeModeType(coeffs_.lookup("volumeMode"));
setFieldData(coeffs_.subDict("sources"));
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -39,14 +39,41 @@ Description
S_p | linearised implicit contribution
\endvartable
Example of the source specification:
Example tabulated heat source specification for internal energy:
\verbatim
volumeMode absolute; // specific
injectionRateSuSp
sources
{
k (30.7 0);
epsilon (1.5 0);
e
{
explicit table ((0 0) (1.5 $power));
implicit 0;
}
}
\endverbatim
Example coded heat source specification for enthalpy:
\verbatim
volumeMode absolute; // specific
sources
{
h
{
explicit
{
type coded;
name heatInjection;
code
#{
// Power amplitude
const scalar powerAmplitude = 1000;
// x is the current time
return mag(powerAmplitude*sin(x));
#};
}
implicit 0;
}
}
\endverbatim
@ -65,8 +92,8 @@ SourceFiles
#ifndef SemiImplicitSource_H
#define SemiImplicitSource_H
#include "Tuple2.H"
#include "cellSetOption.H"
#include "Function1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -75,22 +102,6 @@ namespace Foam
namespace fv
{
// Forward declaration of classes
template<class Type>
class SemiImplicitSource;
// Forward declaration of friend functions
template<class Type>
Ostream& operator<<
(
Ostream&,
const SemiImplicitSource<Type>&
);
/*---------------------------------------------------------------------------*\
Class SemiImplicitSource Declaration
\*---------------------------------------------------------------------------*/
@ -111,25 +122,28 @@ public:
vmSpecific
};
private:
// Private member data
//- Word list of volume mode type names
static const wordList volumeModeTypeNames_;
protected:
// Protected data
//- Volume mode
volumeModeType volumeMode_;
//- Volume normalisation
scalar VDash_;
//- Source field values
List<Tuple2<Type, scalar>> injectionRate_;
//- Explicit source functions for the fields
PtrList<Function1<Type>> Su_;
//- Implicit source functions for the fields
PtrList<Function1<scalar>> Sp_;
// Protected functions
// Private member functions
//- Helper function to convert from a word to a volumeModeType
volumeModeType wordToVolumeModeType(const word& vtName) const;
@ -161,24 +175,6 @@ public:
// Member Functions
// Access
//- Return const access to the volume mode
inline const volumeModeType& volumeMode() const;
//- Return const access to the source field values
inline const List<Tuple2<Type, scalar>>& injectionRate() const;
// Edit
//- Return access to the volume mode
inline volumeModeType& volumeMode();
//- Return access to the source field values
inline List<Tuple2<Type, scalar>>& injectionRate();
// Evaluation
//- Add explicit contribution to equation
@ -213,15 +209,10 @@ public:
#ifdef NoRepository
#include "SemiImplicitSource.C"
#include "SemiImplicitSourceIO.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "SemiImplicitSourceI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,62 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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 "SemiImplicitSource.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
inline const typename Foam::fv::SemiImplicitSource<Type>::volumeModeType&
Foam::fv::SemiImplicitSource<Type>::volumeMode() const
{
return volumeMode_;
}
template<class Type>
inline const Foam::List<Foam::Tuple2<Type, Foam::scalar>>&
Foam::fv::SemiImplicitSource<Type>::injectionRate() const
{
return injectionRate_;
}
template<class Type>
inline typename Foam::fv::SemiImplicitSource<Type>::volumeModeType&
Foam::fv::SemiImplicitSource<Type>::volumeMode()
{
return volumeMode_;
}
template<class Type>
inline Foam::List<Foam::Tuple2<Type,
Foam::scalar>>& Foam::fv::SemiImplicitSource<Type>::injectionRate()
{
return injectionRate_;
}
// ************************************************************************* //

View File

@ -1,47 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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 "SemiImplicitSource.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::fv::SemiImplicitSource<Type>::read(const dictionary& dict)
{
if (cellSetOption::read(dict))
{
volumeMode_ = wordToVolumeModeType(coeffs_.lookup("volumeMode"));
setFieldData(coeffs_.subDict("injectionRateSuSp"));
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -35,10 +35,19 @@ fixedPower
power 100; // Set power (W)
injectionRateSuSp
sources
{
e ($power 0);
h ($power 0);
e
{
explicit $power;
implicit 0;
}
h
{
explicit $power;
implicit 0;
}
}
}

View File

@ -26,9 +26,13 @@ options
selectionMode all;
volumeMode specific;
injectionRateSuSp
sources
{
h (1e7 0); // W/m^3 == kg/m/s^3
h
{
explicit 1e7; // W/m^3 == kg/m/s^3
implicit 0;
}
}
}
}

View File

@ -27,9 +27,13 @@ options
cellSet ignition;
volumeMode specific;
injectionRateSuSp
sources
{
e (5e7 0); // kg/m/s^3
e
{
explicit 5e7; // kg/m/s^3
implicit 0;
}
}
}
}

View File

@ -24,9 +24,14 @@ momentumSource
selectionMode all;
volumeMode specific;
injectionRateSuSp
sources
{
U ((5 0 0) 0);
U
{
explicit (5 0 0);
implicit 0;
}
}
}

View File

@ -50,9 +50,8 @@ IOdictionary fvOptions
)
);
const dictionary& gradPDict =
fvOptions.subDict("momentumSource").subDict("injectionRateSuSp");
const scalar K =
Tuple2<vector, scalar>(gradPDict.lookup("U")).first().x();
fvOptions.subDict("momentumSource").subDict("sources");
const scalar K(vector(gradPDict.subDict("U").lookup("explicit")).x());
dictionary probes(IFstream(runTime.system()/"probes")());
const point location = pointField(probes.lookup("probeLocations"))[0];

View File

@ -1,7 +1,7 @@
#!/bin/sh
tail -n +4 ../postProcessing/probes/0/U | \
tr -s " " | tr -d '(' | cut -d " " -f2-3 > ../Numerical.dat
tr -s " " | tr -d '(' | cut -d " " -f1-2 > ../Numerical.dat
if ! which gnuplot > /dev/null 2>&1
then
@ -24,4 +24,4 @@ gnuplot<<EOF
"../WatersKing.dat" with lines t "Analytical" lt -1
EOF
# ----------------------------------------------------------------- end-of-file
#------------------------------------------------------------------------------

View File

@ -57,10 +57,26 @@ massSource1
);
volumeMode absolute;
injectionRateSuSp
sources
{
rho (1e-4 0); // kg/s
H2O (1e-4 0); // kg/s
rho
{
explicit 1e-4; // kg/s
implicit 0;
}
H2O
{
explicit 1e-4; // kg/s
implicit 0;
}
h
{
explicit 10;
implicit 0;
}
}
}
@ -78,29 +94,14 @@ momentumSource1
);
volumeMode absolute;
injectionRateSuSp
sources
{
U ((0 0.005 0) 0);
}
}
energySource1
{
type scalarSemiImplicitSource;
timeStart 0.2;
duration 2.0;
selectionMode points;
points
(
(2.75 0.5 0)
);
volumeMode absolute;
injectionRateSuSp
{
h (10 0);
U
{
explicit (0 0.005 0);
implicit 0;
}
}
}

View File

@ -35,9 +35,14 @@ options
$injector1;
volumeMode absolute;
injectionRateSuSp
sources
{
thermo:rho.water (1 0); // kg/s
thermo:rho.water
{
explicit 1; // kg/s
implicit 0;
}
}
}
}

View File

@ -35,9 +35,20 @@ options
$injector1;
volumeMode absolute;
injectionRateSuSp
sources
{
thermo:rho.air (1e-3 0); // kg/s
thermo:rho.air
{
explicit 1e-3; // kg/s
implicit 0;
}
e.air
{
explicit 500; // kg*m^2/s^3
implicit 0;
}
}
}
@ -48,22 +59,14 @@ options
$injector1;
volumeMode absolute;
injectionRateSuSp
sources
{
U.air ((0 -1e-2 0) 0); // kg*m/s^2
}
}
energySource1
{
type scalarSemiImplicitSource;
$injector1;
volumeMode absolute;
injectionRateSuSp
{
e.air (500 0); // kg*m^2/s^3
U.air
{
explicit (0 -1e-2 0); // kg*m/s^2
implicit 0; // kg*m/s^2
}
}
}
}

View File

@ -35,9 +35,20 @@ options
$injector1;
volumeMode absolute;
injectionRateSuSp
sources
{
thermo:rho.steam (1.0e-3 0); // kg/s
thermo:rho.steam
{
explicit 1.0e-3; // kg/s
implicit 0;
}
h.steam
{
explicit 3700; // kg*m^2/s^3
implicit 0;
}
}
}
@ -48,22 +59,14 @@ options
$injector1;
volumeMode absolute;
injectionRateSuSp
sources
{
U.steam ((0 1e-1 0) 0); // kg*m/s^2
}
}
energySource1
{
type scalarSemiImplicitSource;
$injector1;
volumeMode absolute;
injectionRateSuSp
{
h.steam (3700 0); // kg*m^2/s^3
U.steam
{
explicit (0 1e-1 0); // kg*m/s^2
implicit 0;
}
}
}

View File

@ -35,9 +35,20 @@ options
$injector1;
volumeMode absolute;
injectionRateSuSp
sources
{
thermo:rho.air (1e-3 0); // kg/s
thermo:rho.air
{
explicit 1e-3; // kg/s
implicit 0;
}
e.air
{
explicit 500; // kg*m^2/s^3
implicit 0;
}
}
}
@ -48,22 +59,14 @@ options
$injector1;
volumeMode absolute;
injectionRateSuSp
sources
{
U.air ((0 -1e-2 0) 0); // kg*m/s^2
}
}
energySource1
{
type scalarSemiImplicitSource;
$injector1;
volumeMode absolute;
injectionRateSuSp
{
e.air (500 0); // kg*m^2/s^3
U.air
{
explicit (0 -1e-2 0); // kg*m/s^2
implicit 0; // kg*m/s^2
}
}
}
}