99#include "CGAL/version.h"
100#if defined(CGAL_VERSION_NR) && (CGAL_VERSION_NR < 1050211000)
101#define BOOST_BIND_GLOBAL_PLACEHOLDERS
103#pragma clang diagnostic ignored "-Wbitwise-instead-of-logical"
104#pragma clang diagnostic ignored "-Wdeprecated-builtins"
105#pragma clang diagnostic ignored "-Wdeprecated-declarations"
108#include <CGAL/Simple_cartesian.h>
109#include <CGAL/AABB_tree.h>
110#if defined(CGAL_VERSION_NR) && (CGAL_VERSION_NR < 1060011000)
111#include <CGAL/AABB_traits.h>
112#include <CGAL/AABB_triangle_primitive.h>
114#include <CGAL/AABB_traits_3.h>
115#include <CGAL/AABB_triangle_primitive_3.h>
117#include <CGAL/Surface_mesh.h>
119typedef CGAL::Simple_cartesian<double>
K;
120typedef K::Point_3
Point;
121typedef K::Direction_3 Vector3C;
125typedef std::vector<Triangle>::iterator Iterator;
126#if defined(CGAL_VERSION_NR) && (CGAL_VERSION_NR < 1060011000)
127typedef CGAL::AABB_triangle_primitive<K, Iterator> Primitive;
128typedef CGAL::AABB_traits<K, Primitive> AABB_triangle_traits;
130typedef CGAL::AABB_triangle_primitive_3<K, Iterator> Primitive;
131typedef CGAL::AABB_traits_3<K, Primitive> AABB_triangle_traits;
133typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
136#if (CGAL_VERSION_NR < 1060000910)
137typedef boost::optional
142 Tree::Intersection_and_primitive_id<Segment>::Type
143> Segment_intersection;
167 label localTriFaceI = 0;
169 for (
const label patchI : includePatches)
184 f.triangles(
points, nTri, triFaces);
186 forAll(triFaces, triFaceI)
188 const face&
f = triFaces[triFaceI];
197 finalAgglom[patchI][patchFaceI]
198 + coarsePatches[patchI].start()
228 List<labelledTri> globalSurfaceTris(globalFaceIdx.gather(surface));
232 for (
const label proci : globalPointIdx.allProcs())
234 const label offset = globalPointIdx.localStart(proci);
241 : globalSurfaceTris.slice(globalFaceIdx.range(proci))
254 std::move(globalSurfaceTris),
255 std::move(globalSurfacePoints)
266 for (
const label patchI : includePatches)
270 surface.patches()[newPatchI].index() = patchI;
272 surface.patches()[newPatchI].geometricType() =
patch.type();
292 Pout<<
"Dumping rays to " << str.name() <<
endl;
296 const labelList visFaces = visibleFaceFaces[faceI];
297 forAll(visFaces, faceRemote)
299 label compactI = visFaces[faceRemote];
300 const point& remoteFc = compactCf[compactI];
306 str <<
"l " << vertI-1 <<
' ' << vertI <<
nl;
313scalar calculateViewFactorFij2AI
322 scalar rMag =
mag(r);
326 scalar dAiMag =
mag(dAi);
327 scalar dAjMag =
mag(dAj);
331 scalar cosThetaJ =
mag(nj & r)/rMag;
332 scalar cosThetaI =
mag(ni & r)/rMag;
336 (cosThetaI*cosThetaJ*dAjMag*dAiMag)
347void insertMatrixElements
350 const label fromProcI,
356 forAll(viewFactors, faceI)
359 const labelList& globalFaces = globalFaceFaces[faceI];
361 label globalI = globalNumbering.
toGlobal(fromProcI, faceI);
364 matrix[globalI][globalFaces[i]] = vf[i];
392 r = (
alpha*magSi)*di;
398 List<vector>
pi(w.
size());
401 pi[i] = ci +
p[i]*(magSi/2)*di;
404 List<vector> pj(w.
size());
407 pj[i] = cj +
p[i]*(magSj/2)*dj;
418 r = (
alpha*magSi)*di;
431 dIntFij *= (magSi/2) * (magSj/2);
440int main(
int argc,
char *argv[])
444 "Calculate view factors from face agglomeration array."
445 " The finalAgglom generated by faceAgglomerate utility."
466 const word viewFactorWall(
"viewFactorWall");
468 const bool writeViewFactors =
469 viewFactorDict.getOrDefault(
"writeViewFactorMatrix",
false);
471 const bool dumpRays =
472 viewFactorDict.getOrDefault(
"dumpRays",
false);
474 const label
debug = viewFactorDict.getOrDefault<label>(
"debug", 0);
476 const scalar GaussQuadTol =
477 viewFactorDict.getOrDefault<scalar>(
"GaussQuadTol", 0.01);
479 const scalar distTol =
480 viewFactorDict.getOrDefault<scalar>(
"distTol", 8);
483 viewFactorDict.getOrDefault<scalar>(
"alpha", 0.21);
485 const scalar intTol =
486 viewFactorDict.getOrDefault<scalar>(
"intTol", 1
e-2);
488 bool useAgglomeration(
true);
499 mesh.facesInstance(),
510 for (label patchi=0; patchi <
patches.size(); patchi++)
514 useAgglomeration =
false;
522 Pout <<
"\nCreating single cell mesh..." <<
endl;
529 "coarse:" +
mesh.name(),
541 Pout <<
"\nCreated single cell mesh..." <<
endl;
548 label nCoarseFaces = 0;
549 label nFineFaces = 0;
553 for (
const label patchi : viewFactorsPatches)
555 nCoarseFaces += coarsePatches[patchi].
size();
556 nFineFaces +=
patches[patchi].size();
560 Info<<
"\nTotal number of coarse faces: "
566 Pout <<
"\nView factor patches included in the calculation : "
567 << viewFactorsPatches <<
endl;
578 for (
const label
patchID : viewFactorsPatches)
585 if (agglom.
size() > 0)
587 label nAgglom =
max(agglom)+1;
590 coarseMesh.patchFaceMap()[
patchID];
593 coarseMesh.Cf().boundaryField()[
patchID];
595 coarseMesh.Sf().boundaryField()[
patchID];
599 point cf = coarseCf[faceI];
601 const label coarseFaceI = coarsePatchFace[faceI];
602 const labelList& fineFaces = coarseToFine[coarseFaceI];
603 const label agglomI =
613 List<point> availablePoints
615 upp.faceCentres().size()
616 + upp.localPoints().size()
622 upp.faceCentres().size()
623 ) = upp.faceCentres();
628 upp.localPoints().size(),
629 upp.faceCentres().size()
630 ) = upp.localPoints();
634 forAll(availablePoints, iPoint)
636 point cfFine = availablePoints[iPoint];
637 if (
mag(cfFine-cfo) < dist)
639 dist =
mag(cfFine-cfo);
644 point sf = coarseSf[faceI];
646 localCoarseSf.append(sf);
647 localAgg.append(agglomI);
702 nVisibleFaceFaces[rayStartFace[i]]++;
708 forAll(nVisibleFaceFaces, faceI)
710 visibleFaceFaces[faceI].
setSize(nVisibleFaceFaces[faceI]);
728 nVisibleFaceFaces = 0;
731 label faceI = rayStartFace[i];
732 label compactI = rayEndFace[i];
733 visibleFaceFaces[faceI][nVisibleFaceFaces[faceI]++] = compactI;
743 List<List<point>> compactFineSf(map.constructSize());
744 List<List<point>> compactFineCf(map.constructSize());
758 forAll(viewFactorsPatches, i)
760 label
patchID = viewFactorsPatches[i];
763 if (agglom.
size() > 0)
765 label nAgglom =
max(agglom)+1;
768 coarseMesh.patchFaceMap()[
patchID];
772 forAll(coarseToFine, coarseI)
774 compactPatchId.append(
patchID);
775 List<point>& fineCf = compactFineCf[compactI];
776 List<point>& fineSf = compactFineSf[compactI];
778 label startFace =
pp.start();
783 faces[coarseI + startFace]
786 const label coarseFaceI = coarsePatchFace[coarseI];
787 const labelList& fineFaces = coarseToFine[coarseFaceI];
792 compactPoints.append(locPoints);
797 coarseToFine[coarseFaceI]
802 coarseToFine[coarseFaceI]
816 map.distribute(compactCoarseSf);
817 map.distribute(compactCoarseCf);
818 map.distribute(compactFineCf);
819 map.distribute(compactFineSf);
820 map.distribute(compactPoints);
821 map.distribute(compactPatchId);
828 runTime.path()/
"allVisibleFaces.obj",
843 mesh.facesInstance(),
852 const label totalPatches =
862 Info<<
"\nCalculating view factors..." <<
endl;
870 GaussPoints[1][0] = 1/std::sqrt(3);
871 GaussPoints[1][1] = -1/std::sqrt(3);
874 GaussPoints[2][0] = 0;
875 GaussPoints[2][1] = std::sqrt(3.0/5.0);
876 GaussPoints[2][2] = -std::sqrt(3.0/5.0);
879 GaussPoints[3][0] = std::sqrt(3.0/7.0 - (2.0/7.0)*std::sqrt(6.0/5.0));
880 GaussPoints[3][1] = -GaussPoints[3][0];
881 GaussPoints[3][2] = std::sqrt(3.0/7.0 + (2.0/7.0)*std::sqrt(6.0/5.0));
882 GaussPoints[3][3] = -GaussPoints[3][2];
885 GaussPoints[4][0] = 0;
886 GaussPoints[4][1] = (1.0/3.0)*std::sqrt(5.0 - 2.0*std::sqrt(10.0/7.0));
887 GaussPoints[4][2] = -GaussPoints[4][1];
888 GaussPoints[4][3] = (1.0/3.0)*std::sqrt(5.0 + 2.0*std::sqrt(10.0/7.0));
889 GaussPoints[4][4] = -GaussPoints[4][3];
897 GaussWeights[1][0] = 1;
898 GaussWeights[1][1] = 1;
901 GaussWeights[2][0] = 8.0/9.0;
902 GaussWeights[2][1] = 5.0/9.0;
903 GaussWeights[2][2] = 5.0/9.0;
906 GaussWeights[3][0] = (18.0 + std::sqrt(30))/36.0;
907 GaussWeights[3][1] = (18.0 + std::sqrt(30))/36.0;
908 GaussWeights[3][2] = (18.0 - std::sqrt(30))/36.0;
909 GaussWeights[3][3] = (18.0 - std::sqrt(30))/36.0;
912 GaussWeights[4][0] = 128.0/225.0;
913 GaussWeights[4][1] = (322.0 + 13.0*std::sqrt(70))/900.0;
914 GaussWeights[4][2] = (322.0 + 13.0*std::sqrt(70))/900.0;
915 GaussWeights[4][3] = (322.0 - 13.0*std::sqrt(70))/900.0;
916 GaussWeights[4][4] = (322.0 - 13.0*std::sqrt(70))/900.0;
918 const label maxQuadOrder = 5;
920 if (
mesh.nSolutionD() == 3)
922 forAll(localCoarseSf, coarseFaceI)
924 const List<point>& localFineSf = compactFineSf[coarseFaceI];
926 const List<point>& localFineCf = compactFineCf[coarseFaceI];
927 const label fromPatchId = compactPatchId[coarseFaceI];
929 const List<point>& lPoints = compactPoints[coarseFaceI];
931 patchArea[fromPatchId] +=
mag(Ai);
933 const labelList& visCoarseFaces = visibleFaceFaces[coarseFaceI];
935 forAll(visCoarseFaces, visCoarseFaceI)
939 label compactJ = visCoarseFaces[visCoarseFaceI];
940 const List<point>& remoteFineSj = compactFineSf[compactJ];
941 const List<point>& remoteFineCj = compactFineCf[compactJ];
943 const List<point>& rPointsCj = compactPoints[compactJ];
945 const label toPatchId = compactPatchId[compactJ];
956 const vector& dCi = localFineCf[i];
965 const vector& dCj = remoteFineCj[j];
967 const scalar dist =
mag(dCi - dCj)/((dAi + dAj)/2);
983 const vector& dAi = localFineSf[i];
984 const vector& dCi = localFineCf[i];
988 const vector& dAj = remoteFineSj[j];
989 const vector& dCj = remoteFineCj[j];
991 scalar dIntFij = calculateViewFactorFij2AI
1002 F2LI[coarseFaceI][visCoarseFaceI] = F2AIij/
mag(Ai);
1007 label nLocal = lPoints.
size();
1008 label nRemote = rPointsCj.
size();
1011 scalar oldEToeInt = 0;
1012 for (label gi=0; gi < maxQuadOrder; gi++)
1015 for(label i=0; i<nLocal; i++)
1025 si = lPoints[i] - lPoints[nLocal-1];
1026 ci = (lPoints[i] + lPoints[nLocal-1])/2;
1030 si = lPoints[i] - lPoints[i-1];
1031 ci = (lPoints[i] + lPoints[i-1])/2;
1034 for(label j=0; j<nRemote; j++)
1038 sj = rPointsCj[j]-rPointsCj[nRemote-1];
1039 cj = (rPointsCj[j]+rPointsCj[nRemote-1])/2;
1043 sj = rPointsCj[j] - rPointsCj[j-1];
1044 cj = (rPointsCj[j] + rPointsCj[j-1])/2;
1048 scalar magSi =
mag(si);
1049 scalar magSj =
mag(sj);
1050 scalar cosij = (si & sj)/(magSi * magSj);
1055 label quadOrder = gi;
1085 mag(F2LIij) > ROOTVSMALL
1086 ? (F2LIij-oldEToeInt)/F2LIij
1092 (
mag(err) < GaussQuadTol && gi > 0)
1093 || gi == maxQuadOrder-1
1096 F2LI[coarseFaceI][visCoarseFaceI] =
1102 oldEToeInt = F2LIij;
1107 sumViewFactorPatch[fromPatchId][toPatchId] +=
1108 F2LI[coarseFaceI][visCoarseFaceI]*
mag(Ai);
1112 else if (
mesh.nSolutionD() == 2)
1125 scalar wideBy2 = (box.
span() & emptyDir)*2.0;
1127 forAll(localCoarseSf, coarseFaceI)
1129 const vector& Ai = localCoarseSf[coarseFaceI];
1130 const vector& Ci = localCoarseCf[coarseFaceI];
1132 vector R1i = Ci + (
mag(Ai)/wideBy2)*(Ain ^ emptyDir);
1133 vector R2i = Ci - (
mag(Ai)/wideBy2)*(Ain ^ emptyDir) ;
1135 const label fromPatchId = compactPatchId[coarseFaceI];
1136 patchArea[fromPatchId] +=
mag(Ai);
1138 const labelList& visCoarseFaces = visibleFaceFaces[coarseFaceI];
1139 forAll(visCoarseFaces, visCoarseFaceI)
1142 label compactJ = visCoarseFaces[visCoarseFaceI];
1143 const vector& Aj = compactCoarseSf[compactJ];
1144 const vector& Cj = compactCoarseCf[compactJ];
1146 const label toPatchId = compactPatchId[compactJ];
1149 vector R1j = Cj + (
mag(Aj)/wideBy2)*(Ajn ^ emptyDir);
1150 vector R2j = Cj - (
mag(Aj)/wideBy2)*(Ajn ^ emptyDir);
1152 scalar d1 =
mag(R1i - R2j);
1153 scalar d2 =
mag(R2i - R1j);
1154 scalar s1 =
mag(R1i - R1j);
1155 scalar s2 =
mag(R2i - R2j);
1157 scalar Fij =
mag((d1 + d2) - (s1 + s2))/(4.0*
mag(Ai)/wideBy2);
1159 F2LI[coarseFaceI][visCoarseFaceI] = Fij;
1160 sumViewFactorPatch[fromPatchId][toPatchId] += Fij*
mag(Ai);
1167 <<
" View factors are not available in 1D "
1179 forAll(viewFactorsPatches, i)
1181 label patchI = viewFactorsPatches[i];
1182 for (label j=i; j<viewFactorsPatches.size(); j++)
1184 label patchJ = viewFactorsPatches[j];
1186 Info <<
"F" << patchI << patchJ <<
": "
1187 << sumViewFactorPatch[patchI][patchJ]/patchArea[patchI]
1193 if (writeViewFactors)
1197 Info <<
"Writing view factor matrix..." <<
endl;
1205 mesh.time().timeName(),
1217 forAll(viewFactorsPatches, i)
1219 label
patchID = viewFactorsPatches[i];
1221 if (agglom.
size() > 0)
1223 label nAgglom =
max(agglom)+1;
1226 coarseMesh.patchFaceMap()[
patchID];
1228 forAll(coarseToFine, coarseI)
1230 const scalar FiSum =
sum(F2LI[compactI]);
1232 const label coarseFaceID = coarsePatchFace[coarseI];
1233 const labelList& fineFaces = coarseToFine[coarseFaceID];
1234 forAll(fineFaces, fineId)
1236 const label faceID = fineFaces[fineId];
1237 vfbf[
patchID][faceID] = FiSum;
1243 viewFactorField.write();
1250 labelList compactToGlobal(map.constructSize());
1253 for (label i = 0; i < globalNumbering.
localSize(); i++)
1255 compactToGlobal[i] = globalNumbering.
toGlobal(i);
1259 forAll(compactMap, procI)
1261 const Map<label>& localToCompactMap = compactMap[procI];
1265 compactToGlobal[*iter] = globalNumbering.
toGlobal
1278 forAll(globalFaceFaces, faceI)
1283 visibleFaceFaces[faceI]
1292 mesh.facesInstance(),
1298 std::move(globalFaceFaces)
1300 IOglobalFaceFaces.write();
1308 mesh.facesInstance(),
CGAL::Segment_3< K > Segment
CGAL::Triangle_3< K > Triangle
CGAL::Exact_predicates_exact_constructions_kernel K
constexpr scalar pi(M_PI)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
A 1D vector of objects of type <T> with a fixed length <N>.
void setSize(const label n)
Dummy function, to make FixedList consistent with List.
GeometricBoundaryField< scalar, fvPatchField, volMesh > Boundary
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
IOmapDistribute is derived from mapDistribute and IOobject to give the mapDistribute automatic IO fun...
@ NO_REGISTER
Do not request registration (bool: false).
@ NO_READ
Nothing to be read.
@ READ_IF_PRESENT
Reading is optional [identical to LAZY_READ].
@ MUST_READ
Reading required.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
bool typeHeaderOk(const bool checkType=true, const bool search=true, const bool verbose=true)
Read header (respects is_globalIOobject trait) and check its info. A void type suppresses trait and t...
void append(const T &val)
Append an element at the end of the list.
void setSize(label n)
Alias for resize().
A HashTable to objects of type <T> with a label key.
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
static void allGatherList(UList< T > &values, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Gather data, but keep individual values separate. Uses MPI_Allgather or manual communication.
static void broadcast(Type &value, const int communicator=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all communicator ranks. Does nothing in non-paral...
A non-owning sub-view of a List (allocated or unallocated storage).
A List with indirect addressing. Like IndirectList but does not store addressing.
void size(const label n)
Older name for setAddressableSize.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
label size() const noexcept
The number of entries in the list.
Templated 3D Vector derived from VectorSpace adding construction from 3 components,...
static void addNote(const string ¬e)
Add extra notes for the usage information.
A bounding box defined in terms of min/max extrema points.
vector span() const
The bounding box span (from minimum to maximum).
A face is a list of labels corresponding to mesh vertices.
A class for handling file names.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
label toGlobal(const label proci, const label i) const
From local to global on proci.
label localSize(const label proci) const
Size of proci data.
A triFace with additional (region) index.
Class containing processor-to-processor mapping information.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
label start() const noexcept
The start label of boundary faces in the polyMesh face list.
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
fvMesh as subset of other mesh. Consists of one cell and all original boundary faces....
Triangulated surface description with patch information.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
const polyBoundaryMesh & patches
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
return returnReduce(nRefine-oldNRefine, sumOp< label >())
constexpr scalar pi(M_PI)
Different types of constants.
Namespace for handling debugging switches.
const wordList surface
Standard surface field types (scalar, vector, tensor, etc).
const std::string patch
OpenFOAM patch number as a std::string.
List< scalarList > scalarListList
List of scalarList.
IOList< scalarList > scalarListIOList
IO for a List of scalarList.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
const dimensionSet dimless
Dimensionless.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
messageStream Info
Information stream (stdout output on master, null elsewhere).
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values within a list.
List< face > faceList
List of faces.
dimensionedScalar log(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
IOList< labelList > labelListIOList
IO for a List of labelList.
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Field< vector > vectorField
Specialisation of Field<T> for vector.
SquareMatrix< scalar > scalarSquareMatrix
vector point
Point is a vector.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
PrimitivePatch< List< face >, const pointField > bMesh
Holder of faceList and points. (v.s. e.g. primitivePatch which references points).
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
PrimitivePatch< UIndirectList< face >, const pointField & > uindirectPrimitivePatch
A PrimitivePatch with UIndirectList for the faces, const reference for the point field.
vectorField pointField
pointField is a vectorField.
labelListList invertOneToMany(const label len, const labelUList &map)
Invert one-to-many map. Unmapped elements will be size 0.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< scalar > scalarList
List of scalar.
constexpr char nl
The newline '\n' character (0x0a).
labelList triSurfaceToAgglom(5 *nFineFaces)
std::vector< Triangle > triangles
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Dispatch tag: Construct 'one-sided' from local sizes, using gather but no broadcast.