1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "PatchToPatchInterpolation.H"
27 #include "objectHit.H"
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 template<class FromPatch, class ToPatch>
38 scalar PatchToPatchInterpolation<FromPatch, ToPatch>::projectionTol_ = 0.05;
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 template<class FromPatch, class ToPatch>
44 void PatchToPatchInterpolation<FromPatch, ToPatch>::calcPointAddressing() const
46 // Calculate pointWeights
48 pointWeightsPtr_ = new FieldField<Field, scalar>(toPatch_.nPoints());
49 FieldField<Field, scalar>& pointWeights = *pointWeightsPtr_;
51 pointDistancePtr_ = new scalarField(toPatch_.nPoints(), GREAT);
52 scalarField& pointDistance = *pointDistancePtr_;
54 const pointField& fromPatchPoints = fromPatch_.localPoints();
55 const List<typename FromPatch::FaceType>& fromPatchFaces =
56 fromPatch_.localFaces();
58 const pointField& toPatchPoints = toPatch_.localPoints();
59 const vectorField& projectionDirection = toPatch_.pointNormals();
60 const edgeList& toPatchEdges = toPatch_.edges();
61 const labelListList& toPatchPointEdges = toPatch_.pointEdges();
65 Info << "projecting points" << endl;
68 List<objectHit> proj =
69 toPatch_.projectPoints(fromPatch_, projectionDirection, alg_, dir_);
71 pointAddressingPtr_ = new labelList(proj.size(), -1);
72 labelList& pointAddressing = *pointAddressingPtr_;
74 bool doWeights = false;
76 forAll (pointAddressing, pointI)
80 const typename FromPatch::FaceType& hitFace =
81 fromPatchFaces[proj[pointI].hitObject()];
83 point hitPoint = point::zero;
85 if (proj[pointI].hit())
90 pointAddressing[pointI] = proj[pointI].hitObject();
95 toPatchPoints[pointI],
96 projectionDirection[pointI],
102 // Grab distance to target
103 if (dir_ == intersection::CONTACT_SPHERE)
105 pointDistance[pointI] =
106 hitFace.contactSphereDiameter
108 toPatchPoints[pointI],
109 projectionDirection[pointI],
115 pointDistance[pointI] = curHit.distance();
119 hitPoint = curHit.hitPoint();
121 else if (projectionTol_ > SMALL)
123 // Check for a near miss
127 toPatchPoints[pointI],
128 projectionDirection[pointI],
137 toPatchPoints[pointI]
138 + projectionDirection[pointI]*ph.distance()
142 // Calculate the local tolerance
143 scalar minEdgeLength = GREAT;
145 // Do shortest edge of hit object
146 edgeList hitFaceEdges =
147 fromPatchFaces[proj[pointI].hitObject()].edges();
149 forAll (hitFaceEdges, edgeI)
155 hitFaceEdges[edgeI].mag(fromPatchPoints)
159 const labelList& curEdges = toPatchPointEdges[pointI];
161 forAll (curEdges, edgeI)
167 toPatchEdges[curEdges[edgeI]].mag(toPatchPoints)
171 if (dist < minEdgeLength*projectionTol_)
173 // This point is being corrected
176 pointAddressing[pointI] = proj[pointI].hitObject();
178 // Grab nearest point on face as hit point
179 hitPoint = ph.missPoint();
181 // Grab distance to target
182 if (dir_ == intersection::CONTACT_SPHERE)
184 pointDistance[pointI] =
185 hitFace.contactSphereDiameter
187 toPatchPoints[pointI],
188 projectionDirection[pointI],
194 pointDistance[pointI] =
196 projectionDirection[pointI]
197 /mag(projectionDirection[pointI])
199 & (hitPoint - toPatchPoints[pointI]);
206 // Set interpolation pointWeights
207 pointWeights.set(pointI, new scalarField(hitFace.size()));
209 pointField hitFacePoints = hitFace.points(fromPatchPoints);
211 forAll (hitFacePoints, masterPointI)
213 pointWeights[pointI][masterPointI] =
218 hitFacePoints[masterPointI]
225 pointWeights[pointI] /= sum(pointWeights[pointI]);
229 pointWeights.set(pointI, new scalarField(0));
235 template<class FromPatch, class ToPatch>
236 void PatchToPatchInterpolation<FromPatch, ToPatch>::calcFaceAddressing() const
238 faceWeightsPtr_ = new FieldField<Field, scalar>(toPatch_.size());
239 FieldField<Field, scalar>& faceWeights = *faceWeightsPtr_;
241 faceDistancePtr_ = new scalarField(toPatch_.size(), GREAT);
242 scalarField& faceDistance = *faceDistancePtr_;
246 Info << "projecting face centres" << endl;
249 const pointField& fromPatchPoints = fromPatch_.points();
250 const typename FromPatch::FaceListType& fromPatchFaces = fromPatch_;
251 const labelListList& fromPatchFaceFaces = fromPatch_.faceFaces();
253 vectorField fromPatchFaceCentres(fromPatchFaces.size());
255 forAll (fromPatchFaceCentres, faceI)
257 fromPatchFaceCentres[faceI] =
258 fromPatchFaces[faceI].centre(fromPatchPoints);
261 const pointField& toPatchPoints = toPatch_.points();
262 const typename ToPatch::FaceListType& toPatchFaces = toPatch_;
264 const vectorField& projectionDirection = toPatch_.faceNormals();
266 List<objectHit> proj =
267 toPatch_.projectFaceCentres
275 faceAddressingPtr_ = new labelList(proj.size(), -1);
276 labelList& faceAddressing = *faceAddressingPtr_;
278 forAll (faceAddressing, faceI)
280 if (proj[faceI].hit())
283 faceAddressing[faceI] = proj[faceI].hitObject();
285 const typename FromPatch::FaceType& hitFace =
286 fromPatchFaces[faceAddressing[faceI]];
291 toPatchFaces[faceI].centre(toPatchPoints),
292 projectionDirection[faceI],
298 // grab distance to target
299 faceDistance[faceI] = curHit.distance();
301 // grab face centre of the hit face
302 const point& hitFaceCentre =
303 fromPatchFaceCentres[faceAddressing[faceI]];
305 // grab neighbours of hit face
306 const labelList& neighbours =
307 fromPatchFaceFaces[faceAddressing[faceI]];
309 scalar m = mag(curHit.hitPoint() - hitFaceCentre);
313 m < directHitTol // Direct hit
314 || neighbours.empty()
317 faceWeights.set(faceI, new scalarField(1));
318 faceWeights[faceI][0] = 1.0;
322 // set interpolation faceWeights
324 // The first coefficient corresponds to the centre face.
325 // The rest is ordered in the same way as the faceFaces list.
326 faceWeights.set(faceI, new scalarField(neighbours.size() + 1));
328 faceWeights[faceI][0] = 1.0/m;
330 forAll (neighbours, nI)
332 faceWeights[faceI][nI + 1] =
337 fromPatchFaceCentres[neighbours[nI]]
345 faceWeights[faceI] /= sum(faceWeights[faceI]);
349 faceWeights.set(faceI, new scalarField(0));
355 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
357 } // End namespace Foam
359 // ************************************************************************* //