shootRays.H
Go to the documentation of this file.
1 // All rays expressed as start face (local) index end end face (global)
2 // Pre-size by assuming a certain percentage is visible.
3 
4 
5 if (Pstream::master())
6 {
7  Info<< "\nShooting rays using distributedTriSurfaceMesh (no CGAL support)"
8  << endl;
9 }
10 
11 
12 
13 // Maximum length for dynamicList
14 const label maxDynListLength
15 (
16  viewFactorDict.getOrDefault<label>("maxDynListLength", 1000000)
17 );
18 
19 for (const int proci : Pstream::allProcs())
20 {
21  // Shoot rays from me to proci. Note that even if processor has
22  // 0 faces we still need to call findLine to keep calls synced.
23 
24  DynamicField<point> start(coarseMesh.nFaces());
25  DynamicField<point> end(start.size());
26  DynamicList<label> startIndex(start.size());
27  DynamicList<label> endIndex(start.size());
28 
29  DynamicList<label> startAgg(start.size());
30  DynamicList<label> endAgg(start.size());
31 
32 
33  const pointField& myFc = remoteCoarseCf[Pstream::myProcNo()];
34  const vectorField& myArea = remoteCoarseSf[Pstream::myProcNo()];
35  const labelField& myAgg = remoteCoarseAgg[Pstream::myProcNo()];
36 
37  const pointField& remoteArea = remoteCoarseSf[proci];
38  const pointField& remoteFc = remoteCoarseCf[proci];
39  const labelField& remoteAgg = remoteCoarseAgg[proci];
40 
41  label i = 0;
42  label j = 0;
43  do
44  {
45  for (; i < myFc.size(); i++)
46  {
47  const point& fc = myFc[i];
48  const vector& fA = myArea[i];
49  const label& fAgg = myAgg[i];
50 
51  for (; j < remoteFc.size(); j++)
52  {
53  if (proci != Pstream::myProcNo() || i != j)
54  {
55  const point& remFc = remoteFc[j];
56  const vector& remA = remoteArea[j];
57  const label& remAgg = remoteAgg[j];
58 
59  const vector d(remFc - fc);
60 
61  if (((d & fA) < 0.) && ((d & remA) > 0))
62  {
63  start.append(fc + 0.001*d);
64  startIndex.append(i);
65  startAgg.append(globalNumbering.toGlobal(proci, fAgg));
66  end.append(fc + 0.999*d);
67  label globalI = globalNumbering.toGlobal(proci, j);
68  endIndex.append(globalI);
69  endAgg.append(globalNumbering.toGlobal(proci, remAgg));
70  if (startIndex.size() > maxDynListLength)
71  {
73  << "Dynamic list need from capacity."
74  << "Actual size maxDynListLength : "
76  << abort(FatalError);
77  }
78  }
79  }
80  }
81 
82  if (j == remoteFc.size())
83  {
84  j = 0;
85  }
86  }
87 
88  } while (returnReduceOr(i < myFc.size()));
89 
90  List<pointIndexHit> hitInfo(startIndex.size());
91  surfacesMesh.findLine(start, end, hitInfo);
92 
93  // Return hit global agglo index
94  labelList aggHitIndex;
95  surfacesMesh.getField(hitInfo, aggHitIndex);
96 
97  DynamicList<label> dRayIs;
98 
99  // Collect the rays which have no obstacle in between rayStartFace
100  // and rayEndFace. If the ray hit itself, it gets stored in dRayIs
101  forAll(hitInfo, rayI)
102  {
103  if (!hitInfo[rayI].hit())
104  {
105  rayStartFace.append(startIndex[rayI]);
106  rayEndFace.append(endIndex[rayI]);
107  }
108  else if (aggHitIndex[rayI] == startAgg[rayI])
109  {
110  dRayIs.append(rayI);
111  }
112  }
113 
114  start.clear();
115 
116 
117  // Continue rays which hit themself. If they hit the target
118  // agglomeration are added to rayStartFace and rayEndFace
119 
120  bool firstLoop = true;
121  DynamicField<point> startHitItself;
122  DynamicField<point> endHitItself;
123  label iter = 0;
124 
125  do
126  {
127  labelField rayIs;
128  rayIs.transfer(dRayIs);
129  dRayIs.clear();
130  forAll(rayIs, rayI)
131  {
132  const label rayID = rayIs[rayI];
133  label hitIndex = -1;
134 
135  if (firstLoop)
136  {
137  hitIndex = rayIs[rayI];
138  }
139  else
140  {
141  hitIndex = rayI;
142  }
143 
144  if (hitInfo[hitIndex].hit())
145  {
146  if (aggHitIndex[hitIndex] == startAgg[rayID])
147  {
148  const vector& endP = end[rayID];
149  const vector& startP = hitInfo[hitIndex].point();
150  const vector& d = endP - startP;
151 
152  startHitItself.append(startP + 0.01*d);
153  endHitItself.append(startP + 1.01*d);
154 
155  dRayIs.append(rayID);
156  }
157  else if (aggHitIndex[hitIndex] == endAgg[rayID])
158  {
159  rayStartFace.append(startIndex[rayID]);
160  rayEndFace.append(endIndex[rayID]);
161  }
162 
163  }
164  }
165 
166  hitInfo.clear();
167  hitInfo.resize(dRayIs.size());
168 
169  surfacesMesh.findLine(startHitItself, endHitItself, hitInfo);
170 
171  surfacesMesh.getField(hitInfo, aggHitIndex);
172 
173 
174  endHitItself.clear();
175  startHitItself.clear();
176  firstLoop = false;
177  iter ++;
178 
179  } while (returnReduceOr(hitInfo.size()) && iter < 10);
180 
181  startIndex.clear();
182  end.clear();
183  endIndex.clear();
184  startAgg.clear();
185  endAgg.clear();
186 }
Field< label > labelField
Specialisation of Field<T> for label.
Definition: labelField.H:48
const label maxDynListLength(viewFactorDict.getOrDefault< label >("maxDynListLength", 1000000))
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition: List.C:326
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
distributedTriSurfaceMesh surfacesMesh(IOobject("wallSurface.stl", runTime.constant(), "triSurface", runTime, IOobject::NO_READ, IOobject::NO_WRITE), localSurface, dict)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
Vector< scalar > vector
Definition: vector.H:57
errorManip< error > abort(error &err)
Definition: errorManip.H:139
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:201
vector point
Point is a vector.
Definition: point.H:37
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< label > labelList
A List of labels.
Definition: List.H:62
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.