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/>.
25 MixingPlaneInterpolation
28 The mixingPlaneInterplation class is implementing the interpolation of face
29 data between two primitivePatches using mixing plane averaging.
31 Some overview of this development can be found here:
33 OpenFOAM TURBO TOOLS: FROM GENERAL PURPOSE CFD TO TURBOMACHINERY
35 H. Jasak, M. Beaudoin, Proceedings of ASME-JSME-KSME Joint Fluids
36 Engineering Conference 2011, AJK2011-FED, July 24-29, 2011, Hamamatsu,
39 Steady-state capabilities for hydroturbines with OpenFOAM,
40 M. Page, M. Beaudoin, A.-M. Giroux, Internationnal Journal of Fluid
41 Machinery and Systems, 4(1):160–170, Jan-Mar 2011.
43 Development of a General Grid Interface for Turbomachinery simulations with
44 OpenFOAM, M. Beaudoin, H. Jasak, Open Source CFD International Conference,
48 Martin Beaudoin, Hydro-Quebec, 2009. All rights reserved
51 Hrvoje Jasak, Wikki Ltd.
54 Giving credit where credit is due:
55 1: Hakan Nilsson from the Chalmers University of Technology came up with
56 the initial idea of using a combination of 2 GGI interfaces sharing a
57 common single-face 360 degree ribbons patch in order to compute the
58 circumferential average of fields. This implementation of the
59 mixingPlane interpolation algorithm is an exploration of this simple
60 but rather powerful idea.
62 2: Maryse Page from Hydro-Quebec provided many test cases and many
63 simulation runs for testing this interpolation algorithm. Testing is
64 obviously an essential part of any new development.
66 3: The authors also want to acknowledge the useful comments from many
67 colleagues in the OpenFOAM Turbomachinery Special Interest Group.
71 ribbon = face object over which we are averaging
73 direction = axis in which ribbon width is measured
75 span = axis in which ribbon length is measured
76 All ribbons have identical length in the chosen coordinate system
79 MixingPlaneInterpolation.C
81 MixingPlaneInterpolationPatches.C
82 MixingPlaneInterpolationAddressing.C
83 MixingPlaneInterpolate.C
85 \*---------------------------------------------------------------------------*/
87 #ifndef MixingPlaneInterpolation_H
88 #define MixingPlaneInterpolation_H
91 #include "className.H"
92 #include "labelList.H"
93 #include "scalarField.H"
94 #include "pointField.H"
95 #include "FieldFields.H"
97 #include "intersection.H"
99 #include "NamedEnum.H"
100 #include "coordinateSystem.H"
101 #include "boundBox.H"
102 #include "ggiInterpolation.H"
103 #include "cylindricalCS.H"
104 #include "primitivePatch.H"
105 #include "standAlonePatch.H"
109 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
114 /*---------------------------------------------------------------------------*\
115 Class MixingPlaneInterpolationName Declaration
116 \*---------------------------------------------------------------------------*/
118 class MixingPlaneInterpolationName
122 // Public enumerations
124 //- Define profile discretisation rule
131 USER_DEFINED // User-defined through a file
134 //- Define the sweepAxis used to generate the mixing ribbon patch
137 // Cartesian coordinate system
142 // Cylindrical coordinate system
145 // SWEEP_Z is already defined for the Cartesian coordinate system
149 //- Define the stackAxis used to generate the mixing ribbon patch
152 // Cartesian coordinate system
157 // Cylindrical coordinate system
160 // STACK_Z is already defined for the Cartesian coordinate system
164 //- Define type of mixing for field over patch
178 ClassName("MixingPlaneInterpolation");
181 //- Discretisation names
182 static const NamedEnum<discretisation, 5> discretisationNames_;
185 static const NamedEnum<sweepAxis, 6> sweepAxisNames_;
188 static const NamedEnum<stackAxis, 6> stackAxisNames_;
191 static const NamedEnum<mixingType, 6> mixingTypeNames_;
197 MixingPlaneInterpolationName()
202 /*---------------------------------------------------------------------------*\
203 Class MixingPlaneInterpolation Declaration
204 \*---------------------------------------------------------------------------*/
206 template<class MasterPatch, class SlavePatch>
207 class MixingPlaneInterpolation
209 public MixingPlaneInterpolationName
211 // Private data types
213 typedef std::map<Foam::scalar, std::list<Foam::point> > profileHistogram;
218 //- Reference to the master patch
219 const MasterPatch& masterPatch_;
221 //- Reference to the slave patch
222 const SlavePatch& slavePatch_;
224 // We need to get some patches identification for debugging purposes
225 // Since we are currently using primitive patches for the interpolator
226 // we need to memorize this information when using the constructor
228 //- Coordinate system for averaging
229 const coordinateSystem& cs_;
231 //- Type of mixing plane discretisation algorithm
232 discretisation discretisationType_;
234 //- Orientation of the mixing plane ribbon patch
235 // sweepAxis = axis in which ribbon length is measured
236 // stackAxis = axis in which ribbon width/height is measured
237 sweepAxis sweepAxisType_;
238 stackAxis stackAxisType_;
240 //- Interpolation profile
241 // This list of points defines the profile generating the 'n'
242 // circular bands we are going to use for
243 // the circumferential averaging algorithm. For for 'n'
244 // circular bands, we need 'n + 1' points.
245 mutable pointField interpolationProfile_;
247 //- Slave-to-master transformation tensor. Transforms slave data to
248 // master plane. Size equals number of slave faces; zero length
249 // indicates no transform. Size 1 indicates constant transform
250 const tensorField forwardT_;
252 //- Master-to-slave transformation tensor. Transforms slave data to
253 // master plane. Size equals number of master faces; zero length
254 // indicates no transform. Size 1 indicates constant transform
255 const tensorField reverseT_;
257 //- Slave-to-master separation vector. Translation of slave data to
258 // master plane. Size equals number of slave faces; zero length
259 // indicates no translation.
260 const vectorField forwardSep_;
263 // Demand-driven data
265 //- Transformed master patch
266 mutable standAlonePatch* transformedMasterPatchPtr_;
268 //- Transformed shadow patch
269 mutable standAlonePatch* transformedShadowPatchPtr_;
271 //- Interpolating patch: strips of the mixing plane
272 mutable standAlonePatch* mixingPlanePatchPtr_;
275 //- Tensors for transforming the fields onto a single profile
277 mutable tensorField* masterPatchToProfileTPtr_;
278 mutable tensorField* masterProfileToPatchTPtr_;
279 mutable tensorField* slavePatchToProfileTPtr_;
280 mutable tensorField* slaveProfileToPatchTPtr_;
283 // Master patch-to-profile interpolation
285 //- Master addressing
286 mutable labelListList* masterPatchToProfileAddrPtr_;
287 mutable labelListList* masterProfileToPatchAddrPtr_;
290 mutable scalarListList* masterPatchToProfileWeightsPtr_;
291 mutable scalarListList* masterProfileToPatchWeightsPtr_;
294 // Slave patch-to-profile interpolation
297 mutable labelListList* slavePatchToProfileAddrPtr_;
298 mutable labelListList* slaveProfileToPatchAddrPtr_;
301 mutable scalarListList* slavePatchToProfileWeightsPtr_;
302 mutable scalarListList* slaveProfileToPatchWeightsPtr_;
305 // Private Member Functions
307 //- Disallow default bitwise copy construct
308 MixingPlaneInterpolation
310 const MixingPlaneInterpolation&
313 //- Disallow default bitwise assignment
314 void operator=(const MixingPlaneInterpolation&);
317 // Helper functions for demand-driven data
319 //- Return ribbon sweep direction
320 direction sweepAxisSwitch() const;
322 //- Return ribbon stack direction
323 direction stackAxisSwitch() const;
325 //- Construct profile histogram
326 void updateProfileHistogram
328 profileHistogram& histo,
329 const point& profileCoord, // 3D point
330 const direction dir, // Sorting dimension 0: x, 1: y, 2: z
331 const scalar halfSizeBin // half size of min histogram bin width
334 //- Create an interpolation profile from histograms
335 // Note: histograms are adjusted to achieve full overlap
337 tmp<pointField> computeProfileFromHistograms
339 const profileHistogram& masterHisto,
340 const profileHistogram& slaveHisto,
341 const scalar halfSizeBin // half size of min histogram bin width
344 //- Remove interpolationProfile_ points located outside of either
345 // master/slave patch boundingBox,
346 // with the exception of the first and last profile points
347 void removeNonOverlappedProfilePoints
353 //- Find and modify patch faces straddling the histogram span
354 // eg. -180,+180 angle cylindrical coordinate system
355 void correctStraddlingFaces
357 faceList& cylCoordFaces,
358 pointField& cylCoordFacesPoint
362 //- Calculate transformed patches
363 void calcTransformedPatches() const;
365 //- Calculate mixing patch
366 void calcMixingPlanePatch() const;
369 //- Calculate addressing and weights
370 void calcAddressing() const;
372 //- Calculate Cartesian to cylindrical tranformation tensor field for
373 // master and slave patches
374 void calcTransforms() const;
376 //- Create an interpolation profile from histograms
377 tmp<pointField> calcProfile() const;
380 //- Clear transformed patches
381 void clearTransfomedPatches();
383 //- Calculate mixing patch
384 void clearMixingPlanePatch();
387 void clearAddressing();
390 void clearTransforms();
392 //- Clear all geometry and addressing
396 // Interpolation data access
398 //- Distribute to profile given addressing and weights
400 static void toProfile
402 const Field<Type>& srcF,
403 const labelListList& srcAddr,
404 const scalarListList& srcWeights,
405 Field<Type>& profileBandValues
408 //- Collect from profile given addressing and weights
410 static void fromProfile
412 const Field<Type>& profileBandValues,
413 const labelListList& dstAddr,
414 const scalarListList& dstWeights,
415 Field<Type>& dstResultF
418 //- Collect from profile given addressing and weights
419 // for masked faces only
421 static void maskedFromProfile
423 const Field<Type>& profileBandValues,
424 const labelListList& dstAddr,
425 const scalarListList& dstWeights,
426 Field<Type>& dstResultF,
427 const labelList& mask
430 //- Execute transform for masked faces only
432 static void maskedTransform
434 Field<Type>& transField,
435 const tensorField& t,
436 const Field<Type>& inField,
437 const labelList& mask
440 //- Interpolate given source and target, addressing and weights
444 const Field<Type>& srcF,
445 const labelListList& srcAddr,
446 const scalarListList& srcWeights,
447 const labelListList& dstAddr,
448 const scalarListList& dstWeights,
449 Field<Type>& dstResultF
453 //- Is a transform required?
454 inline bool doTransform() const
459 //- Is a separation required?
460 inline bool doSeparation() const
470 //- Construct from components
471 MixingPlaneInterpolation
473 const MasterPatch& masterPatch,
474 const SlavePatch& slavePatch,
475 const coordinateSystem& cs,
476 const discretisation& discretisationType,
477 const sweepAxis& sweepAxisType,
478 const stackAxis& stackAxisType,
479 const pointField& interpolationProfile
485 ~MixingPlaneInterpolation();
492 //- Return master patch
493 const MasterPatch& masterPatch() const
498 //- Return slave patch
499 const SlavePatch& slavePatch() const
504 //- Return number of profile bands
505 label nProfileBands() const
507 return interpolationProfile().size() - 1;
510 //- Return interpolation profile
511 const pointField& interpolationProfile() const;
514 //- Return mixing plane patch
515 const standAlonePatch& mixingPlanePatch() const;
517 //- Return transformed patch
518 const standAlonePatch& transformedMasterPatch() const;
520 //- Return transformed patch
521 const standAlonePatch& transformedShadowPatch() const;
524 //- Return reference to master addressing
525 const labelListList& masterPatchToProfileAddr() const;
526 const labelListList& masterProfileToPatchAddr() const;
528 //- Return reference to master weights
529 const scalarListList& masterPatchToProfileWeights() const;
530 const scalarListList& masterProfileToPatchWeights() const;
532 //- Return reference to slave addressing
533 const labelListList& slavePatchToProfileAddr() const;
534 const labelListList& slaveProfileToPatchAddr() const;
536 //- Return reference to slave weights
537 const scalarListList& slavePatchToProfileWeights() const;
538 const scalarListList& slaveProfileToPatchWeights() const;
540 //- Return reference to masterPatchToProfile tensor field
541 const tensorField& masterPatchToProfileT() const;
543 //- Return reference to masterProfileToPatchT tensor field
544 const tensorField& masterProfileToPatchT() const;
546 //- Return reference to slavePatchToProfileT tensor field
547 const tensorField& slavePatchToProfileT() const;
549 //- Return reference to slaveProfileToPatchT tensor field
550 const tensorField& slaveProfileToPatchT() const;
553 // Interpolation functions
555 //- Interpolate from master to slave
557 tmp<Field<Type> > masterToSlave
559 const Field<Type>& pf
563 tmp<Field<Type> > masterToSlave
565 const tmp<Field<Type> >& tpf
569 //- Interpolate from slave to master
571 tmp<Field<Type> > slaveToMaster
573 const Field<Type>& pf
577 tmp<Field<Type> > slaveToMaster
579 const tmp<Field<Type> >& tpf
583 //- Interpolate from master to profile
585 tmp<Field<Type> > masterToProfile
587 const Field<Type>& pf
591 tmp<Field<Type> > masterToProfile
593 const tmp<Field<Type> >& tpf
596 //- Interpolate from slave to profile
598 tmp<Field<Type> > slaveToProfile
600 const Field<Type>& pf
604 tmp<Field<Type> > slaveToProfile
606 const tmp<Field<Type> >& tpf
610 //- Interpolate from profile to master
612 tmp<Field<Type> > profileToMaster
614 const Field<Type>& pf
618 tmp<Field<Type> > profileToMaster
620 const tmp<Field<Type> >& tpf
624 void maskedProfileToMaster
626 const Field<Type>& profileFF,
628 const labelList& mask
631 //- Interpolate from profile to slave
633 tmp<Field<Type> > profileToSlave
635 const Field<Type>& pf
639 tmp<Field<Type> > profileToSlave
641 const tmp<Field<Type> >& tpf
646 void maskedProfileToSlave
648 const Field<Type>& profileFF,
650 const labelList& mask
653 //- Interpolate from master to master
654 //- (self circumferential averaging)
656 tmp<Field<Type> > masterToMaster
658 const Field<Type>& pf
662 tmp<Field<Type> > masterToMaster
664 const tmp<Field<Type> >& tpf
667 //- Interpolate from slave to slave
668 //- (self circumferential averaging)
670 tmp<Field<Type> > slaveToSlave
672 const Field<Type>& pf
676 tmp<Field<Type> > slaveToSlave
678 const tmp<Field<Type> >& tpf
684 //- Correct weighting factors for moving mesh.
689 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
691 } // End namespace Foam
694 # include "MixingPlaneInterpolationTemplate.C"
695 # include "MixingPlaneProfile.C"
696 # include "MixingPlaneInterpolationPatches.C"
697 # include "MixingPlaneInterpolationAddressing.C"
698 # include "MixingPlaneInterpolate.C"
701 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
705 // ************************************************************************* //