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> 119 typedef CGAL::Simple_cartesian<double>
K;
120 typedef K::Point_3
Point;
121 typedef K::Direction_3 Vector3C;
125 typedef std::vector<Triangle>::iterator Iterator;
126 #if defined(CGAL_VERSION_NR) && (CGAL_VERSION_NR < 1060011000) 127 typedef CGAL::AABB_triangle_primitive<K, Iterator> Primitive;
128 typedef CGAL::AABB_traits<K, Primitive> AABB_triangle_traits;
130 typedef CGAL::AABB_triangle_primitive_3<K, Iterator> Primitive;
131 typedef CGAL::AABB_traits_3<K, Primitive> AABB_triangle_traits;
133 typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
136 #if (CGAL_VERSION_NR < 1060000910) 137 typedef boost::optional
139 typedef std::optional
142 Tree::Intersection_and_primitive_id<Segment>::Type
143 > Segment_intersection;
147 using namespace Foam;
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()
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();
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;
313 scalar 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)
347 void 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;
401 pi[i] = ci +
p[i]*(magSi/2)*di;
407 pj[i] = cj +
p[i]*(magSj/2)*dj;
418 r = (
alpha*magSi)*di;
431 dIntFij *= (magSi/2) * (magSj/2);
440 int 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);
485 const scalar intTol =
486 viewFactorDict.getOrDefault<scalar>(
"intTol", 1
e-2);
488 bool useAgglomeration(
true);
510 for (label patchi=0; patchi <
patches.
size(); patchi++)
514 useAgglomeration =
false;
522 Pout <<
"\nCreating single cell mesh..." <<
endl;
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();
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 =
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;
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);
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);
852 const label totalPatches =
862 Info<<
"\nCalculating view factors..." <<
endl;
874 GaussPoints[2][0] = 0;
880 GaussPoints[3][1] = -GaussPoints[3][0];
882 GaussPoints[3][3] = -GaussPoints[3][2];
885 GaussPoints[4][0] = 0;
887 GaussPoints[4][2] = -GaussPoints[4][1];
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;
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)
938 F2LI[coarseFaceI].setSize(visCoarseFaces.
size());
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);
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)
1141 F2LI[coarseFaceI].setSize(visCoarseFaces.
size());
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;
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]
1298 std::move(globalFaceFaces)
1300 IOglobalFaceFaces.
write();
Different types of constants.
static void addNote(const string ¬e)
Add extra notes for the usage information.
void size(const label n)
Older name for setAddressableSize.
const surfaceVectorField & Sf() const
Return cell face area vectors.
fvMesh as subset of other mesh. Consists of one cell and all original boundary faces. Useful when manipulating boundary data. Single internal cell only needed to be able to manipulate in a standard way.
static dimensioned< Type > getOrDefault(const word &name, const dictionary &dict, const dimensionSet &dims=dimless, const Type &deflt=Type(Zero))
Construct dimensioned from dictionary, with default value.
A class for handling file names.
bool typeHeaderOk([[maybe_unused]] 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...
IOmapDistribute is derived from mapDistribute and IOobject to give the mapDistribute automatic IO fun...
dimensionedScalar log(const dimensionedScalar &ds)
errorManipArg< error, int > exit(error &err, const int errNo=1)
const fileName & facesInstance() const
Return the current instance directory for faces.
A face is a list of labels corresponding to mesh vertices.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
A 1D vector of objects of type <T> with a fixed length <N>.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
void append(const T &val)
Append an element at the end of the list.
fileName path() const
The path for the case = rootPath/caseName.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values within a list.
Output to file stream as an OSstream, normally using std::ofstream for the actual output...
constexpr char nl
The newline '\n' character (0x0a)
label start() const noexcept
The start label of boundary faces in the polyMesh face list.
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Dispatch tag: Construct 'one-sided' from local sizes, using gather but no broadcast.
std::vector< Triangle > triangles
A bounding box defined in terms of min/max extrema points.
CGAL::Triangle_3< K > Triangle
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...
Ignore writing from objectRegistry::writeObject()
const dimensionSet dimless
Dimensionless.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
const Time & time() const
Return the top-level database.
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name) ...
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
CGAL::Exact_predicates_exact_constructions_kernel K
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
void setSize(const label n)
Dummy function, to make FixedList consistent with List.
void reduce(T &value, [[maybe_unused]] BinaryOp bop, [[maybe_unused]] const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce)
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
virtual const pointField & points() const
Return raw points.
#define forAll(list, i)
Loop across all elements in list.
labelList indices(const wordRe &matcher, const bool useGroups=true) const
The (sorted) patch indices for all matches, optionally matching patch groups.
const Vector< label > & geometricD() const
Return the vector of geometric directions in mesh.
A list of faces which address into the list of points.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
A non-owning sub-view of a List (allocated or unallocated storage).
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
labelListList invertOneToMany(const label len, const labelUList &map)
Invert one-to-many map. Unmapped elements will be size 0.
labelList triSurfaceToAgglom(5 *nFineFaces)
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A class for handling words, derived from Foam::string.
label size() const noexcept
The number of entries in the list.
Reading is optional [identical to LAZY_READ].
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
constexpr scalar pi(M_PI)
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
label localSize(const label proci) const
Size of proci data.
A triFace with additional (region) index.
const Field< point_type > & points() const noexcept
Return reference to global points.
virtual const faceList & faces() const
Return raw faces.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh...
const wordList surface
Standard surface field types (scalar, vector, tensor, etc)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
const word & constant() const noexcept
Return constant name.
int debug
Static debugging option.
label nSolutionD() const
Return the number of valid solved-for dimensions in the mesh.
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.
Class containing processor-to-processor mapping information.
label toGlobal(const label proci, const label i) const
From local to global on proci.
const word & name() const
Return reference to name.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
A List with indirect addressing. Like IndirectList but does not store addressing. ...
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
const polyBoundaryMesh & patches
Automatically write from objectRegistry::writeObject()
const std::string patch
OpenFOAM patch number as a std::string.
vector span() const
The bounding box span (from minimum to maximum)
messageStream Info
Information stream (stdout output on master, null elsewhere)
const boundBox & bounds() const noexcept
Return mesh bounding box.
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
Triangulated surface description with patch information.
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces)
Defines the attributes of an object for which implicit objectRegistry management is supported...
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
void setSize(label n)
Alias for resize()
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Do not request registration (bool: false)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
forAllConstIters(mixture.phases(), phase)
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...
CGAL::Segment_3< K > Segment
static constexpr const zero Zero
Global zero (0)