/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org \\ / A nd | Copyright (C) 2011-2023 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 . Application viewFactorsGen Description View factors are calculated based on a face agglomeration array (finalAgglom generated by faceAgglomerate utility). Each view factor between the agglomerated faces i and j (Fij) is calculated using a double integral of the sub-areas composing the agglomaration. The patches involved in the view factor calculation are taken from the qr volScalarField (radiative flux) when is greyDiffusiveRadiationViewFactor otherwise they are not included. \*---------------------------------------------------------------------------*/ #include "argList.H" #include "Time.H" #include "singleCellFvMesh.H" #include "volFields.H" #include "surfaceFields.H" #include "fixedValueFvPatchFields.H" #include "distributedTriSurfaceMesh.H" #include "symmetryPolyPatch.H" #include "symmetryPlanePolyPatch.H" #include "wedgePolyPatch.H" #include "meshTools.H" #include "uindirectPrimitivePatch.H" #include "DynamicField.H" #include "scalarListIOList.H" #include "polygonTriangulate.H" #include "vtkWritePolyData.H" #include "scalarMatrices.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // triSurface triangulate ( const polyBoundaryMesh& bMesh, const labelHashSet& includePatches, const labelListIOList& finalAgglom, labelList& triSurfaceToAgglom, const globalIndex& globalNumbering, const polyBoundaryMesh& coarsePatches ) { const polyMesh& mesh = bMesh.mesh(); // Storage for surfaceMesh. Size estimate. DynamicList triangles ( mesh.nFaces() - mesh.nInternalFaces() ); label newPatchi = 0; label localTriFacei = 0; polygonTriangulate triEngine; forAllConstIter(labelHashSet, includePatches, iter) { const label patchi = iter.key(); const polyPatch& patch = bMesh[patchi]; const pointField& points = patch.points(); forAll(patch, patchFacei) { const face& f = patch[patchFacei]; triEngine.triangulate(UIndirectList(points, f)); forAll(triEngine.triPoints(), triFacei) { triangles.append ( labelledTri ( triEngine.triPoints(triFacei, f), newPatchi ) ); triSurfaceToAgglom[localTriFacei++] = globalNumbering.toGlobal ( Pstream::myProcNo(), finalAgglom[patchi][patchFacei] + coarsePatches[patchi].start() ); } } newPatchi++; } triSurfaceToAgglom.resize(localTriFacei); triangles.shrink(); // Create globally numbered tri surface triSurface rawSurface(triangles, mesh.points()); // Create locally numbered tri surface triSurface surface ( rawSurface.localFaces(), rawSurface.localPoints() ); // Add patch names to surface surface.patches().setSize(newPatchi); newPatchi = 0; forAllConstIter(labelHashSet, includePatches, iter) { const label patchi = iter.key(); const polyPatch& patch = bMesh[patchi]; surface.patches()[newPatchi].index() = patchi; surface.patches()[newPatchi].name() = patch.name(); surface.patches()[newPatchi].geometricType() = patch.type(); newPatchi++; } return surface; } void writeRays ( const fileName& fName, const pointField& compactCf, const pointField& myFc, const labelListList& visibleFaceFaces ) { DynamicList allPoints; allPoints.append(myFc); allPoints.append(compactCf); DynamicList rays; forAll(myFc, facei) { const labelList visFaces = visibleFaceFaces[facei]; forAll(visFaces, faceRemote) { rays.append ( labelPair(facei, myFc.size() + visFaces[faceRemote]) ); } } Pout<< "\nDumping rays to " << fName + ".vtk" << endl; vtkWritePolyData::write ( fName + ".vtk", fName.name(), false, allPoints, labelList(), rays, faceList() ); } scalar calculateViewFactorFij ( const vector& i, const vector& j, const vector& dAi, const vector& dAj ) { vector r = i - j; scalar rMag = mag(r); if (rMag > small) { scalar dAiMag = mag(dAi); scalar dAjMag = mag(dAj); vector ni = dAi/dAiMag; vector nj = dAj/dAjMag; scalar cosThetaJ = mag(nj & r)/rMag; scalar cosThetaI = mag(ni & r)/rMag; return ( (cosThetaI*cosThetaJ*dAjMag*dAiMag) /(sqr(rMag)*constant::mathematical::pi) ); } else { return 0; } } void insertMatrixElements ( const globalIndex& globalNumbering, const label fromProci, const labelListList& globalFaceFaces, const scalarListList& viewFactors, scalarSquareMatrix& matrix ) { forAll(viewFactors, facei) { const scalarList& vf = viewFactors[facei]; const labelList& globalFaces = globalFaceFaces[facei]; label globalI = globalNumbering.toGlobal(fromProci, facei); forAll(globalFaces, i) { matrix[globalI][globalFaces[i]] = vf[i]; } } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { #include "addRegionOption.H" #include "setRootCase.H" #include "createTime.H" #include "createNamedMesh.H" const polyBoundaryMesh& patches = mesh.boundaryMesh(); forAll(patches, patchi) { const polyPatch& pp = patches[patchi]; if ( isA(pp) || isA(pp) || isA(pp) || isA(pp) ) { FatalErrorIn(args.executable()) << args.executable() << " does not currently support transforming patches: " "cyclic, symmetry and wedge." << exit(FatalError); } } // Read view factor dictionary IOdictionary viewFactorDict ( IOobject ( "viewFactorsDict", runTime.system(), mesh, IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE ) ); const bool writeViewFactors = viewFactorDict.lookupOrDefault("writeViewFactorMatrix", false); const bool dumpRays = viewFactorDict.lookupOrDefault("dumpRays", false); const label debug = viewFactorDict.lookupOrDefault