1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "viewFactor.H"
27 #include "surfaceFields.H"
28 #include "addToRunTimeSelectionTable.H"
29 #include "mathematicalConstants.H"
30 #include "radiationConstants.H"
31 #include "greyDiffusiveViewFactorFixedValueFvPatchScalarField.H"
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 defineTypeNameAndDebug(viewFactor, 0);
43 addToRunTimeSelectionTable
53 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
55 void Foam::radiation::viewFactor::initialise()
57 const polyBoundaryMesh& coarsePatches = coarseMesh_.boundaryMesh();
58 const volScalarField::GeometricBoundaryField& Qrp = Qr_.boundaryField();
63 //const polyPatch& pp = mesh_.boundaryMesh()[patchI];
64 const fvPatchScalarField& QrPatchI = Qrp[patchI];
66 if ((isA<fixedValueFvPatchScalarField>(QrPatchI)))
68 selectedPatches_[count] = QrPatchI.patch().index();
69 nLocalCoarseFaces_ += coarsePatches[patchI].size();
74 selectedPatches_.resize(count--);
78 Pout<< "Selected patches:" << selectedPatches_ << endl;
79 Pout<< "Number of coarse faces:" << nLocalCoarseFaces_ << endl;
82 totalNCoarseFaces_ = nLocalCoarseFaces_;
83 reduce(totalNCoarseFaces_, sumOp<label>());
85 if (Pstream::master())
87 Info<< "Total number of clusters : " << totalNCoarseFaces_ << endl;
90 labelListIOList subMap
95 mesh_.facesInstance(),
103 labelListIOList constructMap
108 mesh_.facesInstance(),
116 IOList<label> consMapDim
121 mesh_.facesInstance(),
134 Xfer<labelListList>(subMap),
135 Xfer<labelListList>(constructMap)
139 scalarListIOList FmyProc
144 mesh_.facesInstance(),
152 labelListIOList globalFaceFaces
157 mesh_.facesInstance(),
165 List<labelListList> globalFaceFacesProc(Pstream::nProcs());
166 globalFaceFacesProc[Pstream::myProcNo()] = globalFaceFaces;
167 Pstream::gatherList(globalFaceFacesProc);
169 List<scalarListList> F(Pstream::nProcs());
170 F[Pstream::myProcNo()] = FmyProc;
171 Pstream::gatherList(F);
173 globalIndex globalNumbering(nLocalCoarseFaces_);
175 if (Pstream::master())
179 new scalarSquareMatrix(totalNCoarseFaces_, 0.0)
182 Info<< "Insert elements in the matrix..." << endl;
184 for (label procI = 0; procI < Pstream::nProcs(); procI++)
190 globalFaceFacesProc[procI],
197 bool smoothing = readBool(coeffs_.lookup("smoothing"));
200 Info<< "Smoothing the matrix..." << endl;
202 for (label i=0; i<totalNCoarseFaces_; i++)
205 for (label j=0; j<totalNCoarseFaces_; j++)
207 sumF += Fmatrix_()[i][j];
209 scalar delta = 1.0 - sumF;
210 for (label j=0; j<totalNCoarseFaces_; j++)
212 Fmatrix_()[i][j] *= (1.0 - delta/(sumF + 0.001));
217 constEmissivity_ = readBool(coeffs_.lookup("constantEmissivity"));
218 if (constEmissivity_)
222 new scalarSquareMatrix
229 pivotIndices_.setSize(CLU_().n());
235 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
237 Foam::radiation::viewFactor::viewFactor(const volScalarField& T)
239 radiationModel(typeName, T),
245 mesh_.facesInstance(),
258 mesh_.polyMesh::instance(),
271 mesh_.time().timeName(),
280 selectedPatches_(mesh_.boundary().size(), -1),
281 totalNCoarseFaces_(0),
282 nLocalCoarseFaces_(0),
283 constEmissivity_(false),
291 Foam::radiation::viewFactor::viewFactor
293 const dictionary& dict,
294 const volScalarField& T
297 radiationModel(typeName, T),
303 mesh_.facesInstance(),
316 mesh_.polyMesh::instance(),
329 mesh_.time().timeName(),
338 selectedPatches_(mesh_.boundary().size(), -1),
339 totalNCoarseFaces_(0),
340 nLocalCoarseFaces_(0),
341 constEmissivity_(false),
349 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
351 Foam::radiation::viewFactor::~viewFactor()
355 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
357 bool Foam::radiation::viewFactor::read()
359 if (radiationModel::read())
370 void Foam::radiation::viewFactor::insertMatrixElements
372 const globalIndex& globalNumbering,
374 const labelListList& globalFaceFaces,
375 const scalarListList& viewFactors,
376 scalarSquareMatrix& Fmatrix
379 forAll(viewFactors, faceI)
381 const scalarList& vf = viewFactors[faceI];
382 const labelList& globalFaces = globalFaceFaces[faceI];
384 label globalI = globalNumbering.toGlobal(procI, faceI);
385 forAll(globalFaces, i)
387 Fmatrix[globalI][globalFaces[i]] = vf[i];
393 void Foam::radiation::viewFactor::calculate()
395 // Store previous iteration
398 scalarField compactCoarseT(map_->constructSize(), 0.0);
399 scalarField compactCoarseE(map_->constructSize(), 0.0);
400 scalarField compactCoarseHo(map_->constructSize(), 0.0);
402 globalIndex globalNumbering(nLocalCoarseFaces_);
404 // Fill local averaged(T), emissivity(E) and external heatFlux(Ho)
405 DynamicList<scalar> localCoarseTave(nLocalCoarseFaces_);
406 DynamicList<scalar> localCoarseEave(nLocalCoarseFaces_);
407 DynamicList<scalar> localCoarseHoave(nLocalCoarseFaces_);
409 forAll(selectedPatches_, i)
411 label patchID = selectedPatches_[i];
413 const scalarField& Tp = T_.boundaryField()[patchID];
414 const scalarField& sf = mesh_.magSf().boundaryField()[patchID];
416 fvPatchScalarField& QrPatch = Qr_.boundaryField()[patchID];
418 greyDiffusiveViewFactorFixedValueFvPatchScalarField& Qrp =
421 greyDiffusiveViewFactorFixedValueFvPatchScalarField
424 const scalarList eb = Qrp.emissivity();
426 const scalarList& Hoi = Qrp.Qro();
428 const polyPatch& pp = coarseMesh_.boundaryMesh()[patchID];
429 const labelList& coarsePatchFace = coarseMesh_.patchFaceMap()[patchID];
431 scalarList Tave(pp.size(), 0.0);
432 scalarList Eave(Tave.size(), 0.0);
433 scalarList Hoiave(Tave.size(), 0.0);
437 const labelList& agglom = finalAgglom_[patchID];
438 label nAgglom = max(agglom) + 1;
440 labelListList coarseToFine(invertOneToMany(nAgglom, agglom));
442 forAll(coarseToFine, coarseI)
444 const label coarseFaceID = coarsePatchFace[coarseI];
445 const labelList& fineFaces = coarseToFine[coarseFaceID];
446 UIndirectList<scalar> fineSf
451 scalar area = sum(fineSf());
452 // Temperature, emissivity and external flux area weighting
455 label faceI = fineFaces[j];
456 Tave[coarseI] += (Tp[faceI]*sf[faceI])/area;
457 Eave[coarseI] += (eb[faceI]*sf[faceI])/area;
458 Hoiave[coarseI] += (Hoi[faceI]*sf[faceI])/area;
463 localCoarseTave.append(Tave);
464 localCoarseEave.append(Eave);
465 localCoarseHoave.append(Hoiave);
468 // Fill the local values to distribute
469 SubList<scalar>(compactCoarseT,nLocalCoarseFaces_).assign(localCoarseTave);
470 SubList<scalar>(compactCoarseE,nLocalCoarseFaces_).assign(localCoarseEave);
472 (compactCoarseHo,nLocalCoarseFaces_).assign(localCoarseHoave);
475 map_->distribute(compactCoarseT);
476 map_->distribute(compactCoarseE);
477 map_->distribute(compactCoarseHo);
479 // Distribute local global ID
480 labelList compactGlobalIds(map_->constructSize(), 0.0);
482 labelList localGlobalIds(nLocalCoarseFaces_);
484 for(label k = 0; k < nLocalCoarseFaces_; k++)
486 localGlobalIds[k] = globalNumbering.toGlobal(Pstream::myProcNo(), k);
493 ).assign(localGlobalIds);
495 map_->distribute(compactGlobalIds);
497 // Create global size vectors
498 scalarField T(totalNCoarseFaces_, 0.0);
499 scalarField E(totalNCoarseFaces_, 0.0);
500 scalarField QrExt(totalNCoarseFaces_, 0.0);
502 // Fill lists from compact to global indexes.
503 forAll(compactCoarseT, i)
505 T[compactGlobalIds[i]] = compactCoarseT[i];
506 E[compactGlobalIds[i]] = compactCoarseE[i];
507 QrExt[compactGlobalIds[i]] = compactCoarseHo[i];
510 Pstream::listCombineGather(T, maxEqOp<scalar>());
511 Pstream::listCombineGather(E, maxEqOp<scalar>());
512 Pstream::listCombineGather(QrExt, maxEqOp<scalar>());
514 Pstream::listCombineScatter(T);
515 Pstream::listCombineScatter(E);
516 Pstream::listCombineScatter(QrExt);
519 scalarField q(totalNCoarseFaces_, 0.0);
521 if (Pstream::master())
523 // Variable emissivity
524 if (!constEmissivity_)
526 scalarSquareMatrix C(totalNCoarseFaces_, 0.0);
528 for (label i=0; i<totalNCoarseFaces_; i++)
530 for (label j=0; j<totalNCoarseFaces_; j++)
532 scalar invEj = 1.0/E[j];
534 radiation::sigmaSB.value()*pow(T[j], 4.0);
538 C[i][j] = invEj - (invEj - 1.0)*Fmatrix_()[i][j];
539 q[i] += (Fmatrix_()[i][j] - 1.0)*sigmaT4 - QrExt[j];
543 C[i][j] = (1.0 - invEj)*Fmatrix_()[i][j];
544 q[i] += Fmatrix_()[i][j]*sigmaT4 - QrExt[j];
550 Info<< "\nSolving view factor equations..." << endl;
551 // Negative coming into the fluid
552 scalarSquareMatrix::LUsolve(C, q);
554 else //Constant emissivity
556 // Initial iter calculates CLU and chaches it
557 if (iterCounter_ == 0)
559 for (label i=0; i<totalNCoarseFaces_; i++)
561 for (label j=0; j<totalNCoarseFaces_; j++)
563 scalar invEj = 1.0/E[j];
566 CLU_()[i][j] = invEj-(invEj-1.0)*Fmatrix_()[i][j];
570 CLU_()[i][j] = (1.0 - invEj)*Fmatrix_()[i][j];
574 Info<< "\nDecomposing C matrix..." << endl;
575 scalarSquareMatrix::LUDecompose(CLU_(), pivotIndices_);
578 for (label i=0; i<totalNCoarseFaces_; i++)
580 for (label j=0; j<totalNCoarseFaces_; j++)
583 radiation::sigmaSB.value()
588 q[i] += (Fmatrix_()[i][j] - 1.0)*sigmaT4 - QrExt[j];
592 q[i] += Fmatrix_()[i][j]*sigmaT4 - QrExt[j];
597 Info<< "\nLU Back substitute C matrix.." << endl;
598 scalarSquareMatrix::LUBacksubstitute(CLU_(), pivotIndices_, q);
603 // Scatter q and fill Qr
604 Pstream::listCombineScatter(q);
605 Pstream::listCombineGather(q, maxEqOp<scalar>());
608 label globCoarseId = 0;
609 forAll(selectedPatches_, i)
611 const label patchID = selectedPatches_[i];
612 const polyPatch& pp = mesh_.boundaryMesh()[patchID];
615 scalarField& Qrp = Qr_.boundaryField()[patchID];
616 const scalarField& sf = mesh_.magSf().boundaryField()[patchID];
617 const labelList& agglom = finalAgglom_[patchID];
618 label nAgglom = max(agglom)+1;
620 labelListList coarseToFine(invertOneToMany(nAgglom, agglom));
622 const labelList& coarsePatchFace =
623 coarseMesh_.patchFaceMap()[patchID];
625 scalar heatFlux = 0.0;
626 forAll(coarseToFine, coarseI)
629 globalNumbering.toGlobal(Pstream::myProcNo(), globCoarseId);
630 const label coarseFaceID = coarsePatchFace[coarseI];
631 const labelList& fineFaces = coarseToFine[coarseFaceID];
634 label faceI = fineFaces[k];
636 Qrp[faceI] = q[globalCoarse];
637 heatFlux += Qrp[faceI]*sf[faceI];
646 forAll(Qr_.boundaryField(), patchID)
648 const scalarField& Qrp = Qr_.boundaryField()[patchID];
649 const scalarField& magSf = mesh_.magSf().boundaryField()[patchID];
650 scalar heatFlux = gSum(Qrp*magSf);
651 Info<< "Total heat flux at patch: "
653 << heatFlux << " [W]" << endl;
657 // Relax Qr if necessary
662 Foam::tmp<Foam::volScalarField> Foam::radiation::viewFactor::Rp() const
664 return tmp<volScalarField>
671 mesh_.time().timeName(),
681 dimMass/pow3(dimTime)/dimLength/pow4(dimTemperature),
689 Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> >
690 Foam::radiation::viewFactor::Ru() const
692 return tmp<DimensionedField<scalar, volMesh> >
694 new DimensionedField<scalar, volMesh>
699 mesh_.time().timeName(),
706 dimensionedScalar("zero", dimMass/dimLength/pow3(dimTime), 0.0)
711 // ************************************************************************* //