AMIInterpolation.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
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
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "AMIInterpolation.H"
27 #include "AMIMethod.H"
28 #include "meshTools.H"
29 #include "mapDistribute.H"
30 #include "flipOp.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 template<class SourcePatch, class TargetPatch>
37 (
38  const interpolationMethod& im
39 )
40 {
41  word method = "unknown-interpolationMethod";
42 
43  switch (im)
44  {
45  case imDirect:
46  {
47  method = "directAMI";
48  break;
49  }
50  case imMapNearest:
51  {
52  method = "mapNearestAMI";
53  break;
54  }
55  case imFaceAreaWeight:
56  {
57  method = "faceAreaWeightAMI";
58  break;
59  }
60  case imPartialFaceAreaWeight:
61  {
62  method = "partialFaceAreaWeightAMI";
63  break;
64  }
65  default:
66  {
68  << "Unhandled interpolationMethod enumeration " << method
69  << abort(FatalError);
70  }
71  }
72 
73  return method;
74 }
75 
76 
77 template<class SourcePatch, class TargetPatch>
80 (
81  const word& im
82 )
83 {
84  interpolationMethod method = imDirect;
85 
86  wordList methods
87  (
89  (
90  "("
91  "directAMI "
92  "mapNearestAMI "
93  "faceAreaWeightAMI "
94  "partialFaceAreaWeightAMI"
95  ")"
96  )()
97  );
98 
99  if (im == "directAMI")
100  {
101  method = imDirect;
102  }
103  else if (im == "mapNearestAMI")
104  {
105  method = imMapNearest;
106  }
107  else if (im == "faceAreaWeightAMI")
108  {
109  method = imFaceAreaWeight;
110  }
111  else if (im == "partialFaceAreaWeightAMI")
112  {
113  method = imPartialFaceAreaWeight;
114  }
115  else
116  {
118  << "Invalid interpolationMethod " << im
119  << ". Valid methods are:" << methods
120  << exit(FatalError);
121  }
122 
123  return method;
124 }
125 
126 
127 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
128 
129 template<class SourcePatch, class TargetPatch>
131 (
132  const searchableSurface& surf,
133  pointField& pts
134 ) const
135 {
136  if (debug)
137  {
138  Info<< "AMI: projecting points to surface" << endl;
139  }
140 
142 
143  surf.findNearest(pts, scalarField(pts.size(), GREAT), nearInfo);
144 
145  label nMiss = 0;
146  forAll(nearInfo, i)
147  {
148  const pointIndexHit& pi = nearInfo[i];
149 
150  if (pi.hit())
151  {
152  pts[i] = pi.hitPoint();
153  }
154  else
155  {
156  pts[i] = pts[i];
157  nMiss++;
158  }
159  }
160 
161  if (nMiss > 0)
162  {
164  << "Error projecting points to surface: "
165  << nMiss << " faces could not be determined"
166  << abort(FatalError);
167  }
168 }
169 
170 
171 template<class SourcePatch, class TargetPatch>
173 (
174  const scalarField& patchAreas,
175  const word& patchName,
176  const labelListList& addr,
177  scalarListList& wght,
178  scalarField& wghtSum,
179  const bool conformal,
180  const bool output,
181  const scalar lowWeightTol
182 )
183 {
184  // Normalise the weights
185  wghtSum.setSize(wght.size(), 0.0);
186  label nLowWeight = 0;
187 
188  forAll(wght, faceI)
189  {
190  scalarList& w = wght[faceI];
191 
192  if (w.size())
193  {
194  scalar denom = patchAreas[faceI];
195 
196  scalar s = sum(w);
197  scalar t = s/denom;
198 
199  if (conformal)
200  {
201  denom = s;
202  }
203 
204  forAll(w, i)
205  {
206  w[i] /= denom;
207  }
208 
209  wghtSum[faceI] = t;
210 
211  if (t < lowWeightTol)
212  {
213  nLowWeight++;
214  }
215  }
216  else
217  {
218  wghtSum[faceI] = 0;
219  }
220  }
221 
222 
223  if (output)
224  {
225  const label nFace = returnReduce(wght.size(), sumOp<label>());
226 
227  if (nFace)
228  {
229  Info<< indent
230  << "AMI: Patch " << patchName
231  << " sum(weights) min/max/average = "
232  << gMin(wghtSum) << ", "
233  << gMax(wghtSum) << ", "
234  << gAverage(wghtSum) << endl;
235 
236  const label nLow = returnReduce(nLowWeight, sumOp<label>());
237 
238  if (nLow)
239  {
240  Info<< indent
241  << "AMI: Patch " << patchName
242  << " identified " << nLow
243  << " faces with weights less than " << lowWeightTol
244  << endl;
245  }
246  }
247  }
248 }
249 
250 
251 template<class SourcePatch, class TargetPatch>
253 (
254  const autoPtr<mapDistribute>& targetMapPtr,
255  const scalarField& fineSrcMagSf,
256  const labelListList& fineSrcAddress,
257  const scalarListList& fineSrcWeights,
258 
259  const labelList& sourceRestrictAddressing,
260  const labelList& targetRestrictAddressing,
261 
262  scalarField& srcMagSf,
263  labelListList& srcAddress,
264  scalarListList& srcWeights,
265  scalarField& srcWeightsSum,
266  autoPtr<mapDistribute>& tgtMap
267 )
268 {
269  label sourceCoarseSize =
270  (
271  sourceRestrictAddressing.size()
272  ? max(sourceRestrictAddressing)+1
273  : 0
274  );
275 
276  label targetCoarseSize =
277  (
278  targetRestrictAddressing.size()
279  ? max(targetRestrictAddressing)+1
280  : 0
281  );
282 
283  // Agglomerate face areas
284  {
285  srcMagSf.setSize(sourceRestrictAddressing.size(), 0.0);
286  forAll(sourceRestrictAddressing, faceI)
287  {
288  label coarseFaceI = sourceRestrictAddressing[faceI];
289  srcMagSf[coarseFaceI] += fineSrcMagSf[faceI];
290  }
291  }
292 
293 
294  // Agglomerate weights and indices
295  if (targetMapPtr.valid())
296  {
297  const mapDistribute& map = targetMapPtr();
298 
299  // Get all restriction addressing.
300  labelList allRestrict(targetRestrictAddressing);
301  map.distribute(allRestrict);
302 
303  // So now we have agglomeration of the target side in
304  // allRestrict:
305  // 0..size-1 : local agglomeration (= targetRestrictAddressing
306  // (but potentially permutated))
307  // size.. : agglomeration data from other processors
308 
309 
310  // The trickiness in this algorithm is finding out the compaction
311  // of the remote data (i.e. allocation of the coarse 'slots'). We could
312  // either send across the slot compaction maps or just make sure
313  // that we allocate the slots in exactly the same order on both sending
314  // and receiving side (e.g. if the submap is set up to send 4 items,
315  // the constructMap is also set up to receive 4 items.
316 
317 
318  // Short note about the various types of indices:
319  // - face indices : indices into the geometry.
320  // - coarse face indices : how the faces get agglomerated
321  // - transferred data : how mapDistribute sends/receives data,
322  // - slots : indices into data after distribution (e.g. stencil,
323  // srcAddress/tgtAddress). Note: for fully local addressing
324  // the slots are equal to face indices.
325  // A mapDistribute has:
326  // - a subMap : these are face indices
327  // - a constructMap : these are from 'transferred-date' to slots
328 
329  labelListList tgtSubMap(Pstream::nProcs());
330 
331  // Local subMap is just identity
332  {
333  tgtSubMap[Pstream::myProcNo()] = identity(targetCoarseSize);
334  }
335 
336  forAll(map.subMap(), procI)
337  {
338  if (procI != Pstream::myProcNo())
339  {
340  // Combine entries that point to the same coarse element.
341  // The important bit is to loop over the data (and hand out
342  // compact indices ) in 'transferred data' order. This
343  // guarantees that we're doing exactly the
344  // same on sending and receiving side - e.g. the fourth element
345  // in the subMap is the fourth element received in the
346  // constructMap
347 
348  const labelList& elems = map.subMap()[procI];
349  const labelList& elemsMap =
350  map.constructMap()[Pstream::myProcNo()];
351  labelList& newSubMap = tgtSubMap[procI];
352  newSubMap.setSize(elems.size());
353 
354  labelList oldToNew(targetCoarseSize, -1);
355  label newI = 0;
356 
357  forAll(elems, i)
358  {
359  label fineElem = elemsMap[elems[i]];
360  label coarseElem = allRestrict[fineElem];
361  if (oldToNew[coarseElem] == -1)
362  {
363  oldToNew[coarseElem] = newI;
364  newSubMap[newI] = coarseElem;
365  newI++;
366  }
367  }
368  newSubMap.setSize(newI);
369  }
370  }
371 
372  // Reconstruct constructMap by combining entries. Note that order
373  // of handing out indices should be the same as loop above to compact
374  // the sending map
375 
376  labelListList tgtConstructMap(Pstream::nProcs());
377 
378  // Local constructMap is just identity
379  {
380  tgtConstructMap[Pstream::myProcNo()] =
381  identity(targetCoarseSize);
382  }
383 
384  labelList tgtCompactMap(map.constructSize());
385 
386  {
387  // Note that in special cases (e.g. 'appending' two AMIs) the
388  // local size after distributing can be longer than the number
389  // of faces. I.e. it duplicates elements.
390  // Since we don't know this size instead we loop over all
391  // reachable elements (using the local constructMap)
392 
393  const labelList& elemsMap = map.constructMap()[Pstream::myProcNo()];
394  forAll(elemsMap, i)
395  {
396  label fineElem = elemsMap[i];
397  label coarseElem = allRestrict[fineElem];
398  tgtCompactMap[fineElem] = coarseElem;
399  }
400  }
401 
402  label compactI = targetCoarseSize;
403 
404  // Compact data from other processors
405  forAll(map.constructMap(), procI)
406  {
407  if (procI != Pstream::myProcNo())
408  {
409  // Combine entries that point to the same coarse element. All
410  // elements now are remote data so we cannot use any local
411  // data here - use allRestrict instead.
412  const labelList& elems = map.constructMap()[procI];
413 
414  labelList& newConstructMap = tgtConstructMap[procI];
415  newConstructMap.setSize(elems.size());
416 
417  if (elems.size())
418  {
419  // Get the maximum target coarse size for this set of
420  // received data.
421  label remoteTargetCoarseSize = labelMin;
422  forAll(elems, i)
423  {
424  remoteTargetCoarseSize = max
425  (
426  remoteTargetCoarseSize,
427  allRestrict[elems[i]]
428  );
429  }
430  remoteTargetCoarseSize += 1;
431 
432  // Combine locally data coming from procI
433  labelList oldToNew(remoteTargetCoarseSize, -1);
434  label newI = 0;
435 
436  forAll(elems, i)
437  {
438  label fineElem = elems[i];
439  // fineElem now points to section from procI
440  label coarseElem = allRestrict[fineElem];
441  if (oldToNew[coarseElem] == -1)
442  {
443  oldToNew[coarseElem] = newI;
444  tgtCompactMap[fineElem] = compactI;
445  newConstructMap[newI] = compactI++;
446  newI++;
447  }
448  else
449  {
450  // Get compact index
451  label compactI = oldToNew[coarseElem];
452  tgtCompactMap[fineElem] = newConstructMap[compactI];
453  }
454  }
455  newConstructMap.setSize(newI);
456  }
457  }
458  }
459 
460  srcAddress.setSize(sourceCoarseSize);
461  srcWeights.setSize(sourceCoarseSize);
462 
463  forAll(fineSrcAddress, faceI)
464  {
465  // All the elements contributing to faceI. Are slots in
466  // mapDistribute'd data.
467  const labelList& elems = fineSrcAddress[faceI];
468  const scalarList& weights = fineSrcWeights[faceI];
469  const scalar fineArea = fineSrcMagSf[faceI];
470 
471  label coarseFaceI = sourceRestrictAddressing[faceI];
472 
473  labelList& newElems = srcAddress[coarseFaceI];
474  scalarList& newWeights = srcWeights[coarseFaceI];
475 
476  forAll(elems, i)
477  {
478  label elemI = elems[i];
479  label coarseElemI = tgtCompactMap[elemI];
480 
481  label index = findIndex(newElems, coarseElemI);
482  if (index == -1)
483  {
484  newElems.append(coarseElemI);
485  newWeights.append(fineArea*weights[i]);
486  }
487  else
488  {
489  newWeights[index] += fineArea*weights[i];
490  }
491  }
492  }
493 
494  tgtMap.reset
495  (
496  new mapDistribute
497  (
498  compactI,
499  tgtSubMap.xfer(),
500  tgtConstructMap.xfer()
501  )
502  );
503  }
504  else
505  {
506  srcAddress.setSize(sourceCoarseSize);
507  srcWeights.setSize(sourceCoarseSize);
508 
509  forAll(fineSrcAddress, faceI)
510  {
511  // All the elements contributing to faceI. Are slots in
512  // target data.
513  const labelList& elems = fineSrcAddress[faceI];
514  const scalarList& weights = fineSrcWeights[faceI];
515  const scalar fineArea = fineSrcMagSf[faceI];
516 
517  label coarseFaceI = sourceRestrictAddressing[faceI];
518 
519  labelList& newElems = srcAddress[coarseFaceI];
520  scalarList& newWeights = srcWeights[coarseFaceI];
521 
522  forAll(elems, i)
523  {
524  label elemI = elems[i];
525  label coarseElemI = targetRestrictAddressing[elemI];
526 
527  label index = findIndex(newElems, coarseElemI);
528  if (index == -1)
529  {
530  newElems.append(coarseElemI);
531  newWeights.append(fineArea*weights[i]);
532  }
533  else
534  {
535  newWeights[index] += fineArea*weights[i];
536  }
537  }
538  }
539  }
540 
541  // weights normalisation
542  normaliseWeights
543  (
544  srcMagSf,
545  "source",
546  srcAddress,
547  srcWeights,
548  srcWeightsSum,
549  true,
550  false,
551  -1
552  );
553 }
554 
555 
556 template<class SourcePatch, class TargetPatch>
558 (
559  const SourcePatch& srcPatch,
560  const TargetPatch& tgtPatch,
561  const autoPtr<searchableSurface>& surfPtr
562 )
563 {
564  if (surfPtr.valid())
565  {
566  // create new patches for source and target
567  pointField srcPoints = srcPatch.points();
568  SourcePatch srcPatch0
569  (
571  (
572  srcPatch,
573  srcPatch.size(),
574  0
575  ),
576  srcPoints
577  );
578 
579  if (debug)
580  {
581  OFstream os("amiSrcPoints.obj");
582  forAll(srcPoints, i)
583  {
584  meshTools::writeOBJ(os, srcPoints[i]);
585  }
586  }
587 
588  pointField tgtPoints = tgtPatch.points();
589  TargetPatch tgtPatch0
590  (
592  (
593  tgtPatch,
594  tgtPatch.size(),
595  0
596  ),
597  tgtPoints
598  );
599 
600  if (debug)
601  {
602  OFstream os("amiTgtPoints.obj");
603  forAll(tgtPoints, i)
604  {
605  meshTools::writeOBJ(os, tgtPoints[i]);
606  }
607  }
608 
609 
610  // map source and target patches onto projection surface
611  projectPointsToSurface(surfPtr(), srcPoints);
612  projectPointsToSurface(surfPtr(), tgtPoints);
613 
614 
615  // calculate AMI interpolation
616  update(srcPatch0, tgtPatch0);
617  }
618  else
619  {
620  update(srcPatch, tgtPatch);
621  }
622 }
623 
624 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
625 
626 template<class SourcePatch, class TargetPatch>
628 (
629  const SourcePatch& srcPatch,
630  const TargetPatch& tgtPatch,
632  const bool requireMatch,
633  const interpolationMethod& method,
634  const scalar lowWeightCorrection,
635  const bool reverseTarget
636 )
637 :
638  methodName_(interpolationMethodToWord(method)),
639  reverseTarget_(reverseTarget),
640  requireMatch_(requireMatch),
641  singlePatchProc_(-999),
642  lowWeightCorrection_(lowWeightCorrection),
643  srcAddress_(),
644  srcWeights_(),
645  srcWeightsSum_(),
646  tgtAddress_(),
647  tgtWeights_(),
648  tgtWeightsSum_(),
649  triMode_(triMode),
650  srcMapPtr_(NULL),
651  tgtMapPtr_(NULL)
652 {
653  update(srcPatch, tgtPatch);
654 }
655 
656 
657 template<class SourcePatch, class TargetPatch>
659 (
660  const SourcePatch& srcPatch,
661  const TargetPatch& tgtPatch,
663  const bool requireMatch,
664  const word& methodName,
665  const scalar lowWeightCorrection,
666  const bool reverseTarget
667 )
668 :
669  methodName_(methodName),
670  reverseTarget_(reverseTarget),
671  requireMatch_(requireMatch),
672  singlePatchProc_(-999),
673  lowWeightCorrection_(lowWeightCorrection),
674  srcAddress_(),
675  srcWeights_(),
676  srcWeightsSum_(),
677  tgtAddress_(),
678  tgtWeights_(),
679  tgtWeightsSum_(),
680  triMode_(triMode),
681  srcMapPtr_(NULL),
682  tgtMapPtr_(NULL)
683 {
684  update(srcPatch, tgtPatch);
685 }
686 
687 
688 template<class SourcePatch, class TargetPatch>
690 (
691  const SourcePatch& srcPatch,
692  const TargetPatch& tgtPatch,
693  const autoPtr<searchableSurface>& surfPtr,
695  const bool requireMatch,
696  const interpolationMethod& method,
697  const scalar lowWeightCorrection,
698  const bool reverseTarget
699 )
700 :
701  methodName_(interpolationMethodToWord(method)),
702  reverseTarget_(reverseTarget),
703  requireMatch_(requireMatch),
704  singlePatchProc_(-999),
705  lowWeightCorrection_(lowWeightCorrection),
706  srcAddress_(),
707  srcWeights_(),
708  srcWeightsSum_(),
709  tgtAddress_(),
710  tgtWeights_(),
711  tgtWeightsSum_(),
712  triMode_(triMode),
713  srcMapPtr_(NULL),
714  tgtMapPtr_(NULL)
715 {
716  constructFromSurface(srcPatch, tgtPatch, surfPtr);
717 }
718 
719 
720 template<class SourcePatch, class TargetPatch>
722 (
723  const SourcePatch& srcPatch,
724  const TargetPatch& tgtPatch,
725  const autoPtr<searchableSurface>& surfPtr,
727  const bool requireMatch,
728  const word& methodName,
729  const scalar lowWeightCorrection,
730  const bool reverseTarget
731 )
732 :
733  methodName_(methodName),
734  reverseTarget_(reverseTarget),
735  requireMatch_(requireMatch),
736  singlePatchProc_(-999),
737  lowWeightCorrection_(lowWeightCorrection),
738  srcAddress_(),
739  srcWeights_(),
740  srcWeightsSum_(),
741  tgtAddress_(),
742  tgtWeights_(),
743  tgtWeightsSum_(),
744  triMode_(triMode),
745  srcMapPtr_(NULL),
746  tgtMapPtr_(NULL)
747 {
748  constructFromSurface(srcPatch, tgtPatch, surfPtr);
749 }
750 
751 
752 template<class SourcePatch, class TargetPatch>
754 (
756  const labelList& sourceRestrictAddressing,
757  const labelList& targetRestrictAddressing
758 )
759 :
760  methodName_(fineAMI.methodName_),
761  reverseTarget_(fineAMI.reverseTarget_),
762  requireMatch_(fineAMI.requireMatch_),
763  singlePatchProc_(fineAMI.singlePatchProc_),
764  lowWeightCorrection_(-1.0),
765  srcAddress_(),
766  srcWeights_(),
767  srcWeightsSum_(),
768  tgtAddress_(),
769  tgtWeights_(),
770  tgtWeightsSum_(),
771  triMode_(fineAMI.triMode_),
772  srcMapPtr_(NULL),
773  tgtMapPtr_(NULL)
774 {
775  label sourceCoarseSize =
776  (
777  sourceRestrictAddressing.size()
778  ? max(sourceRestrictAddressing)+1
779  : 0
780  );
781 
782  label neighbourCoarseSize =
783  (
784  targetRestrictAddressing.size()
785  ? max(targetRestrictAddressing)+1
786  : 0
787  );
788 
789  if (debug & 2)
790  {
791  Pout<< "AMI: Creating addressing and weights as agglomeration of AMI :"
792  << " source:" << fineAMI.srcAddress().size()
793  << " target:" << fineAMI.tgtAddress().size()
794  << " coarse source size:" << sourceCoarseSize
795  << " neighbour source size:" << neighbourCoarseSize
796  << endl;
797  }
798 
799  if
800  (
801  fineAMI.srcAddress().size() != sourceRestrictAddressing.size()
802  || fineAMI.tgtAddress().size() != targetRestrictAddressing.size()
803  )
804  {
806  << "Size mismatch." << nl
807  << "Source patch size:" << fineAMI.srcAddress().size() << nl
808  << "Source agglomeration size:"
809  << sourceRestrictAddressing.size() << nl
810  << "Target patch size:" << fineAMI.tgtAddress().size() << nl
811  << "Target agglomeration size:"
812  << targetRestrictAddressing.size()
813  << exit(FatalError);
814  }
815 
816 
817  // Agglomerate addresses and weights
818 
819  agglomerate
820  (
821  fineAMI.tgtMapPtr_,
822  fineAMI.srcMagSf(),
823  fineAMI.srcAddress(),
824  fineAMI.srcWeights(),
825 
826  sourceRestrictAddressing,
827  targetRestrictAddressing,
828 
829  srcMagSf_,
830  srcAddress_,
831  srcWeights_,
832  srcWeightsSum_,
833  tgtMapPtr_
834  );
835 
836  //if (tgtMapPtr_.valid())
837  //{
838  // Pout<< "tgtMap:" << endl;
839  // string oldPrefix = Pout.prefix();
840  // Pout.prefix() = oldPrefix + " ";
841  // tgtMapPtr_().printLayout(Pout);
842  // Pout.prefix() = oldPrefix;
843  //}
844 
845  agglomerate
846  (
847  fineAMI.srcMapPtr_,
848  fineAMI.tgtMagSf(),
849  fineAMI.tgtAddress(),
850  fineAMI.tgtWeights(),
851 
852  targetRestrictAddressing,
853  sourceRestrictAddressing,
854 
855  tgtMagSf_,
856  tgtAddress_,
857  tgtWeights_,
858  tgtWeightsSum_,
859  srcMapPtr_
860  );
861 
862  //if (srcMapPtr_.valid())
863  //{
864  // Pout<< "srcMap:" << endl;
865  // string oldPrefix = Pout.prefix();
866  // Pout.prefix() = oldPrefix + " ";
867  // srcMapPtr_().printLayout(Pout);
868  // Pout.prefix() = oldPrefix;
869  //}
870 }
871 
872 
873 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
874 
875 template<class SourcePatch, class TargetPatch>
877 {}
878 
879 
880 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
881 
882 template<class SourcePatch, class TargetPatch>
884 (
885  const SourcePatch& srcPatch,
886  const TargetPatch& tgtPatch
887 )
888 {
889  label srcTotalSize = returnReduce(srcPatch.size(), sumOp<label>());
890  label tgtTotalSize = returnReduce(tgtPatch.size(), sumOp<label>());
891 
892  if (srcTotalSize == 0)
893  {
894  if (debug)
895  {
896  Info<< "AMI: no source faces present - no addressing constructed"
897  << endl;
898  }
899 
900  return;
901  }
902 
903  Info<< indent
904  << "AMI: Creating addressing and weights between "
905  << srcTotalSize << " source faces and "
906  << tgtTotalSize << " target faces"
907  << endl;
908 
909  // Calculate face areas
910  srcMagSf_.setSize(srcPatch.size());
911  forAll(srcMagSf_, faceI)
912  {
913  srcMagSf_[faceI] = srcPatch[faceI].mag(srcPatch.points());
914  }
915  tgtMagSf_.setSize(tgtPatch.size());
916  forAll(tgtMagSf_, faceI)
917  {
918  tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points());
919  }
920 
921  // Calculate if patches present on multiple processors
922  singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
923 
924  if (singlePatchProc_ == -1)
925  {
926  // convert local addressing to global addressing
927  globalIndex globalSrcFaces(srcPatch.size());
928  globalIndex globalTgtFaces(tgtPatch.size());
929 
930  // Create processor map of overlapping faces. This map gets
931  // (possibly remote) faces from the tgtPatch such that they (together)
932  // cover all of the srcPatch
933  autoPtr<mapDistribute> mapPtr = calcProcMap(srcPatch, tgtPatch);
934  const mapDistribute& map = mapPtr();
935 
936  // create new target patch that fully encompasses source patch
937 
938  // faces and points
939  faceList newTgtFaces;
940  pointField newTgtPoints;
941  // original faces from tgtPatch (in globalIndexing since might be
942  // remote)
943  labelList tgtFaceIDs;
944  distributeAndMergePatches
945  (
946  map,
947  tgtPatch,
948  globalTgtFaces,
949  newTgtFaces,
950  newTgtPoints,
951  tgtFaceIDs
952  );
953 
954  TargetPatch
955  newTgtPatch
956  (
958  (
959  newTgtFaces,
960  newTgtFaces.size()
961  ),
962  newTgtPoints
963  );
964 
965  // calculate AMI interpolation
967  (
969  (
970  methodName_,
971  srcPatch,
972  newTgtPatch,
973  srcMagSf_,
974  tgtMagSf_,
975  triMode_,
976  reverseTarget_,
977  requireMatch_ && (lowWeightCorrection_ < 0)
978  )
979  );
980 
981  AMIPtr->calculate
982  (
983  srcAddress_,
984  srcWeights_,
985  tgtAddress_,
986  tgtWeights_
987  );
988 
989  // Now
990  // ~~~
991  // srcAddress_ : per srcPatch face a list of the newTgtPatch (not
992  // tgtPatch) faces it overlaps
993  // tgtAddress_ : per newTgtPatch (not tgtPatch) face a list of the
994  // srcPatch faces it overlaps
995 
996 
997  // Rework newTgtPatch indices into globalIndices of tgtPatch
998  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
999 
1000 
1001  forAll(srcAddress_, i)
1002  {
1003  labelList& addressing = srcAddress_[i];
1004  forAll(addressing, addrI)
1005  {
1006  addressing[addrI] = tgtFaceIDs[addressing[addrI]];
1007  }
1008  }
1009 
1010  forAll(tgtAddress_, i)
1011  {
1012  labelList& addressing = tgtAddress_[i];
1013  forAll(addressing, addrI)
1014  {
1015  addressing[addrI] = globalSrcFaces.toGlobal(addressing[addrI]);
1016  }
1017  }
1018 
1019  // send data back to originating procs. Note that contributions
1020  // from different processors get added (ListAppendEqOp)
1021 
1022  mapDistributeBase::distribute
1023  (
1024  Pstream::nonBlocking,
1025  List<labelPair>(),
1026  tgtPatch.size(),
1027  map.constructMap(),
1028  false, // has flip
1029  map.subMap(),
1030  false, // has flip
1031  tgtAddress_,
1033  flipOp(), // flip operation
1034  labelList()
1035  );
1036 
1037  mapDistributeBase::distribute
1038  (
1039  Pstream::nonBlocking,
1040  List<labelPair>(),
1041  tgtPatch.size(),
1042  map.constructMap(),
1043  false,
1044  map.subMap(),
1045  false,
1046  tgtWeights_,
1048  flipOp(),
1049  scalarList()
1050  );
1051 
1052  // weights normalisation
1053  normaliseWeights(AMIPtr->conformal(), true);
1054 
1055  // cache maps and reset addresses
1056  List<Map<label> > cMap;
1057  srcMapPtr_.reset(new mapDistribute(globalSrcFaces, tgtAddress_, cMap));
1058  tgtMapPtr_.reset(new mapDistribute(globalTgtFaces, srcAddress_, cMap));
1059 
1060  if (debug)
1061  {
1062  writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_);
1063  }
1064  }
1065  else
1066  {
1067  // calculate AMI interpolation
1069  (
1071  (
1072  methodName_,
1073  srcPatch,
1074  tgtPatch,
1075  srcMagSf_,
1076  tgtMagSf_,
1077  triMode_,
1078  reverseTarget_,
1079  requireMatch_ && (lowWeightCorrection_ < 0)
1080  )
1081  );
1082 
1083  AMIPtr->calculate
1084  (
1085  srcAddress_,
1086  srcWeights_,
1087  tgtAddress_,
1088  tgtWeights_
1089  );
1090 
1091  normaliseWeights(AMIPtr->conformal(), true);
1092  }
1093 
1094  if (debug)
1095  {
1096  Info<< "AMIInterpolation : Constructed addressing and weights" << nl
1097  << " triMode :"
1098  << faceAreaIntersect::triangulationModeNames_[triMode_] << nl
1099  << " singlePatchProc:" << singlePatchProc_ << nl
1100  << " srcMagSf :" << gSum(srcMagSf_) << nl
1101  << " tgtMagSf :" << gSum(tgtMagSf_) << nl
1102  << endl;
1103  }
1104 }
1105 
1106 
1107 template<class SourcePatch, class TargetPatch>
1110  const SourcePatch& srcPatch,
1111  const TargetPatch& tgtPatch
1112 )
1113 {
1114  // Create a new interpolation
1116  (
1118  (
1119  srcPatch,
1120  tgtPatch,
1121  triMode_,
1122  requireMatch_,
1123  methodName_,
1124  lowWeightCorrection_,
1125  reverseTarget_
1126  )
1127  );
1128 
1129  // If parallel then combine the mapDistribution and re-index
1130  if (singlePatchProc_ == -1)
1131  {
1132  labelListList& srcSubMap = srcMapPtr_->subMap();
1133  labelListList& srcConstructMap = srcMapPtr_->constructMap();
1134 
1135  labelListList& tgtSubMap = tgtMapPtr_->subMap();
1136  labelListList& tgtConstructMap = tgtMapPtr_->constructMap();
1137 
1138  labelListList& newSrcSubMap = newPtr->srcMapPtr_->subMap();
1139  labelListList& newSrcConstructMap = newPtr->srcMapPtr_->constructMap();
1140 
1141  labelListList& newTgtSubMap = newPtr->tgtMapPtr_->subMap();
1142  labelListList& newTgtConstructMap = newPtr->tgtMapPtr_->constructMap();
1143 
1144  // Re-calculate the source indices
1145  {
1146  labelList mapMap(0), newMapMap(0);
1147  forAll(srcSubMap, procI)
1148  {
1149  mapMap.append
1150  (
1151  identity(srcConstructMap[procI].size())
1152  + mapMap.size() + newMapMap.size()
1153  );
1154  newMapMap.append
1155  (
1156  identity(newSrcConstructMap[procI].size())
1157  + mapMap.size() + newMapMap.size()
1158  );
1159  }
1160 
1161  forAll(srcSubMap, procI)
1162  {
1163  forAll(srcConstructMap[procI], srcI)
1164  {
1165  srcConstructMap[procI][srcI] =
1166  mapMap[srcConstructMap[procI][srcI]];
1167  }
1168  }
1169 
1170  forAll(srcSubMap, procI)
1171  {
1172  forAll(newSrcConstructMap[procI], srcI)
1173  {
1174  newSrcConstructMap[procI][srcI] =
1175  newMapMap[newSrcConstructMap[procI][srcI]];
1176  }
1177  }
1178 
1179  forAll(tgtAddress_, tgtI)
1180  {
1181  forAll(tgtAddress_[tgtI], tgtJ)
1182  {
1183  tgtAddress_[tgtI][tgtJ] =
1184  mapMap[tgtAddress_[tgtI][tgtJ]];
1185  }
1186  }
1187 
1188  forAll(newPtr->tgtAddress_, tgtI)
1189  {
1190  forAll(newPtr->tgtAddress_[tgtI], tgtJ)
1191  {
1192  newPtr->tgtAddress_[tgtI][tgtJ] =
1193  newMapMap[newPtr->tgtAddress_[tgtI][tgtJ]];
1194  }
1195  }
1196  }
1197 
1198  // Re-calculate the target indices
1199  {
1200  labelList mapMap(0), newMapMap(0);
1201  forAll(srcSubMap, procI)
1202  {
1203  mapMap.append
1204  (
1205  identity(tgtConstructMap[procI].size())
1206  + mapMap.size() + newMapMap.size()
1207  );
1208  newMapMap.append
1209  (
1210  identity(newTgtConstructMap[procI].size())
1211  + mapMap.size() + newMapMap.size()
1212  );
1213  }
1214 
1215  forAll(srcSubMap, procI)
1216  {
1217  forAll(tgtConstructMap[procI], tgtI)
1218  {
1219  tgtConstructMap[procI][tgtI] =
1220  mapMap[tgtConstructMap[procI][tgtI]];
1221  }
1222  }
1223 
1224  forAll(srcSubMap, procI)
1225  {
1226  forAll(newTgtConstructMap[procI], tgtI)
1227  {
1228  newTgtConstructMap[procI][tgtI] =
1229  newMapMap[newTgtConstructMap[procI][tgtI]];
1230  }
1231  }
1232 
1233  forAll(srcAddress_, srcI)
1234  {
1235  forAll(srcAddress_[srcI], srcJ)
1236  {
1237  srcAddress_[srcI][srcJ] =
1238  mapMap[srcAddress_[srcI][srcJ]];
1239  }
1240  }
1241 
1242  forAll(newPtr->srcAddress_, srcI)
1243  {
1244  forAll(newPtr->srcAddress_[srcI], srcJ)
1245  {
1246  newPtr->srcAddress_[srcI][srcJ] =
1247  newMapMap[newPtr->srcAddress_[srcI][srcJ]];
1248  }
1249  }
1250  }
1251 
1252  // Sum the construction sizes
1253  srcMapPtr_->constructSize() += newPtr->srcMapPtr_->constructSize();
1254  tgtMapPtr_->constructSize() += newPtr->tgtMapPtr_->constructSize();
1255 
1256  // Combine the maps
1257  forAll(srcSubMap, procI)
1258  {
1259  srcSubMap[procI].append(newSrcSubMap[procI]);
1260  srcConstructMap[procI].append(newSrcConstructMap[procI]);
1261 
1262  tgtSubMap[procI].append(newTgtSubMap[procI]);
1263  tgtConstructMap[procI].append(newTgtConstructMap[procI]);
1264  }
1265  }
1266 
1267  // Combine new and current source data
1268  forAll(srcMagSf_, srcFaceI)
1269  {
1270  srcAddress_[srcFaceI].append(newPtr->srcAddress()[srcFaceI]);
1271  srcWeights_[srcFaceI].append(newPtr->srcWeights()[srcFaceI]);
1272  srcWeightsSum_[srcFaceI] += newPtr->srcWeightsSum()[srcFaceI];
1273  }
1274 
1275  // Combine new and current target data
1276  forAll(tgtMagSf_, tgtFaceI)
1277  {
1278  tgtAddress_[tgtFaceI].append(newPtr->tgtAddress()[tgtFaceI]);
1279  tgtWeights_[tgtFaceI].append(newPtr->tgtWeights()[tgtFaceI]);
1280  tgtWeightsSum_[tgtFaceI] += newPtr->tgtWeightsSum()[tgtFaceI];
1281  }
1282 }
1283 
1284 
1285 template<class SourcePatch, class TargetPatch>
1288  const bool conformal,
1289  const bool output
1290 )
1291 {
1292  normaliseWeights
1293  (
1294  srcMagSf_,
1295  "source",
1296  srcAddress_,
1297  srcWeights_,
1298  srcWeightsSum_,
1299  conformal,
1300  output,
1301  lowWeightCorrection_
1302  );
1303 
1304  normaliseWeights
1305  (
1306  tgtMagSf_,
1307  "target",
1308  tgtAddress_,
1309  tgtWeights_,
1310  tgtWeightsSum_,
1311  conformal,
1312  output,
1313  lowWeightCorrection_
1314  );
1315 }
1316 
1317 
1318 template<class SourcePatch, class TargetPatch>
1319 template<class Type, class CombineOp>
1322  const UList<Type>& fld,
1323  const CombineOp& cop,
1324  List<Type>& result,
1325  const UList<Type>& defaultValues
1326 ) const
1327 {
1328  if (fld.size() != srcAddress_.size())
1329  {
1331  << "Supplied field size is not equal to source patch size" << nl
1332  << " source patch = " << srcAddress_.size() << nl
1333  << " target patch = " << tgtAddress_.size() << nl
1334  << " supplied field = " << fld.size()
1335  << abort(FatalError);
1336  }
1337 
1338  if (lowWeightCorrection_ > 0)
1339  {
1340  if (defaultValues.size() != tgtAddress_.size())
1341  {
1343  << "Employing default values when sum of weights falls below "
1344  << lowWeightCorrection_
1345  << " but supplied default field size is not equal to target "
1346  << "patch size" << nl
1347  << " default values = " << defaultValues.size() << nl
1348  << " target patch = " << tgtAddress_.size() << nl
1349  << abort(FatalError);
1350  }
1351  }
1352 
1353  result.setSize(tgtAddress_.size());
1354 
1355  if (singlePatchProc_ == -1)
1356  {
1357  const mapDistribute& map = srcMapPtr_();
1358 
1359  List<Type> work(fld);
1360  map.distribute(work);
1361 
1362  forAll(result, faceI)
1363  {
1364  if (tgtWeightsSum_[faceI] < lowWeightCorrection_)
1365  {
1366  result[faceI] = defaultValues[faceI];
1367  }
1368  else
1369  {
1370  const labelList& faces = tgtAddress_[faceI];
1371  const scalarList& weights = tgtWeights_[faceI];
1372 
1373  forAll(faces, i)
1374  {
1375  cop(result[faceI], faceI, work[faces[i]], weights[i]);
1376  }
1377  }
1378  }
1379  }
1380  else
1381  {
1382  forAll(result, faceI)
1383  {
1384  if (tgtWeightsSum_[faceI] < lowWeightCorrection_)
1385  {
1386  result[faceI] = defaultValues[faceI];
1387  }
1388  else
1389  {
1390  const labelList& faces = tgtAddress_[faceI];
1391  const scalarList& weights = tgtWeights_[faceI];
1392 
1393  forAll(faces, i)
1394  {
1395  cop(result[faceI], faceI, fld[faces[i]], weights[i]);
1396  }
1397  }
1398  }
1399  }
1400 }
1401 
1402 
1403 template<class SourcePatch, class TargetPatch>
1404 template<class Type, class CombineOp>
1407  const UList<Type>& fld,
1408  const CombineOp& cop,
1409  List<Type>& result,
1410  const UList<Type>& defaultValues
1411 ) const
1412 {
1413  if (fld.size() != tgtAddress_.size())
1414  {
1416  << "Supplied field size is not equal to target patch size" << nl
1417  << " source patch = " << srcAddress_.size() << nl
1418  << " target patch = " << tgtAddress_.size() << nl
1419  << " supplied field = " << fld.size()
1420  << abort(FatalError);
1421  }
1422 
1423  if (lowWeightCorrection_ > 0)
1424  {
1425  if (defaultValues.size() != srcAddress_.size())
1426  {
1428  << "Employing default values when sum of weights falls below "
1429  << lowWeightCorrection_
1430  << " but supplied default field size is not equal to target "
1431  << "patch size" << nl
1432  << " default values = " << defaultValues.size() << nl
1433  << " source patch = " << srcAddress_.size() << nl
1434  << abort(FatalError);
1435  }
1436  }
1437 
1438  result.setSize(srcAddress_.size());
1439 
1440  if (singlePatchProc_ == -1)
1441  {
1442  const mapDistribute& map = tgtMapPtr_();
1443 
1444  List<Type> work(fld);
1445  map.distribute(work);
1446 
1447  forAll(result, faceI)
1448  {
1449  if (srcWeightsSum_[faceI] < lowWeightCorrection_)
1450  {
1451  result[faceI] = defaultValues[faceI];
1452  }
1453  else
1454  {
1455  const labelList& faces = srcAddress_[faceI];
1456  const scalarList& weights = srcWeights_[faceI];
1457 
1458  forAll(faces, i)
1459  {
1460  cop(result[faceI], faceI, work[faces[i]], weights[i]);
1461  }
1462  }
1463  }
1464  }
1465  else
1466  {
1467  forAll(result, faceI)
1468  {
1469  if (srcWeightsSum_[faceI] < lowWeightCorrection_)
1470  {
1471  result[faceI] = defaultValues[faceI];
1472  }
1473  else
1474  {
1475  const labelList& faces = srcAddress_[faceI];
1476  const scalarList& weights = srcWeights_[faceI];
1477 
1478  forAll(faces, i)
1479  {
1480  cop(result[faceI], faceI, fld[faces[i]], weights[i]);
1481  }
1482  }
1483  }
1484  }
1485 }
1486 
1487 
1488 template<class SourcePatch, class TargetPatch>
1489 template<class Type, class CombineOp>
1493  const Field<Type>& fld,
1494  const CombineOp& cop,
1495  const UList<Type>& defaultValues
1496 ) const
1497 {
1498  tmp<Field<Type> > tresult
1499  (
1500  new Field<Type>
1501  (
1502  srcAddress_.size(),
1504  )
1505  );
1506 
1507  interpolateToSource
1508  (
1509  fld,
1511  tresult(),
1512  defaultValues
1513  );
1514 
1515  return tresult;
1516 }
1517 
1518 
1519 template<class SourcePatch, class TargetPatch>
1520 template<class Type, class CombineOp>
1524  const tmp<Field<Type> >& tFld,
1525  const CombineOp& cop,
1526  const UList<Type>& defaultValues
1527 ) const
1528 {
1529  return interpolateToSource(tFld(), cop, defaultValues);
1530 }
1531 
1532 
1533 template<class SourcePatch, class TargetPatch>
1534 template<class Type, class CombineOp>
1538  const Field<Type>& fld,
1539  const CombineOp& cop,
1540  const UList<Type>& defaultValues
1541 ) const
1542 {
1543  tmp<Field<Type> > tresult
1544  (
1545  new Field<Type>
1546  (
1547  tgtAddress_.size(),
1549  )
1550  );
1551 
1552  interpolateToTarget
1553  (
1554  fld,
1556  tresult(),
1557  defaultValues
1558  );
1559 
1560  return tresult;
1561 }
1562 
1563 
1564 template<class SourcePatch, class TargetPatch>
1565 template<class Type, class CombineOp>
1569  const tmp<Field<Type> >& tFld,
1570  const CombineOp& cop,
1571  const UList<Type>& defaultValues
1572 ) const
1573 {
1574  return interpolateToTarget(tFld(), cop, defaultValues);
1575 }
1576 
1577 
1578 template<class SourcePatch, class TargetPatch>
1579 template<class Type>
1583  const Field<Type>& fld,
1584  const UList<Type>& defaultValues
1585 ) const
1586 {
1587  return interpolateToSource(fld, plusEqOp<Type>(), defaultValues);
1588 }
1589 
1590 
1591 template<class SourcePatch, class TargetPatch>
1592 template<class Type>
1596  const tmp<Field<Type> >& tFld,
1597  const UList<Type>& defaultValues
1598 ) const
1599 {
1600  return interpolateToSource(tFld(), plusEqOp<Type>(), defaultValues);
1601 }
1602 
1603 
1604 template<class SourcePatch, class TargetPatch>
1605 template<class Type>
1609  const Field<Type>& fld,
1610  const UList<Type>& defaultValues
1611 ) const
1612 {
1613  return interpolateToTarget(fld, plusEqOp<Type>(), defaultValues);
1614 }
1615 
1616 
1617 template<class SourcePatch, class TargetPatch>
1618 template<class Type>
1622  const tmp<Field<Type> >& tFld,
1623  const UList<Type>& defaultValues
1624 ) const
1625 {
1626  return interpolateToTarget(tFld(), plusEqOp<Type>(), defaultValues);
1627 }
1628 
1629 
1630 template<class SourcePatch, class TargetPatch>
1633  const SourcePatch& srcPatch,
1634  const TargetPatch& tgtPatch,
1635  const vector& n,
1636  const label tgtFaceI,
1637  point& tgtPoint
1638 )
1639 const
1640 {
1641  const pointField& srcPoints = srcPatch.points();
1642 
1643  // source face addresses that intersect target face tgtFaceI
1644  const labelList& addr = tgtAddress_[tgtFaceI];
1645 
1646  forAll(addr, i)
1647  {
1648  label srcFaceI = addr[i];
1649  const face& f = srcPatch[srcFaceI];
1650 
1651  pointHit ray = f.ray(tgtPoint, n, srcPoints);
1652 
1653  if (ray.hit())
1654  {
1655  tgtPoint = ray.rawPoint();
1656 
1657  return srcFaceI;
1658  }
1659  }
1660 
1661  // no hit registered - try with face normal instead of input normal
1662  forAll(addr, i)
1663  {
1664  label srcFaceI = addr[i];
1665  const face& f = srcPatch[srcFaceI];
1666 
1667  vector nFace(-srcPatch.faceNormals()[srcFaceI]);
1668  nFace += tgtPatch.faceNormals()[tgtFaceI];
1669 
1670  pointHit ray = f.ray(tgtPoint, nFace, srcPoints);
1671 
1672  if (ray.hit())
1673  {
1674  tgtPoint = ray.rawPoint();
1675 
1676  return srcFaceI;
1677  }
1678  }
1679 
1680  return -1;
1681 }
1682 
1683 
1684 template<class SourcePatch, class TargetPatch>
1687  const SourcePatch& srcPatch,
1688  const TargetPatch& tgtPatch,
1689  const vector& n,
1690  const label srcFaceI,
1691  point& srcPoint
1692 )
1693 const
1694 {
1695  const pointField& tgtPoints = tgtPatch.points();
1696 
1697  // target face addresses that intersect source face srcFaceI
1698  const labelList& addr = srcAddress_[srcFaceI];
1699 
1700  forAll(addr, i)
1701  {
1702  label tgtFaceI = addr[i];
1703  const face& f = tgtPatch[tgtFaceI];
1704 
1705  pointHit ray = f.ray(srcPoint, n, tgtPoints);
1706 
1707  if (ray.hit())
1708  {
1709  srcPoint = ray.rawPoint();
1710 
1711  return tgtFaceI;
1712  }
1713  }
1714 
1715  // no hit registered - try with face normal instead of input normal
1716  forAll(addr, i)
1717  {
1718  label tgtFaceI = addr[i];
1719  const face& f = tgtPatch[tgtFaceI];
1720 
1721  vector nFace(-srcPatch.faceNormals()[srcFaceI]);
1722  nFace += tgtPatch.faceNormals()[tgtFaceI];
1723 
1724  pointHit ray = f.ray(srcPoint, n, tgtPoints);
1725 
1726  if (ray.hit())
1727  {
1728  srcPoint = ray.rawPoint();
1729 
1730  return tgtFaceI;
1731  }
1732  }
1733 
1734  return -1;
1735 }
1736 
1737 
1738 template<class SourcePatch, class TargetPatch>
1741  const SourcePatch& srcPatch,
1742  const TargetPatch& tgtPatch,
1743  const labelListList& srcAddress
1744 )
1745 const
1746 {
1747  OFstream os("faceConnectivity" + Foam::name(Pstream::myProcNo()) + ".obj");
1748 
1749  label ptI = 1;
1750 
1751  forAll(srcAddress, i)
1752  {
1753  const labelList& addr = srcAddress[i];
1754  const point& srcPt = srcPatch.faceCentres()[i];
1755  forAll(addr, j)
1756  {
1757  label tgtPtI = addr[j];
1758  const point& tgtPt = tgtPatch.faceCentres()[tgtPtI];
1759 
1760  meshTools::writeOBJ(os, srcPt);
1761  meshTools::writeOBJ(os, tgtPt);
1762 
1763  os << "l " << ptI << " " << ptI + 1 << endl;
1764 
1765  ptI += 2;
1766  }
1767  }
1768 }
1769 
1770 
1771 // ************************************************************************* //
Foam::AMIInterpolation::interpolationMethod
interpolationMethod
Enumeration specifying interpolation method.
Definition: AMIInterpolation.H:86
Foam::mapDistributeBase::subMap
const labelListList & subMap() const
From subsetted data back to original data.
Definition: mapDistributeBase.H:256
Foam::AMIInterpolation::append
void append(const SourcePatch &srcPatch, const TargetPatch &tgtPatch)
Append additional addressing and weights.
Definition: AMIInterpolation.C:1109
meshTools.H
Foam::scalarList
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
Foam::AMIInterpolation::interpolationMethodToWord
static word interpolationMethodToWord(const interpolationMethod &method)
Convert interpolationMethod to word representation.
Definition: AMIInterpolation.C:37
Foam::AMIInterpolation::tgtMapPtr_
autoPtr< mapDistribute > tgtMapPtr_
Target map pointer - parallel running only.
Definition: AMIInterpolation.H:167
w
volScalarField w(IOobject("w", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE), mesh, dimensionedScalar("w", dimensionSet(0, 0, 0, 0, 0, 0, 0), 0.0))
Foam::PointHit::hit
bool hit() const
Is there a hit.
Definition: PointHit.H:120
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:86
Foam::AMIInterpolation::srcMagSf
const scalarField & srcMagSf() const
Return const access to source patch face areas.
Definition: AMIInterpolationI.H:53
Foam::AMIInterpolation::methodName_
const word methodName_
Interpolation method.
Definition: AMIInterpolation.H:112
Foam::AMIInterpolation::constructFromSurface
void constructFromSurface(const SourcePatch &srcPatch, const TargetPatch &tgtPatch, const autoPtr< searchableSurface > &surfPtr)
Definition: AMIInterpolation.C:558
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
writeOBJ
void writeOBJ(Ostream &os, label &vertI, const tetPoints &tet)
Definition: Test-tetTetOverlap.C:38
Foam::faceAreaIntersect::triangulationMode
triangulationMode
Definition: faceAreaIntersect.H:59
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::PointHit
This class describes the interaction of a face and a point. It carries the info of a successful hit a...
Definition: PointHit.H:51
Foam::findIndex
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:571
Foam::List::xfer
Xfer< List< T > > xfer()
Transfer contents to the Xfer container.
Definition: ListI.H:90
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::PointHit::rawPoint
const Point & rawPoint() const
Return point with no checking.
Definition: PointHit.H:158
Foam::AMIInterpolation::singlePatchProc_
label singlePatchProc_
Index of processor that holds all of both sides. -1 in all other.
Definition: AMIInterpolation.H:124
Foam::flipOp
Class containing functor to negate primitives. Dummy for all other types.
Definition: flipOp.H:50
Foam::ListAppendEqOp
Helper class for list to append y onto the end of x.
Definition: ListOps.H:259
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::gSum
Type gSum(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:564
AMIInterpolation.H
Foam::AMIInterpolation::tgtAddress
const labelListList & tgtAddress() const
Return const access to target patch addressing.
Definition: AMIInterpolationI.H:101
Foam::AMIInterpolation::tgtWeights
const scalarListList & tgtWeights() const
Return const access to target patch weights.
Definition: AMIInterpolationI.H:109
Foam::AMIMethod
Base class for Arbitrary Mesh Interface (AMI) methods.
Definition: AMIMethod.H:55
Foam::AMIInterpolation::interpolateToTarget
void interpolateToTarget(const UList< Type > &fld, const CombineOp &cop, List< Type > &result, const UList< Type > &defaultValues=UList< Type >::null()) const
Interpolate from source to target with supplied op.
Definition: AMIInterpolation.C:1321
Foam::AMIInterpolation::normaliseWeights
static void normaliseWeights(const scalarField &patchAreas, const word &patchName, const labelListList &addr, scalarListList &wght, scalarField &wghtSum, const bool conformal, const bool output, const scalar lowWeightTol)
Normalise the (area) weights - suppresses numerical error in.
Definition: AMIInterpolation.C:173
Foam::nearInfo
Tuple2< scalar, label > nearInfo
Private class for finding nearest.
Definition: sampledTriSurfaceMesh.C:64
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::AMIInterpolation::agglomerate
static void agglomerate(const autoPtr< mapDistribute > &targetMap, const scalarField &fineSrcMagSf, const labelListList &fineSrcAddress, const scalarListList &fineSrcWeights, const labelList &sourceRestrictAddressing, const labelList &targetRestrictAddressing, scalarField &srcMagSf, labelListList &srcAddress, scalarListList &srcWeights, scalarField &srcWeightsSum, autoPtr< mapDistribute > &tgtMap)
Definition: AMIInterpolation.C:253
Foam::AMIInterpolation::AMIInterpolation
AMIInterpolation(const AMIInterpolation &)
Disallow default bitwise copy construct.
Foam::PointIndexHit
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:53
Foam::labelMin
static const label labelMin
Definition: label.H:61
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::AMIInterpolation::interpolateToSource
void interpolateToSource(const UList< Type > &fld, const CombineOp &cop, List< Type > &result, const UList< Type > &defaultValues=UList< Type >::null()) const
Interpolate from target to source with supplied op.
Definition: AMIInterpolation.C:1406
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::List::append
void append(const T &)
Append an element at the end of the list.
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::AMIInterpolation::~AMIInterpolation
~AMIInterpolation()
Destructor.
Definition: AMIInterpolation.C:876
Foam::searchableSurface
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Definition: searchableSurface.H:66
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:152
Foam::AMIInterpolation::srcMapPtr_
autoPtr< mapDistribute > srcMapPtr_
Source map pointer - parallel running only.
Definition: AMIInterpolation.H:164
Foam::AMIInterpolation::writeFaceConnectivity
void writeFaceConnectivity(const SourcePatch &srcPatch, const TargetPatch &tgtPatch, const labelListList &srcAddress) const
Write face connectivity as OBJ file.
Definition: AMIInterpolation.C:1740
Foam::mapDistribute::distribute
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
Definition: mapDistributeTemplates.C:155
Foam::identity
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Foam::FatalError
error FatalError
fld
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< ' ';}gmvFile<< nl;forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Foam::plusEqOp
Definition: ops.H:71
Foam::AMIInterpolation::tgtMagSf
const scalarField & tgtMagSf() const
Return const access to target patch face areas.
Definition: AMIInterpolationI.H:93
Foam::IStringStream
Input from memory buffer stream.
Definition: IStringStream.H:49
flipOp.H
Foam::searchableSurface::findNearest
virtual void findNearest(const pointField &sample, const scalarField &nearestDistSqr, List< pointIndexHit > &) const =0
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
Foam::indent
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:221
s
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::AMIInterpolation::requireMatch_
const bool requireMatch_
Flag to indicate that the two patches must be matched/an overlap.
Definition: AMIInterpolation.H:120
Foam::OFstream
Output to file stream.
Definition: OFstream.H:81
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::mapDistributeBase::constructSize
label constructSize() const
Constructed data size.
Definition: mapDistributeBase.H:244
Foam::multiplyWeightedOp
Definition: ops.H:185
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::sumOp
Definition: ops.H:162
Foam::Pout
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
mapDistribute.H
f
labelList f(nPoints)
Foam::AMIInterpolation::tgtPointFace
label tgtPointFace(const SourcePatch &srcPatch, const TargetPatch &tgtPatch, const vector &n, const label srcFaceI, point &srcPoint) const
Return target patch face index of point on source patch face.
Definition: AMIInterpolation.C:1686
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::pTraits
Traits class for primitives.
Definition: pTraits.H:50
scalarField
volScalarField scalarField(fieldObject, mesh)
Foam::AMIInterpolation
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
Definition: AMIInterpolation.H:77
Foam::autoPtr::valid
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set).
Definition: autoPtrI.H:83
Foam::UList< Type >
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:333
AMIMethod.H
Foam::AMIInterpolation::reverseTarget_
const bool reverseTarget_
Flag to indicate that the two patches are co-directional and.
Definition: AMIInterpolation.H:116
Foam::AMIInterpolation::projectPointsToSurface
void projectPointsToSurface(const searchableSurface &surf, pointField &pts) const
Project points to surface.
Definition: AMIInterpolation.C:131
Foam::constant::mathematical::pi
const scalar pi(M_PI)
Foam::autoPtr::reset
void reset(T *=0)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
Foam::AMIInterpolation::update
void update(const SourcePatch &srcPatch, const TargetPatch &tgtPatch)
Update addressing and weights.
Definition: AMIInterpolation.C:884
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::gMin
Type gMin(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:563
Foam::Tuple2
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:47
Foam::UList::size
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
Foam::mapDistributeBase::constructMap
const labelListList & constructMap() const
From subsetted data to new reconstructed data.
Definition: mapDistributeBase.H:268
Foam::AMIInterpolation::triMode_
const faceAreaIntersect::triangulationMode triMode_
Face triangulation mode.
Definition: AMIInterpolation.H:161
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:562
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::AMIInterpolation::srcAddress
const labelListList & srcAddress() const
Return const access to source patch addressing.
Definition: AMIInterpolationI.H:61
Foam::AMIInterpolation::srcWeights
const scalarListList & srcWeights() const
Return const access to source patch weights.
Definition: AMIInterpolationI.H:69
Foam::globalIndex::toGlobal
label toGlobal(const label i) const
From local to global.
Definition: globalIndexI.H:82
Foam::AMIInterpolation::srcPointFace
label srcPointFace(const SourcePatch &srcPatch, const TargetPatch &tgtPatch, const vector &n, const label tgtFaceI, point &tgtPoint) const
Return source patch face index of point on target patch face.
Definition: AMIInterpolation.C:1632
Foam::AMIInterpolation::wordTointerpolationMethod
static interpolationMethod wordTointerpolationMethod(const word &method)
Convert word to interpolationMethod.
Definition: AMIInterpolation.C:80