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-2014 OpenFOAM Foundation
6  \\/ M anipulation |
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 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 template<class SourcePatch, class TargetPatch>
36 (
37  const interpolationMethod& im
38 )
39 {
40  word method = "unknown-interpolationMethod";
41 
42  switch (im)
43  {
44  case imDirect:
45  {
46  method = "directAMI";
47  break;
48  }
49  case imMapNearest:
50  {
51  method = "mapNearestAMI";
52  break;
53  }
54  case imFaceAreaWeight:
55  {
56  method = "faceAreaWeightAMI";
57  break;
58  }
59  case imPartialFaceAreaWeight:
60  {
61  method = "partialFaceAreaWeightAMI";
62  break;
63  }
64  default:
65  {
67  (
68  "const Foam::word"
69  "Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
70  "interpolationMethodToWord"
71  "("
72  "const interpolationMethod&"
73  ")"
74  )
75  << "Unhandled interpolationMethod enumeration " << method
76  << abort(FatalError);
77  }
78  }
79 
80  return method;
81 }
82 
83 
84 template<class SourcePatch, class TargetPatch>
87 (
88  const word& im
89 )
90 {
91  interpolationMethod method = imDirect;
92 
93  wordList methods
94  (
96  (
97  "("
98  "directAMI "
99  "mapNearestAMI "
100  "faceAreaWeightAMI "
101  "partialFaceAreaWeightAMI"
102  ")"
103  )()
104  );
105 
106  if (im == "directAMI")
107  {
108  method = imDirect;
109  }
110  else if (im == "mapNearestAMI")
111  {
112  method = imMapNearest;
113  }
114  else if (im == "faceAreaWeightAMI")
115  {
116  method = imFaceAreaWeight;
117  }
118  else if (im == "partialFaceAreaWeightAMI")
119  {
120  method = imPartialFaceAreaWeight;
121  }
122  else
123  {
125  (
126  "Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
127  "interpolationMethod"
128  "Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
129  "wordTointerpolationMethod"
130  "("
131  "const word&"
132  ")"
133  )
134  << "Invalid interpolationMethod " << im
135  << ". Valid methods are:" << methods
136  << exit(FatalError);
137  }
138 
139  return method;
140 }
141 
142 
143 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
144 
145 template<class SourcePatch, class TargetPatch>
147 (
148  const searchableSurface& surf,
149  pointField& pts
150 ) const
151 {
152  if (debug)
153  {
154  Info<< "AMI: projecting points to surface" << endl;
155  }
156 
158 
159  surf.findNearest(pts, scalarField(pts.size(), GREAT), nearInfo);
160 
161  label nMiss = 0;
162  forAll(nearInfo, i)
163  {
164  const pointIndexHit& pi = nearInfo[i];
165 
166  if (pi.hit())
167  {
168  pts[i] = pi.hitPoint();
169  }
170  else
171  {
172  pts[i] = pts[i];
173  nMiss++;
174  }
175  }
176 
177  if (nMiss > 0)
178  {
180  (
181  "void Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
182  "projectPointsToSurface"
183  "("
184  "const searchableSurface&, "
185  "pointField&"
186  ") const"
187  )
188  << "Error projecting points to surface: "
189  << nMiss << " faces could not be determined"
190  << abort(FatalError);
191  }
192 }
193 
194 
195 template<class SourcePatch, class TargetPatch>
197 (
198  const scalarField& patchAreas,
199  const word& patchName,
200  const labelListList& addr,
201  scalarListList& wght,
202  scalarField& wghtSum,
203  const bool conformal,
204  const bool output,
205  const scalar lowWeightTol
206 )
207 {
208  // Normalise the weights
209  wghtSum.setSize(wght.size(), 0.0);
210  label nLowWeight = 0;
211 
212  forAll(wght, faceI)
213  {
214  scalarList& w = wght[faceI];
215 
216  if (w.size())
217  {
218  scalar denom = patchAreas[faceI];
219 
220  scalar s = sum(w);
221  scalar t = s/denom;
222 
223  if (conformal)
224  {
225  denom = s;
226  }
227 
228  forAll(w, i)
229  {
230  w[i] /= denom;
231  }
232 
233  wghtSum[faceI] = t;
234 
235  if (t < lowWeightTol)
236  {
237  nLowWeight++;
238  }
239  }
240  else
241  {
242  wghtSum[faceI] = 0;
243  }
244  }
245 
246 
247  if (output)
248  {
249  const label nFace = returnReduce(wght.size(), sumOp<label>());
250 
251  if (nFace)
252  {
253  Info<< indent
254  << "AMI: Patch " << patchName
255  << " sum(weights) min/max/average = "
256  << gMin(wghtSum) << ", "
257  << gMax(wghtSum) << ", "
258  << gAverage(wghtSum) << endl;
259 
260  const label nLow = returnReduce(nLowWeight, sumOp<label>());
261 
262  if (nLow)
263  {
264  Info<< indent
265  << "AMI: Patch " << patchName
266  << " identified " << nLow
267  << " faces with weights less than " << lowWeightTol
268  << endl;
269  }
270  }
271  }
272 }
273 
274 
275 template<class SourcePatch, class TargetPatch>
277 (
278  const autoPtr<mapDistribute>& targetMapPtr,
279  const scalarField& fineSrcMagSf,
280  const labelListList& fineSrcAddress,
281  const scalarListList& fineSrcWeights,
282 
283  const labelList& sourceRestrictAddressing,
284  const labelList& targetRestrictAddressing,
285 
286  scalarField& srcMagSf,
287  labelListList& srcAddress,
288  scalarListList& srcWeights,
289  scalarField& srcWeightsSum,
290  autoPtr<mapDistribute>& tgtMap
291 )
292 {
293  label sourceCoarseSize =
294  (
295  sourceRestrictAddressing.size()
296  ? max(sourceRestrictAddressing)+1
297  : 0
298  );
299 
300  label targetCoarseSize =
301  (
302  targetRestrictAddressing.size()
303  ? max(targetRestrictAddressing)+1
304  : 0
305  );
306 
307  // Agglomerate face areas
308  {
309  srcMagSf.setSize(sourceRestrictAddressing.size(), 0.0);
310  forAll(sourceRestrictAddressing, faceI)
311  {
312  label coarseFaceI = sourceRestrictAddressing[faceI];
313  srcMagSf[coarseFaceI] += fineSrcMagSf[faceI];
314  }
315  }
316 
317 
318  // Agglomerate weights and indices
319  if (targetMapPtr.valid())
320  {
321  const mapDistribute& map = targetMapPtr();
322 
323  // Get all restriction addressing.
324  labelList allRestrict(targetRestrictAddressing);
325  map.distribute(allRestrict);
326 
327  // So now we have agglomeration of the target side in
328  // allRestrict:
329  // 0..size-1 : local agglomeration (= targetRestrictAddressing)
330  // size.. : agglomeration data from other processors
331 
332  labelListList tgtSubMap(Pstream::nProcs());
333 
334  // Local subMap is just identity
335  {
336  tgtSubMap[Pstream::myProcNo()] = identity(targetCoarseSize);
337  }
338 
339  forAll(map.subMap(), procI)
340  {
341  if (procI != Pstream::myProcNo())
342  {
343  // Combine entries that point to the same coarse element. All
344  // the elements refer to local data so index into
345  // targetRestrictAddressing or allRestrict (since the same
346  // for local data).
347  const labelList& elems = map.subMap()[procI];
348  labelList& newSubMap = tgtSubMap[procI];
349  newSubMap.setSize(elems.size());
350 
351  labelList oldToNew(targetCoarseSize, -1);
352  label newI = 0;
353 
354  forAll(elems, i)
355  {
356  label fineElem = elems[i];
357  label coarseElem = allRestrict[fineElem];
358  if (oldToNew[coarseElem] == -1)
359  {
360  oldToNew[coarseElem] = newI;
361  newSubMap[newI] = coarseElem;
362  newI++;
363  }
364  }
365  newSubMap.setSize(newI);
366  }
367  }
368 
369  // Reconstruct constructMap by combining entries. Note that order
370  // of handing out indices should be the same as loop above to compact
371  // the sending map
372 
373  labelListList tgtConstructMap(Pstream::nProcs());
374  labelList tgtCompactMap;
375 
376  // Local constructMap is just identity
377  {
378  tgtConstructMap[Pstream::myProcNo()] =
379  identity(targetCoarseSize);
380 
381  tgtCompactMap = targetRestrictAddressing;
382  }
383  tgtCompactMap.setSize(map.constructSize());
384  label compactI = targetCoarseSize;
385 
386  // Compact data from other processors
387  forAll(map.constructMap(), procI)
388  {
389  if (procI != Pstream::myProcNo())
390  {
391  // Combine entries that point to the same coarse element. All
392  // elements now are remote data so we cannot use any local
393  // data here - use allRestrict instead.
394  const labelList& elems = map.constructMap()[procI];
395 
396  labelList& newConstructMap = tgtConstructMap[procI];
397  newConstructMap.setSize(elems.size());
398 
399  if (elems.size())
400  {
401  // Get the maximum target coarse size for this set of
402  // received data.
403  label remoteTargetCoarseSize = labelMin;
404  forAll(elems, i)
405  {
406  remoteTargetCoarseSize = max
407  (
408  remoteTargetCoarseSize,
409  allRestrict[elems[i]]
410  );
411  }
412  remoteTargetCoarseSize += 1;
413 
414  // Combine locally data coming from procI
415  labelList oldToNew(remoteTargetCoarseSize, -1);
416  label newI = 0;
417 
418  forAll(elems, i)
419  {
420  label fineElem = elems[i];
421  // fineElem now points to section from procI
422  label coarseElem = allRestrict[fineElem];
423  if (oldToNew[coarseElem] == -1)
424  {
425  oldToNew[coarseElem] = newI;
426  tgtCompactMap[fineElem] = compactI;
427  newConstructMap[newI] = compactI++;
428  newI++;
429  }
430  else
431  {
432  // Get compact index
433  label compactI = oldToNew[coarseElem];
434  tgtCompactMap[fineElem] = newConstructMap[compactI];
435  }
436  }
437  newConstructMap.setSize(newI);
438  }
439  }
440  }
441 
442 
443  srcAddress.setSize(sourceCoarseSize);
444  srcWeights.setSize(sourceCoarseSize);
445 
446  forAll(fineSrcAddress, faceI)
447  {
448  // All the elements contributing to faceI. Are slots in
449  // mapDistribute'd data.
450  const labelList& elems = fineSrcAddress[faceI];
451  const scalarList& weights = fineSrcWeights[faceI];
452  const scalar fineArea = fineSrcMagSf[faceI];
453 
454  label coarseFaceI = sourceRestrictAddressing[faceI];
455 
456  labelList& newElems = srcAddress[coarseFaceI];
457  scalarList& newWeights = srcWeights[coarseFaceI];
458 
459  forAll(elems, i)
460  {
461  label elemI = elems[i];
462  label coarseElemI = tgtCompactMap[elemI];
463 
464  label index = findIndex(newElems, coarseElemI);
465  if (index == -1)
466  {
467  newElems.append(coarseElemI);
468  newWeights.append(fineArea*weights[i]);
469  }
470  else
471  {
472  newWeights[index] += fineArea*weights[i];
473  }
474  }
475  }
476 
477  tgtMap.reset
478  (
479  new mapDistribute
480  (
481  compactI,
482  tgtSubMap.xfer(),
483  tgtConstructMap.xfer()
484  )
485  );
486  }
487  else
488  {
489  srcAddress.setSize(sourceCoarseSize);
490  srcWeights.setSize(sourceCoarseSize);
491 
492  forAll(fineSrcAddress, faceI)
493  {
494  // All the elements contributing to faceI. Are slots in
495  // mapDistribute'd data.
496  const labelList& elems = fineSrcAddress[faceI];
497  const scalarList& weights = fineSrcWeights[faceI];
498  const scalar fineArea = fineSrcMagSf[faceI];
499 
500  label coarseFaceI = sourceRestrictAddressing[faceI];
501 
502  labelList& newElems = srcAddress[coarseFaceI];
503  scalarList& newWeights = srcWeights[coarseFaceI];
504 
505  forAll(elems, i)
506  {
507  label elemI = elems[i];
508  label coarseElemI = targetRestrictAddressing[elemI];
509 
510  label index = findIndex(newElems, coarseElemI);
511  if (index == -1)
512  {
513  newElems.append(coarseElemI);
514  newWeights.append(fineArea*weights[i]);
515  }
516  else
517  {
518  newWeights[index] += fineArea*weights[i];
519  }
520  }
521  }
522  }
523 
524  // weights normalisation
525  normaliseWeights
526  (
527  srcMagSf,
528  "source",
529  srcAddress,
530  srcWeights,
531  srcWeightsSum,
532  true,
533  false,
534  -1
535  );
536 }
537 
538 
539 template<class SourcePatch, class TargetPatch>
541 (
542  const SourcePatch& srcPatch,
543  const TargetPatch& tgtPatch,
544  const autoPtr<searchableSurface>& surfPtr
545 )
546 {
547  if (surfPtr.valid())
548  {
549  // create new patches for source and target
550  pointField srcPoints = srcPatch.points();
551  SourcePatch srcPatch0
552  (
554  (
555  srcPatch,
556  srcPatch.size(),
557  0
558  ),
559  srcPoints
560  );
561 
562  if (debug)
563  {
564  OFstream os("amiSrcPoints.obj");
565  forAll(srcPoints, i)
566  {
567  meshTools::writeOBJ(os, srcPoints[i]);
568  }
569  }
570 
571  pointField tgtPoints = tgtPatch.points();
572  TargetPatch tgtPatch0
573  (
575  (
576  tgtPatch,
577  tgtPatch.size(),
578  0
579  ),
580  tgtPoints
581  );
582 
583  if (debug)
584  {
585  OFstream os("amiTgtPoints.obj");
586  forAll(tgtPoints, i)
587  {
588  meshTools::writeOBJ(os, tgtPoints[i]);
589  }
590  }
591 
592 
593  // map source and target patches onto projection surface
594  projectPointsToSurface(surfPtr(), srcPoints);
595  projectPointsToSurface(surfPtr(), tgtPoints);
596 
597 
598  // calculate AMI interpolation
599  update(srcPatch0, tgtPatch0);
600  }
601  else
602  {
603  update(srcPatch, tgtPatch);
604  }
605 }
606 
607 
608 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
609 
610 template<class SourcePatch, class TargetPatch>
612 (
613  const SourcePatch& srcPatch,
614  const TargetPatch& tgtPatch,
616  const bool requireMatch,
617  const interpolationMethod& method,
618  const scalar lowWeightCorrection,
619  const bool reverseTarget
620 )
621 :
622  methodName_(interpolationMethodToWord(method)),
623  reverseTarget_(reverseTarget),
624  requireMatch_(requireMatch),
625  singlePatchProc_(-999),
626  lowWeightCorrection_(lowWeightCorrection),
627  srcAddress_(),
628  srcWeights_(),
629  srcWeightsSum_(),
630  tgtAddress_(),
631  tgtWeights_(),
632  tgtWeightsSum_(),
633  triMode_(triMode),
634  srcMapPtr_(NULL),
635  tgtMapPtr_(NULL)
636 {
637  update(srcPatch, tgtPatch);
638 }
639 
640 
641 template<class SourcePatch, class TargetPatch>
643 (
644  const SourcePatch& srcPatch,
645  const TargetPatch& tgtPatch,
647  const bool requireMatch,
648  const word& methodName,
649  const scalar lowWeightCorrection,
650  const bool reverseTarget
651 )
652 :
653  methodName_(methodName),
654  reverseTarget_(reverseTarget),
655  requireMatch_(requireMatch),
656  singlePatchProc_(-999),
657  lowWeightCorrection_(lowWeightCorrection),
658  srcAddress_(),
659  srcWeights_(),
660  srcWeightsSum_(),
661  tgtAddress_(),
662  tgtWeights_(),
663  tgtWeightsSum_(),
664  triMode_(triMode),
665  srcMapPtr_(NULL),
666  tgtMapPtr_(NULL)
667 {
668  update(srcPatch, tgtPatch);
669 }
670 
671 
672 template<class SourcePatch, class TargetPatch>
674 (
675  const SourcePatch& srcPatch,
676  const TargetPatch& tgtPatch,
677  const autoPtr<searchableSurface>& surfPtr,
679  const bool requireMatch,
680  const interpolationMethod& method,
681  const scalar lowWeightCorrection,
682  const bool reverseTarget
683 )
684 :
685  methodName_(interpolationMethodToWord(method)),
686  reverseTarget_(reverseTarget),
687  requireMatch_(requireMatch),
688  singlePatchProc_(-999),
689  lowWeightCorrection_(lowWeightCorrection),
690  srcAddress_(),
691  srcWeights_(),
692  srcWeightsSum_(),
693  tgtAddress_(),
694  tgtWeights_(),
695  tgtWeightsSum_(),
696  triMode_(triMode),
697  srcMapPtr_(NULL),
698  tgtMapPtr_(NULL)
699 {
700  constructFromSurface(srcPatch, tgtPatch, surfPtr);
701 }
702 
703 
704 template<class SourcePatch, class TargetPatch>
706 (
707  const SourcePatch& srcPatch,
708  const TargetPatch& tgtPatch,
709  const autoPtr<searchableSurface>& surfPtr,
711  const bool requireMatch,
712  const word& methodName,
713  const scalar lowWeightCorrection,
714  const bool reverseTarget
715 )
716 :
717  methodName_(methodName),
718  reverseTarget_(reverseTarget),
719  requireMatch_(requireMatch),
720  singlePatchProc_(-999),
721  lowWeightCorrection_(lowWeightCorrection),
722  srcAddress_(),
723  srcWeights_(),
724  srcWeightsSum_(),
725  tgtAddress_(),
726  tgtWeights_(),
727  tgtWeightsSum_(),
728  triMode_(triMode),
729  srcMapPtr_(NULL),
730  tgtMapPtr_(NULL)
731 {
732  constructFromSurface(srcPatch, tgtPatch, surfPtr);
733 }
734 
735 
736 template<class SourcePatch, class TargetPatch>
738 (
740  const labelList& sourceRestrictAddressing,
741  const labelList& targetRestrictAddressing
742 )
743 :
744  methodName_(fineAMI.methodName_),
745  reverseTarget_(fineAMI.reverseTarget_),
746  requireMatch_(fineAMI.requireMatch_),
747  singlePatchProc_(fineAMI.singlePatchProc_),
748  lowWeightCorrection_(-1.0),
749  srcAddress_(),
750  srcWeights_(),
751  srcWeightsSum_(),
752  tgtAddress_(),
753  tgtWeights_(),
754  tgtWeightsSum_(),
755  triMode_(fineAMI.triMode_),
756  srcMapPtr_(NULL),
757  tgtMapPtr_(NULL)
758 {
759  label sourceCoarseSize =
760  (
761  sourceRestrictAddressing.size()
762  ? max(sourceRestrictAddressing)+1
763  : 0
764  );
765 
766  label neighbourCoarseSize =
767  (
768  targetRestrictAddressing.size()
769  ? max(targetRestrictAddressing)+1
770  : 0
771  );
772 
773  if (debug & 2)
774  {
775  Pout<< "AMI: Creating addressing and weights as agglomeration of AMI :"
776  << " source:" << fineAMI.srcAddress().size()
777  << " target:" << fineAMI.tgtAddress().size()
778  << " coarse source size:" << sourceCoarseSize
779  << " neighbour source size:" << neighbourCoarseSize
780  << endl;
781  }
782 
783  if
784  (
785  fineAMI.srcAddress().size() != sourceRestrictAddressing.size()
786  || fineAMI.tgtAddress().size() != targetRestrictAddressing.size()
787  )
788  {
790  (
791  "AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation"
792  "("
793  "const AMIInterpolation<SourcePatch, TargetPatch>&, "
794  "const labelList&, "
795  "const labelList&"
796  ")"
797  ) << "Size mismatch." << nl
798  << "Source patch size:" << fineAMI.srcAddress().size() << nl
799  << "Source agglomeration size:"
800  << sourceRestrictAddressing.size() << nl
801  << "Target patch size:" << fineAMI.tgtAddress().size() << nl
802  << "Target agglomeration size:"
803  << targetRestrictAddressing.size()
804  << exit(FatalError);
805  }
806 
807 
808  // Agglomerate addresses and weights
809 
810  agglomerate
811  (
812  fineAMI.tgtMapPtr_,
813  fineAMI.srcMagSf(),
814  fineAMI.srcAddress(),
815  fineAMI.srcWeights(),
816 
817  sourceRestrictAddressing,
818  targetRestrictAddressing,
819 
820  srcMagSf_,
821  srcAddress_,
822  srcWeights_,
823  srcWeightsSum_,
824  tgtMapPtr_
825  );
826 
827  //if (tgtMapPtr_.valid())
828  //{
829  // Pout<< "tgtMap:" << endl;
830  // string oldPrefix = Pout.prefix();
831  // Pout.prefix() = oldPrefix + " ";
832  // tgtMapPtr_().printLayout(Pout);
833  // Pout.prefix() = oldPrefix;
834  //}
835 
836  agglomerate
837  (
838  fineAMI.srcMapPtr_,
839  fineAMI.tgtMagSf(),
840  fineAMI.tgtAddress(),
841  fineAMI.tgtWeights(),
842 
843  targetRestrictAddressing,
844  sourceRestrictAddressing,
845 
846  tgtMagSf_,
847  tgtAddress_,
848  tgtWeights_,
849  tgtWeightsSum_,
850  srcMapPtr_
851  );
852 
853  //if (srcMapPtr_.valid())
854  //{
855  // Pout<< "srcMap:" << endl;
856  // string oldPrefix = Pout.prefix();
857  // Pout.prefix() = oldPrefix + " ";
858  // srcMapPtr_().printLayout(Pout);
859  // Pout.prefix() = oldPrefix;
860  //}
861 }
862 
863 
864 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
865 
866 template<class SourcePatch, class TargetPatch>
868 {}
869 
870 
871 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
872 
873 template<class SourcePatch, class TargetPatch>
875 (
876  const SourcePatch& srcPatch,
877  const TargetPatch& tgtPatch
878 )
879 {
880  label srcTotalSize = returnReduce(srcPatch.size(), sumOp<label>());
881  label tgtTotalSize = returnReduce(tgtPatch.size(), sumOp<label>());
882 
883  if (srcTotalSize == 0)
884  {
885  if (debug)
886  {
887  Info<< "AMI: no source faces present - no addressing constructed"
888  << endl;
889  }
890 
891  return;
892  }
893 
894  Info<< indent
895  << "AMI: Creating addressing and weights between "
896  << srcTotalSize << " source faces and "
897  << tgtTotalSize << " target faces"
898  << endl;
899 
900  // Calculate face areas
901  srcMagSf_.setSize(srcPatch.size());
902  forAll(srcMagSf_, faceI)
903  {
904  srcMagSf_[faceI] = srcPatch[faceI].mag(srcPatch.points());
905  }
906  tgtMagSf_.setSize(tgtPatch.size());
907  forAll(tgtMagSf_, faceI)
908  {
909  tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points());
910  }
911 
912  // Calculate if patches present on multiple processors
913  singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
914 
915  if (singlePatchProc_ == -1)
916  {
917  // convert local addressing to global addressing
918  globalIndex globalSrcFaces(srcPatch.size());
919  globalIndex globalTgtFaces(tgtPatch.size());
920 
921  // Create processor map of overlapping faces. This map gets
922  // (possibly remote) faces from the tgtPatch such that they (together)
923  // cover all of the srcPatch
924  autoPtr<mapDistribute> mapPtr = calcProcMap(srcPatch, tgtPatch);
925  const mapDistribute& map = mapPtr();
926 
927  // create new target patch that fully encompasses source patch
928 
929  // faces and points
930  faceList newTgtFaces;
931  pointField newTgtPoints;
932  // original faces from tgtPatch (in globalIndexing since might be
933  // remote)
934  labelList tgtFaceIDs;
935  distributeAndMergePatches
936  (
937  map,
938  tgtPatch,
939  globalTgtFaces,
940  newTgtFaces,
941  newTgtPoints,
942  tgtFaceIDs
943  );
944 
945  TargetPatch
946  newTgtPatch
947  (
949  (
950  newTgtFaces,
951  newTgtFaces.size()
952  ),
953  newTgtPoints
954  );
955 
956  // calculate AMI interpolation
958  (
960  (
961  methodName_,
962  srcPatch,
963  newTgtPatch,
964  srcMagSf_,
965  tgtMagSf_,
966  triMode_,
967  reverseTarget_,
968  requireMatch_
969  )
970  );
971 
972  AMIPtr->calculate
973  (
974  srcAddress_,
975  srcWeights_,
976  tgtAddress_,
977  tgtWeights_
978  );
979 
980  // Now
981  // ~~~
982  // srcAddress_ : per srcPatch face a list of the newTgtPatch (not
983  // tgtPatch) faces it overlaps
984  // tgtAddress_ : per newTgtPatch (not tgtPatch) face a list of the
985  // srcPatch faces it overlaps
986 
987 
988  // Rework newTgtPatch indices into globalIndices of tgtPatch
989  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
990 
991 
992  forAll(srcAddress_, i)
993  {
994  labelList& addressing = srcAddress_[i];
995  forAll(addressing, addrI)
996  {
997  addressing[addrI] = tgtFaceIDs[addressing[addrI]];
998  }
999  }
1000 
1001  forAll(tgtAddress_, i)
1002  {
1003  labelList& addressing = tgtAddress_[i];
1004  forAll(addressing, addrI)
1005  {
1006  addressing[addrI] = globalSrcFaces.toGlobal(addressing[addrI]);
1007  }
1008  }
1009 
1010  // send data back to originating procs. Note that contributions
1011  // from different processors get added (ListAppendEqOp)
1012 
1013  mapDistribute::distribute
1014  (
1015  Pstream::nonBlocking,
1016  List<labelPair>(),
1017  tgtPatch.size(),
1018  map.constructMap(),
1019  map.subMap(),
1020  tgtAddress_,
1022  labelList()
1023  );
1024 
1025  mapDistribute::distribute
1026  (
1027  Pstream::nonBlocking,
1028  List<labelPair>(),
1029  tgtPatch.size(),
1030  map.constructMap(),
1031  map.subMap(),
1032  tgtWeights_,
1034  scalarList()
1035  );
1036 
1037  // weights normalisation
1038  normaliseWeights
1039  (
1040  srcMagSf_,
1041  "source",
1042  srcAddress_,
1043  srcWeights_,
1044  srcWeightsSum_,
1045  AMIPtr->conformal(),
1046  true,
1047  lowWeightCorrection_
1048  );
1049  normaliseWeights
1050  (
1051  tgtMagSf_,
1052  "target",
1053  tgtAddress_,
1054  tgtWeights_,
1055  tgtWeightsSum_,
1056  AMIPtr->conformal(),
1057  true,
1058  lowWeightCorrection_
1059  );
1060 
1061  // cache maps and reset addresses
1062  List<Map<label> > cMap;
1063  srcMapPtr_.reset(new mapDistribute(globalSrcFaces, tgtAddress_, cMap));
1064  tgtMapPtr_.reset(new mapDistribute(globalTgtFaces, srcAddress_, cMap));
1065 
1066  if (debug)
1067  {
1068  writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_);
1069  }
1070  }
1071  else
1072  {
1073  // calculate AMI interpolation
1075  (
1077  (
1078  methodName_,
1079  srcPatch,
1080  tgtPatch,
1081  srcMagSf_,
1082  tgtMagSf_,
1083  triMode_,
1084  reverseTarget_,
1085  requireMatch_
1086  )
1087  );
1088 
1089  AMIPtr->calculate
1090  (
1091  srcAddress_,
1092  srcWeights_,
1093  tgtAddress_,
1094  tgtWeights_
1095  );
1096 
1097  normaliseWeights
1098  (
1099  srcMagSf_,
1100  "source",
1101  srcAddress_,
1102  srcWeights_,
1103  srcWeightsSum_,
1104  AMIPtr->conformal(),
1105  true,
1106  lowWeightCorrection_
1107  );
1108  normaliseWeights
1109  (
1110  tgtMagSf_,
1111  "target",
1112  tgtAddress_,
1113  tgtWeights_,
1114  tgtWeightsSum_,
1115  AMIPtr->conformal(),
1116  true,
1117  lowWeightCorrection_
1118  );
1119  }
1120 
1121  if (debug)
1122  {
1123  Info<< "AMIInterpolation : Constructed addressing and weights" << nl
1124  << " triMode :"
1125  << faceAreaIntersect::triangulationModeNames_[triMode_] << nl
1126  << " singlePatchProc:" << singlePatchProc_ << nl
1127  << " srcMagSf :" << gSum(srcMagSf_) << nl
1128  << " tgtMagSf :" << gSum(tgtMagSf_) << nl
1129  << endl;
1130  }
1131 }
1132 
1133 
1134 template<class SourcePatch, class TargetPatch>
1135 template<class Type, class CombineOp>
1138  const UList<Type>& fld,
1139  const CombineOp& cop,
1140  List<Type>& result,
1141  const UList<Type>& defaultValues
1142 ) const
1143 {
1144  if (fld.size() != srcAddress_.size())
1145  {
1146  FatalErrorIn
1147  (
1148  "AMIInterpolation::interpolateToTarget"
1149  "("
1150  "const UList<Type>&, "
1151  "const CombineOp&, "
1152  "List<Type>&, "
1153  "const UList<Type>&"
1154  ") const"
1155  ) << "Supplied field size is not equal to source patch size" << nl
1156  << " source patch = " << srcAddress_.size() << nl
1157  << " target patch = " << tgtAddress_.size() << nl
1158  << " supplied field = " << fld.size()
1159  << abort(FatalError);
1160  }
1161 
1162  if (lowWeightCorrection_ > 0)
1163  {
1164  if (defaultValues.size() != tgtAddress_.size())
1165  {
1166  FatalErrorIn
1167  (
1168  "AMIInterpolation::interpolateToTarget"
1169  "("
1170  "const UList<Type>&, "
1171  "const CombineOp&, "
1172  "List<Type>&, "
1173  "const UList<Type>&"
1174  ") const"
1175  ) << "Employing default values when sum of weights falls below "
1176  << lowWeightCorrection_
1177  << " but supplied default field size is not equal to target "
1178  << "patch size" << nl
1179  << " default values = " << defaultValues.size() << nl
1180  << " target patch = " << tgtAddress_.size() << nl
1181  << abort(FatalError);
1182  }
1183  }
1184 
1185  result.setSize(tgtAddress_.size());
1186 
1187  if (singlePatchProc_ == -1)
1188  {
1189  const mapDistribute& map = srcMapPtr_();
1190 
1191  List<Type> work(fld);
1192  map.distribute(work);
1193 
1194  forAll(result, faceI)
1195  {
1196  if (tgtWeightsSum_[faceI] < lowWeightCorrection_)
1197  {
1198  result[faceI] = defaultValues[faceI];
1199  }
1200  else
1201  {
1202  const labelList& faces = tgtAddress_[faceI];
1203  const scalarList& weights = tgtWeights_[faceI];
1204 
1205  forAll(faces, i)
1206  {
1207  cop(result[faceI], faceI, work[faces[i]], weights[i]);
1208  }
1209  }
1210  }
1211  }
1212  else
1213  {
1214  forAll(result, faceI)
1215  {
1216  if (tgtWeightsSum_[faceI] < lowWeightCorrection_)
1217  {
1218  result[faceI] = defaultValues[faceI];
1219  }
1220  else
1221  {
1222  const labelList& faces = tgtAddress_[faceI];
1223  const scalarList& weights = tgtWeights_[faceI];
1224 
1225  forAll(faces, i)
1226  {
1227  cop(result[faceI], faceI, fld[faces[i]], weights[i]);
1228  }
1229  }
1230  }
1231  }
1232 }
1233 
1234 
1235 template<class SourcePatch, class TargetPatch>
1236 template<class Type, class CombineOp>
1239  const UList<Type>& fld,
1240  const CombineOp& cop,
1241  List<Type>& result,
1242  const UList<Type>& defaultValues
1243 ) const
1244 {
1245  if (fld.size() != tgtAddress_.size())
1246  {
1247  FatalErrorIn
1248  (
1249  "AMIInterpolation::interpolateToSource"
1250  "("
1251  "const UList<Type>&, "
1252  "const CombineOp&, "
1253  "List<Type>&, "
1254  "const UList<Type>&"
1255  ") const"
1256  ) << "Supplied field size is not equal to target patch size" << nl
1257  << " source patch = " << srcAddress_.size() << nl
1258  << " target patch = " << tgtAddress_.size() << nl
1259  << " supplied field = " << fld.size()
1260  << abort(FatalError);
1261  }
1262 
1263  if (lowWeightCorrection_ > 0)
1264  {
1265  if (defaultValues.size() != srcAddress_.size())
1266  {
1267  FatalErrorIn
1268  (
1269  "AMIInterpolation::interpolateToSource"
1270  "("
1271  "const UList<Type>&, "
1272  "const CombineOp&, "
1273  "List<Type>&, "
1274  "const UList<Type>&"
1275  ") const"
1276  ) << "Employing default values when sum of weights falls below "
1277  << lowWeightCorrection_
1278  << " but supplied default field size is not equal to target "
1279  << "patch size" << nl
1280  << " default values = " << defaultValues.size() << nl
1281  << " source patch = " << srcAddress_.size() << nl
1282  << abort(FatalError);
1283  }
1284  }
1285 
1286  result.setSize(srcAddress_.size());
1287 
1288  if (singlePatchProc_ == -1)
1289  {
1290  const mapDistribute& map = tgtMapPtr_();
1291 
1292  List<Type> work(fld);
1293  map.distribute(work);
1294 
1295  forAll(result, faceI)
1296  {
1297  if (srcWeightsSum_[faceI] < lowWeightCorrection_)
1298  {
1299  result[faceI] = defaultValues[faceI];
1300  }
1301  else
1302  {
1303  const labelList& faces = srcAddress_[faceI];
1304  const scalarList& weights = srcWeights_[faceI];
1305 
1306  forAll(faces, i)
1307  {
1308  cop(result[faceI], faceI, work[faces[i]], weights[i]);
1309  }
1310  }
1311  }
1312  }
1313  else
1314  {
1315  forAll(result, faceI)
1316  {
1317  if (srcWeightsSum_[faceI] < lowWeightCorrection_)
1318  {
1319  result[faceI] = defaultValues[faceI];
1320  }
1321  else
1322  {
1323  const labelList& faces = srcAddress_[faceI];
1324  const scalarList& weights = srcWeights_[faceI];
1325 
1326  forAll(faces, i)
1327  {
1328  cop(result[faceI], faceI, fld[faces[i]], weights[i]);
1329  }
1330  }
1331  }
1332  }
1333 }
1334 
1335 
1336 template<class SourcePatch, class TargetPatch>
1337 template<class Type, class CombineOp>
1341  const Field<Type>& fld,
1342  const CombineOp& cop,
1343  const UList<Type>& defaultValues
1344 ) const
1345 {
1346  tmp<Field<Type> > tresult
1347  (
1348  new Field<Type>
1349  (
1350  srcAddress_.size(),
1352  )
1353  );
1354 
1355  interpolateToSource
1356  (
1357  fld,
1359  tresult(),
1360  defaultValues
1361  );
1362 
1363  return tresult;
1364 }
1365 
1366 
1367 template<class SourcePatch, class TargetPatch>
1368 template<class Type, class CombineOp>
1372  const tmp<Field<Type> >& tFld,
1373  const CombineOp& cop,
1374  const UList<Type>& defaultValues
1375 ) const
1376 {
1377  return interpolateToSource(tFld(), cop, defaultValues);
1378 }
1379 
1380 
1381 template<class SourcePatch, class TargetPatch>
1382 template<class Type, class CombineOp>
1386  const Field<Type>& fld,
1387  const CombineOp& cop,
1388  const UList<Type>& defaultValues
1389 ) const
1390 {
1391  tmp<Field<Type> > tresult
1392  (
1393  new Field<Type>
1394  (
1395  tgtAddress_.size(),
1397  )
1398  );
1399 
1400  interpolateToTarget
1401  (
1402  fld,
1404  tresult(),
1405  defaultValues
1406  );
1407 
1408  return tresult;
1409 }
1410 
1411 
1412 template<class SourcePatch, class TargetPatch>
1413 template<class Type, class CombineOp>
1417  const tmp<Field<Type> >& tFld,
1418  const CombineOp& cop,
1419  const UList<Type>& defaultValues
1420 ) const
1421 {
1422  return interpolateToTarget(tFld(), cop, defaultValues);
1423 }
1424 
1425 
1426 template<class SourcePatch, class TargetPatch>
1427 template<class Type>
1431  const Field<Type>& fld,
1432  const UList<Type>& defaultValues
1433 ) const
1434 {
1435  return interpolateToSource(fld, plusEqOp<Type>(), defaultValues);
1436 }
1437 
1438 
1439 template<class SourcePatch, class TargetPatch>
1440 template<class Type>
1444  const tmp<Field<Type> >& tFld,
1445  const UList<Type>& defaultValues
1446 ) const
1447 {
1448  return interpolateToSource(tFld(), plusEqOp<Type>(), defaultValues);
1449 }
1450 
1451 
1452 template<class SourcePatch, class TargetPatch>
1453 template<class Type>
1457  const Field<Type>& fld,
1458  const UList<Type>& defaultValues
1459 ) const
1460 {
1461  return interpolateToTarget(fld, plusEqOp<Type>(), defaultValues);
1462 }
1463 
1464 
1465 template<class SourcePatch, class TargetPatch>
1466 template<class Type>
1470  const tmp<Field<Type> >& tFld,
1471  const UList<Type>& defaultValues
1472 ) const
1473 {
1474  return interpolateToTarget(tFld(), plusEqOp<Type>(), defaultValues);
1475 }
1476 
1477 
1478 template<class SourcePatch, class TargetPatch>
1481  const SourcePatch& srcPatch,
1482  const TargetPatch& tgtPatch,
1483  const vector& n,
1484  const label tgtFaceI,
1485  point& tgtPoint
1486 )
1487 const
1488 {
1489  const pointField& srcPoints = srcPatch.points();
1490 
1491  // source face addresses that intersect target face tgtFaceI
1492  const labelList& addr = tgtAddress_[tgtFaceI];
1493 
1494  forAll(addr, i)
1495  {
1496  label srcFaceI = addr[i];
1497  const face& f = srcPatch[srcFaceI];
1498 
1499  pointHit ray = f.ray(tgtPoint, n, srcPoints);
1500 
1501  if (ray.hit())
1502  {
1503  tgtPoint = ray.rawPoint();
1504 
1505  return srcFaceI;
1506  }
1507  }
1508 
1509  // no hit registered - try with face normal instead of input normal
1510  forAll(addr, i)
1511  {
1512  label srcFaceI = addr[i];
1513  const face& f = srcPatch[srcFaceI];
1514 
1515  vector nFace(-srcPatch.faceNormals()[srcFaceI]);
1516  nFace += tgtPatch.faceNormals()[tgtFaceI];
1517 
1518  pointHit ray = f.ray(tgtPoint, nFace, srcPoints);
1519 
1520  if (ray.hit())
1521  {
1522  tgtPoint = ray.rawPoint();
1523 
1524  return srcFaceI;
1525  }
1526  }
1527 
1528  return -1;
1529 }
1530 
1531 
1532 template<class SourcePatch, class TargetPatch>
1535  const SourcePatch& srcPatch,
1536  const TargetPatch& tgtPatch,
1537  const vector& n,
1538  const label srcFaceI,
1539  point& srcPoint
1540 )
1541 const
1542 {
1543  const pointField& tgtPoints = tgtPatch.points();
1544 
1545  // target face addresses that intersect source face srcFaceI
1546  const labelList& addr = srcAddress_[srcFaceI];
1547 
1548  forAll(addr, i)
1549  {
1550  label tgtFaceI = addr[i];
1551  const face& f = tgtPatch[tgtFaceI];
1552 
1553  pointHit ray = f.ray(srcPoint, n, tgtPoints);
1554 
1555  if (ray.hit())
1556  {
1557  srcPoint = ray.rawPoint();
1558 
1559  return tgtFaceI;
1560  }
1561  }
1562 
1563  // no hit registered - try with face normal instead of input normal
1564  forAll(addr, i)
1565  {
1566  label tgtFaceI = addr[i];
1567  const face& f = tgtPatch[tgtFaceI];
1568 
1569  vector nFace(-srcPatch.faceNormals()[srcFaceI]);
1570  nFace += tgtPatch.faceNormals()[tgtFaceI];
1571 
1572  pointHit ray = f.ray(srcPoint, n, tgtPoints);
1573 
1574  if (ray.hit())
1575  {
1576  srcPoint = ray.rawPoint();
1577 
1578  return tgtFaceI;
1579  }
1580  }
1581 
1582  return -1;
1583 }
1584 
1585 
1586 template<class SourcePatch, class TargetPatch>
1589  const SourcePatch& srcPatch,
1590  const TargetPatch& tgtPatch,
1591  const labelListList& srcAddress
1592 )
1593 const
1594 {
1595  OFstream os("faceConnectivity" + Foam::name(Pstream::myProcNo()) + ".obj");
1596 
1597  label ptI = 1;
1598 
1599  forAll(srcAddress, i)
1600  {
1601  const labelList& addr = srcAddress[i];
1602  const point& srcPt = srcPatch.faceCentres()[i];
1603  forAll(addr, j)
1604  {
1605  label tgtPtI = addr[j];
1606  const point& tgtPt = tgtPatch.faceCentres()[tgtPtI];
1607 
1608  meshTools::writeOBJ(os, srcPt);
1609  meshTools::writeOBJ(os, tgtPt);
1610 
1611  os << "l " << ptI << " " << ptI + 1 << endl;
1612 
1613  ptI += 2;
1614  }
1615  }
1616 }
1617 
1618 
1619 // ************************************************************************* //
Input from memory buffer stream.
Definition: IStringStream.H:49
Output to file stream.
Definition: OFstream.H:81
const Point & rawPoint() const
Return point with no checking.
Definition: PointHit.H:158
const labelListList & subMap() const
From subsetted data back to original data.
pointHit ray(const point &p, const vector &n, const pointField &, const intersection::algorithm alg=intersection::FULL_RAY, const intersection::direction dir=intersection::VECTOR) const
Return potential intersection with face with a ray starting.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:53
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
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 ))
static void distribute(const Pstream::commsTypes commsType, const List< labelPair > &schedule, const label constructSize, const labelListList &subMap, const labelListList &constructMap, List< T > &, const int tag=UPstream::msgType())
Distribute data. Note:schedule only used for Pstream::scheduled.
Tuple2< scalar, label > nearInfo
Private class for finding nearest.
Base class of (analytical or triangulated) surface. Encapsulates all the search routines. WIP.
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
labelList f(nPoints)
Base class for Arbitrary Mesh Interface (AMI) methods.
Definition: AMIMethod.H:55
void reset(T *=0)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
Xfer< List< T > > xfer()
Transfer contents to the Xfer container.
Definition: ListI.H:90
const labelListList & constructMap() const
From subsetted data to new reconstructed data.
Class containing processor-to-processor mapping information.
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:221
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set).
Definition: autoPtrI.H:83
Helper class for list to append y onto the end of x.
Definition: ListOps.H:259
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
A class for handling words, derived from string.
Definition: word.H:59
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
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
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.
messageStream Info
bool hit() const
Is there a hit.
void update(const SourcePatch &srcPatch, const TargetPatch &tgtPatch)
Update addressing and weights.
const labelListList & tgtAddress() const
Return const access to target patch addressing.
const Point & hitPoint() const
Return hit point.
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.
Type gSum(const FieldField< Field, Type > &f)
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.
interpolationMethod
Enumeration specifying interpolation method.
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
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.
const scalarListList & tgtWeights() const
Return const access to target patch weights.
static const char nl
Definition: Ostream.H:260
void setSize(const label)
Reset size of List.
Definition: List.C:318
const scalarField & srcMagSf() const
Return const access to source patch face areas.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
~AMIInterpolation()
Destructor.
const labelListList & srcAddress() const
Return const access to source patch addressing.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
#define forAll(list, i)
Definition: UList.H:421
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
static const label labelMin
Definition: label.H:61
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Type gMin(const FieldField< Field, Type > &f)
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
Traits class for primitives.
Definition: pTraits.H:50
error FatalError
Type gAverage(const FieldField< Field, Type > &f)
List< label > labelList
A List of labels.
Definition: labelList.H:56
const scalarListList & srcWeights() const
Return const access to source patch weights.
bool hit() const
Is there a hit.
Definition: PointHit.H:120
static word interpolationMethodToWord(const interpolationMethod &method)
Convert interpolationMethod to word representation.
const scalarField & tgtMagSf() const
Return const access to target patch face areas.
A List obtained as a section of another List.
Definition: SubList.H:53
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:97
virtual void findNearest(const pointField &sample, const scalarField &nearestDistSqr, List< pointIndexHit > &) const =0
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
Definition: meshTools.C:209
static interpolationMethod wordTointerpolationMethod(const word &method)
Convert word to interpolationMethod.
volScalarField scalarField(fieldObject, mesh)
Type gMax(const FieldField< Field, Type > &f)
void writeFaceConnectivity(const SourcePatch &srcPatch, const TargetPatch &tgtPatch, const labelListList &srcAddress) const
Write face connectivity as OBJ file.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
A class for managing temporary objects.
Definition: PtrList.H:118
prefixOSstream Pout(cout,"Pout")
Definition: IOstreams.H:53
label constructSize() const
Constructed data size.