45 void Foam::faceReflecting::initialise(
const dictionary& coeffs)
48 forAll(qreflective_, bandI)
58 mesh_.time().timeName(),
71 if (mesh_.nSolutionD() == 3)
73 nRay_ = 4*nPhi_*nTheta_;
74 refDiscAngles_.resize(nRay_);
75 const scalar deltaPhi =
pi/(2.0*nPhi_);
76 const scalar deltaTheta =
pi/nTheta_;
78 for (label
n = 1;
n <= nTheta_;
n++)
80 for (label m = 1; m <= 4*nPhi_; m++)
82 const scalar thetai = (2*
n - 1)*deltaTheta/2.0;
83 const scalar phii = (2*m - 1)*deltaPhi/2.0;
89 refDiscAngles_[rayI++] =
96 else if (mesh_.nSolutionD() == 2)
99 refDiscAngles_.resize(nRay_);
102 const scalar deltaPhi =
pi/(2.0*nPhi_);
103 for (label m = 1; m <= 4*nPhi_; m++)
105 const scalar phii = (2*m - 1)*deltaPhi/2.0;
112 refDiscAngles_[rayI++] =
119 <<
"The reflected rays are available in 2D or 3D " 123 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
125 const radiation::boundaryRadiationProperties& boundaryRadiation =
129 globalIndex globalNumbering(mesh_.nFaces());
134 DynamicList<point> dynCf;
135 DynamicList<vector> dynNf;
136 DynamicList<label> dynFacesI;
142 if (!
pp.coupled() && !isA<cyclicAMIPolyPatch>(
pp))
144 const tmp<scalarField> tt =
145 boundaryRadiation.transmissivity(patchI);
147 const tmp<scalarField>
tr =
148 boundaryRadiation.specReflectivity(patchI);
150 const tmp<scalarField> ta =
151 boundaryRadiation.absorptivity(patchI);
170 dynFacesI.append(faceI +
pp.start());
171 dynCf.append(cf[faceI]);
172 dynNf.append(
n[faceI]);
179 (r[faceI] > 0 && t[faceI] == 0) ||
180 (t[faceI] == 0 && a[faceI] > 0 && r[faceI] == 0)
183 includePatches_.insert(patchI);
189 shootFacesIds_.reset(
new labelList(dynFacesI));
201 treeBoundBox(mesh_.points()).extend(
rndGen, 1
e-3)
215 dict.add(
"mergeDistance", SMALL);
220 mesh_.boundaryMesh(),
227 new distributedTriSurfaceMesh
231 "reflectiveSurface.stl",
232 mesh_.time().constant(),
245 surfacesMesh_->searchableSurface::write();
250 void Foam::faceReflecting::calculate()
252 const radiation::boundaryRadiationProperties& boundaryRadiation =
257 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
259 const fvBoundaryMesh& fvPatches = mesh_.boundary();
261 label nBands = spectralDistribution_.size();
265 const vector sunDir = directHitFaces_.direction();
266 const labelList& directHits = directHitFaces_.rayStartFaces();
268 globalIndex globalNumbering(mesh_.nFaces());
270 Map<label> refFacesDirIndex;
277 if (!
pp.coupled() && !isA<cyclicAMIPolyPatch>(
pp))
279 const tmp<scalarField>
tr =
280 boundaryRadiation.specReflectivity(patchI);
287 label globalID = faceI +
pp.start();
289 if (r[faceI] > 0.0 && directHits.found(globalID))
292 sunDir + 2.0*(-sunDir &
n[faceI]) *
n[faceI];
297 forAll(refDiscAngles_, iDisc)
299 scalar dotProd = refDir & refDiscAngles_[iDisc];
309 if (refDisDirsIndex[rayIndex] == -1)
311 refDisDirsIndex[rayIndex] = 1;
315 refFacesDirIndex.insert
317 globalNumbering.toGlobal(globalID),
333 const scalar maxBounding =
334 returnReduce(5.0*mesh_.bounds().mag(), maxOp<scalar>());
340 DynamicField<point> start(nFaces);
341 DynamicField<point>
end(start.size());
342 DynamicList<label> startIndex(start.size());
343 DynamicField<label> dirStartIndex(start.size());
348 for (; i < Cfs_->size(); i++)
350 const point& fc = Cfs_()[i];
352 const vector nf = Nfs_()[i];
354 const label myFaceId = shootFacesIds_()[i];
356 forAll(refDisDirsIndex, dirIndex)
358 if (refDisDirsIndex[dirIndex] > -1)
360 if ((nf & refDiscAngles_[dirIndex]) > 0)
366 startIndex.append(myFaceId);
367 dirStartIndex.append(dirIndex);
377 List<pointIndexHit> hitInfo(startIndex.size());
379 surfacesMesh_->findLine(start,
end, hitInfo);
383 autoPtr<mapDistribute> mapPtr
385 surfacesMesh_->localQueries
391 const mapDistribute& map = mapPtr();
393 PtrList<List<scalarField>> patchr(
patches.size());
394 PtrList<List<scalarField>> patcha(
patches.size());
397 patchr.emplace_set(patchi, nBands);
398 patcha.emplace_set(patchi, nBands);
406 if (!
pp.coupled() && !isA<cyclicAMIPolyPatch>(
pp))
408 for (label bandI = 0; bandI < nBands; bandI++)
410 patchr[patchi][bandI] =
411 boundaryRadiation.specReflectivity
418 patcha[patchi][bandI] =
419 boundaryRadiation.absorptivity
429 List<scalarField> r(nBands);
430 for (label bandI = 0; bandI < nBands; bandI++)
432 r[bandI].setSize(triangleIndex.size());
434 labelList refDirIndex(triangleIndex.size(), -1);
435 labelList refIndex(triangleIndex.size(), -1);
439 label trii = triangleIndex[i];
440 label facei = mapTriToGlobal_[trii];
441 label patchI =
patches.whichPatch(facei);
443 label localFaceI =
pp.whichFace(facei);
446 if (refFacesDirIndex.found(globalFace))
448 refDirIndex[i] = refFacesDirIndex.find(globalFace)();
449 refIndex[i] = globalFace;
451 for (label bandI = 0; bandI < nBands; bandI++)
453 r[bandI][i] = patchr[patchI][bandI][localFaceI];
456 map.reverseDistribute(hitInfo.size(), refDirIndex);
457 map.reverseDistribute(hitInfo.size(), refIndex);
458 for (label bandI = 0; bandI < nBands; bandI++)
460 map.reverseDistribute(hitInfo.size(), r[bandI]);
463 for (label bandI = 0; bandI < nBands; bandI++)
466 qreflective_[bandI].boundaryFieldRef();
470 const vector qPrim(solarCalc_.directSolarRad()*solarCalc_.direction());
476 if (hitInfo[rayI].hit())
480 dirStartIndex[rayI] == refDirIndex[rayI]
481 && refFacesDirIndex.found(refIndex[rayI])
484 for (label bandI = 0; bandI < nBands; bandI++)
487 qreflective_[bandI].boundaryFieldRef();
489 label startFaceId = startIndex[rayI];
490 label startPatchI =
patches.whichPatch(startFaceId);
492 const polyPatch& ppStart =
patches[startPatchI];
493 label localStartFaceI = ppStart.whichFace(startFaceId);
495 scalar a = patcha[startPatchI][bandI][localStartFaceI];
499 vector rayIn = refDiscAngles_[dirStartIndex[rayI]];
503 qrefBf[startPatchI][localStartFaceI] +=
508 *spectralDistribution_[bandI]
512 & nStart[localStartFaceI]
522 dirStartIndex.clear();
528 Foam::faceReflecting::faceReflecting
538 nTheta_(
dict.subDict(
"reflecting").getOrDefault<label>(
"nTheta", 10)),
539 nPhi_(
dict.subDict(
"reflecting").getOrDefault<label>(
"nPhi", 10)),
542 spectralDistribution_(spectralDistribution),
543 qreflective_(spectralDistribution_.size()),
544 directHitFaces_(directHiyFaces),
static const Enum< distributionType > distributionTypeNames_
const triSurface localSurface
A solar calculator model providing models for the solar direction and solar loads.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
static const boundaryRadiationProperties & New(const fvMesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
Ignore writing from objectRegistry::writeObject()
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
SubField is a Field obtained as a section of another Field, without its own allocation. SubField is derived from a SubList rather than a List.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
#define forAll(list, i)
Loop across all elements in list.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
vectorField pointField
pointField is a vectorField.
dimensionedSymmTensor dev(const dimensionedSymmTensor &dt)
dimensionedScalar cos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
constexpr scalar pi(M_PI)
dimensionedScalar tr(const dimensionedSphericalTensor &dt)
constexpr scalar piByTwo(0.5 *M_PI)
errorManip< error > abort(error &err)
Helper class to calculate visible faces for global, sun-like illumination.
dimensionedScalar sin(const dimensionedScalar &ds)
int debug
Static debugging option.
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
defineTypeNameAndDebug(combustionModel, 0)
void correct()
Correct reflected flux.
dimensionedScalar pow3(const dimensionedScalar &ds)
vector point
Point is a vector.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Mesh data needed to do the Finite Volume discretisation.
const polyBoundaryMesh & patches
Automatically write from objectRegistry::writeObject()
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
Field< vector > vectorField
Specialisation of Field<T> for vector.
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
List< label > labelList
A List of labels.
static void mapCombineReduce(Container &values, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) applying cop to inplace combine map values from different processo...
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Request registration (bool: true)
List< treeBoundBox > meshBb(1, treeBoundBox(coarseMesh.points()).extend(rndGen, 1e-3))
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
static void listCombineReduce(List< T > &values, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Combines List elements. After completion all processors have the same data.
static constexpr const zero Zero
Global zero (0)