1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "PatchToPatchInterpolationTemplate.H"
27 #include "objectHit.H"
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 template<class FromPatch, class ToPatch>
38 void PatchToPatchInterpolation<FromPatch, ToPatch>::calcPointAddressing() const
40 // Calculate pointWeights
42 pointWeightsPtr_ = new FieldField<Field, scalar>(toPatch_.nPoints());
43 FieldField<Field, scalar>& pointWeights = *pointWeightsPtr_;
45 pointDistancePtr_ = new scalarField(toPatch_.nPoints(), GREAT);
46 scalarField& pointDistance = *pointDistancePtr_;
48 const pointField& fromPatchPoints = fromPatch_.localPoints();
49 const List<typename FromPatch::FaceType>& fromPatchFaces =
50 fromPatch_.localFaces();
52 const pointField& toPatchPoints = toPatch_.localPoints();
53 const vectorField& projectionDirection = toPatch_.pointNormals();
54 const edgeList& toPatchEdges = toPatch_.edges();
55 const labelListList& toPatchPointEdges = toPatch_.pointEdges();
59 Info << "projecting points" << endl;
62 List<objectHit> proj =
63 toPatch_.projectPoints(fromPatch_, projectionDirection, alg_, dir_);
65 pointAddressingPtr_ = new labelList(proj.size(), -1);
66 labelList& pointAddressing = *pointAddressingPtr_;
68 bool doWeights = false;
70 forAll (pointAddressing, pointI)
74 const typename FromPatch::FaceType& hitFace =
75 fromPatchFaces[proj[pointI].hitObject()];
77 point hitPoint = point::zero;
79 if (proj[pointI].hit())
84 pointAddressing[pointI] = proj[pointI].hitObject();
89 toPatchPoints[pointI],
90 projectionDirection[pointI],
96 // Grab distance to target
97 if (dir_ == intersection::CONTACT_SPHERE)
99 pointDistance[pointI] =
100 hitFace.contactSphereDiameter
102 toPatchPoints[pointI],
103 projectionDirection[pointI],
109 pointDistance[pointI] = curHit.distance();
113 hitPoint = curHit.hitPoint();
115 else if (projectionTol_() > SMALL)
117 // Check for a near miss
121 toPatchPoints[pointI],
122 projectionDirection[pointI],
131 toPatchPoints[pointI]
132 + projectionDirection[pointI]*ph.distance()
136 // Calculate the local tolerance
137 scalar minEdgeLength = GREAT;
139 // Do shortest edge of hit object
140 edgeList hitFaceEdges =
141 fromPatchFaces[proj[pointI].hitObject()].edges();
143 forAll (hitFaceEdges, edgeI)
149 hitFaceEdges[edgeI].mag(fromPatchPoints)
153 const labelList& curEdges = toPatchPointEdges[pointI];
155 forAll (curEdges, edgeI)
161 toPatchEdges[curEdges[edgeI]].mag(toPatchPoints)
165 if (dist < minEdgeLength*projectionTol_())
167 // This point is being corrected
170 pointAddressing[pointI] = proj[pointI].hitObject();
172 // Grab nearest point on face as hit point
173 hitPoint = ph.missPoint();
175 // Grab distance to target
176 if (dir_ == intersection::CONTACT_SPHERE)
178 pointDistance[pointI] =
179 hitFace.contactSphereDiameter
181 toPatchPoints[pointI],
182 projectionDirection[pointI],
188 pointDistance[pointI] =
190 projectionDirection[pointI]
191 /mag(projectionDirection[pointI])
193 & (hitPoint - toPatchPoints[pointI]);
200 // Set interpolation pointWeights
201 pointWeights.set(pointI, new scalarField(hitFace.size()));
203 pointField hitFacePoints = hitFace.points(fromPatchPoints);
205 forAll (hitFacePoints, masterPointI)
207 pointWeights[pointI][masterPointI] =
212 hitFacePoints[masterPointI]
219 pointWeights[pointI] /= sum(pointWeights[pointI]);
223 pointWeights.set(pointI, new scalarField(0));
229 template<class FromPatch, class ToPatch>
230 void PatchToPatchInterpolation<FromPatch, ToPatch>::calcFaceAddressing() const
232 faceWeightsPtr_ = new FieldField<Field, scalar>(toPatch_.size());
233 FieldField<Field, scalar>& faceWeights = *faceWeightsPtr_;
235 faceDistancePtr_ = new scalarField(toPatch_.size(), GREAT);
236 scalarField& faceDistance = *faceDistancePtr_;
240 Info << "projecting face centres" << endl;
243 const pointField& fromPatchPoints = fromPatch_.points();
244 const typename FromPatch::FaceListType& fromPatchFaces = fromPatch_;
245 const labelListList& fromPatchFaceFaces = fromPatch_.faceFaces();
247 vectorField fromPatchFaceCentres(fromPatchFaces.size());
249 forAll (fromPatchFaceCentres, faceI)
251 fromPatchFaceCentres[faceI] =
252 fromPatchFaces[faceI].centre(fromPatchPoints);
255 const pointField& toPatchPoints = toPatch_.points();
256 const typename ToPatch::FaceListType& toPatchFaces = toPatch_;
258 const vectorField& projectionDirection = toPatch_.faceNormals();
260 List<objectHit> proj =
261 toPatch_.projectFaceCentres
269 faceAddressingPtr_ = new labelList(proj.size(), -1);
270 labelList& faceAddressing = *faceAddressingPtr_;
272 forAll (faceAddressing, faceI)
274 if (proj[faceI].hit())
277 faceAddressing[faceI] = proj[faceI].hitObject();
279 const typename FromPatch::FaceType& hitFace =
280 fromPatchFaces[faceAddressing[faceI]];
285 toPatchFaces[faceI].centre(toPatchPoints),
286 projectionDirection[faceI],
292 // grab distance to target
293 faceDistance[faceI] = curHit.distance();
295 // grab face centre of the hit face
296 const point& hitFaceCentre =
297 fromPatchFaceCentres[faceAddressing[faceI]];
299 // grab neighbours of hit face
300 const labelList& neighbours =
301 fromPatchFaceFaces[faceAddressing[faceI]];
303 scalar m = mag(curHit.hitPoint() - hitFaceCentre);
307 m < directHitTol_() // Direct hit
308 || neighbours.empty()
311 faceWeights.set(faceI, new scalarField(1));
312 faceWeights[faceI][0] = 1.0;
316 // set interpolation faceWeights
318 // The first coefficient corresponds to the centre face.
319 // The rest is ordered in the same way as the faceFaces list.
320 faceWeights.set(faceI, new scalarField(neighbours.size() + 1));
322 faceWeights[faceI][0] = 1.0/m;
324 forAll (neighbours, nI)
326 faceWeights[faceI][nI + 1] =
331 fromPatchFaceCentres[neighbours[nI]]
339 faceWeights[faceI] /= sum(faceWeights[faceI]);
343 faceWeights.set(faceI, new scalarField(0));
349 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
351 } // End namespace Foam
353 // ************************************************************************* //