00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "PatchToPatchInterpolation_.H"
00027 #include <OpenFOAM/objectHit.H>
00028 #include <OpenFOAM/pointHit.H>
00029
00030
00031
00032 namespace Foam
00033 {
00034
00035
00036
00037 template<class FromPatch, class ToPatch>
00038 scalar PatchToPatchInterpolation<FromPatch, ToPatch>::projectionTol_ = 0.05;
00039
00040
00041
00042
00043 template<class FromPatch, class ToPatch>
00044 void PatchToPatchInterpolation<FromPatch, ToPatch>::calcPointAddressing() const
00045 {
00046
00047
00048 pointWeightsPtr_ = new FieldField<Field, scalar>(toPatch_.nPoints());
00049 FieldField<Field, scalar>& pointWeights = *pointWeightsPtr_;
00050
00051 pointDistancePtr_ = new scalarField(toPatch_.nPoints(), GREAT);
00052 scalarField& pointDistance = *pointDistancePtr_;
00053
00054 const pointField& fromPatchPoints = fromPatch_.localPoints();
00055 const List<typename FromPatch::FaceType>& fromPatchFaces =
00056 fromPatch_.localFaces();
00057
00058 const pointField& toPatchPoints = toPatch_.localPoints();
00059 const vectorField& projectionDirection = toPatch_.pointNormals();
00060 const edgeList& toPatchEdges = toPatch_.edges();
00061 const labelListList& toPatchPointEdges = toPatch_.pointEdges();
00062
00063 if (debug)
00064 {
00065 Info << "projecting points" << endl;
00066 }
00067
00068 List<objectHit> proj =
00069 toPatch_.projectPoints(fromPatch_, projectionDirection, alg_, dir_);
00070
00071 pointAddressingPtr_ = new labelList(proj.size(), -1);
00072 labelList& pointAddressing = *pointAddressingPtr_;
00073
00074 bool doWeights = false;
00075
00076 forAll (pointAddressing, pointI)
00077 {
00078 doWeights = false;
00079
00080 const typename FromPatch::FaceType& hitFace =
00081 fromPatchFaces[proj[pointI].hitObject()];
00082
00083 point hitPoint = point::zero;
00084
00085 if (proj[pointI].hit())
00086 {
00087
00088 doWeights = true;
00089
00090 pointAddressing[pointI] = proj[pointI].hitObject();
00091
00092 pointHit curHit =
00093 hitFace.ray
00094 (
00095 toPatchPoints[pointI],
00096 projectionDirection[pointI],
00097 fromPatchPoints,
00098 alg_,
00099 dir_
00100 );
00101
00102
00103 if (dir_ == intersection::CONTACT_SPHERE)
00104 {
00105 pointDistance[pointI] =
00106 hitFace.contactSphereDiameter
00107 (
00108 toPatchPoints[pointI],
00109 projectionDirection[pointI],
00110 fromPatchPoints
00111 );
00112 }
00113 else
00114 {
00115 pointDistance[pointI] = curHit.distance();
00116 }
00117
00118
00119 hitPoint = curHit.hitPoint();
00120 }
00121 else if (projectionTol_ > SMALL)
00122 {
00123
00124 pointHit ph =
00125 hitFace.ray
00126 (
00127 toPatchPoints[pointI],
00128 projectionDirection[pointI],
00129 fromPatchPoints,
00130 alg_,
00131 dir_
00132 );
00133
00134 scalar dist =
00135 Foam::mag
00136 (
00137 toPatchPoints[pointI]
00138 + projectionDirection[pointI]*ph.distance()
00139 - ph.missPoint()
00140 );
00141
00142
00143 scalar minEdgeLength = GREAT;
00144
00145
00146 edgeList hitFaceEdges =
00147 fromPatchFaces[proj[pointI].hitObject()].edges();
00148
00149 forAll (hitFaceEdges, edgeI)
00150 {
00151 minEdgeLength =
00152 min
00153 (
00154 minEdgeLength,
00155 hitFaceEdges[edgeI].mag(fromPatchPoints)
00156 );
00157 }
00158
00159 const labelList& curEdges = toPatchPointEdges[pointI];
00160
00161 forAll (curEdges, edgeI)
00162 {
00163 minEdgeLength =
00164 min
00165 (
00166 minEdgeLength,
00167 toPatchEdges[curEdges[edgeI]].mag(toPatchPoints)
00168 );
00169 }
00170
00171 if (dist < minEdgeLength*projectionTol_)
00172 {
00173
00174 doWeights = true;
00175
00176 pointAddressing[pointI] = proj[pointI].hitObject();
00177
00178
00179 hitPoint = ph.missPoint();
00180
00181
00182 if (dir_ == intersection::CONTACT_SPHERE)
00183 {
00184 pointDistance[pointI] =
00185 hitFace.contactSphereDiameter
00186 (
00187 toPatchPoints[pointI],
00188 projectionDirection[pointI],
00189 fromPatchPoints
00190 );
00191 }
00192 else
00193 {
00194 pointDistance[pointI] =
00195 (
00196 projectionDirection[pointI]
00197 /mag(projectionDirection[pointI])
00198 )
00199 & (hitPoint - toPatchPoints[pointI]);
00200 }
00201 }
00202 }
00203
00204 if (doWeights)
00205 {
00206
00207 pointWeights.set(pointI, new scalarField(hitFace.size()));
00208
00209 pointField hitFacePoints = hitFace.points(fromPatchPoints);
00210
00211 forAll (hitFacePoints, masterPointI)
00212 {
00213 pointWeights[pointI][masterPointI] =
00214 1.0/
00215 (
00216 mag
00217 (
00218 hitFacePoints[masterPointI]
00219 - hitPoint
00220 )
00221 + VSMALL
00222 );
00223 }
00224
00225 pointWeights[pointI] /= sum(pointWeights[pointI]);
00226 }
00227 else
00228 {
00229 pointWeights.set(pointI, new scalarField(0));
00230 }
00231 }
00232 }
00233
00234
00235 template<class FromPatch, class ToPatch>
00236 void PatchToPatchInterpolation<FromPatch, ToPatch>::calcFaceAddressing() const
00237 {
00238 faceWeightsPtr_ = new FieldField<Field, scalar>(toPatch_.size());
00239 FieldField<Field, scalar>& faceWeights = *faceWeightsPtr_;
00240
00241 faceDistancePtr_ = new scalarField(toPatch_.size(), GREAT);
00242 scalarField& faceDistance = *faceDistancePtr_;
00243
00244 if (debug)
00245 {
00246 Info << "projecting face centres" << endl;
00247 }
00248
00249 const pointField& fromPatchPoints = fromPatch_.points();
00250 const typename FromPatch::FaceListType& fromPatchFaces = fromPatch_;
00251 const labelListList& fromPatchFaceFaces = fromPatch_.faceFaces();
00252
00253 vectorField fromPatchFaceCentres(fromPatchFaces.size());
00254
00255 forAll (fromPatchFaceCentres, faceI)
00256 {
00257 fromPatchFaceCentres[faceI] =
00258 fromPatchFaces[faceI].centre(fromPatchPoints);
00259 }
00260
00261 const pointField& toPatchPoints = toPatch_.points();
00262 const typename ToPatch::FaceListType& toPatchFaces = toPatch_;
00263
00264 const vectorField& projectionDirection = toPatch_.faceNormals();
00265
00266 List<objectHit> proj =
00267 toPatch_.projectFaceCentres
00268 (
00269 fromPatch_,
00270 projectionDirection,
00271 alg_,
00272 dir_
00273 );
00274
00275 faceAddressingPtr_ = new labelList(proj.size(), -1);
00276 labelList& faceAddressing = *faceAddressingPtr_;
00277
00278 forAll (faceAddressing, faceI)
00279 {
00280 if (proj[faceI].hit())
00281 {
00282
00283 faceAddressing[faceI] = proj[faceI].hitObject();
00284
00285 const typename FromPatch::FaceType& hitFace =
00286 fromPatchFaces[faceAddressing[faceI]];
00287
00288 pointHit curHit =
00289 hitFace.ray
00290 (
00291 toPatchFaces[faceI].centre(toPatchPoints),
00292 projectionDirection[faceI],
00293 fromPatchPoints,
00294 alg_,
00295 dir_
00296 );
00297
00298
00299 faceDistance[faceI] = curHit.distance();
00300
00301
00302 const point& hitFaceCentre =
00303 fromPatchFaceCentres[faceAddressing[faceI]];
00304
00305
00306 const labelList& neighbours =
00307 fromPatchFaceFaces[faceAddressing[faceI]];
00308
00309 scalar m = mag(curHit.hitPoint() - hitFaceCentre);
00310
00311 if
00312 (
00313 m < directHitTol
00314 || neighbours.empty()
00315 )
00316 {
00317 faceWeights.set(faceI, new scalarField(1));
00318 faceWeights[faceI][0] = 1.0;
00319 }
00320 else
00321 {
00322
00323
00324
00325
00326 faceWeights.set(faceI, new scalarField(neighbours.size() + 1));
00327
00328 faceWeights[faceI][0] = 1.0/m;
00329
00330 forAll (neighbours, nI)
00331 {
00332 faceWeights[faceI][nI + 1] =
00333 1.0/
00334 (
00335 mag
00336 (
00337 fromPatchFaceCentres[neighbours[nI]]
00338 - curHit.hitPoint()
00339 )
00340 + VSMALL
00341 );
00342 }
00343 }
00344
00345 faceWeights[faceI] /= sum(faceWeights[faceI]);
00346 }
00347 else
00348 {
00349 faceWeights.set(faceI, new scalarField(0));
00350 }
00351 }
00352 }
00353
00354
00355
00356
00357 }
00358
00359