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 GGI interpolation functions
28 Hrvoje Jasak, Wikki Ltd. All rights reserved
30 \*---------------------------------------------------------------------------*/
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 template<class MasterPatch, class SlavePatch>
39 void GGIInterpolation<MasterPatch, SlavePatch>::interpolate
41 const Field<Type>& ff,
43 const labelListList& addr,
44 const scalarListList& weights
47 forAll (result, faceI)
49 const labelList& curAddr = addr[faceI];
50 const scalarList& curWeights = weights[faceI];
52 result[faceI] = pTraits<Type>::zero;
56 result[faceI] += ff[curAddr[i]]*curWeights[i];
62 template<class MasterPatch, class SlavePatch>
64 void GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
66 const Field<Type>& ff,
68 const labelList& mask,
69 const labelListList& addr,
70 const scalarListList& weights
75 // Pick the masked face
76 const label faceI = mask[maskI];
78 const labelList& curAddr = addr[faceI];
80 const scalarList& curWeights = weights[faceI];
82 // Clear condensed list entry: masked faces only
83 result[maskI] = pTraits<Type>::zero;
87 // Put the result into condensed list: masked faces only
88 result[maskI] += ff[curAddr[i]]*curWeights[i];
94 template<class MasterPatch, class SlavePatch>
96 void GGIInterpolation<MasterPatch, SlavePatch>::bridge
98 const Field<Type>& bridgeField,
100 const labelList& addr
105 ff[addr[faceI]] = bridgeField[addr[faceI]];
110 template<class MasterPatch, class SlavePatch>
112 void GGIInterpolation<MasterPatch, SlavePatch>::maskedBridge
114 const Field<Type>& bridgeField,
116 const labelList& mask,
117 const labelList& uncoveredFaces
120 // Note: tricky algorithm
121 // In order for a face to be bridged it needs to be both in the
122 // mask and in selection of faces that are bridged (addr).
123 // This implies an n-squared search, but we can use the fact that
124 // both lists are ordered.
128 forAll (uncoveredFaces, uncoI)
130 // Pick the uncovered face
131 const label faceI = uncoveredFaces[uncoI];
133 // Search through the mask
134 for (; maskAddrI < mask.size(); maskAddrI++)
136 if (faceI == mask[maskAddrI])
138 // Found masked bridged face
139 // Put the result into condensed list: masked faces only
140 ff[maskAddrI] = bridgeField[maskAddrI];
144 else if (mask[maskAddrI] > faceI)
146 // Gone beyond my index: my face is not present in the mask
147 // Go one back and check for next uncovered face
160 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
162 template<class MasterPatch, class SlavePatch>
165 GGIInterpolation<MasterPatch, SlavePatch>::masterToSlave
167 const Field<Type>& ff
170 if (ff.size() != masterPatch_.size())
174 "GGIInterpolation::masterToSlave(const Field<Type> ff)"
175 ) << "given field does not correspond to patch. Patch size: "
176 << masterPatch_.size() << " field size: " << ff.size()
177 << abort(FatalError);
180 tmp<Field<Type> > tresult
190 Field<Type>& result = tresult();
192 if (this->doTransform() && pTraits<Type>::rank > 0)
194 // Transform master data to slave
195 Field<Type> transformFF;
197 if (reverseT_.size() == 1)
199 // Constant transform
200 transformFF = transform(reverseT_[0], ff);
204 // Full patch transform
205 transformFF = transform(reverseT_, ff);
208 GGIInterpolation<MasterPatch, SlavePatch>::interpolate
218 GGIInterpolation<MasterPatch, SlavePatch>::interpolate
231 template<class MasterPatch, class SlavePatch>
234 GGIInterpolation<MasterPatch, SlavePatch>::masterToSlave
236 const tmp<Field<Type> >& tff
239 tmp<Field<Type> > tint = masterToSlave(tff());
245 template<class MasterPatch, class SlavePatch>
247 void GGIInterpolation<MasterPatch, SlavePatch>::maskedMasterToSlave
249 const Field<Type>& ff,
251 const labelList& mask
254 if (ff.size() != masterPatch_.size())
258 "void GGIInterpolation::maskedMasterToSlave\n"
260 " const Field<Type>& ff,\n"
261 " Field<Type>& result,\n"
262 " const labelList& mask\n"
264 ) << "given field does not correspond to patch. Patch size: "
265 << masterPatch_.size() << " field size: " << ff.size()
266 << abort(FatalError);
269 if (result.size() != mask.size())
273 "void GGIInterpolation::maskedMasterToSlave\n"
275 " const Field<Type>& ff,\n"
276 " Field<Type>& result,\n"
277 " const labelList& mask\n"
279 ) << "result field does not correspond to mask. Field size: "
280 << result.size() << " mask size: " << mask.size()
281 << abort(FatalError);
284 if (this->doTransform() && pTraits<Type>::rank > 0)
286 // Transform master data to slave
287 Field<Type> transformFF;
289 if (reverseT_.size() == 1)
291 // Constant transform
292 transformFF = transform(reverseT_[0], ff);
296 // Full patch transform
297 transformFF = transform(reverseT_, ff);
300 GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
311 GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
323 template<class MasterPatch, class SlavePatch>
326 GGIInterpolation<MasterPatch, SlavePatch>::slaveToMaster
328 const Field<Type>& ff
331 if (ff.size() != slavePatch_.size())
335 "GGIInterpolation::slaveToMaster"
336 "(const Field<Type> ff)"
337 ) << "given field does not correspond to patch. Patch size: "
338 << slavePatch_.size() << " field size: " << ff.size()
339 << abort(FatalError);
342 tmp<Field<Type> > tresult
352 Field<Type>& result = tresult();
354 if (this->doTransform() && pTraits<Type>::rank > 0)
356 // Transform slave data to master
357 Field<Type> transformFF;
358 if (forwardT_.size() == 1)
360 // Constant transform
361 transformFF = transform(forwardT_[0], ff);
365 // Full patch transform
366 transformFF = transform(forwardT_, ff);
369 GGIInterpolation<MasterPatch, SlavePatch>::interpolate
374 this->masterWeights()
379 GGIInterpolation<MasterPatch, SlavePatch>::interpolate
384 this->masterWeights()
392 template<class MasterPatch, class SlavePatch>
395 GGIInterpolation<MasterPatch, SlavePatch>::slaveToMaster
397 const tmp<Field<Type> >& tff
400 tmp<Field<Type> > tint = slaveToMaster(tff());
406 template<class MasterPatch, class SlavePatch>
408 void GGIInterpolation<MasterPatch, SlavePatch>::maskedSlaveToMaster
410 const Field<Type>& ff,
412 const labelList& mask
415 if (ff.size() != slavePatch_.size())
419 "void GGIInterpolation::maskedSlaveToMaster"
421 " const Field<Type>& ff,\n"
422 " Field<Type>& result,\n"
423 " const labelList& mask\n"
425 ) << "given field does not correspond to patch. Patch size: "
426 << slavePatch_.size() << " field size: " << ff.size()
427 << abort(FatalError);
430 if (result.size() != mask.size())
434 "void GGIInterpolation::maskedSlaveToMaster\n"
436 " const Field<Type>& ff,\n"
437 " Field<Type>& result,\n"
438 " const labelList& mask\n"
440 ) << "result field does not correspond to mask. Field size: "
441 << result.size() << " mask size: " << mask.size()
442 << abort(FatalError);
445 if (this->doTransform() && pTraits<Type>::rank > 0)
447 // Transform slave data to master
448 Field<Type> transformFF;
449 if (forwardT_.size() == 1)
451 // Constant transform
452 transformFF = transform(forwardT_[0], ff);
456 // Full patch transform
457 transformFF = transform(forwardT_, ff);
460 GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
466 this->masterWeights()
471 GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
477 this->masterWeights()
483 template<class MasterPatch, class SlavePatch>
485 void GGIInterpolation<MasterPatch, SlavePatch>::bridgeMaster
487 const Field<Type>& bridgeField,
493 bridgeField.size() != masterPatch_.size()
494 || ff.size() != masterPatch_.size())
498 "void GGIInterpolation<MasterPatch, SlavePatch>::bridgeMaster\n"
500 " const Field<Type>& bridgeField,\n"
503 ) << "given field does not correspond to patch. Patch size: "
504 << masterPatch_.size()
505 << " bridge field size: " << bridgeField.size()
506 << " field size: " << ff.size()
507 << abort(FatalError);
510 bridge(bridgeField, ff, uncoveredMasterFaces());
514 template<class MasterPatch, class SlavePatch>
516 void GGIInterpolation<MasterPatch, SlavePatch>::maskedBridgeMaster
518 const Field<Type>& bridgeField,
520 const labelList& mask
523 if (ff.size() != mask.size())
527 "void GGIInterpolation<MasterPatch, SlavePatch>::"
528 "maskedBridgeMaster\n"
530 " const Field<Type>& bridgeField,\n"
531 " Field<Type>& ff,\n"
532 " const labelList& mask\n"
534 ) << "given field does not correspond to patch. Patch size: "
535 << masterPatch_.size()
536 << " bridge field size: " << bridgeField.size()
537 << " field size: " << ff.size()
538 << " mask size: " << mask.size()
539 << abort(FatalError);
542 maskedBridge(bridgeField, ff, mask, uncoveredMasterFaces());
546 template<class MasterPatch, class SlavePatch>
548 void GGIInterpolation<MasterPatch, SlavePatch>::bridgeSlave
550 const Field<Type>& bridgeField,
556 bridgeField.size() != slavePatch_.size()
557 || ff.size() != slavePatch_.size()
562 "void GGIInterpolation<MasterPatch, SlavePatch>::"
565 " const Field<Type>& bridgeField,\n"
568 ) << "given field does not correspond to patch. Patch size: "
569 << slavePatch_.size()
570 << " bridge field size: " << bridgeField.size()
571 << " field size: " << ff.size()
572 << abort(FatalError);
575 bridge(bridgeField, ff, uncoveredSlaveFaces());
579 template<class MasterPatch, class SlavePatch>
581 void GGIInterpolation<MasterPatch, SlavePatch>::maskedBridgeSlave
583 const Field<Type>& bridgeField,
585 const labelList& mask
588 if (ff.size() != mask.size())
592 "void GGIInterpolation<MasterPatch, SlavePatch>::"
593 "maskedBridgeSlave\n"
595 " const Field<Type>& bridgeField,\n"
596 " Field<Type>& ff\n,"
597 " const labelList& mask\n"
599 ) << "given field does not correspond to patch. Patch size: "
600 << slavePatch_.size()
601 << " bridge field size: " << bridgeField.size()
602 << " field size: " << ff.size()
603 << " mask size: " << mask.size()
604 << abort(FatalError);
607 maskedBridge(bridgeField, ff, mask, uncoveredSlaveFaces());
611 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
613 } // End namespace Foam
615 // ************************************************************************* //