ENH: Adding mixed coupled BC for pyrolysis, film and gas regions incorporating radiation

This commit is contained in:
Sergio Ferraris
2013-09-11 11:31:43 +01:00
parent 154f809440
commit 39f0971c72
4 changed files with 614 additions and 0 deletions

View File

@ -1,4 +1,5 @@
derivedFvPatchFields/filmPyrolysisVelocityCoupled/filmPyrolysisVelocityCoupledFvPatchVectorField.C
derivedFvPatchFields/filmPyrolysisTemperatureCoupled/filmPyrolysisTemperatureCoupledFvPatchScalarField.C
derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.C
LIB = $(FOAM_LIBBIN)/libregionCoupling

View File

@ -6,8 +6,15 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solid/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/SLGThermo/lnInclude\
-I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidChemistryModel/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/liquidMixtureProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/liquidProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/solidMixtureProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidSpecie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/solidProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel/lnInclude \
@ -23,6 +30,8 @@ LIB_LIBS = \
-lpyrolysisModels \
-lsurfaceFilmModels \
-lsolidChemistryModel \
-lreactionThermophysicalModels \
-lSLGThermo \
-lfiniteVolume \
-lmeshTools \
-lcompressibleRASModels \

View File

@ -0,0 +1,372 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenCFD Ltd.
\\/ 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 "filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "mappedPatchBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::filmModelType&
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::
filmModel() const
{
const regionModels::regionModel& model =
db().time().lookupObject<regionModels::regionModel>
(
"surfaceFilmProperties"
);
return dynamic_cast<const filmModelType&>(model);
}
const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::
pyrolysisModelType&
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::
pyrModel() const
{
const regionModels::regionModel& model =
db().time().lookupObject<regionModels::regionModel>
(
"pyrolysisProperties"
);
return dynamic_cast<const pyrolysisModelType&>(model);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(p, iF),
temperatureCoupledBase(patch(), "undefined", "undefined-K"),
TnbrName_("undefined-Tnbr"),
QrNbrName_("undefined-QrNbr"),
QrName_("undefined-Qr"),
convectiveScaling_(1.0),
filmDeltaDry_(0.0),
filmDeltaWet_(0.0)
{
this->refValue() = 0.0;
this->refGrad() = 0.0;
this->valueFraction() = 1.0;
}
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField& psf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchScalarField(psf, p, iF, mapper),
temperatureCoupledBase(patch(), psf.KMethod(), psf.kappaName()),
TnbrName_(psf.TnbrName_),
QrNbrName_(psf.QrNbrName_),
QrName_(psf.QrName_),
convectiveScaling_(psf.convectiveScaling_),
filmDeltaDry_(psf.filmDeltaDry_),
filmDeltaWet_(psf.filmDeltaWet_)
{}
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchScalarField(p, iF),
temperatureCoupledBase(patch(), dict),
TnbrName_(dict.lookup("Tnbr")),
QrNbrName_(dict.lookup("QrNbr")),
QrName_(dict.lookup("Qr")),
convectiveScaling_(dict.lookupOrDefault<scalar>("convectiveScaling", 1.0)),
filmDeltaDry_(readScalar(dict.lookup("filmDeltaDry"))),
filmDeltaWet_(readScalar(dict.lookup("filmDeltaWet")))
{
if (!isA<mappedPatchBase>(this->patch().patch()))
{
FatalErrorIn
(
"filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::"
"filmPyrolysisRadiativeCoupledMixedFvPatchScalarField\n"
"(\n"
" const fvPatch& p,\n"
" const DimensionedField<scalar, volMesh>& iF,\n"
" const dictionary& dict\n"
")\n"
) << "\n patch type '" << p.type()
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << dimensionedInternalField().name()
<< " in file " << dimensionedInternalField().objectPath()
<< exit(FatalError);
}
fvPatchScalarField::operator=(scalarField("value", dict, p.size()));
if (dict.found("refValue"))
{
// Full restart
refValue() = scalarField("refValue", dict, p.size());
refGrad() = scalarField("refGradient", dict, p.size());
valueFraction() = scalarField("valueFraction", dict, p.size());
}
else
{
// Start from user entered data. Assume fixedValue.
refValue() = *this;
refGrad() = 0.0;
valueFraction() = 1.0;
}
}
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField& psf,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(psf, iF),
temperatureCoupledBase(patch(), psf.KMethod(), psf.kappaName()),
TnbrName_(psf.TnbrName_),
QrNbrName_(psf.QrNbrName_),
QrName_(psf.QrName_),
convectiveScaling_(psf.convectiveScaling_),
filmDeltaDry_(psf.filmDeltaDry_),
filmDeltaWet_(psf.filmDeltaWet_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::
updateCoeffs()
{
if (updated())
{
return;
}
// Get the coupling information from the mappedPatchBase
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const label patchI = patch().index();
const label nbrPatchI = mpp.samplePolyPatch().index();
const polyMesh& mesh = patch().boundaryMesh().mesh();
const polyMesh& nbrMesh = mpp.sampleMesh();
const fvPatch& nbrPatch =
refCast<const fvMesh>(nbrMesh).boundary()[nbrPatchI];
scalarField intFld(patchInternalField());
const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField&
nbrField =
refCast
<
const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
>
(
nbrPatch.lookupPatchField<volScalarField, scalar>(TnbrName_)
);
// Swap to obtain full local values of neighbour internal field
scalarField nbrIntFld(nbrField.patchInternalField());
mpp.distribute(nbrIntFld);
scalarField& Tp = *this;
const scalarField K(this->kappa(*this));
const scalarField nbrK(nbrField.kappa(*this));
// Swap to obtain full local values of neighbour K*delta
scalarField KDeltaNbr(nbrK*nbrPatch.deltaCoeffs());
mpp.distribute(KDeltaNbr);
scalarField myKDelta(K*patch().deltaCoeffs());
scalarList Tfilm(patch().size(), 0.0);
scalarList htcwfilm(patch().size(), 0.0);
scalarList filmDelta(patch().size(), 0.0);
const pyrolysisModelType& pyrolysis = pyrModel();
const filmModelType& film = filmModel();
label myPatchINrbPatchI = -1;
// Obtain Rad heat (Qr)
scalarField Qr(patch().size(), 0.0);
if (QrName_ != "none") //region0
{
Qr = patch().lookupPatchField<volScalarField, scalar>(QrName_);
myPatchINrbPatchI = nbrPatch.index();
}
if (QrNbrName_ != "none") //pyrolysis
{
Qr = nbrPatch.lookupPatchField<volScalarField, scalar>(QrNbrName_);
mpp.distribute(Qr);
myPatchINrbPatchI = patchI;
}
const label filmPatchI =
pyrolysis.nbrCoupledPatchID(film, myPatchINrbPatchI);
const scalarField htcw(film.htcw().h()().boundaryField()[filmPatchI]);
// Obtain htcw
htcwfilm =
const_cast<pyrolysisModelType&>(pyrolysis).mapRegionPatchField
(
film,
myPatchINrbPatchI,
filmPatchI,
htcw,
true
);
// Obtain Tfilm at the boundary through Ts.
// NOTE: Tf is not good as at the boundary it will retrieve Tp
Tfilm = film.Ts().boundaryField()[filmPatchI];
film.toPrimary(filmPatchI, Tfilm);
// Obtain delta
filmDelta =
const_cast<pyrolysisModelType&>(pyrolysis).mapRegionPatchField<scalar>
(
film,
"deltaf",
myPatchINrbPatchI,
true
);
// Estimate wetness of the film (1: wet , 0: dry)
scalarField ratio
(
min
(
max
(
(filmDelta - filmDeltaDry_)/(filmDeltaWet_ - filmDeltaDry_),
scalar(0.0)
),
scalar(1.0)
)
);
scalarField qConv(ratio*htcwfilm*(Tfilm - Tp)*convectiveScaling_);
scalarField qRad((1.0 - ratio)*Qr);
scalarField alpha(KDeltaNbr - (qRad + qConv)/Tp);
valueFraction() = alpha/(alpha + (1.0 - ratio)*myKDelta);
refValue() = ratio*Tfilm + (1.0 - ratio)*(KDeltaNbr*nbrIntFld)/alpha;
mixedFvPatchScalarField::updateCoeffs();
if (debug)
{
scalar Qc = gSum(qConv*patch().magSf());
scalar Qr = gSum(qRad*patch().magSf());
scalar Qt = gSum((qConv + qRad)*patch().magSf());
Info<< mesh.name() << ':'
<< patch().name() << ':'
<< this->dimensionedInternalField().name() << " <- "
<< nbrMesh.name() << ':'
<< nbrPatch.name() << ':'
<< this->dimensionedInternalField().name() << " :" << nl
<< " convective heat[W] : " << Qc << nl
<< " radiative heat [W] : " << Qr << nl
<< " total heat [W] : " << Qt << nl
<< " walltemperature "
<< " min:" << gMin(*this)
<< " max:" << gMax(*this)
<< " avg:" << gAverage(*this)
<< endl;
}
}
void filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::write
(
Ostream& os
) const
{
mixedFvPatchScalarField::write(os);
os.writeKeyword("Tnbr")<< TnbrName_ << token::END_STATEMENT << nl;
os.writeKeyword("QrNbr")<< QrNbrName_ << token::END_STATEMENT << nl;
os.writeKeyword("Qr")<< QrName_ << token::END_STATEMENT << nl;
os.writeKeyword("convectiveScaling") << convectiveScaling_
<< token::END_STATEMENT << nl;
os.writeKeyword("filmDeltaDry") << filmDeltaDry_ <<
token::END_STATEMENT << nl;
os.writeKeyword("filmDeltaWet") << filmDeltaWet_ <<
token::END_STATEMENT << endl;
temperatureCoupledBase::write(os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,232 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenCFD Ltd.
\\/ 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::
compressible::
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
Description
Mixed boundary condition for temperature, to be used in the flow and
pyrolysis regions when a film region model is used.
Example usage:
myInterfacePatchName
{
type filmPyrolysisRadiativeCoupledMixed;
Tnbr T;
kappa fluidThermo;
QrNbr none;
Qr Qr;
kappaName none;
filmDeltaDry 0.0;
filmDeltaWet 3e-4;
value $internalField;
}
Needs to be on underlying mapped(Wall)FvPatch.
It calculates local field as
ratio = (filmDelta - filmDeltaDry)/(filmDeltaWet - filmDeltaDry),
when ratio = 1 is considered wet and the film temperarture is fixed at
the wall. If ratio = 0 (dry) it emulates the normal radiative solid BC.
In between ratio 0 and 1 the gradient and value contributions are
weighted using the ratio field in the followig way:
qConv = ratio*htcwfilm*(Tfilm - *this)*convectiveScaling_;
qRad = (1.0 - ratio)*Qr;
Then the solid can gain or loose energy through radiation or conduction
towards the film.
Note: kappa : heat conduction at patch.
Gets supplied how to lookup/calculate kappa:
- 'lookup' : lookup volScalarField (or volSymmTensorField) with name
- 'basicThermo' : use basicThermo and compressible::RASmodel to calculate K
- 'solidThermo' : use basicSolidThermo K()
Qr is the radiative flux defined in the radiation model.
SourceFiles
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef filmPyrolysisRadiativeCoupledMixedFvPatchScalarField_H
#define filmPyrolysisRadiativeCoupledMixedFvPatchScalarField_H
#include "mixedFvPatchFields.H"
#include "temperatureCoupledBase.H"
#include "thermoSingleLayer.H"
#include "pyrolysisModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class filmPyrolysisRadiativeCoupledMixedFvPatchScalarField Declaration
\*---------------------------------------------------------------------------*/
class filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
:
public mixedFvPatchScalarField,
public temperatureCoupledBase
{
public:
typedef Foam::regionModels::surfaceFilmModels::thermoSingleLayer
filmModelType;
typedef Foam::regionModels::pyrolysisModels::pyrolysisModel
pyrolysisModelType;
private:
// Private data
//- Name of field on the neighbour region
const word TnbrName_;
//- Name of the radiative heat flux in the neighbout region
const word QrNbrName_;
//- Name of the radiative heat flux in local region
const word QrName_;
//- Convective Scaling Factor (as determined by Prateep's tests)
const scalar convectiveScaling_;
//- Minimum delta film to be consired dry
const scalar filmDeltaDry_;
//- Maximum delta film to be consired wet
const scalar filmDeltaWet_;
//- Retrieve film model from the database
const filmModelType& filmModel() const;
//- Retrieve pyrolysis model from the database
const pyrolysisModelType& pyrModel() const;
public:
//- Runtime type information
TypeName("filmPyrolysisRadiativeCoupledMixed");
// Constructors
//- Construct from patch and internal field
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// turbulentTemperatureCoupledBaffleMixedFvPatchScalarField onto a
// new patch
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
const
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
*this
)
);
}
//- Construct as copy setting internal field reference
filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
(
*this,
iF
)
);
}
// Member functions
//- Get corresponding K field
tmp<scalarField> K() const;
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //