From 39f0971c72bbb5b5ec7163c2567ab54f7ae88ee0 Mon Sep 17 00:00:00 2001 From: Sergio Ferraris <sergio@alex.opencfd.co.uk> Date: Wed, 11 Sep 2013 11:31:43 +0100 Subject: [PATCH] ENH: Adding mixed coupled BC for pyrolysis, film and gas regions incorporating radiation --- src/regionModels/regionCoupling/Make/files | 1 + src/regionModels/regionCoupling/Make/options | 9 + ...sRadiativeCoupledMixedFvPatchScalarField.C | 372 ++++++++++++++++++ ...sRadiativeCoupledMixedFvPatchScalarField.H | 232 +++++++++++ 4 files changed, 614 insertions(+) create mode 100644 src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.C create mode 100644 src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.H diff --git a/src/regionModels/regionCoupling/Make/files b/src/regionModels/regionCoupling/Make/files index 846df33e9ea..c1ebaf79905 100644 --- a/src/regionModels/regionCoupling/Make/files +++ b/src/regionModels/regionCoupling/Make/files @@ -1,4 +1,5 @@ derivedFvPatchFields/filmPyrolysisVelocityCoupled/filmPyrolysisVelocityCoupledFvPatchVectorField.C derivedFvPatchFields/filmPyrolysisTemperatureCoupled/filmPyrolysisTemperatureCoupledFvPatchScalarField.C +derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.C LIB = $(FOAM_LIBBIN)/libregionCoupling diff --git a/src/regionModels/regionCoupling/Make/options b/src/regionModels/regionCoupling/Make/options index 28569ccda68..741293c78e3 100644 --- a/src/regionModels/regionCoupling/Make/options +++ b/src/regionModels/regionCoupling/Make/options @@ -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 \ diff --git a/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.C b/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.C new file mode 100644 index 00000000000..ed3d509d60f --- /dev/null +++ b/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.C @@ -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 + + +// ************************************************************************* // diff --git a/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.H b/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.H new file mode 100644 index 00000000000..734b19b3646 --- /dev/null +++ b/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisRadiativeCoupledMixed/filmPyrolysisRadiativeCoupledMixedFvPatchScalarField.H @@ -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 + +// ************************************************************************* // -- GitLab