1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
28 #include "addToRunTimeSelectionTable.H"
30 #include "mathematicalConstants.H"
31 #include "radiationConstants.H"
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 defineTypeNameAndDebug(fvDOM, 0);
41 addToRunTimeSelectionTable
51 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
53 Foam::radiation::fvDOM::fvDOM(const volScalarField& T)
55 radiationModel(typeName, T),
61 mesh_.time().timeName(),
67 dimensionedScalar("G", dimMass/pow3(dimTime), 0.0)
74 mesh_.time().timeName(),
80 dimensionedScalar("Qr", dimMass/pow3(dimTime), 0.0)
87 mesh_.time().timeName(),
93 dimensionedScalar("a", dimless/dimLength, 0.0)
100 mesh_.time().timeName(),
106 dimensionedScalar("a", dimless/dimLength, 0.0)
113 mesh_.time().timeName(),
119 dimensionedScalar("E", dimMass/dimLength/pow3(dimTime), 0.0)
121 nTheta_(readLabel(coeffs_.lookup("nTheta"))),
122 nPhi_(readLabel(coeffs_.lookup("nPhi"))),
124 nLambda_(absorptionEmission_->nBands()),
126 blackBody_(nLambda_, T),
128 convergence_(coeffs_.lookupOrDefault<scalar>("convergence", 0.0)),
129 maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50))
131 if (mesh_.nSolutionD() == 3) //3D
133 nRay_ = 4*nPhi_*nTheta_;
134 IRay_.setSize(nRay_);
135 scalar deltaPhi = mathematicalConstant::pi/(2.0*nPhi_);
136 scalar deltaTheta = mathematicalConstant::pi/nTheta_;
138 for (label n = 1; n <= nTheta_; n++)
140 for (label m = 1; m <= 4*nPhi_; m++)
142 scalar thetai = (2.0*n - 1.0)*deltaTheta/2.0;
143 scalar phii = (2.0*m - 1.0)*deltaPhi/2.0;
147 new radiativeIntensityRay
166 if (mesh_.nSolutionD() == 2) //2D (X & Y)
168 scalar thetai = mathematicalConstant::piByTwo;
169 scalar deltaTheta = mathematicalConstant::pi;
171 IRay_.setSize(nRay_);
172 scalar deltaPhi = mathematicalConstant::pi/(2.0*nPhi_);
174 for (label m = 1; m <= 4*nPhi_; m++)
176 scalar phii = (2.0*m - 1.0)*deltaPhi/2.0;
180 new radiativeIntensityRay
198 scalar thetai = mathematicalConstant::piByTwo;
199 scalar deltaTheta = mathematicalConstant::pi;
201 IRay_.setSize(nRay_);
202 scalar deltaPhi = mathematicalConstant::pi;
204 for (label m = 1; m <= 2; m++)
206 scalar phii = (2.0*m - 1.0)*deltaPhi/2.0;
210 new radiativeIntensityRay
230 // Construct absorption field for each wavelength
231 forAll(aLambda_, lambdaI)
240 "aLambda_" + Foam::name(lambdaI) ,
241 mesh_.time().timeName(),
251 Info<< "fvDOM : Allocated " << IRay_.size()
252 << " rays with average orientation:" << nl;
255 Info<< '\t' << IRay_[i].I().name()
256 << '\t' << IRay_[i].dAve() << nl;
262 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
264 Foam::radiation::fvDOM::~fvDOM()
268 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
270 bool Foam::radiation::fvDOM::read()
272 if (radiationModel::read())
274 // Only reading solution parameters - not changing ray geometry
276 coeffs_.readIfPresent("convergence", convergence_);
277 coeffs_.readIfPresent("maxIter", maxIter_);
288 void Foam::radiation::fvDOM::calculate()
290 absorptionEmission_->correct(a_, aLambda_);
292 updateBlackBodyEmission();
294 scalar maxResidual = 0.0;
302 scalar maxBandResidual = IRay_[rayI].correct();
303 maxResidual = max(maxBandResidual, maxResidual);
306 Info << "Radiation solver iter: " << radIter << endl;
308 } while(maxResidual > convergence_ && radIter < maxIter_);
314 Foam::tmp<Foam::volScalarField> Foam::radiation::fvDOM::Rp() const
316 return tmp<volScalarField>
323 mesh_.time().timeName(),
329 4.0*a_*radiation::sigmaSB //absorptionEmission_->a()
335 Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> >
336 Foam::radiation::fvDOM::Ru() const
339 const DimensionedField<scalar, volMesh>& G =
340 G_.dimensionedInternalField();
341 const DimensionedField<scalar, volMesh> E =
342 absorptionEmission_->ECont()().dimensionedInternalField();
343 const DimensionedField<scalar, volMesh> a =
344 a_.dimensionedInternalField(); //absorptionEmission_->aCont()()
350 void Foam::radiation::fvDOM::updateBlackBodyEmission()
352 for (label j=0; j < nLambda_; j++)
354 blackBody_.correct(j, absorptionEmission_->bands(j));
359 void Foam::radiation::fvDOM::updateG()
361 G_ = dimensionedScalar("zero",dimMass/pow3(dimTime), 0.0);
362 Qr_ = dimensionedScalar("zero",dimMass/pow3(dimTime), 0.0);
366 IRay_[rayI].addIntensity();
367 G_ += IRay_[rayI].I()*IRay_[rayI].omega();
368 //Qr_ += IRay_[rayI].Qr();
369 Qr_.boundaryField() += IRay_[rayI].Qr().boundaryField();
374 void Foam::radiation::fvDOM::setRayIdLambdaId
381 // assuming name is in the form: CHARS_rayId_lambdaId
382 size_type i1 = name.find_first_of("_");
383 size_type i2 = name.find_last_of("_");
385 rayId = readLabel(IStringStream(name.substr(i1+1, i2-1))());
386 lambdaId = readLabel(IStringStream(name.substr(i2+1, name.size()-1))());
390 // ************************************************************************* //