CalcPatchToPatchWeights.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2020-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
30 #include "objectHit.H"
31 #include "pointHit.H"
32 
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 template<class FromPatch, class ToPatch>
41 void PatchToPatchInterpolation<FromPatch, ToPatch>::calcPointAddressing() const
42 {
43  // Calculate pointWeights
44 
45  pointWeightsPtr_.reset(new FieldField<Field, scalar>(toPatch_.nPoints()));
46  auto& pointWeights = *pointWeightsPtr_;
47 
48  pointDistancePtr_.reset(new scalarField(toPatch_.nPoints(), GREAT));
49  auto& pointDistance = *pointDistancePtr_;
50 
51  const pointField& fromPatchPoints = fromPatch_.localPoints();
52  const auto& fromPatchFaces = fromPatch_.localFaces();
53 
54  const pointField& toPatchPoints = toPatch_.localPoints();
55  const vectorField& projectionDirection = toPatch_.pointNormals();
56  const edgeList& toPatchEdges = toPatch_.edges();
57  const labelListList& toPatchPointEdges = toPatch_.pointEdges();
58 
59  if (debug)
60  {
61  Info<< "projecting points" << endl;
62  }
63 
64  List<objectHit> proj =
65  toPatch_.projectPoints(fromPatch_, projectionDirection, alg_, dir_);
66 
67  pointAddressingPtr_.reset(new labelList(proj.size(), -1));
68  auto& pointAddressing = *pointAddressingPtr_;
69 
70  bool doWeights = false;
71 
72  forAll(pointAddressing, pointi)
73  {
74  doWeights = false;
75 
76  const auto& hitFace = fromPatchFaces[proj[pointi].hitObject()];
77 
78  point hitPoint = Zero;
79 
80  if (proj[pointi].hit())
81  {
82  // A hit exists
83  doWeights = true;
84 
85  pointAddressing[pointi] = proj[pointi].hitObject();
86 
87  pointHit curHit =
88  hitFace.ray
89  (
90  toPatchPoints[pointi],
91  projectionDirection[pointi],
92  fromPatchPoints,
93  alg_,
94  dir_
95  );
96 
97  // Grab distance to target
98  if (dir_ == intersection::CONTACT_SPHERE)
99  {
100  pointDistance[pointi] =
101  hitFace.contactSphereDiameter
102  (
103  toPatchPoints[pointi],
104  projectionDirection[pointi],
105  fromPatchPoints
106  );
107  }
108  else
109  {
110  pointDistance[pointi] = curHit.distance();
111  }
112 
113  // Grab hit point
114  hitPoint = curHit.hitPoint();
115  }
116  else if (projectionTol_ > SMALL)
117  {
118  // Check for a near miss
119  pointHit ph =
120  hitFace.ray
121  (
122  toPatchPoints[pointi],
123  projectionDirection[pointi],
124  fromPatchPoints,
125  alg_,
126  dir_
127  );
128 
129  scalar dist =
130  Foam::mag
131  (
132  toPatchPoints[pointi]
133  + projectionDirection[pointi]*ph.distance()
134  - ph.missPoint()
135  );
136 
137  // Calculate the local tolerance
138  scalar minEdgeLength = GREAT;
139 
140  // Do shortest edge of hit object
141  edgeList hitFaceEdges =
142  fromPatchFaces[proj[pointi].hitObject()].edges();
143 
144  forAll(hitFaceEdges, edgeI)
145  {
146  minEdgeLength =
147  min
148  (
149  minEdgeLength,
150  hitFaceEdges[edgeI].mag(fromPatchPoints)
151  );
152  }
153 
154  const labelList& curEdges = toPatchPointEdges[pointi];
155 
156  forAll(curEdges, edgeI)
157  {
158  minEdgeLength =
159  min
160  (
161  minEdgeLength,
162  toPatchEdges[curEdges[edgeI]].mag(toPatchPoints)
163  );
164  }
165 
166  if (dist < minEdgeLength*projectionTol_)
167  {
168  // This point is being corrected
169  doWeights = true;
170 
171  pointAddressing[pointi] = proj[pointi].hitObject();
172 
173  // Grab nearest point on face as hit point
174  hitPoint = ph.missPoint();
175 
176  // Grab distance to target
177  if (dir_ == intersection::CONTACT_SPHERE)
178  {
179  pointDistance[pointi] =
180  hitFace.contactSphereDiameter
181  (
182  toPatchPoints[pointi],
183  projectionDirection[pointi],
184  fromPatchPoints
185  );
186  }
187  else
188  {
189  pointDistance[pointi] =
190  (
191  projectionDirection[pointi]
192  /mag(projectionDirection[pointi])
193  )
194  & (hitPoint - toPatchPoints[pointi]);
195  }
196  }
197  }
198 
199  if (doWeights)
200  {
201  // Set interpolation pointWeights
202  pointWeights.set(pointi, new scalarField(hitFace.size()));
203 
204  pointField hitFacePoints = hitFace.points(fromPatchPoints);
205 
206  forAll(hitFacePoints, masterPointi)
207  {
208  pointWeights[pointi][masterPointi] =
209  1.0/
210  (
211  hitPoint.dist(hitFacePoints[masterPointi])
212  + VSMALL
213  );
214  }
215 
216  pointWeights[pointi] /= sum(pointWeights[pointi]);
217  }
218  else
219  {
220  pointWeights.set(pointi, new scalarField());
221  }
222  }
223 }
224 
225 
226 template<class FromPatch, class ToPatch>
227 void PatchToPatchInterpolation<FromPatch, ToPatch>::calcFaceAddressing() const
228 {
229  faceWeightsPtr_.reset(new FieldField<Field, scalar>(toPatch_.size()));
230  auto& faceWeights = *faceWeightsPtr_;
231 
232  faceDistancePtr_.reset(new scalarField(toPatch_.size(), GREAT));
233  auto& faceDistance = *faceDistancePtr_;
234 
235  if (debug)
236  {
237  Info<< "projecting face centres" << endl;
238  }
239 
240  const pointField& fromPatchPoints = fromPatch_.points();
241  const auto& fromPatchFaces = fromPatch_;
242  const labelListList& fromPatchFaceFaces = fromPatch_.faceFaces();
243 
244  vectorField fromPatchFaceCentres(fromPatchFaces.size());
245 
246  forAll(fromPatchFaceCentres, facei)
247  {
248  fromPatchFaceCentres[facei] =
249  fromPatchFaces[facei].centre(fromPatchPoints);
250  }
251 
252  const pointField& toPatchPoints = toPatch_.points();
253  const auto& toPatchFaces = toPatch_;
254 
255  const vectorField& projectionDirection = toPatch_.faceNormals();
256 
257  List<objectHit> proj =
258  toPatch_.projectFaceCentres
259  (
260  fromPatch_,
261  projectionDirection,
262  alg_,
263  dir_
264  );
265 
266  faceAddressingPtr_.reset(new labelList(proj.size(), -1));
267  auto& faceAddressing = *faceAddressingPtr_;
268 
269  forAll(faceAddressing, facei)
270  {
271  if (proj[facei].hit())
272  {
273  // A hit exists
274  faceAddressing[facei] = proj[facei].hitObject();
275 
276  const auto& hitFace = fromPatchFaces[faceAddressing[facei]];
277 
278  pointHit curHit =
279  hitFace.ray
280  (
281  toPatchFaces[facei].centre(toPatchPoints),
282  projectionDirection[facei],
283  fromPatchPoints,
284  alg_,
285  dir_
286  );
287 
288  // grab distance to target
289  faceDistance[facei] = curHit.distance();
290 
291  // grab face centre of the hit face
292  const point& hitFaceCentre =
293  fromPatchFaceCentres[faceAddressing[facei]];
294 
295  // grab neighbours of hit face
296  const labelList& neighbours =
297  fromPatchFaceFaces[faceAddressing[facei]];
298 
299  scalar m = curHit.hitPoint().dist(hitFaceCentre);
300 
301  if
302  (
303  m < directHitTol // Direct hit
304  || neighbours.empty()
305  )
306  {
307  faceWeights.set(facei, new scalarField(1));
308  faceWeights[facei][0] = 1.0;
309  }
310  else
311  {
312  // set interpolation faceWeights
313 
314  // The first coefficient corresponds to the centre face.
315  // The rest is ordered in the same way as the faceFaces list.
316  faceWeights.set(facei, new scalarField(neighbours.size() + 1));
317 
318  faceWeights[facei][0] = 1.0/m;
319 
320  forAll(neighbours, nI)
321  {
322  faceWeights[facei][nI + 1] =
323  1.0/
324  (
325  curHit.hitPoint().dist
326  (
327  fromPatchFaceCentres[neighbours[nI]]
328  )
329  + VSMALL
330  );
331  }
332  }
333 
334  faceWeights[facei] /= sum(faceWeights[facei]);
335  }
336  else
337  {
338  faceWeights.set(facei, new scalarField());
339  }
340  }
341 }
342 
343 
344 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
345 
346 } // End namespace Foam
347 
348 // ************************************************************************* //
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:51
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:463
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
List< edge > edgeList
A List of edges.
Definition: edgeList.H:60
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
int debug
Static debugging option.
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
PointHit< point > pointHit
A PointHit with a 3D point.
Definition: pointHit.H:43
Namespace for OpenFOAM.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157