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/>.
28 Mass-conservative face interpolation of face data between two
32 Hrvoje Jasak, Wikki Ltd. All rights reserved
35 Martin Beaudoin, Hydro-Quebec, (2008)
40 GGIInterpolationWeights.C
42 \*---------------------------------------------------------------------------*/
44 #ifndef GGIInterpolation_H
45 #define GGIInterpolation_H
47 #include "className.H"
48 #include "labelList.H"
49 #include "scalarField.H"
50 #include "pointField.H"
51 #include "FieldFields.H"
53 #include "intersection.H"
55 #include "NamedEnum.H"
56 #include "tolerancesSwitch.H"
57 #include "optimisationSwitch.H"
59 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
64 /*---------------------------------------------------------------------------*\
65 Class GGIInterpolationName Declaration
66 \*---------------------------------------------------------------------------*/
68 class GGIInterpolationName
72 // Public enumerations
74 //- Define a return type for isVertexInsidePolygon.
75 // The names are rather obvious
76 // on vertex, or on edge or inside == inside
84 //- Quick reject overlap search algorithm
96 ClassName("GGIInterpolation");
98 //- Quick reject names
99 static const NamedEnum<quickReject, 4> quickRejectNames_;
105 GGIInterpolationName()
111 /*---------------------------------------------------------------------------*\
112 Class GGIInterpolation Declaration
113 \*---------------------------------------------------------------------------*/
115 template<class MasterPatch, class SlavePatch>
116 class GGIInterpolation
118 public GGIInterpolationName
120 // Private data types
122 // Definition for a 3D orthoNormalBasis type
123 typedef VectorSpace<Vector<vector>, vector, 3> orthoNormalBasis;
128 //- Reference to the master patch
129 const MasterPatch& masterPatch_;
131 //- Reference to the slave patch
132 const SlavePatch& slavePatch_;
134 //- Slave-to-master transformation tensor. Transforms slave data to
135 // master plane. Size equals number of slave faces; zero length
136 // indicates no transform. Size 1 indicates constant transform
138 tensorField forwardT_;
140 //- Master-to-slave transformation tensor. Transforms slave data to
141 // master plane. Size equals number of master faces; zero length
142 // indicates no transform. Size 1 indicates constant transform
144 tensorField reverseT_;
146 //- Slave-to-master separation vector. Translation of slave data to
147 // master plane. Size equals number of slave faces; zero length
148 // indicates no translation. MB, 28/Jan/2009
149 vectorField forwardSep_;
151 //- Master non-overlap face tolerance factor
152 const scalar masterNonOverlapFaceTol_;
154 //- Slave non-overlap face tolerance factor
155 const scalar slaveNonOverlapFaceTol_;
157 //- Rescale the GGI weighting factors or not
158 const bool rescaleGGIWeightingFactors_;
160 //- Quick reject search algorithm
164 // Demand-driven data
166 // Master-to-slave interpolation
168 //- Master to slave addressing
169 mutable labelListList* masterAddrPtr_;
171 //- Master to slave weights
172 mutable scalarListList* masterWeightsPtr_;
175 // Slave-to-master interpolation
177 //- Slave to master addressing
178 mutable labelListList* slaveAddrPtr_;
180 //- Slave to master weights
181 mutable scalarListList* slaveWeightsPtr_;
183 //- List of uncovered master faces
184 mutable labelList* uncoveredMasterAddrPtr_;
186 //- List of uncovered slave faces
187 mutable labelList* uncoveredSlaveAddrPtr_;
190 // Private static data
192 //- Facet area error tolerance
193 static const debug::tolerancesSwitch areaErrorTol_;
195 //- Facet normal featureCos criteria
196 static const debug::tolerancesSwitch featureCosTol_;
198 //- Facet bound box extension factor
199 static const debug::tolerancesSwitch faceBoundBoxExtendSpanFraction_;
201 //- The next 3 attributes are parameters controlling the creation
202 // of an octree search engine for the GGI facets neighbourhood
205 // Tests using GGI patches of up to ~100K facets have shown that
206 // the following values gave the best compromise between the
207 // "octree creation time" vs "octree search time":
209 // octreeSearchMinNLevel_ : 3
210 // octreeSearchMaxLeafRatio_ : 3
211 // octreeSearchMaxShapeRatio_ : 1
213 // For GGI patches larger than ~100K facets, your mileage may vary.
214 // So these 3 control parameters are adjustable using the following
215 // global optimization switches:
217 // GGIOctreeSearchMinNLevel
218 // GGIOctreeSearchMaxLeafRatio
219 // GGIOctreeSearchMaxShapeRatio
222 //- Octree search: minNlevel parameter for octree constructor
223 static const debug::optimisationSwitch octreeSearchMinNLevel_;
225 //- Octree search: maxLeafRatio parameter for octree constructor
226 static const debug::optimisationSwitch octreeSearchMaxLeafRatio_;
228 //- Octree search: maxShapeRatio parameter for octree constructor
229 static const debug::optimisationSwitch octreeSearchMaxShapeRatio_;
232 // Private Member Functions
234 //- Disallow default bitwise copy construct
235 GGIInterpolation(const GGIInterpolation&);
237 //- Disallow default bitwise assignment
238 void operator=(const GGIInterpolation&);
241 // Helper functions for demand-driven data
243 //- Evaluate faces neighborhood based of sphere defined by faces BB
244 void findNeighbours3D(labelListList& result) const;
246 //- Evaluate faces neighborhood based of faces Axis Aligned BB
247 void findNeighboursAABB(labelListList& result) const;
249 //- Evaluate faces neighborhood based of faces BB and an octree
251 void findNeighboursBBOctree(labelListList& result) const;
253 //- Projects a list of points onto a plane located at
254 // planeOrig, oriented along planeNormal
255 tmp<pointField> projectPointsOnPlane
257 const pointField& lpoints,
258 const vector& planeOrig,
259 const vector& planeDirection,
260 scalarField& distanceProjection
263 //- Compute an orthonormal basis. Useful for 2D projection
264 orthoNormalBasis computeOrthonormalBasis
266 const vector& normalVectorCentre,
267 const vector& normalVector,
268 const pointField& pointsOnPlane
271 //- Compute the 2D projection of a 3D list of point into the
272 // orthonormal basis orthoBase
273 List<point2D> projectPoints3Dto2D
275 const orthoNormalBasis& orthoBase,
276 const vector& orthoBaseOffset,
277 const pointField& pointsIn3D,
278 scalarField& distanceProjection
281 //- Compute the 1D projection of a 2D list of points onto the
282 // projectionDir direction
283 scalarField projectPoints2Dto1D
285 const vector2D& normalizedProjectionDir,
286 const point2D& normalizedProjectionDirOffset,
287 const List<point2D>& lPoints2D
290 //- Detect the intersection of 2 2D polygons using the method of
291 // Separating Axes Theorem
292 bool detect2dPolygonsOverlap
294 const List<point2D>& poly1,
295 const List<point2D>& poly2,
296 const scalar& tolFactor,
297 const bool firstCall = true // Optional parameter: first call
300 //- Compute the intersection area between 2 2D polygons
301 scalar polygonIntersection
303 const List<point2D>& poly1,
304 const List<point2D>& poly2
307 //- Detect is the points from a subject polygon are inside or
308 // outside a clipping polygon
309 insideOutside isVertexInsidePolygon
311 const List<point2D>& clippingPolygon,
312 const List<point2D>& subjectPolygon,
313 List<bool>& subjectVertexInside
316 //- Compute the intersection between two 2D polygons using the
317 // Sutherland Hodgman algorithm
318 List<point2D> clipPolygon2DSutherlandHodgman
320 const List<point2D>& clippingPolygon,
321 const List<point2D>& subjectPolygon
324 //- Compute the intersection between two 2D polygons using the
325 // Greiner Hormann algorithm
326 List<point2D> clipPolygon2DGreinerHormann
328 const List<point2D>& clippingPolygon,
329 const List<point2D>& subjectPolygon,
330 const List<bool>& subjectVertexInside
333 //- Compute the area of a 2D polygon
336 const List<point2D>& polygon
340 //- Calculate addressing and weights
341 void calcAddressing() const;
343 //- Rescale GGI weighting factors
344 void rescaleWeightingFactors() const;
346 //- Find non-overlapping faces
347 tmp<labelField> findNonOverlappingFaces
349 const scalarListList& patchWeights,
350 const scalar& nonOverlapFaceTol
353 //- Clear all geometry and addressing
357 // Interpolation data access
359 //- Interpolate given source and target, addressing and weights
361 static void interpolate
363 const Field<Type>& ff,
365 const labelListList& addr,
366 const scalarListList& weights
369 //- Interpolate given source and target, addressing and weights
370 // for masked faces only
372 static void maskedInterpolate
374 const Field<Type>& ff,
376 const labelList& mask,
377 const labelListList& addr,
378 const scalarListList& weights
381 //- Bridge uncovered faces given addressing
385 const Field<Type>& bridgeField,
387 const labelList& addr
390 //- Bridge uncovered faces given addressing
391 // for masked faces only
393 static void maskedBridge
395 const Field<Type>& bridgeField,
397 const labelList& mask,
398 const labelList& uncoveredFaces
401 //- Is a transform required?
402 inline bool doTransform() const
404 return forwardT_.size() > 0;
407 //- Is a separation required?
408 inline bool doSeparation() const
410 return forwardSep_.size() > 0;
418 //- Construct from components
421 const MasterPatch& masterPatch,
422 const SlavePatch& slavePatch,
423 const tensorField& forwardT,
424 const tensorField& reverseT,
425 const vectorField& forwardSep,
426 const scalar masterFaceNonOverlapFaceTol = 0,
427 const scalar slaveFaceNonOverlapFaceTol = 0,
428 const bool rescaleGGIWeightingFactors = true,
429 const quickReject reject = AABB
442 //- Reference to the master patch
443 const MasterPatch& masterPatch() const
448 //- Reference to the slave patch
449 const SlavePatch& slavePatch() const
454 //- Return reference to master addressing
455 const labelListList& masterAddr() const;
457 //- Return reference to master weights
458 const scalarListList& masterWeights() const;
460 //- Return reference to slave addressing
461 const labelListList& slaveAddr() const;
463 //- Return reference to slave weights
464 const scalarListList& slaveWeights() const;
466 //- Return reference to the master list of non-overlap faces
467 const labelList& uncoveredMasterFaces() const;
469 //- Return reference to the slave list of non-overlap faces
470 const labelList& uncoveredSlaveFaces() const;
473 // Interpolation functions
475 //- Interpolate from master to slave
477 tmp<Field<Type> > masterToSlave(const Field<Type>& ff) const;
480 tmp<Field<Type> > masterToSlave
482 const tmp<Field<Type> >& tff
485 //- Interpolate from master to slave, only for marked master faces
486 // Addressing picks the faces from patch that are selected
487 // for collection into the result field
489 void maskedMasterToSlave
491 const Field<Type>& ff,
493 const labelList& mask
497 //- Interpolate from slave to master
499 tmp<Field<Type> > slaveToMaster(const Field<Type>& ff) const;
502 tmp<Field<Type> > slaveToMaster
504 const tmp<Field<Type> >& tff
507 //- Interpolate from slave to master, only for marked slave faces
508 // Addressing picks the faces from patch that are selected
509 // for collection into the result field
511 void maskedSlaveToMaster
513 const Field<Type>& ff,
515 const labelList& mask
519 //- Bridge uncovered master patch field
523 const Field<Type>& bridgeField,
527 //- Bridge uncovered master patch field, only for marked master faces
529 void maskedBridgeMaster
531 const Field<Type>& bridgeField,
533 const labelList& mask
536 //- Bridge uncovered slave patch field
540 const Field<Type>& bridgeField,
544 //- Bridge uncovered slave patch field, only for marked slave faces
546 void maskedBridgeSlave
548 const Field<Type>& bridgeField,
550 const labelList& mask
556 //- Correct weighting factors for moving mesh.
559 const tensorField& forwardT,
560 const tensorField& reverseT,
561 const vectorField& forwardSep
566 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
568 } // End namespace Foam
571 # include "GGIInterpolation.C"
574 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
578 // ************************************************************************* //