1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 Mass-conservative face interpolation of face data between two
33 Hrvoje Jasak, Wikki Ltd. All rights reserved
36 Martin Beaudoin, Hydro-Quebec, (2008)
41 GGIInterpolationWeights.C
43 \*---------------------------------------------------------------------------*/
45 #ifndef GGIInterpolation_H
46 #define GGIInterpolation_H
48 #include "className.H"
49 #include "labelList.H"
50 #include "scalarField.H"
51 #include "pointField.H"
52 #include "FieldFields.H"
54 #include "intersection.H"
56 #include "NamedEnum.H"
58 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
63 /*---------------------------------------------------------------------------*\
64 Class GGIInterpolationName Declaration
65 \*---------------------------------------------------------------------------*/
67 class GGIInterpolationName
71 // Public enumerations
73 //- Define a return type for isVertexInsidePolygon.
74 // The names are rather obvious
75 // on vertex, or on edge or inside == inside
83 //- Quick reject overlap search algorithm
95 ClassName("GGIInterpolation");
97 //- Quick reject names
98 static const NamedEnum<quickReject, 3> quickRejectNames_;
104 GGIInterpolationName()
110 /*---------------------------------------------------------------------------*\
111 Class GGIInterpolation Declaration
112 \*---------------------------------------------------------------------------*/
114 template<class MasterPatch, class SlavePatch>
115 class GGIInterpolation
117 public GGIInterpolationName
119 // Private data types
121 // Definition for a 3D orthoNormalBasis type
122 typedef VectorSpace<Vector<vector>, vector, 3> orthoNormalBasis;
127 //- Reference to the master patch
128 const MasterPatch& masterPatch_;
130 //- Reference to the slave patch
131 const SlavePatch& slavePatch_;
133 //- Slave-to-master transformation tensor. Transforms slave data to
134 // master plane. Size equals number of slave faces; zero length
135 // indicates no transform. Size 1 indicates constant transform
137 const tensorField forwardT_;
139 //- Master-to-slave transformation tensor. Transforms slave data to
140 // master plane. Size equals number of master faces; zero length
141 // indicates no transform. Size 1 indicates constant transform
143 const tensorField reverseT_;
145 //- Slave-to-master separation vector. Translation of slave data to
146 // master plane. Size equals number of slave faces; zero length
147 // indicates no translation. MB, 28/Jan/2009
148 const vectorField forwardSep_;
150 //- Master non-overlap face tolerance factor
151 const scalar masterNonOverlapFaceTol_;
153 //- Slave non-overlap face tolerance factor
154 const scalar slaveNonOverlapFaceTol_;
156 //- Rescale the GGI weighting factors or not
157 const bool rescaleGGIWeightingFactors_;
159 //- Quick reject search algorithm
163 // Demand-driven data
165 // Master-to-slave interpolation
167 //- Master to slave addressing
168 mutable labelListList* masterAddrPtr_;
170 //- Master to slave weights
171 mutable scalarListList* masterWeightsPtr_;
173 // Slave-to-master interpolation
175 //- Slave to master addressing
176 mutable labelListList* slaveAddrPtr_;
178 //- Slave to master weights
179 mutable scalarListList* slaveWeightsPtr_;
181 //- List of uncovered master faces
182 mutable labelList* uncoveredMasterAddrPtr_;
184 //- List of uncovered slave faces
185 mutable labelList* uncoveredSlaveAddrPtr_;
188 // Private static data
190 //- Facet area error tolerance
191 static const scalar areaErrorTol_;
193 //- Facet normal featureCos criteria
194 static const scalar featureCosTol_;
196 //- Facet bound box extension factor
197 static const scalar faceBoundBoxExtendSpanFraction_;
199 //- The next 3 attributes are parameters controlling the creation
200 // of an octree search engine for the GGI facets neighbourhood
203 // Tests using GGI patches of up to ~100K facets have shown that
204 // the following values gave the best compromise between the
205 // "octree creation time" vs "octree search time":
207 // octreeSearchMinNLevel_ : 3
208 // octreeSearchMaxLeafRatio_ : 3
209 // octreeSearchMaxShapeRatio_ : 1
211 // For GGI patches larger than ~100K facets, your mileage may vary.
212 // So these 3 control parameters are adjustable using the following
213 // global optimization switches:
215 // GGIOctreeSearchMinNLevel
216 // GGIOctreeSearchMaxLeafRatio
217 // GGIOctreeSearchMaxShapeRatio
220 //- Octree search: minNlevel parameter for octree constructor
221 static const label octreeSearchMinNLevel_;
223 //- Octree search: maxLeafRatio parameter for octree constructor
224 static const scalar octreeSearchMaxLeafRatio_;
226 //- Octree search: maxShapeRatio parameter for octree constructor
227 static const scalar octreeSearchMaxShapeRatio_;
230 // Private Member Functions
232 //- Disallow default bitwise copy construct
233 GGIInterpolation(const GGIInterpolation&);
235 //- Disallow default bitwise assignment
236 void operator=(const GGIInterpolation&);
239 // Helper functions for demand-driven data
241 //- Evaluate faces neighborhood based of sphere defined by faces BB
242 void findNeighbours3D(labelListList& result) const;
244 //- Evaluate faces neighborhood based of faces Axis Aligned BB
245 void findNeighboursAABB(labelListList& result) const;
247 //- Evaluate faces neighborhood based of faces BB and an octree
249 void findNeighboursBBOctree(labelListList& result) const;
251 //- Projects a list of points onto a plane located at
252 // planeOrig, oriented along planeNormal
253 tmp<pointField> projectPointsOnPlane
255 const pointField& lpoints,
256 const vector& planeOrig,
257 const vector& planeDirection,
258 scalarField& distanceProjection
261 //- Compute an orthonormal basis. Useful for 2D projection
262 orthoNormalBasis computeOrthonormalBasis
264 const vector& normalVectorCentre,
265 const vector& normalVector,
266 const pointField& pointsOnPlane
269 //- Compute the 2D projection of a 3D list of point into the
270 // orthonormal basis orthoBase
271 List<point2D> projectPoints3Dto2D
273 const orthoNormalBasis& orthoBase,
274 const vector& orthoBaseOffset,
275 const pointField& pointsIn3D,
276 scalarField& distanceProjection
279 //- Compute the 1D projection of a 2D list of points onto the
280 // projectionDir direction
281 scalarField projectPoints2Dto1D
283 const vector2D& normalizedProjectionDir,
284 const point2D& normalizedProjectionDirOffset,
285 const List<point2D>& lPoints2D
288 //- Detect the intersection of 2 2D polygons using the method of
289 // Separating Axes Theorem
290 bool detect2dPolygonsOverlap
292 const List<point2D>& poly1,
293 const List<point2D>& poly2,
294 const scalar& tolFactor,
295 const bool firstCall = true // Optional parameter: first call
298 //- Compute the intersection area between 2 2D polygons
299 scalar polygonIntersection
301 const List<point2D>& poly1,
302 const List<point2D>& poly2
305 //- Detect is the points from a subject polygon are inside or
306 // outside a clipping polygon
307 insideOutside isVertexInsidePolygon
309 const List<point2D>& clippingPolygon,
310 const List<point2D>& subjectPolygon,
311 List<bool>& subjectVertexInside
314 //- Compute the intersection between two 2D polygons using the
315 // Sutherland Hodgman algorithm
316 List<point2D> clipPolygon2DSutherlandHodgman
318 const List<point2D>& clippingPolygon,
319 const List<point2D>& subjectPolygon
322 //- Compute the intersection between two 2D polygons using the
323 // Greiner Hormann algorithm
324 List<point2D> clipPolygon2DGreinerHormann
326 const List<point2D>& clippingPolygon,
327 const List<point2D>& subjectPolygon,
328 const List<bool>& subjectVertexInside
331 //- Compute the area of a 2D polygon
334 const List<point2D>& polygon
338 //- Calculate addressing and weights
339 void calcAddressing() const;
341 //- Rescale GGI weighting factors
342 void rescaleWeightingFactors() const;
344 //- Find non-overlapping faces
345 tmp<labelField> findNonOverlappingFaces
347 const scalarListList& patchWeights,
348 const scalar& nonOverlapFaceTol
351 //- Clear all geometry and addressing
355 // Interpolation data access
357 //- Interpolate given source and target, addressing and weights
359 static void interpolate
361 const Field<Type>& ff,
363 const labelListList& addr,
364 const scalarListList& weights
367 //- Interpolate given source and target, addressing and weights
368 // for masked faces only
370 static void maskedInterpolate
372 const Field<Type>& ff,
374 const labelList& mask,
375 const labelListList& addr,
376 const scalarListList& weights
379 //- Bridge uncovered faces given addressing
383 const Field<Type>& bridgeField,
385 const labelList& addr
388 //- Bridge uncovered faces given addressing
389 // for masked faces only
391 static void maskedBridge
393 const Field<Type>& bridgeField,
395 const labelList& mask,
396 const labelList& addr
399 //- Is a transform required?
400 inline bool doTransform() const
402 return forwardT_.size() > 0;
405 //- Is a separation required?
406 inline bool doSeparation() const
408 return forwardSep_.size() > 0;
416 //- Construct from components
419 const MasterPatch& masterPatch,
420 const SlavePatch& slavePatch,
421 const tensorField& forwardT,
422 const tensorField& reverseT,
423 const vectorField& forwardSep,
424 const scalar masterFaceNonOverlapFaceTol = 0,
425 const scalar slaveFaceNonOverlapFaceTol = 0,
426 const bool rescaleGGIWeightingFactors = true,
427 const quickReject reject = AABB
440 //- Return reference to master addressing
441 const labelListList& masterAddr() const;
443 //- Return reference to master weights
444 const scalarListList& masterWeights() const;
446 //- Return reference to slave addressing
447 const labelListList& slaveAddr() const;
449 //- Return reference to slave weights
450 const scalarListList& slaveWeights() const;
452 //- Return reference to the master list of non-overlap faces
453 const labelList& uncoveredMasterFaces() const;
455 //- Return reference to the slave list of non-overlap faces
456 const labelList& uncoveredSlaveFaces() const;
459 // Interpolation functions
461 //- Interpolate from master to slave
463 tmp<Field<Type> > masterToSlave(const Field<Type>& ff) const;
466 tmp<Field<Type> > masterToSlave
468 const tmp<Field<Type> >& tff
471 //- Interpolate from master to slave, only for marked master faces
472 // Addressing picks the faces from patch that are selected
473 // for collection into the result field
475 void maskedMasterToSlave
477 const Field<Type>& ff,
479 const labelList& mask
483 //- Interpolate from slave to master
485 tmp<Field<Type> > slaveToMaster(const Field<Type>& ff) const;
488 tmp<Field<Type> > slaveToMaster
490 const tmp<Field<Type> >& tff
493 //- Interpolate from slave to master, only for marked slave faces
494 // Addressing picks the faces from patch that are selected
495 // for collection into the result field
497 void maskedSlaveToMaster
499 const Field<Type>& ff,
501 const labelList& mask
505 //- Bridge uncovered master patch field
509 const Field<Type>& bridgeField,
513 //- Bridge uncovered master patch field, only for marked master faces
515 void maskedBridgeMaster
517 const Field<Type>& bridgeField,
519 const labelList& mask
522 //- Bridge uncovered slave patch field
526 const Field<Type>& bridgeField,
530 //- Bridge uncovered slave patch field, only for marked slave faces
532 void maskedBridgeSlave
534 const Field<Type>& bridgeField,
536 const labelList& mask
542 //- Correct weighting factors for moving mesh.
547 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
549 } // End namespace Foam
552 # include "GGIInterpolation.C"
555 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
559 // ************************************************************************* //