Report patch name instead of index in debug
[foam-extend-3.2.git] / src / foam / interpolations / MixingPlaneInterpolation / MixingPlaneInterpolate.C
blob367636e6f1f692434dbeb120741773a2c4b8d492
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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/>.
24 Description
25     MixingPlane interpolation functions
27 Author
28     Martin Beaudoin, Hydro-Quebec, 2009.  All rights reserved
30 Contributor
31     Hrvoje Jasak, Wikki Ltd.
33 \*---------------------------------------------------------------------------*/
35 namespace Foam
38 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
40 template<class MasterPatch, class SlavePatch>
41 template<class Type>
42 void MixingPlaneInterpolation<MasterPatch, SlavePatch>::toProfile
44     const Field<Type>& srcF,
45     const labelListList& srcAddr,
46     const scalarListList& srcWeights,
47     Field<Type>& profileBandValues
50     // The src to profile transfer is done using weighted averaging
51     // evaluation of srcF.
52     // See:  http://en.wikipedia.org/wiki/Weighted_mean
53     //
54     //                            sum(w*phi)
55     //         average(phi)  ==  -----------
56     //                             sum(w)
57     //
58     // Note however that in our case, the weighting factors utilized
59     // for the computation of the weighted average are GGI weighting
60     // factors. So for every interpolation band, we have the following
61     // situation, thanks to the intrinsic conservativeness of the GGI
62     // interface:
63     //
64     //         sum(w) == 1.0
65     //
66     //  which leads to the following simplification:
67     //
68     //         average(phi)  ==  sum(w*phi)
70     forAll (srcAddr, bandI)
71     {
72         forAll (srcAddr[bandI], faceI)
73         {
74             profileBandValues[bandI] +=
75                 srcF[srcAddr[bandI][faceI]]*srcWeights[bandI][faceI];
76         }
77     }
81 template<class MasterPatch, class SlavePatch>
82 template<class Type>
83 void MixingPlaneInterpolation<MasterPatch, SlavePatch>::fromProfile
85     const Field<Type>& profileBandValues,
86     const labelListList& dstAddr,
87     const scalarListList& dstWeights,
88     Field<Type>& dstResultF
91     // The profile to dst transfer is done by distributing the
92     // average value accordingly to the dst weighting factors
93     forAll (dstAddr, faceI)
94     {
95         const labelList& curAddr = dstAddr[faceI];
96         const scalarList& curW = dstWeights[faceI];
98         dstResultF[faceI] = pTraits<Type>::zero;
100         forAll (curAddr, bandI)
101         {
102             dstResultF[faceI] += profileBandValues[curAddr[bandI]]*curW[bandI];
103         }
104     }
108 template<class MasterPatch, class SlavePatch>
109 template<class Type>
110 void MixingPlaneInterpolation<MasterPatch, SlavePatch>::maskedFromProfile
112     const Field<Type>& profileBandValues,
113     const labelListList& dstAddr,
114     const scalarListList& dstWeights,
115     Field<Type>& dstResultF,
116     const labelList& mask
119     // The profile to dst transfer is done by distributing the
120     // average value accordingly to the dst weighting factors
121     forAll (mask, maskI)
122     {
123         // Pick the masked face
124         const label faceI = mask[maskI];
126         const labelList& curAddr = dstAddr[faceI];
127         const scalarList& curW = dstWeights[faceI];
129         dstResultF[maskI] = pTraits<Type>::zero;
131         forAll (curAddr, bandI)
132         {
133             dstResultF[maskI] += profileBandValues[curAddr[bandI]]*curW[bandI];
134         }
135     }
139 template<class MasterPatch, class SlavePatch>
140 template<class Type>
141 void MixingPlaneInterpolation<MasterPatch, SlavePatch>::maskedTransform
143     Field<Type>& transField,
144     const tensorField& t,
145     const Field<Type>& inField,
146     const labelList& mask
149     // The profile to dst transfer is done by distributing the
150     // average value accordingly to the dst weighting factors
151     forAll (mask, maskI)
152     {
153         // Pick the masked face
154         const label faceI = mask[maskI];
156         transField[maskI] = transform(t[faceI], inField[maskI]);
157     }
161 template<class MasterPatch, class SlavePatch>
162 template<class Type>
163 void MixingPlaneInterpolation<MasterPatch, SlavePatch>::interpolate
165     const Field<Type>& srcF,
166     const labelListList& srcAddr,
167     const scalarListList& srcWeights,
168     const labelListList& dstAddr,
169     const scalarListList& dstWeights,
170     Field<Type>& dstResultF
171 ) const
173     Field<Type> profileBandValues(nProfileBands(), pTraits<Type>::zero);
175     // Interpolate from patch to profile
176     toProfile
177     (
178         srcF,
179         srcAddr,
180         srcWeights,
181         profileBandValues
182     );
184     // profileBandValues are now the circumferentially averaged values
186     // Collect from profile to patch
187     fromProfile
188     (
189         profileBandValues,
190         dstAddr,
191         dstWeights,
192         dstResultF
193     );
197 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
199 template<class MasterPatch, class SlavePatch>
200 template<class Type>
201 tmp<Field<Type> >
202 MixingPlaneInterpolation<MasterPatch, SlavePatch>::masterToSlave
204     const Field<Type>& patchFF
205 ) const
207     if (patchFF.size() != masterPatch_.size())
208     {
209         FatalErrorIn
210         (
211             "MixingPlaneInterpolation::masterToSlave("
212             "const Field<Type> ff) const"
213         )   << "given field does not correspond to patch. Patch size: "
214             << masterPatch_.size() << " field size: " << patchFF.size()
215             << abort(FatalError);
216     }
218     // Move master data from 'patch space' to 'profile space'
219     // MB: We need this back
220     Field<Type> profileFF = transform(masterPatchToProfileT(), patchFF);
222     // Do interpolation
223     tmp<Field<Type> > tresult
224     (
225         new Field<Type>
226         (
227             slavePatch_.size(),
228             pTraits<Type>::zero
229         )
230     );
232     Field<Type>& result = tresult();
234     interpolate
235     (
236         profileFF,                     // Master data in 'profile space'
237         masterPatchToProfileAddr(),    // From master: compute the average
238         masterPatchToProfileWeights(),
239         slaveProfileToPatchAddr(),     // To slave distribute average from
240         slaveProfileToPatchWeights(),  // profile to patch
241         result
242     );
244     // Apply transform to bring the slave field back from 'profile space'
245     // to 'patch space'
246     transform(result, slaveProfileToPatchT(), result);
248     return tresult;
252 template<class MasterPatch, class SlavePatch>
253 template<class Type>
254 tmp<Field<Type> >
255 MixingPlaneInterpolation<MasterPatch, SlavePatch>::masterToSlave
257     const tmp<Field<Type> >& tff
258 ) const
260     tmp<Field<Type> > tint = masterToSlave(tff());
261     tff.clear();
262     return tint;
266 template<class MasterPatch, class SlavePatch>
267 template<class Type>
268 tmp<Field<Type> >
269 MixingPlaneInterpolation<MasterPatch, SlavePatch>::slaveToMaster
271     const Field<Type>& patchFF
272 ) const
274     if (patchFF.size() != slavePatch_.size())
275     {
276         FatalErrorIn
277         (
278             "MixingPlaneInterpolation::slaveToMaster("
279             "const Field<Type> ff) const"
280         )   << "given field does not correspond to patch. Patch size: "
281             << slavePatch_.size() << " field size: " << patchFF.size()
282             << abort(FatalError);
283     }
285     // Move slave data from 'patch space' to 'profile space'
286      Field<Type> profileFF = transform(slavePatchToProfileT(), patchFF);
288     // Do interpolation
289     tmp<Field<Type> > tresult
290     (
291         new Field<Type>
292         (
293             masterPatch_.size(),
294             pTraits<Type>::zero
295         )
296     );
298     Field<Type>& result = tresult();
300     interpolate
301     (
302         profileFF,                     // Slave data in 'profile space'
303         slavePatchToProfileAddr(),     // From slave: compute the average
304         slavePatchToProfileWeights(),
305         masterProfileToPatchAddr(),    // To master: distribute the average
306         masterProfileToPatchWeights(),
307         result
308     );
310     // Apply transform to bring the master field back from 'profile space'
311     // to 'patch space'
312     transform(result, masterProfileToPatchT(), result);
314     return tresult;
318 template<class MasterPatch, class SlavePatch>
319 template<class Type>
320 tmp<Field<Type> >
321 MixingPlaneInterpolation<MasterPatch, SlavePatch>::slaveToMaster
323     const tmp<Field<Type> >& tff
324 ) const
326     tmp<Field<Type> > tint = slaveToMaster(tff());
327     tff.clear();
328     return tint;
332 template<class MasterPatch, class SlavePatch>
333 template<class Type>
334 tmp<Field<Type> >
335 MixingPlaneInterpolation<MasterPatch, SlavePatch>::masterToProfile
337     const Field<Type>& patchFF
338 ) const
340     if (patchFF.size() != masterPatch_.size())
341     {
342         FatalErrorIn
343         (
344             "MixingPlaneInterpolation::masterToProfile("
345             "const Field<Type> ff) const"
346         )   << "given field does not correspond to patch. Patch size: "
347             << masterPatch_.size() << " field size: " << patchFF.size()
348             << abort(FatalError);
349     }
351     // Move master data from 'patch space' to 'profile space'
352     Field<Type> profileFF = transform(masterPatchToProfileT(), patchFF);
354     // Do interpolation
355     tmp<Field<Type> > tresult
356     (
357         new Field<Type>
358         (
359             nProfileBands(),
360             pTraits<Type>::zero
361         )
362     );
364     Field<Type>& result = tresult();
366     toProfile
367     (
368         profileFF,                      // Master data in 'profile space'
369         masterPatchToProfileAddr(),     // From master: compute the average
370         masterPatchToProfileWeights(),
371         result
372     );
374     return tresult;
378 template<class MasterPatch, class SlavePatch>
379 template<class Type>
380 tmp<Field<Type> >
381 MixingPlaneInterpolation<MasterPatch, SlavePatch>::masterToProfile
383     const tmp<Field<Type> >& tff
384 ) const
386     tmp<Field<Type> > tint = masterToProfile(tff());
387     tff.clear();
388     return tint;
392 template<class MasterPatch, class SlavePatch>
393 template<class Type>
394 tmp<Field<Type> >
395 MixingPlaneInterpolation<MasterPatch, SlavePatch>::slaveToProfile
397     const Field<Type>& patchFF
398 ) const
400     if (patchFF.size() != slavePatch_.size())
401     {
402         FatalErrorIn
403         (
404             "MixingPlaneInterpolation::slaveToProfile("
405             "const Field<Type> ff) const"
406         )   << "given field does not correspond to patch. Patch size: "
407             << slavePatch_.size() << " field size: " << patchFF.size()
408             << abort(FatalError);
409     }
411     // Move slave data from 'patch space' to 'profile space'
412     Field<Type> profileFF = transform(slavePatchToProfileT(), patchFF);
414     // Do interpolation
415     tmp<Field<Type> > tresult
416     (
417         new Field<Type>
418         (
419             nProfileBands(),
420             pTraits<Type>::zero
421         )
422     );
424     Field<Type>& result = tresult();
426     toProfile
427     (
428         profileFF,                     // Slave data in 'profile space'
429         slavePatchToProfileAddr(),     // From slave: compute the average
430         slavePatchToProfileWeights(),
431         result
432     );
434     return tresult;
438 template<class MasterPatch, class SlavePatch>
439 template<class Type>
440 tmp<Field<Type> >
441 MixingPlaneInterpolation<MasterPatch, SlavePatch>::slaveToProfile
443     const tmp<Field<Type> >& tff
444 ) const
446     tmp<Field<Type> > tint = slaveToProfile(tff());
447     tff.clear();
448     return tint;
452 template<class MasterPatch, class SlavePatch>
453 template<class Type>
454 tmp<Field<Type> >
455 MixingPlaneInterpolation<MasterPatch, SlavePatch>::profileToMaster
457     const Field<Type>& profileFF
458 ) const
460     if (profileFF.size() != nProfileBands())
461     {
462         FatalErrorIn
463         (
464             "MixingPlaneInterpolation::profileToMaster("
465             "const Field<Type> ff) const"
466         )   << "given field does not correspond to profile.  Profile size: "
467             << nProfileBands() << " field size: " << profileFF.size()
468             << abort(FatalError);
469     }
471     // Do interpolation
472     tmp<Field<Type> > tresult
473     (
474         new Field<Type>
475         (
476             masterPatch_.size(),
477             pTraits<Type>::zero
478         )
479     );
481     Field<Type>& result = tresult();
483     fromProfile
484     (
485         profileFF,                      // Master data in 'profile space'
486         masterProfileToPatchAddr(),     // To master: distribute the average
487         masterProfileToPatchWeights(),
488         result
489     );
491     // Apply transform to bring the master field back from 'profile space'
492     // to 'patch space'
493     transform(result, masterProfileToPatchT(), result);
495     return tresult;
499 template<class MasterPatch, class SlavePatch>
500 template<class Type>
501 tmp<Field<Type> >
502 MixingPlaneInterpolation<MasterPatch, SlavePatch>::profileToMaster
504     const tmp<Field<Type> >& tff
505 ) const
507     tmp<Field<Type> > tint = profileToMaster(tff());
508     tff.clear();
509     return tint;
513 template<class MasterPatch, class SlavePatch>
514 template<class Type>
515 void MixingPlaneInterpolation<MasterPatch, SlavePatch>::maskedProfileToMaster
517     const Field<Type>& profileFF,
518     Field<Type>& result,
519     const labelList& mask
520 ) const
522     if (profileFF.size() != nProfileBands() || result.size() != mask.size())
523     {
524         FatalErrorIn
525         (
526             "bvoid MixingPlaneInterpolation<MasterPatch, SlavePatch>::"
527             "maskedProfileToMaster\n"
528             "(\n"
529             "    const Field<Type>& profileFF,\n"
530             "    Field<Type>& result,\n"
531             "    const labelList& mask\n"
532             ") const"
533         )   << "given field does not correspond to profile.  Profile size: "
534             << nProfileBands() << " field size: " << profileFF.size()
535             << " result size: " << result.size()
536             << " mask size: " << mask.size()
537             << abort(FatalError);
538     }
540     // Do interpolation
541     maskedFromProfile
542     (
543         profileFF,                      // Master data in 'profile space'
544         masterProfileToPatchAddr(),     // To master: distribute the average
545         masterProfileToPatchWeights(),
546         result,
547         mask
548     );
550     // Apply transform to bring the master field back from 'profile space'
551     // to 'patch space'
552     maskedTransform(result, masterProfileToPatchT(), result, mask);
556 template<class MasterPatch, class SlavePatch>
557 template<class Type>
558 tmp<Field<Type> >
559 MixingPlaneInterpolation<MasterPatch, SlavePatch>::profileToSlave
561     const Field<Type>& profileFF
562 ) const
564     if (profileFF.size() != nProfileBands())
565     {
566         FatalErrorIn
567         (
568             "MixingPlaneInterpolation::profileToSlave("
569             "const Field<Type> ff) const"
570         )   << "given field does not correspond to profile.  Profile size: "
571             << nProfileBands() << " field size: " << profileFF.size()
572             << abort(FatalError);
573     }
575     // Do interpolation
576     tmp<Field<Type> > tresult
577     (
578         new Field<Type>
579         (
580             slavePatch_.size(),
581             pTraits<Type>::zero
582         )
583     );
585     Field<Type>& result = tresult();
587     fromProfile
588     (
589         profileFF,                     // Slave data in 'profile space'
590         slaveProfileToPatchAddr(),     // To slave distribute average from
591         slaveProfileToPatchWeights(),  // profile to patch
592         result
593     );
595     // Apply transform to bring the slave field back from 'profile space'
596     // to 'patch space'
597     transform(result, slaveProfileToPatchT(), result);
599     return tresult;
603 template<class MasterPatch, class SlavePatch>
604 template<class Type>
605 tmp<Field<Type> >
606 MixingPlaneInterpolation<MasterPatch, SlavePatch>::profileToSlave
608     const tmp<Field<Type> >& tff
609 ) const
611     tmp<Field<Type> > tint = profileToSlave(tff());
612     tff.clear();
613     return tint;
617 template<class MasterPatch, class SlavePatch>
618 template<class Type>
619 void MixingPlaneInterpolation<MasterPatch, SlavePatch>::maskedProfileToSlave
621     const Field<Type>& profileFF,
622     Field<Type>& result,
623     const labelList& mask
624 ) const
626     if (profileFF.size() != nProfileBands() || result.size() != mask.size())
627     {
628         FatalErrorIn
629         (
630             "void MixingPlaneInterpolation<MasterPatch, SlavePatch>::"
631             "maskedProfileToSlave\n"
632             "(\n"
633             "    const Field<Type>& profileFF,\n"
634             "    Field<Type>& result,\n"
635             "    const labelList& mask\n"
636             ") const"
637         )   << "given field does not correspond to profile.  Profile size: "
638             << nProfileBands() << " field size: " << profileFF.size()
639             << " result size: " << result.size()
640             << " mask size: " << mask.size()
641             << abort(FatalError);
642     }
644     maskedFromProfile
645     (
646         profileFF,                     // Slave data in 'profile space'
647         slaveProfileToPatchAddr(),     // To slave distribute average from
648         slaveProfileToPatchWeights(),  // profile to patch
649         result,
650         mask
651     );
653     // Apply transform to bring the slave field back from 'profile space'
654     // to 'patch space'
655     maskedTransform(result, slaveProfileToPatchT(), result, mask);
659 template<class MasterPatch, class SlavePatch>
660 template<class Type>
661 tmp<Field<Type> >
662 MixingPlaneInterpolation<MasterPatch, SlavePatch>::masterToMaster
664     const Field<Type>& patchFF
665 ) const
667     if (patchFF.size() != masterPatch_.size())
668     {
669         FatalErrorIn
670         (
671             "MixingPlaneInterpolation::masterToMaster("
672             "const Field<Type> ff)"
673         )   << "given field does not correspond to patch. Patch size: "
674             << masterPatch_.size() << " field size: " << patchFF.size()
675             << abort(FatalError);
676     }
678     // Move master data from 'patch space' to 'profile space'
679     Field<Type> profileFF = transform(masterPatchToProfileT(), patchFF);
681     // Do interpolation
682     tmp<Field<Type> > tresult
683     (
684         new Field<Type>
685         (
686             masterPatch_.size(),
687             pTraits<Type>::zero
688         )
689     );
691     Field<Type>& result = tresult();
693     interpolate
694     (
695         profileFF,                      // Master data in 'profile space'
696         masterPatchToProfileAddr(),     // From master: compute the average
697         masterPatchToProfileWeights(),
698         masterProfileToPatchAddr(),     // To master: distribute the average
699         masterProfileToPatchWeights(),
700         result
701     );
703     // Apply transform to bring the master field back from 'profile space'
704     // to 'patch space'
705     transform(result, masterProfileToPatchT(), result);
707     return tresult;
711 template<class MasterPatch, class SlavePatch>
712 template<class Type>
713 tmp<Field<Type> >
714 MixingPlaneInterpolation<MasterPatch, SlavePatch>::masterToMaster
716     const tmp<Field<Type> >& tff
717 ) const
719     tmp<Field<Type> > tint = masterToMaster(tff());
720     tff.clear();
721     return tint;
725 template<class MasterPatch, class SlavePatch>
726 template<class Type>
727 tmp<Field<Type> >
728 MixingPlaneInterpolation<MasterPatch, SlavePatch>::slaveToSlave
730     const Field<Type>& patchFF
731 ) const
733     if (patchFF.size() != slavePatch_.size())
734     {
735         FatalErrorIn
736         (
737             "MixingPlaneInterpolation::slaveToSlave("
738             "const Field<Type> ff)"
739         )   << "given field does not correspond to patch. Patch size: "
740             << slavePatch_.size() << " field size: " << patchFF.size()
741             << abort(FatalError);
742     }
744     // Move slave data from 'patch space' to 'profile space'
745     Field<Type> profileFF = transform(slavePatchToProfileT(), patchFF);
747     // Do interpolation
748     tmp<Field<Type> > tresult
749     (
750         new Field<Type>
751         (
752             slavePatch_.size(),
753             pTraits<Type>::zero
754         )
755     );
757     Field<Type>& result = tresult();
759     interpolate
760     (
761         profileFF,                     // Slave data in 'profile space'
762         slavePatchToProfileAddr(),     // From slave: compute the average
763         slavePatchToProfileWeights(),
764         slaveProfileToPatchAddr(),     // To slave: distribute the average
765         slaveProfileToPatchWeights(),
766         result
767     );
769     // Apply transform to bring the slave field back from 'profile space'
770     // to 'patch space'
771     transform(result, slaveProfileToPatchT(), result);
773     return tresult;
777 template<class MasterPatch, class SlavePatch>
778 template<class Type>
779 tmp<Field<Type> >
780 MixingPlaneInterpolation<MasterPatch, SlavePatch>::slaveToSlave
782     const tmp<Field<Type> >& tff
783 ) const
785     tmp<Field<Type> > tint = slaveToSlave(tff());
786     tff.clear();
787     return tint;
791 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
793 } // End namespace Foam
795 // ************************************************************************* //