mappedPatchBase.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "mappedPatchBase.H"
31 #include "ListListOps.H"
32 #include "meshSearchMeshObject.H"
33 #include "meshTools.H"
34 #include "OFstream.H"
35 #include "Random.H"
36 #include "treeDataFace.H"
37 #include "treeDataPoint.H"
38 #include "indexedOctree.H"
39 #include "polyMesh.H"
40 #include "polyPatch.H"
41 #include "Time.H"
42 #include "mapDistribute.H"
43 #include "SubField.H"
44 #include "triPointRef.H"
45 #include "syncTools.H"
46 #include "treeDataCell.H"
47 #include "DynamicField.H"
48 #include "faceAreaWeightAMI.H"
49 #include "OTstream.H"
50 
51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
52 
53 namespace Foam
54 {
55  defineTypeNameAndDebug(mappedPatchBase, 0);
56 }
57 
58 
59 const Foam::Enum
60 <
62 >
64 ({
65  { sampleMode::NEARESTCELL, "nearestCell" },
66  { sampleMode::NEARESTPATCHFACE, "nearestPatchFace" },
67  { sampleMode::NEARESTPATCHFACEAMI, "nearestPatchFaceAMI" },
68  { sampleMode::NEARESTPATCHPOINT, "nearestPatchPoint" },
69  { sampleMode::NEARESTFACE, "nearestFace" },
70  { sampleMode::NEARESTONLYCELL, "nearestOnlyCell" },
71 });
72 
73 
74 const Foam::Enum
75 <
77 >
79 ({
80  { offsetMode::UNIFORM, "uniform" },
81  { offsetMode::NONUNIFORM, "nonuniform" },
82  { offsetMode::NORMAL, "normal" },
83 });
84 
85 
86 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
87 
89 (
90  const dictionary& dict
91 )
92 {
93  autoPtr<fileName> dbNamePtr_;
94 
95  if (dict.found("sampleDatabase"))
96  {
97  const bool useDb = dict.get<bool>("sampleDatabase");
98  if (useDb)
99  {
100  dbNamePtr_.set
101  (
102  new fileName
103  (
104  dict.lookupOrDefault<fileName>
105  (
106  "sampleDatabasePath",
107  fileName::null
108  )
109  )
110  );
111  }
112  }
113  else if (dict.found("sampleDatabasePath"))
114  {
115  dbNamePtr_.set(new fileName(dict.get<fileName>("sampleDatabasePath")));
116  }
117 
118  return dbNamePtr_;
119 }
120 
121 
123 (
124  const word& sampleWorld
125 )
126 {
127  // Start off with local world
128  label comm = UPstream::worldComm;
129 
130  if (!sampleWorld.empty() && Pstream::parRun())
131  {
132  if (!UPstream::allWorlds().found(sampleWorld))
133  {
134  FatalErrorInFunction << "Cannot find sampleWorld " << sampleWorld
135  << " in set of worlds " << UPstream::allWorlds()
136  << exit(FatalError);
137  }
138 
139  const labelList& worldIDs = UPstream::worldIDs();
140 
141  DynamicList<label> subRanks(worldIDs.size());
142  forAll(worldIDs, proci)
143  {
144  const label worldi = worldIDs[proci];
145  if
146  (
147  worldi == UPstream::myWorldID()
148  || UPstream::allWorlds()[worldi] == sampleWorld
149  )
150  {
151  subRanks.append(proci);
152  }
153  }
154 
155  // Allocate new communicator with parent 0 (= world)
156  comm = UPstream::allocateCommunicator(0, subRanks, true);
157 
158  if (debug)
159  {
160  Pout<< "mappedPatchBase::communicator :"
161  << " myWorld:" << UPstream::myWorld()
162  << " sampleWorld:" << sampleWorld
163  << " using subRanks:" << subRanks
164  << " new comm:" << comm << endl;
165  }
166  }
167 
168  return comm;
169 }
170 
171 
173 (
174  const polyPatch& pp
175 ) const
176 {
177  const polyMesh& mesh = pp.boundaryMesh().mesh();
178 
179  // Force construction of min-tet decomp
180  (void)mesh.tetBasePtIs();
181 
182  // Initialise to face-centre
183  tmp<pointField> tfacePoints(new pointField(patch_.size()));
184  pointField& facePoints = tfacePoints.ref();
185 
186  forAll(pp, facei)
187  {
188  facePoints[facei] = facePoint
189  (
190  mesh,
191  pp.start()+facei,
192  polyMesh::FACE_DIAG_TRIS
193  ).rawPoint();
194  }
195 
196  return tfacePoints;
197 }
198 
199 
201 (
202  const label mySampleWorld, // Wanted world
203  const pointField& facePoints,
204  pointField& samples, // All samples
205  labelList& patchFaceWorlds, // Per sample: wanted world
206  labelList& patchFaceProcs, // Per sample: originating processor
207  labelList& patchFaces, // Per sample: originating patchFace index
208  pointField& patchFc // Per sample: originating centre
209 ) const
210 {
211  const label oldComm(Pstream::warnComm);
212  Pstream::warnComm = comm_;
213 
214  const label myRank = Pstream::myProcNo(comm_);
215  const label nProcs = Pstream::nProcs(comm_);
216 
217  // Collect all sample points and the faces they come from.
218  {
219  List<pointField> globalFc(nProcs);
220  globalFc[myRank] = facePoints;
221  Pstream::gatherList(globalFc, Pstream::msgType(), comm_);
222  Pstream::scatterList(globalFc, Pstream::msgType(), comm_);
223  // Rework into straight list
224  patchFc = ListListOps::combine<pointField>
225  (
226  globalFc,
228  );
229  }
230 
231  {
232  List<pointField> globalSamples(nProcs);
233  globalSamples[myRank] = samplePoints(facePoints);
234  Pstream::gatherList(globalSamples, Pstream::msgType(), comm_);
235  Pstream::scatterList(globalSamples, Pstream::msgType(), comm_);
236  // Rework into straight list
237  samples = ListListOps::combine<pointField>
238  (
239  globalSamples,
241  );
242  }
243 
244  {
245  labelListList globalFaces(nProcs);
246  globalFaces[myRank] = identity(patch_.size());
247  // Distribute to all processors
248  Pstream::gatherList(globalFaces, Pstream::msgType(), comm_);
249  Pstream::scatterList(globalFaces, Pstream::msgType(), comm_);
250 
251  patchFaces = ListListOps::combine<labelList>
252  (
253  globalFaces,
255  );
256  }
257 
258  {
259  labelList procToWorldIndex(nProcs);
260  procToWorldIndex[myRank] = mySampleWorld;
261  Pstream::gatherList(procToWorldIndex, Pstream::msgType(), comm_);
262  Pstream::scatterList(procToWorldIndex, Pstream::msgType(), comm_);
263 
264  labelList nPerProc(nProcs);
265  nPerProc[myRank] = patch_.size();
266  Pstream::gatherList(nPerProc, Pstream::msgType(), comm_);
267  Pstream::scatterList(nPerProc, Pstream::msgType(), comm_);
268 
269  patchFaceWorlds.setSize(patchFaces.size());
270  patchFaceProcs.setSize(patchFaces.size());
271 
272  label sampleI = 0;
273  forAll(nPerProc, proci)
274  {
275  for (label i = 0; i < nPerProc[proci]; i++)
276  {
277  patchFaceWorlds[sampleI] = procToWorldIndex[proci];
278  patchFaceProcs[sampleI] = proci;
279  sampleI++;
280  }
281  }
282  }
283  Pstream::warnComm = oldComm;
284 }
285 
286 
288 (
289  const sampleMode mode,
290 
291  const label mySampleWorld, // local world to sample == my own world
292  const word& sampleRegion, // local region to sample
293  const word& samplePatch, // local patch to sample
294 
295  const pointField& samples,
296  List<nearInfoWorld>& nearest
297 ) const
298 {
299  // Find the local cell containing the samples
300 
301  const label myRank = Pstream::myProcNo(comm_);
302 
303  // Lookup the correct region
304  const polyMesh& mesh = lookupMesh(sampleRegion);
305 
306  // All the info for nearest. Construct to miss
307  nearest.setSize(samples.size());
308  nearInfoWorld miss;
309  {
310  miss.first().second() = Tuple2<scalar, label>(Foam::sqr(GREAT), -1);
311  miss.second() = -1; // set world to be ignored
312  }
313  nearest = miss;
314 
315  switch (mode)
316  {
317  case NEARESTCELL:
318  {
319  if (samplePatch.size() && samplePatch != "none")
320  {
322  << "No need to supply a patch name when in "
323  << sampleModeNames_[mode] << " mode." << exit(FatalError);
324  }
325 
326  //- Note: face-diagonal decomposition
327  const indexedOctree<Foam::treeDataCell>& tree = mesh.cellTree();
328 
329  forAll(samples, sampleI)
330  {
331  const point& sample = samples[sampleI];
332  nearInfoWorld& near = nearest[sampleI];
333 
334  label celli = tree.findInside(sample);
335 
336  if (celli == -1)
337  {
338  near.first().second().first() = Foam::sqr(GREAT);
339  near.first().second().second() = myRank;
340  near.second() = mySampleWorld;
341  }
342  else
343  {
344  const point& cc = mesh.cellCentres()[celli];
345 
346  near.first().first() = pointIndexHit
347  (
348  true,
349  cc,
350  celli
351  );
352  near.first().second().first() = magSqr(cc-sample);
353  near.first().second().second() = myRank;
354  near.second() = mySampleWorld;
355  }
356  }
357  break;
358  }
359 
360  case NEARESTONLYCELL:
361  {
362  if (samplePatch.size() && samplePatch != "none")
363  {
365  << "No need to supply a patch name when in "
366  << sampleModeNames_[mode] << " mode." << exit(FatalError);
367  }
368 
369  //- Note: face-diagonal decomposition
370  const indexedOctree<Foam::treeDataCell>& tree = mesh.cellTree();
371 
372  forAll(samples, sampleI)
373  {
374  const point& sample = samples[sampleI];
375  nearInfoWorld& near = nearest[sampleI];
376 
377  near.first().first() = tree.findNearest(sample, sqr(GREAT));
378  near.first().second().first() = magSqr
379  (
380  near.first().first().hitPoint()
381  -sample
382  );
383  near.first().second().second() = myRank;
384  near.second() = mySampleWorld;
385  }
386  break;
387  }
388 
389  case NEARESTPATCHFACE:
390  {
391  Random rndGen(123456);
392 
393  const polyPatch& pp = lookupPatch(sampleRegion, samplePatch);
394 
395  if (pp.empty())
396  {
397  forAll(samples, sampleI)
398  {
399  nearInfoWorld& near = nearest[sampleI];
400  near.first().second().first() = Foam::sqr(GREAT);
401  near.first().second().second() = myRank;
402  near.second() = mySampleWorld;
403  }
404  }
405  else
406  {
407  treeBoundBox patchBb
408  (
409  treeBoundBox(pp.points(), pp.meshPoints()).extend
410  (
411  rndGen,
412  1e-4
413  )
414  );
415  patchBb.min() -= point::uniform(ROOTVSMALL);
416  patchBb.max() += point::uniform(ROOTVSMALL);
417 
418  indexedOctree<treeDataFace> boundaryTree
419  (
420  treeDataFace // all information needed to search faces
421  (
422  false, // do not cache bb
423  mesh,
424  identity(pp.range()) // boundary faces only
425  ),
426  patchBb, // overall search domain
427  8, // maxLevel
428  10, // leafsize
429  3.0 // duplicity
430  );
431 
432  forAll(samples, sampleI)
433  {
434  const point& sample = samples[sampleI];
435 
436  nearInfoWorld& near = nearest[sampleI];
437  pointIndexHit& nearInfo = near.first().first();
438  nearInfo = boundaryTree.findNearest
439  (
440  sample,
441  magSqr(patchBb.span())
442  );
443 
444  if (!nearInfo.hit())
445  {
446  near.first().second().first() = Foam::sqr(GREAT);
447  near.first().second().second() = myRank;
448  near.second() = mySampleWorld;
449  }
450  else
451  {
452  point fc(pp[nearInfo.index()].centre(pp.points()));
453  nearInfo.setPoint(fc);
454  near.first().second().first() = magSqr(fc-sample);
455  near.first().second().second() = myRank;
456  near.second() = mySampleWorld;
457  }
458  }
459  }
460  break;
461  }
462 
463  case NEARESTPATCHPOINT:
464  {
465  Random rndGen(123456);
466 
467  const polyPatch& pp = lookupPatch(sampleRegion, samplePatch);
468 
469  if (pp.empty())
470  {
471  forAll(samples, sampleI)
472  {
473  nearInfoWorld& near = nearest[sampleI];
474  near.first().second().first() = Foam::sqr(GREAT);
475  near.first().second().second() = myRank;
476  near.second() = mySampleWorld;
477  }
478  }
479  else
480  {
481  // patch (local) points
482  treeBoundBox patchBb
483  (
484  treeBoundBox(pp.points(), pp.meshPoints()).extend
485  (
486  rndGen,
487  1e-4
488  )
489  );
490  patchBb.min() -= point::uniform(ROOTVSMALL);
491  patchBb.max() += point::uniform(ROOTVSMALL);
492 
493  indexedOctree<treeDataPoint> boundaryTree
494  (
495  treeDataPoint // all information needed to search faces
496  (
497  mesh.points(),
498  pp.meshPoints() // selection of points to search on
499  ),
500  patchBb, // overall search domain
501  8, // maxLevel
502  10, // leafsize
503  3.0 // duplicity
504  );
505 
506  forAll(samples, sampleI)
507  {
508  const point& sample = samples[sampleI];
509 
510  nearInfoWorld& near = nearest[sampleI];
511  pointIndexHit& nearInfo = near.first().first();
512  nearInfo = boundaryTree.findNearest
513  (
514  sample,
515  magSqr(patchBb.span())
516  );
517 
518  if (!nearInfo.hit())
519  {
520  near.first().second().first() = Foam::sqr(GREAT);
521  near.first().second().second() = myRank;
522  near.second() = mySampleWorld;
523  }
524  else
525  {
526  const point& pt = nearInfo.hitPoint();
527 
528  near.first().second().first() = magSqr(pt-sample);
529  near.first().second().second() = myRank;
530  near.second() = mySampleWorld;
531  }
532  }
533  }
534  break;
535  }
536 
537  case NEARESTFACE:
538  {
539  if (samplePatch.size() && samplePatch != "none")
540  {
542  << "No need to supply a patch name when in "
543  << sampleModeNames_[mode] << " mode." << exit(FatalError);
544  }
545 
546  //- Note: face-diagonal decomposition
547  const meshSearchMeshObject& meshSearchEngine =
549 
550  forAll(samples, sampleI)
551  {
552  const point& sample = samples[sampleI];
553  nearInfoWorld& near = nearest[sampleI];
554 
555  label facei = meshSearchEngine.findNearestFace(sample);
556 
557  if (facei == -1)
558  {
559  near.first().second().first() = Foam::sqr(GREAT);
560  near.first().second().second() = myRank;
561  near.second() = mySampleWorld;
562  }
563  else
564  {
565  const point& fc = mesh.faceCentres()[facei];
566 
567  near.first().first() = pointIndexHit(true, fc, facei);
568  near.first().second().first() = magSqr(fc-sample);
569  near.first().second().second() = myRank;
570  near.second() = mySampleWorld;
571  }
572  }
573  break;
574  }
575 
576  case NEARESTPATCHFACEAMI:
577  {
578  // nothing to do here
579  return;
580  }
581 
582  default:
583  {
585  << "problem." << abort(FatalError);
586  }
587  }
588 }
589 
590 
592 (
593  const sampleMode mode,
594  const label myWorld,
595  const pointField& samples,
596  const labelList& wantedWorlds,
597  const labelList& origProcs,
598 
599  labelList& sampleProcs,
600  labelList& sampleIndices,
601  pointField& sampleLocations
602 ) const
603 {
604  // Find the processor/cell containing the samples. Does not account
605  // for samples being found in two processors.
606 
607 
608  const label myRank = Pstream::myProcNo(comm_);
609  const label nProcs = Pstream::nProcs(comm_);
610 
611  wordList samplePatches(nProcs);
612  {
613  const label oldComm(Pstream::warnComm);
614  Pstream::warnComm = comm_;
615  samplePatches[myRank] = samplePatch_;
616  Pstream::gatherList(samplePatches, Pstream::msgType(), comm_);
617  Pstream::scatterList(samplePatches, Pstream::msgType(), comm_);
618  Pstream::warnComm = oldComm;
619  }
620  wordList sampleRegions(nProcs);
621  {
622  const label oldComm(Pstream::warnComm);
623  Pstream::warnComm = comm_;
624  sampleRegions[myRank] = sampleRegion_;
625  Pstream::gatherList(sampleRegions, Pstream::msgType(), comm_);
626  Pstream::scatterList(sampleRegions, Pstream::msgType(), comm_);
627  Pstream::warnComm = oldComm;
628  }
629 
630  // Find all the info for nearest
631  List<nearInfoWorld> nearest(samples.size());
632  forAll(nearest, samplei)
633  {
634  nearest[samplei].first() = nearInfo
635  (
636  pointIndexHit(),
637  Tuple2<scalar, label>(Foam::sqr(GREAT), -1)
638  );
639  nearest[samplei].second() = wantedWorlds[samplei];
640  }
641 
642 
643  // Extract samples to search for locally
644  {
645  DynamicList<label> localMap(samples.size());
646  forAll(wantedWorlds, samplei)
647  {
648  if (wantedWorlds[samplei] == myWorld)
649  {
650  localMap.append(samplei);
651  }
652  }
653 
654  if (localMap.size())
655  {
656  pointField localSamples(samples, localMap);
657  labelList localOrigProcs(origProcs, localMap);
658 
659  //Assume single patch to sample for now
660  const word localOrigPatch(samplePatches[localOrigProcs[0]]);
661  const word localOrigRegion(sampleRegions[localOrigProcs[0]]);
662  List<nearInfoWorld> localNearest(localSamples.size());
663 
664  if (debug)
665  {
666  Pout<< "Searching locally for " << localSamples.size()
667  << " samples on region:" << localOrigRegion
668  << " on patch:" << localOrigPatch << endl;
669  }
670  findLocalSamples
671  (
672  mode,
673  myWorld,
674  localOrigRegion,
675  localOrigPatch,
676  localSamples,
677  localNearest
678  );
679  UIndirectList<nearInfoWorld>(nearest, localMap) = localNearest;
680  }
681  }
682 
683  const label oldComm(Pstream::warnComm);
684  Pstream::warnComm = comm_;
685 
686  // Find nearest. Combine on master.
687  Pstream::listCombineGather
688  (
689  nearest,
691  Pstream::msgType(),
692  comm_
693  );
694  Pstream::listCombineScatter(nearest, Pstream::msgType(), comm_);
695 
696  //if (debug)
697  //{
698  // Pout<< "** AFter combining:" << endl;
699  // forAll(nearest, samplei)
700  // {
701  // Pout<< " sample:" << samples[samplei]
702  // << " origating from proc:" << origProcs[samplei]
703  // << " to be found on world:" << wantedWorlds[samplei] << nl
704  // << " found on world:" << nearest[samplei].second() << nl
705  // << " found on proc:"
706  // << nearest[samplei].first().second().second() << nl
707  // << " found on patchfacei:"
708  // << nearest[samplei].first().first().index() << nl
709  // << " found at location:"
710  // << nearest[samplei].first().first().rawPoint() << nl;
711  // }
712  // Pout<< endl;
713  //}
714 
715  // Convert back into proc+local index
716  sampleProcs.setSize(samples.size());
717  sampleIndices.setSize(samples.size());
718  sampleLocations.setSize(samples.size());
719 
720  forAll(nearest, sampleI)
721  {
722  const nearInfo& ni = nearest[sampleI].first();
723 
724  if (!ni.first().hit())
725  {
726  sampleProcs[sampleI] = -1;
727  sampleIndices[sampleI] = -1;
728  sampleLocations[sampleI] = vector::max;
729  }
730  else
731  {
732  sampleProcs[sampleI] = ni.second().second();
733  sampleIndices[sampleI] = ni.first().index();
734  sampleLocations[sampleI] = ni.first().hitPoint();
735  }
736  }
737 
738  Pstream::warnComm = oldComm;
739 }
740 
741 
743 {
744  static bool hasWarned = false;
745  if (mapPtr_)
746  {
748  << "Mapping already calculated" << exit(FatalError);
749  }
750 
752  //if (sampleDatabase() && !sameWorld())
753  //{
754  // const word syncName("syncObjects");
755  // const polyMesh& mesh = patch_.boundaryMesh().mesh();
756  // const Time& runTime = mesh.time();
757  // const functionObjectList& fos = runTime.functionObjects();
758  //
759  // forAll(fos, i)
760  // {
761  // Pout<< "** FO:" << fos[i].name() << " tpye:" << fos[i].type()
762  // << endl;
763  // }
764  //
765  // if (fos.findObjectID(syncName) == -1)
766  // {
767  // //FatalErrorInFunction
768  // WarningInFunction
769  // << "Did not detect functionObject " << syncName
770  // << ". This is used to synchronise data inbetween worlds"
771  // << endl;
772  // }
773  //}
774 
775 
776  // Get points on face (since cannot use face-centres - might be off
777  // face-diagonal decomposed tets.
778  tmp<pointField> patchPoints(facePoints(patch_));
779 
780  // Get offsetted points
781  const pointField offsettedPoints(samplePoints(patchPoints()));
782 
783  // Do a sanity check - am I sampling my own patch?
784  // This only makes sense for a non-zero offset.
785  bool sampleMyself =
786  (
790  && samplePatch() == patch_.name()
791  );
792 
793  if (sampleMyself)
794  {
795  // Check offset
796  vectorField d(offsettedPoints-patchPoints());
797  bool coincident = (gAverage(mag(d)) <= ROOTVSMALL);
798 
799  if (sampleMyself && coincident)
800  {
802  << "Invalid offset " << d << endl
803  << "Offset is the vector added to the patch face centres to"
804  << " find the patch face supplying the data." << endl
805  << "Setting it to " << d
806  << " on the same patch, on the same region"
807  << " will find the faces themselves which does not make sense"
808  << " for anything but testing." << endl
809  << "patch_:" << patch_.name() << endl
810  << "sampleRegion_:" << sampleRegion() << endl
811  << "mode_:" << sampleModeNames_[mode_] << endl
812  << "samplePatch_:" << samplePatch() << endl
813  << "offsetMode_:" << offsetModeNames_[offsetMode_] << endl;
814  }
815  }
816 
817  // Get local world and world-to-sample in index form
818  const label myWorld = Pstream::myWorldID();
819  const label mySampleWorld = Pstream::allWorlds().find(sampleWorld_);
820 
821 
822  // Get global list of all samples and the processor and face they come from.
823  pointField samples; // coordinates
824  labelList patchFaceWorlds; // world to sample
825  labelList patchFaceProcs; // originating processor
826  labelList patchFaces; // originating face on processor patch
827  pointField patchFc; // originating face centre
829  (
830  mySampleWorld, // world I want to sample
831  patchPoints,
832 
833  samples,
834  patchFaceWorlds,
835  patchFaceProcs,
836  patchFaces,
837  patchFc
838  );
839 
840  //if (debug)
841  //{
842  // forAll(samples, samplei)
843  // {
844  // Pout<< " sample:" << samples[samplei]
845  // << " origating from proc:" << patchFaceProcs[samplei]
846  // << " face:" << patchFaces[samplei]
847  // << " to be found on world:" << patchFaceWorlds[samplei] << nl;
848  // }
849  //}
850 
851  // Find processor and cell/face samples are in and actual location.
852  labelList sampleProcs;
853  labelList sampleIndices;
854  pointField sampleLocations;
856  (
857  mode_,
858  myWorld, // my world (in index form)
859  samples,
860  patchFaceWorlds,
861  patchFaceProcs,
862 
863  sampleProcs,
864  sampleIndices,
865  sampleLocations
866  );
867 
868  // Check for samples that were not found. This will only happen for
869  // NEARESTCELL since finds cell containing a location
870  if (mode_ == NEARESTCELL)
871  {
872  label nNotFound = 0;
873  forAll(sampleProcs, sampleI)
874  {
875  if (sampleProcs[sampleI] == -1)
876  {
877  nNotFound++;
878  }
879  }
880  reduce(nNotFound, sumOp<label>(), Pstream::msgType(), comm_);
881 
882  if (nNotFound > 0)
883  {
884  if (!hasWarned)
885  {
887  << "Did not find " << nNotFound
888  << " out of " << sampleProcs.size() << " total samples."
889  << " Sampling these on owner cell centre instead." << endl
890  << "On patch " << patch_.name()
891  << " on region " << sampleRegion()
892  << " in mode " << sampleModeNames_[mode_] << endl
893  << "with offset mode " << offsetModeNames_[offsetMode_]
894  << ". Suppressing further warnings from " << type() << endl;
895 
896  hasWarned = true;
897  }
898 
899  // Collect the samples that cannot be found
900  DynamicList<label> subMap;
901  forAll(sampleProcs, sampleI)
902  {
903  if (sampleProcs[sampleI] == -1)
904  {
905  subMap.append(sampleI);
906  }
907  }
908 
909  // And re-search for pure nearest (should not fail)
910  labelList subSampleProcs;
911  labelList subSampleIndices;
912  pointField subSampleLocations;
914  (
916  myWorld, // my world (in index form)
917 
918  pointField(samples, subMap),
919  UIndirectList<label>(patchFaceWorlds, subMap)(),
920  UIndirectList<label>(patchFaceProcs, subMap)(),
921 
922  subSampleProcs,
923  subSampleIndices,
924  subSampleLocations
925  );
926 
927  // Insert
928  labelUIndList(sampleProcs, subMap) = subSampleProcs;
929  labelUIndList(sampleIndices, subMap) = subSampleIndices;
930  UIndirectList<point>(sampleLocations, subMap) = subSampleLocations;
931  }
932  }
933 
934  // Now we have all the data we need:
935  // - where sample originates from (so destination when mapping):
936  // patchFaces, patchFaceProcs.
937  // - cell/face sample is in (so source when mapping)
938  // sampleIndices, sampleProcs.
939 
940  if (Pstream::master(comm_))
941  {
942  forAll(samples, i)
943  {
944  if (sampleProcs[i] == -1)
945  {
946  FatalErrorInFunction << "did not find sample "
947  << patchFc[i] << " on patch " << patch_.name()
948  << " on region "
949  << patch_.boundaryMesh().mesh().name()
950  << " on processor " << patchFaceProcs[i]
951  << exit(FatalError);
952  }
953  }
954  }
955 
956 
957  if (debug && Pstream::master(comm_))
958  {
959  //forAll(samples, i)
960  //{
961  // Pout<< i << " need data in region "
962  // << patch_.boundaryMesh().mesh().name()
963  // << " for proc:" << patchFaceProcs[i]
964  // << " face:" << patchFaces[i]
965  // << " at:" << patchFc[i] << endl
966  // << "Found data in region " << sampleRegion()
967  // << " at proc:" << sampleProcs[i]
968  // << " face:" << sampleIndices[i]
969  // << " at:" << sampleLocations[i]
970  // << nl << endl;
971  //}
972 
973  OFstream str
974  (
976  / patch_.name()
977  + "_mapped.obj"
978  );
979  Pout<< "Dumping mapping as lines from patch faceCentres to"
980  << " sampled cell/faceCentres/points to file " << str.name()
981  << endl;
982 
983  label vertI = 0;
984 
985  forAll(patchFc, i)
986  {
987  meshTools::writeOBJ(str, patchFc[i]);
988  vertI++;
989  meshTools::writeOBJ(str, sampleLocations[i]);
990  vertI++;
991  str << "l " << vertI-1 << ' ' << vertI << nl;
992  }
993  }
994 
995  // Determine schedule.
996  mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs, comm_));
997 
998  // Rework the schedule from indices into samples to cell data to send,
999  // face data to receive.
1000 
1001  labelListList& subMap = mapPtr_().subMap();
1002  labelListList& constructMap = mapPtr_().constructMap();
1003 
1004  forAll(subMap, proci)
1005  {
1006  subMap[proci] = labelUIndList(sampleIndices, subMap[proci]);
1007  constructMap[proci] = labelUIndList(patchFaces, constructMap[proci]);
1008 
1009  if (debug)
1010  {
1011  Pout<< "To proc:" << proci << " sending values of cells/faces:"
1012  << subMap[proci] << endl;
1013  Pout<< "From proc:" << proci
1014  << " receiving values of patch faces:"
1015  << constructMap[proci] << endl;
1016  }
1017  }
1018 
1019 
1020  // Redo constructSize
1021  mapPtr_().constructSize() = patch_.size();
1022 
1023  if (debug)
1024  {
1025  // Check that all elements get a value.
1026  bitSet used(patch_.size());
1027  forAll(constructMap, proci)
1028  {
1029  const labelList& map = constructMap[proci];
1030 
1031  forAll(map, i)
1032  {
1033  label facei = map[i];
1034 
1035  if (used.test(facei))
1036  {
1038  << "On patch " << patch_.name()
1039  << " patchface " << facei
1040  << " is assigned to more than once."
1041  << abort(FatalError);
1042  }
1043  else
1044  {
1045  used.set(facei);
1046  }
1047  }
1048  }
1049  forAll(used, facei)
1050  {
1051  if (!used.test(facei))
1052  {
1054  << "On patch " << patch_.name()
1055  << " patchface " << facei
1056  << " is never assigned to."
1057  << abort(FatalError);
1058  }
1059  }
1060  }
1061 }
1062 
1063 
1065 const
1066 {
1067  const word surfType(surfDict_.getOrDefault<word>("type", "none"));
1068 
1069  if (!surfPtr_ && surfType != "none")
1070  {
1071  word surfName(surfDict_.getOrDefault("name", patch_.name()));
1072 
1073  const polyMesh& mesh = patch_.boundaryMesh().mesh();
1074 
1075  surfPtr_ =
1077  (
1078  surfType,
1079  IOobject
1080  (
1081  surfName,
1082  mesh.time().constant(),
1083  "triSurface",
1084  mesh,
1087  ),
1088  surfDict_
1089  );
1090  }
1091 
1092  return surfPtr_;
1093 }
1094 
1095 
1097 {
1098  if (AMIPtr_->upToDate())
1099  {
1101  << "AMI already up-to-date"
1102  << endl;
1103 
1104  return;
1105  }
1106 
1107  // Check if running locally
1108  if (sampleWorld_.empty())
1109  {
1110  const polyPatch& nbr = samplePolyPatch();
1111 
1112  // Transform neighbour patch to local system
1113  pointField nbrPoints(samplePoints(nbr.localPoints()));
1114 
1115  primitivePatch nbrPatch0
1116  (
1118  (
1119  nbr.localFaces(),
1120  nbr.size()
1121  ),
1122  nbrPoints
1123  );
1124 
1125 
1126  if (debug)
1127  {
1128  OFstream os(patch_.name() + "_neighbourPatch-org.obj");
1129  meshTools::writeOBJ(os, samplePolyPatch().localFaces(), nbrPoints);
1130 
1131  OFstream osN(patch_.name() + "_neighbourPatch-trans.obj");
1132  meshTools::writeOBJ(osN, nbrPatch0, nbrPoints);
1133 
1134  OFstream osO(patch_.name() + "_ownerPatch.obj");
1135  meshTools::writeOBJ(osO, patch_.localFaces(), patch_.localPoints());
1136  }
1137 
1138  // Construct/apply AMI interpolation to determine addressing and weights
1139  AMIPtr_->calculate(patch_, nbrPatch0, surfPtr());
1140  }
1141  else
1142  {
1143  faceList nbrFaces;
1144  pointField nbrPoints;
1145  if (sampleWorld() == UPstream::myWorld())
1146  {
1147  const polyPatch& nbr = samplePolyPatch();
1148  nbrFaces = nbr.localFaces();
1149  nbrPoints = samplePoints(nbr.localPoints());
1150  }
1151  else
1152  {
1153  // Leave empty
1154  }
1155 
1156  primitivePatch nbrPatch0
1157  (
1159  (
1160  nbrFaces,
1161  nbrFaces.size()
1162  ),
1163  nbrPoints
1164  );
1165 
1166  // Change to use ALL processors communicator
1167  const label oldWorldComm = Pstream::worldComm;
1168  Pstream::worldComm = comm_;
1169 
1170  const label oldComm(Pstream::warnComm);
1172 
1173  // Construct/apply AMI interpolation to determine addressing and weights
1174  AMIPtr_->calculate(patch_, nbrPatch0, surfPtr());
1175 
1176  Pstream::warnComm = oldComm;
1177  Pstream::worldComm = oldWorldComm;
1178  }
1179 }
1180 
1181 
1184  const objectRegistry& obr,
1185  const wordList& names,
1186  const label index
1187 )
1188 {
1189  const objectRegistry& sub = obr.subRegistry(names[index], true);
1190  if (index == names.size()-1)
1191  {
1192  return sub;
1193  }
1194  else
1195  {
1196  return subRegistry(sub, names, index+1);
1197  }
1198 }
1199 
1200 
1201 // * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
1202 
1204 :
1205  patch_(pp),
1206  sampleWorld_(word::null),
1207  sampleRegion_(patch_.boundaryMesh().mesh().name()),
1208  mode_(NEARESTPATCHFACE),
1209  samplePatch_(word::null),
1210  coupleGroup_(),
1211  sampleDatabasePtr_(),
1212  offsetMode_(UNIFORM),
1213  offset_(Zero),
1214  offsets_(pp.size(), offset_),
1215  distance_(0),
1216  comm_(communicator(sampleWorld_)),
1217  sameRegion_
1218  (
1219  sampleWorld_.empty()
1220  && sampleRegion_ == patch_.boundaryMesh().mesh().name()
1221  ),
1222  mapPtr_(nullptr),
1223  AMIReverse_(false),
1224  AMIPtr_(new faceAreaWeightAMI(true, AMIReverse_)),
1225  surfPtr_(nullptr),
1226  surfDict_(fileName("surface"))
1227 {}
1228 
1229 
1232  const polyPatch& pp,
1233  const word& sampleRegion,
1234  const sampleMode mode,
1235  const word& samplePatch,
1236  const vectorField& offsets
1237 )
1238 :
1239  patch_(pp),
1240  sampleWorld_(word::null),
1241  sampleRegion_(sampleRegion),
1242  mode_(mode),
1243  samplePatch_(samplePatch),
1244  coupleGroup_(),
1245  sampleDatabasePtr_(),
1246  offsetMode_(NONUNIFORM),
1247  offset_(Zero),
1248  offsets_(offsets),
1249  distance_(0),
1250  comm_(communicator(sampleWorld_)),
1251  sameRegion_
1252  (
1253  sampleWorld_.empty()
1254  && sampleRegion_ == patch_.boundaryMesh().mesh().name()
1255  ),
1256  mapPtr_(nullptr),
1257  AMIReverse_(false),
1258  AMIPtr_(new faceAreaWeightAMI(true, AMIReverse_)),
1259  surfPtr_(nullptr),
1260  surfDict_(fileName("surface"))
1261 {}
1262 
1263 
1266  const polyPatch& pp,
1267  const word& sampleRegion,
1268  const sampleMode mode,
1269  const word& samplePatch,
1270  const vector& offset
1271 )
1272 :
1273  patch_(pp),
1274  sampleWorld_(word::null),
1275  sampleRegion_(sampleRegion),
1276  mode_(mode),
1277  samplePatch_(samplePatch),
1278  coupleGroup_(),
1279  sampleDatabasePtr_(),
1280  offsetMode_(UNIFORM),
1281  offset_(offset),
1282  offsets_(0),
1283  distance_(0),
1284  comm_(communicator(sampleWorld_)),
1285  sameRegion_
1286  (
1287  sampleWorld_.empty()
1288  && sampleRegion_ == patch_.boundaryMesh().mesh().name()
1289  ),
1290  mapPtr_(nullptr),
1291  AMIReverse_(false),
1292  AMIPtr_(new faceAreaWeightAMI(true, AMIReverse_)),
1293  surfPtr_(nullptr),
1294  surfDict_(fileName("surface"))
1295 {}
1296 
1297 
1300  const polyPatch& pp,
1301  const word& sampleRegion,
1302  const sampleMode mode,
1303  const word& samplePatch,
1304  const scalar distance
1305 )
1306 :
1307  patch_(pp),
1308  sampleWorld_(word::null),
1309  sampleRegion_(sampleRegion),
1310  mode_(mode),
1311  samplePatch_(samplePatch),
1312  coupleGroup_(),
1313  sampleDatabasePtr_(),
1314  offsetMode_(NORMAL),
1315  offset_(Zero),
1316  offsets_(0),
1317  distance_(distance),
1318  comm_(communicator(sampleWorld_)),
1319  sameRegion_
1320  (
1321  sampleWorld_.empty()
1322  && sampleRegion_ == patch_.boundaryMesh().mesh().name()
1323  ),
1324  mapPtr_(nullptr),
1325  AMIReverse_(false),
1326  AMIPtr_(new faceAreaWeightAMI(true, AMIReverse_)),
1327  surfPtr_(nullptr),
1328  surfDict_(fileName("surface"))
1329 {}
1330 
1331 
1334  const polyPatch& pp,
1335  const dictionary& dict
1336 )
1337 :
1338  patch_(pp),
1339  sampleWorld_(dict.getOrDefault<word>("sampleWorld", word::null)),
1340  sampleRegion_(dict.getOrDefault<word>("sampleRegion", word::null)),
1341  mode_(sampleModeNames_.get("sampleMode", dict)),
1342  samplePatch_(dict.getOrDefault<word>("samplePatch", word::null)),
1343  coupleGroup_(dict),
1344  sampleDatabasePtr_(readDatabase(dict)),
1345  offsetMode_(UNIFORM),
1346  offset_(Zero),
1347  offsets_(0),
1348  distance_(0.0),
1349  comm_(communicator(sampleWorld_)),
1350  sameRegion_
1351  (
1352  sampleWorld_.empty()
1353  && sampleRegion_ == patch_.boundaryMesh().mesh().name()
1354  ),
1355  mapPtr_(nullptr),
1356  AMIReverse_(dict.getOrDefault("flipNormals", false)),
1357  AMIPtr_
1358  (
1360  (
1361  dict.getOrDefault("AMIMethod", faceAreaWeightAMI::typeName),
1362  dict,
1363  AMIReverse_
1364  )
1365  ),
1366  surfPtr_(nullptr),
1367  surfDict_(dict.subOrEmptyDict("surface"))
1368 {
1369  if (!coupleGroup_.valid())
1370  {
1371  if (sampleWorld_.empty() && sampleRegion_.empty())
1372  {
1373  // If no coupleGroup and no sampleRegion assume local region
1374  sampleRegion_ = patch_.boundaryMesh().mesh().name();
1375  sameRegion_ = true;
1376  }
1377  }
1378 
1379  if (offsetModeNames_.readIfPresent("offsetMode", dict, offsetMode_))
1380  {
1381  switch (offsetMode_)
1382  {
1383  case UNIFORM:
1384  {
1385  dict.readEntry("offset", offset_);
1386  }
1387  break;
1388 
1389  case NONUNIFORM:
1390  {
1391  offsets_ = pointField("offsets", dict, patch_.size());
1392  }
1393  break;
1394 
1395  case NORMAL:
1396  {
1397  dict.readEntry("distance", distance_);
1398  }
1399  break;
1400  }
1401  }
1402  else if (dict.readIfPresent("offset", offset_))
1403  {
1404  offsetMode_ = UNIFORM;
1405  }
1406  else if (dict.found("offsets"))
1407  {
1408  offsetMode_ = NONUNIFORM;
1409  offsets_ = pointField("offsets", dict, patch_.size());
1410  }
1411  else if (mode_ != NEARESTPATCHFACE && mode_ != NEARESTPATCHFACEAMI)
1412  {
1414  << "Please supply the offsetMode as one of "
1415  << offsetModeNames_
1416  << exit(FatalIOError);
1417  }
1418 }
1419 
1420 
1423  const polyPatch& pp,
1424  const sampleMode mode,
1425  const dictionary& dict
1426 )
1427 :
1428  patch_(pp),
1429  sampleWorld_(dict.getOrDefault<word>("sampleWorld", word::null)),
1430  sampleRegion_(dict.getOrDefault<word>("sampleRegion", word::null)),
1431  mode_(mode),
1432  samplePatch_(dict.getOrDefault<word>("samplePatch", word::null)),
1433  coupleGroup_(dict), //dict.getOrDefault<word>("coupleGroup", word::null)),
1434  sampleDatabasePtr_(readDatabase(dict)),
1435  offsetMode_(UNIFORM),
1436  offset_(Zero),
1437  offsets_(0),
1438  distance_(0.0),
1439  comm_(communicator(sampleWorld_)),
1440  sameRegion_
1441  (
1442  sampleWorld_.empty()
1443  && sampleRegion_ == patch_.boundaryMesh().mesh().name()
1444  ),
1445  mapPtr_(nullptr),
1446  AMIReverse_(dict.getOrDefault("flipNormals", false)),
1447  AMIPtr_
1448  (
1450  (
1451  dict.getOrDefault("AMIMethod", faceAreaWeightAMI::typeName),
1452  dict,
1453  AMIReverse_
1454  )
1455  ),
1456  surfPtr_(nullptr),
1457  surfDict_(dict.subOrEmptyDict("surface"))
1458 {
1459  if (mode != NEARESTPATCHFACE && mode != NEARESTPATCHFACEAMI)
1460  {
1462  << "Construct from sampleMode and dictionary only applicable for "
1463  << " collocated patches in modes "
1464  << sampleModeNames_[NEARESTPATCHFACE] << ','
1465  << sampleModeNames_[NEARESTPATCHFACEAMI]
1466  << exit(FatalIOError);
1467  }
1468 
1469 
1470  if (!coupleGroup_.valid())
1471  {
1472  if (sampleWorld_.empty() && sampleRegion_.empty())
1473  {
1474  // If no coupleGroup and no sampleRegion assume local region
1475  sampleRegion_ = patch_.boundaryMesh().mesh().name();
1476  sameRegion_ = true;
1477  }
1478  }
1479 }
1480 
1481 
1484  const polyPatch& pp,
1485  const mappedPatchBase& mpb
1486 )
1487 :
1488  patch_(pp),
1489  sampleWorld_(mpb.sampleWorld_),
1490  sampleRegion_(mpb.sampleRegion_),
1491  mode_(mpb.mode_),
1492  samplePatch_(mpb.samplePatch_),
1493  coupleGroup_(mpb.coupleGroup_),
1494  sampleDatabasePtr_
1495  (
1496  mpb.sampleDatabasePtr_
1497  ? new fileName(mpb.sampleDatabasePtr_())
1498  : nullptr
1499  ),
1500  offsetMode_(mpb.offsetMode_),
1501  offset_(mpb.offset_),
1502  offsets_(mpb.offsets_),
1503  distance_(mpb.distance_),
1504  comm_(mpb.comm_),
1505  sameRegion_(mpb.sameRegion_),
1506  mapPtr_(nullptr),
1507  AMIReverse_(mpb.AMIReverse_),
1508  AMIPtr_(mpb.AMIPtr_->clone()),
1509  surfPtr_(nullptr),
1510  surfDict_(mpb.surfDict_)
1511 {}
1512 
1513 
1516  const polyPatch& pp,
1517  const mappedPatchBase& mpb,
1518  const labelUList& mapAddressing
1519 )
1520 :
1521  patch_(pp),
1522  sampleWorld_(mpb.sampleWorld_),
1523  sampleRegion_(mpb.sampleRegion_),
1524  mode_(mpb.mode_),
1525  samplePatch_(mpb.samplePatch_),
1526  coupleGroup_(mpb.coupleGroup_),
1527  sampleDatabasePtr_
1528  (
1529  mpb.sampleDatabasePtr_
1530  ? new fileName(mpb.sampleDatabasePtr_())
1531  : nullptr
1532  ),
1533  offsetMode_(mpb.offsetMode_),
1534  offset_(mpb.offset_),
1535  offsets_
1536  (
1537  offsetMode_ == NONUNIFORM
1538  ? vectorField(mpb.offsets_, mapAddressing)
1539  : vectorField()
1540  ),
1541  distance_(mpb.distance_),
1542  comm_(mpb.comm_),
1543  sameRegion_(mpb.sameRegion_),
1544  mapPtr_(nullptr),
1545  AMIReverse_(mpb.AMIReverse_),
1546  AMIPtr_(mpb.AMIPtr_->clone()),
1547  surfPtr_(nullptr),
1548  surfDict_(mpb.surfDict_)
1549 {}
1550 
1551 
1552 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
1553 
1555 {
1556  clearOut();
1557 }
1558 
1559 
1561 {
1562  mapPtr_.clear();
1563  surfPtr_.clear();
1564  AMIPtr_->upToDate() = false;
1565 }
1566 
1567 
1568 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1569 
1572  const word& sampleRegion
1573 ) const
1574 {
1575  const polyMesh& thisMesh = patch_.boundaryMesh().mesh();
1576  return
1577  (
1578  sampleRegion.empty() || sampleRegion == thisMesh.name()
1579  ? thisMesh
1580  : thisMesh.time().lookupObject<polyMesh>(sampleRegion)
1581  );
1582 }
1583 
1584 
1587  const word& sampleRegion,
1588  const word& samplePatch
1589 ) const
1590 {
1591  const polyMesh& nbrMesh = lookupMesh(sampleRegion);
1592 
1593  const label patchi = nbrMesh.boundaryMesh().findPatchID(samplePatch);
1594 
1595  if (patchi == -1)
1596  {
1598  << "Cannot find patch " << samplePatch
1599  << " in region " << sampleRegion_ << endl
1600  << exit(FatalError);
1601  }
1602  return nbrMesh.boundaryMesh()[patchi];
1603 }
1604 
1605 
1607 {
1608  if (UPstream::myWorld() != sampleWorld_)
1609  {
1611  << "sampleWorld : " << sampleWorld_
1612  << " is not the current world : " << UPstream::myWorld()
1613  << exit(FatalError);
1614  }
1615  return lookupMesh(sampleRegion());
1616 }
1617 
1618 
1620 {
1621  const polyMesh& nbrMesh = sampleMesh();
1622 
1623  const label patchi = nbrMesh.boundaryMesh().findPatchID(samplePatch());
1624 
1625  if (patchi == -1)
1626  {
1628  << "Cannot find patch " << samplePatch()
1629  << " in region " << sampleRegion_ << endl
1630  << "Valid patches are " << nbrMesh.boundaryMesh().names()
1631  << exit(FatalError);
1632  }
1633 
1634  return nbrMesh.boundaryMesh()[patchi];
1635 }
1636 
1637 
1640  const pointField& fc
1641 ) const
1642 {
1643  tmp<pointField> tfld(new pointField(fc));
1644  pointField& fld = tfld.ref();
1645 
1646  switch (offsetMode_)
1647  {
1648  case UNIFORM:
1649  {
1650  fld += offset_;
1651  break;
1652  }
1653  case NONUNIFORM:
1654  {
1655  fld += offsets_;
1656  break;
1657  }
1658  case NORMAL:
1659  {
1660  // Get outwards pointing normal
1661  vectorField n(patch_.faceAreas());
1662  n /= mag(n);
1663 
1664  fld += distance_*n;
1665  break;
1666  }
1667  }
1668 
1669  return tfld;
1670 }
1671 
1672 
1674 {
1675  return samplePoints(facePoints(patch_));
1676 }
1677 
1678 
1681  const polyMesh& mesh,
1682  const label facei,
1683  const polyMesh::cellDecomposition decompMode
1684 )
1685 {
1686  const point& fc = mesh.faceCentres()[facei];
1687 
1688  switch (decompMode)
1689  {
1690  case polyMesh::FACE_PLANES:
1692  {
1693  // For both decompositions the face centre is guaranteed to be
1694  // on the face
1695  return pointIndexHit(true, fc, facei);
1696  }
1697  break;
1698 
1700  case polyMesh::CELL_TETS:
1701  {
1702  // Find the intersection of a ray from face centre to cell centre
1703  // Find intersection of (face-centre-decomposition) centre to
1704  // cell-centre with face-diagonal-decomposition triangles.
1705 
1706  const pointField& p = mesh.points();
1707  const face& f = mesh.faces()[facei];
1708 
1709  if (f.size() <= 3)
1710  {
1711  // Return centre of triangle.
1712  return pointIndexHit(true, fc, 0);
1713  }
1714 
1715  label celli = mesh.faceOwner()[facei];
1716  const point& cc = mesh.cellCentres()[celli];
1717  vector d = fc-cc;
1718 
1719  const label fp0 = mesh.tetBasePtIs()[facei];
1720  const point& basePoint = p[f[fp0]];
1721 
1722  label fp = f.fcIndex(fp0);
1723  for (label i = 2; i < f.size(); i++)
1724  {
1725  const point& thisPoint = p[f[fp]];
1726  label nextFp = f.fcIndex(fp);
1727  const point& nextPoint = p[f[nextFp]];
1728 
1729  const triPointRef tri(basePoint, thisPoint, nextPoint);
1730  pointHit hitInfo = tri.intersection
1731  (
1732  cc,
1733  d,
1735  );
1736 
1737  if (hitInfo.hit() && hitInfo.distance() > 0)
1738  {
1739  return pointIndexHit(true, hitInfo.hitPoint(), i-2);
1740  }
1741 
1742  fp = nextFp;
1743  }
1744 
1745  // Fall-back
1746  return pointIndexHit(false, fc, -1);
1747  }
1748  break;
1749 
1750  default:
1751  {
1753  << "problem" << abort(FatalError);
1754  return pointIndexHit();
1755  }
1756  }
1757 }
1758 
1759 
1762  const objectRegistry& obr,
1763  const fileName& rawFName
1764 )
1765 {
1766  // Lookup (and create if non existing) a registry using a '/' separated
1767  // path.
1768 
1769  const fileName fName(rawFName.clean());
1770  const wordList names(fName.components());
1771 
1772  if (names.empty())
1773  {
1774  return obr;
1775  }
1776  else
1777  {
1778  return subRegistry(obr, names, 0);
1779  }
1780 }
1781 
1782 
1785  const fileName& root,
1786  const label proci
1787 )
1788 {
1789  const word processorName("processor"+Foam::name(proci));
1790  return root/"send"/processorName;
1791 }
1792 
1793 
1795 {
1796  return sendPath(sampleDatabasePath(), proci);
1797 }
1798 
1799 
1802  const fileName& root,
1803  const label proci
1804 )
1805 {
1806  const word processorName("processor"+Foam::name(proci));
1807  return root/"receive"/processorName;
1808 }
1809 
1810 
1812 {
1813  return receivePath(sampleDatabasePath(), proci);
1814 }
1815 
1816 
1819  const objectRegistry& obr,
1820  dictionary& dict
1821 )
1822 {
1823  forAllIters(obr, iter)
1824  {
1825  regIOobject* objPtr = iter.val();
1826  const regIOobject& obj = *objPtr;
1827 
1828  if (isA<objectRegistry>(obj))
1829  {
1830  dictionary& d = dict.subDictOrAdd(obj.name());
1831  writeDict(dynamic_cast<const objectRegistry&>(obj), d);
1832  }
1833  else if
1834  (
1835  writeIOField<scalar>(obj, dict)
1836  || writeIOField<vector>(obj, dict)
1837  || writeIOField<sphericalTensor>(obj, dict)
1838  || writeIOField<symmTensor>(obj, dict)
1839  || writeIOField<tensor>(obj, dict)
1840  )
1841  {
1842  // IOField specialisation
1843  }
1844  else
1845  {
1846  // Not tested. No way of retrieving data anyway ...
1847  OTstream os;
1848  obj.writeData(os);
1849 
1850  primitiveEntry* pePtr = new primitiveEntry(obj.name(), os.tokens());
1851  dict.add(pePtr);
1852  }
1853  }
1854 }
1855 
1856 
1858 {
1859  // Reverse of writeDict - reads fields from dictionary into objectRegistry
1860  for (const entry& e : d)
1861  {
1862  if (e.isDict())
1863  {
1864  // Add sub registry
1865  objectRegistry& sub = const_cast<objectRegistry&>
1866  (
1867  obr.subRegistry(e.keyword(), true)
1868  );
1869 
1870  readDict(e.dict(), sub);
1871  }
1872  else
1873  {
1874  ITstream& is = e.stream();
1875  token tok(is);
1876 
1877  if
1878  (
1879  constructIOField<scalar>(e.keyword(), tok, is, obr)
1880  || constructIOField<vector>(e.keyword(), tok, is, obr)
1881  || constructIOField<sphericalTensor>(e.keyword(), tok, is, obr)
1882  || constructIOField<symmTensor>(e.keyword(), tok, is, obr)
1883  || constructIOField<tensor>(e.keyword(), tok, is, obr)
1884  )
1885  {
1886  // Done storing field
1887  }
1888  else
1889  {
1890  FatalErrorInFunction << "Unsupported type " << e.keyword()
1891  << exit(FatalError);
1892  }
1893  }
1894  }
1895 }
1896 
1897 
1899 {
1900  os.writeEntry("sampleMode", sampleModeNames_[mode_]);
1901  os.writeEntryIfDifferent<word>("sampleWorld", word::null, sampleWorld_);
1902  os.writeEntryIfDifferent<word>("sampleRegion", word::null, sampleRegion_);
1903  os.writeEntryIfDifferent<word>("samplePatch", word::null, samplePatch_);
1904 
1905  if (sampleDatabasePtr_)
1906  {
1907  os.writeEntry("sampleDatabase", sampleDatabasePtr_.valid());
1908  // Write database path if differing
1910  (
1911  "sampleDatabasePath",
1913  sampleDatabasePtr_()
1914  );
1915  }
1916  coupleGroup_.write(os);
1917 
1918  if
1919  (
1920  offsetMode_ == UNIFORM
1921  && offset_ == vector::zero
1922  && (mode_ == NEARESTPATCHFACE || mode_ == NEARESTPATCHFACEAMI)
1923  )
1924  {
1925  // Collocated mode. No need to write offset data
1926  }
1927  else
1928  {
1929  os.writeEntry("offsetMode", offsetModeNames_[offsetMode_]);
1930 
1931  switch (offsetMode_)
1932  {
1933  case UNIFORM:
1934  {
1935  os.writeEntry("offset", offset_);
1936  break;
1937  }
1938  case NONUNIFORM:
1939  {
1940  offsets_.writeEntry("offsets", os);
1941  break;
1942  }
1943  case NORMAL:
1944  {
1945  os.writeEntry("distance", distance_);
1946  break;
1947  }
1948  }
1949 
1950  if (mode_ == NEARESTPATCHFACEAMI)
1951  {
1952  if (AMIReverse_)
1953  {
1954  os.writeEntry("flipNormals", AMIReverse_);
1955  }
1956 
1957  if (!surfDict_.empty())
1958  {
1959  surfDict_.writeEntry(surfDict_.dictName(), os);
1960  }
1961  }
1962  }
1963 }
1964 
1965 
1966 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::UPstream::warnComm
static label warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:298
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::Random
Random number generator.
Definition: Random.H:59
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1069
Foam::Ostream::writeEntryIfDifferent
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
Definition: Ostream.H:244
Foam::mappedPatchBase::write
virtual void write(Ostream &) const
Write as a dictionary.
Definition: mappedPatchBase.C:1898
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
meshTools.H
Foam::mappedPatchBase::clearOut
void clearOut()
Definition: mappedPatchBase.C:1560
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::polyMesh::FACE_DIAG_TRIS
Definition: polyMesh.H:107
Foam::mappedPatchBase::sendPath
static fileName sendPath(const fileName &root, const label proci)
Helper: return path to store data to be sent to processor i.
Definition: mappedPatchBase.C:1784
Foam::mappedPatchBase::readDict
static void readDict(const dictionary &d, objectRegistry &obr)
(recursively) construct and register IOFields from dictionary
Definition: mappedPatchBase.C:1857
Foam::polyMesh::cellDecomposition
cellDecomposition
Enumeration defining the decomposition of the cell for.
Definition: polyMesh.H:100
Foam::accessOp
Definition: UList.H:614
Foam::mappedPatchBase::AMIReverse_
const bool AMIReverse_
Flag to indicate that slave patch should be reversed for AMI.
Definition: mappedPatchBase.H:282
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:70
Foam::primitiveEntry
A keyword and a list of tokens comprise a primitiveEntry. A primitiveEntry can be read,...
Definition: primitiveEntry.H:63
Foam::mappedPatchBase::subRegistry
static const objectRegistry & subRegistry(const objectRegistry &obr, const wordList &names, const label index)
Definition: mappedPatchBase.C:1183
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
SubField.H
Foam::intersection::HALF_RAY
Definition: intersection.H:75
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
polyPatch.H
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::PointHit
Describes the interaction of a face and a point. It carries the info of a successful hit and (if succ...
Definition: PointHit.H:53
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
meshSearchMeshObject.H
Foam::DynamicList< label >
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionary.C:364
Foam::mappedPatchBase::map
const mapDistribute & map() const
Return reference to the parallel distribution map.
Definition: mappedPatchBaseI.H:167
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:604
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
ListListOps.H
Foam::regIOobject::writeData
virtual bool writeData(Ostream &) const =0
Pure virtual writeData function.
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::mappedPatchBase::sampleWorld_
word sampleWorld_
World to sample.
Definition: mappedPatchBase.H:233
Foam::mappedPatchBase::samplePolyPatch
const polyPatch & samplePolyPatch() const
Get the patch on the region.
Definition: mappedPatchBase.C:1619
Foam::treeBoundBox
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:86
Foam::objectRegistry::time
const Time & time() const
Return time.
Definition: objectRegistry.H:186
indexedOctree.H
Foam::mappedPatchBase::mappedPatchBase
mappedPatchBase(const polyPatch &)
Construct from patch.
Definition: mappedPatchBase.C:1203
Foam::mappedPatchBase::lookupMesh
const polyMesh & lookupMesh(const word &region) const
Lookup mesh.
Definition: mappedPatchBase.C:1571
Foam::mappedPatchBase::offset_
vector offset_
Offset vector (uniform)
Definition: mappedPatchBase.H:254
Foam::mappedPatchBase::findLocalSamples
void findLocalSamples(const sampleMode mode, const label sampleWorld, const word &sampleRegion, const word &samplePatch, const pointField &samplePoints, List< nearInfoWorld > &nearest) const
Find (local) cells/faces containing samples.
Definition: mappedPatchBase.C:288
Foam::PointHit::distance
scalar distance() const noexcept
Return distance to hit.
Definition: PointHit.H:139
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:458
Foam::mappedPatchBase::mode_
const sampleMode mode_
What to sample.
Definition: mappedPatchBase.H:239
Foam::HashSet::test
bool test(const Key &key) const noexcept
Same as found() - return true if key exists in the set.
Definition: HashSet.H:170
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:182
Foam::PointHit::hitPoint
const point_type & hitPoint() const
Return the hit point. Fatal if not hit.
Definition: PointHit.H:145
Foam::mappedPatchBase::offsetModeNames_
static const Enum< offsetMode > offsetModeNames_
Definition: mappedPatchBase.H:140
Foam::FatalIOError
IOerror FatalIOError
Foam::mappedPatchBase::writeDict
static void writeDict(const objectRegistry &obr, dictionary &dict)
Convert objectRegistry contents into dictionary.
Definition: mappedPatchBase.C:1818
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::mappedPatchBase::findSamples
void findSamples(const sampleMode mode, const label myWorldIndex, const pointField &, const labelList &wantedWorlds, const labelList &origProcs, labelList &sampleProcs, labelList &sampleIndices, pointField &sampleLocations) const
Find (global) cells/faces containing samples.
Definition: mappedPatchBase.C:592
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::mappedPatchBase::samplePatch_
word samplePatch_
Patch (if in sampleMode NEARESTPATCH*)
Definition: mappedPatchBase.H:242
triPointRef.H
Foam::AMIInterpolation::New
static autoPtr< AMIInterpolation > New(const word &modelName, const dictionary &dict, const bool reverseTarget=false)
Selector for dictionary.
Definition: AMIInterpolationNew.C:33
Foam::mappedPatchBase
Determines a mapping between patch face centres and mesh cell or face centres and processors they're ...
Definition: mappedPatchBase.H:112
polyMesh.H
Foam::mappedPatchBase::NEARESTONLYCELL
nearest cell (even if not containing cell)
Definition: mappedPatchBase.H:127
syncTools.H
Foam::dictionary::subDictOrAdd
dictionary & subDictOrAdd(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary for manipulation.
Definition: dictionary.C:568
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::mappedPatchBase::coupleGroup_
const coupleGroupIdentifier coupleGroup_
PatchGroup (if in sampleMode NEARESTPATCH*)
Definition: mappedPatchBase.H:245
Foam::polyBoundaryMesh::names
wordList names() const
Return a list of patch names.
Definition: polyBoundaryMesh.C:593
Foam::boundBox::min
const point & min() const
Minimum describing the bounding box.
Definition: boundBoxI.H:91
Foam::sumOp
Definition: ops.H:213
Foam::mappedPatchBase::~mappedPatchBase
virtual ~mappedPatchBase()
Destructor.
Definition: mappedPatchBase.C:1554
Foam::treeDataPoint
Holds (reference to) pointField. Encapsulation of data needed for octree searches....
Definition: treeDataPoint.H:62
Foam::mappedPatchBase::sampleModeNames_
static const Enum< sampleMode > sampleModeNames_
Definition: mappedPatchBase.H:138
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::mappedPatchBase::surfPtr
const autoPtr< Foam::searchableSurface > & surfPtr() const
Return a pointer to the AMI projection surface.
Definition: mappedPatchBase.C:1064
OFstream.H
Foam::faceAreaWeightAMI
Face area weighted Arbitrary Mesh Interface (AMI) method.
Definition: faceAreaWeightAMI.H:51
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::meshSearchMeshObject
MeshObject wrapper around meshSearch(mesh).
Definition: meshSearchMeshObject.H:51
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
treeDataFace.H
Foam::facePoint
label facePoint(const int facei, const block &block, const label i, const label j)
Definition: blockMeshMergeTopological.C:212
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::mode
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
Definition: MSwindows.C:564
Foam::mappedPatchBase::mapPtr_
autoPtr< mapDistribute > mapPtr_
Communication schedule:
Definition: mappedPatchBase.H:276
Foam::mappedPatchBase::sampleRegion_
word sampleRegion_
Region to sample.
Definition: mappedPatchBase.H:236
Foam::mappedPatchBase::nearestWorldEqOp
Definition: mappedPatchBase.H:197
Foam::mappedPatchBase::samplePoints
tmp< pointField > samplePoints() const
Get the sample points.
Definition: mappedPatchBase.C:1673
Foam::triangle
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:61
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::mappedPatchBase::sampleMesh
const polyMesh & sampleMesh() const
Get the region mesh.
Definition: mappedPatchBase.C:1606
Foam::meshSearch::findNearestFace
label findNearestFace(const point &location, const label seedFacei=-1, const bool useTreeSearch=true) const
Definition: meshSearch.C:758
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::PointIndexHit
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:52
Foam::autoPtr::set
void set(T *p) noexcept
Deprecated(2018-02) Identical to reset().
Definition: autoPtr.H:280
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:228
Foam::UPstream::myWorldID
static label myWorldID()
My worldID.
Definition: UPstream.H:496
Foam::Field< vector >
treeDataPoint.H
Foam::polyPatch::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:307
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:55
Foam::polyMesh::FACE_CENTRE_TRIS
Definition: polyMesh.H:104
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:365
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::OSstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:107
Foam::polyPatch::range
labelRange range() const
Return start/size range of this patch.
Definition: polyPatch.H:319
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:474
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:163
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1107
Foam::indexedOctree< Foam::treeDataCell >
Foam::dictionary::readEntry
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
Definition: dictionaryTemplates.C:314
samples
scalarField samples(nIntervals, Zero)
Foam::polyBoundaryMesh::mesh
const polyMesh & mesh() const
Return the mesh reference.
Definition: polyBoundaryMesh.H:144
Foam::objectRegistry::lookupObject
const Type & lookupObject(const word &name, const bool recursive=false) const
Definition: objectRegistryTemplates.C:434
Foam::polyBoundaryMesh::findPatchID
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
Definition: polyBoundaryMesh.C:766
Foam::mappedPatchBase::comm_
label comm_
Communicator.
Definition: mappedPatchBase.H:263
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
fld
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputLagrangian.H:23
Foam::indexedOctree::findInside
label findInside(const point &) const
Find shape containing point. Only implemented for certain.
Definition: indexedOctree.C:2629
forAllIters
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:223
Foam::UPstream::myWorld
static const word & myWorld()
My world.
Definition: UPstream.H:502
Foam::mappedPatchBase::sampleWorld
const word & sampleWorld() const
World to sample.
Definition: mappedPatchBaseI.H:36
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::mappedPatchBase::offsets_
vectorField offsets_
Offset vector (nonuniform)
Definition: mappedPatchBase.H:257
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::PrimitivePatch::points
const Field< point_type > & points() const
Return reference to global points.
Definition: PrimitivePatch.H:305
Foam::mappedPatchBase::receivePath
static fileName receivePath(const fileName &root, const label proci)
Definition: mappedPatchBase.C:1801
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::mappedPatchBase::distance_
scalar distance_
Offset distance (normal)
Definition: mappedPatchBase.H:260
Foam::PrimitivePatch::localFaces
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
Definition: PrimitivePatch.C:297
Foam::mappedPatchBase::calcAMI
void calcAMI() const
Calculate AMI interpolator.
Definition: mappedPatchBase.C:1096
Foam::UPstream::allWorlds
static const wordList & allWorlds()
All worlds.
Definition: UPstream.H:484
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
treeDataCell.H
Foam::mappedPatchBase::collectSamples
void collectSamples(const label mySampleWorld, const pointField &facePoints, pointField &samples, labelList &patchFaceWorlds, labelList &patchFaceProcs, labelList &patchFaces, pointField &patchFc) const
Collect single list of samples and originating processor+face +.
Definition: mappedPatchBase.C:201
Foam::searchableSurface::New
static autoPtr< searchableSurface > New(const word &surfaceType, const IOobject &io, const dictionary &dict)
Return a reference to the selected searchableSurface.
Definition: searchableSurface.C:43
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:313
Foam::mappedPatchBase::sampleRegion
const word & sampleRegion() const
Region to sample.
Definition: mappedPatchBaseI.H:42
Foam::dictionary::subOrEmptyDict
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Definition: dictionary.C:608
Foam::distance
scalar distance(const vector &p1, const vector &p2)
Definition: curveTools.C:12
Random.H
Foam::fileName::null
static const fileName null
An empty fileName.
Definition: fileName.H:97
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::PrimitivePatch::localPoints
const Field< point_type > & localPoints() const
Return pointField of points in patch.
Definition: PrimitivePatch.C:339
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::mappedPatchBase::calcMapping
void calcMapping() const
Calculate mapping.
Definition: mappedPatchBase.C:742
Time.H
Foam::autoPtr< Foam::fileName >
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:71
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:84
Foam::polyMesh::CELL_TETS
Definition: polyMesh.H:109
Foam::UPstream::msgType
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:541
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
DynamicField.H
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
Foam::pointIndexHit
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
Definition: pointIndexHit.H:46
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::Time::path
fileName path() const
Return path.
Definition: Time.H:358
Foam::OTstream
A simple output token stream that can be used to build token lists. Always UNCOMPRESSED.
Definition: OTstream.H:56
mapDistribute.H
f
labelList f(nPoints)
Foam::objectRegistry::subRegistry
const objectRegistry & subRegistry(const word &name, const bool forceCreate=false, const bool recursive=false) const
Lookup and return a const sub-objectRegistry.
Definition: objectRegistry.C:191
faceAreaWeightAMI.H
Foam::mappedPatchBase::NEARESTPATCHFACE
nearest face on selected patch
Definition: mappedPatchBase.H:123
Foam::mappedPatchBase::sampleDatabasePtr_
const autoPtr< fileName > sampleDatabasePtr_
Empty or location of database.
Definition: mappedPatchBase.H:248
Foam::Vector< scalar >
Foam::UPstream::worldComm
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:295
Foam::List< label >
Foam::HashSetOps::used
labelHashSet used(const bitSet &select)
Convert a bitset to a labelHashSet of the indices used.
Definition: HashOps.C:35
Foam::OTstream::tokens
const DynamicList< token > & tokens() const
The tokens.
Definition: OTstream.H:113
Foam::treeDataFace
Encapsulation of data needed to search for faces.
Definition: treeDataFace.H:59
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::primitiveMesh::faceCentres
const vectorField & faceCentres() const
Definition: primitiveMeshFaceCentresAndAreas.C:77
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::UList< label >
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
Foam::mappedPatchBase::offsetMode_
offsetMode offsetMode_
How to obtain samples.
Definition: mappedPatchBase.H:251
Foam::mappedPatchBase::readDatabase
static autoPtr< fileName > readDatabase(const dictionary &dict)
Read optional database name from dictionary.
Definition: mappedPatchBase.C:89
Foam::triangle::intersection
pointHit intersection(const point &p, const vector &q, const intersection::algorithm alg, const scalar tol=0.0) const
Fast intersection with a ray.
Definition: triangleI.H:439
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:232
Foam::mappedPatchBase::NEARESTCELL
nearest cell containing sample
Definition: mappedPatchBase.H:122
Foam::Tuple2::second
const T2 & second() const noexcept
Return second.
Definition: Tuple2.H:130
Foam::mappedPatchBase::offsetMode
offsetMode
How to project face centres.
Definition: mappedPatchBase.H:131
Foam::fileName::clean
static bool clean(std::string &str)
Cleanup filename.
Definition: fileName.C:298
rndGen
Random rndGen
Definition: createFields.H:23
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:275
Foam::VectorSpace< Vector< Cmpt >, Cmpt, 3 >::zero
static const Vector< Cmpt > zero
Definition: VectorSpace.H:115
Foam::UIndirectList
A List with indirect addressing.
Definition: faMatrix.H:60
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:62
Foam::mappedPatchBase::facePoints
tmp< pointField > facePoints(const polyPatch &) const
Get the points from face-centre-decomposition face centres.
Definition: mappedPatchBase.C:173
Foam::polyMesh::FACE_PLANES
Definition: polyMesh.H:102
Foam::mappedPatchBase::surfDict_
dictionary surfDict_
Dictionary storing projection surface description.
Definition: mappedPatchBase.H:291
Foam::dictionary::add
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:708
Foam::mappedPatchBase::AMIPtr_
autoPtr< AMIPatchToPatchInterpolation > AMIPtr_
Pointer to AMI interpolator.
Definition: mappedPatchBase.H:285
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::mappedPatchBase::patch_
const polyPatch & patch_
Patch to sample.
Definition: mappedPatchBase.H:230
Foam::mappedPatchBase::sameRegion_
bool sameRegion_
Same region.
Definition: mappedPatchBase.H:266
Foam::Tuple2
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: Tuple2.H:57
Foam::mappedPatchBase::lookupPatch
const polyPatch & lookupPatch(const word &sampleRegion, const word &samplePatch) const
Lookup patch.
Definition: mappedPatchBase.C:1586
Foam::PrimitivePatch::meshPoints
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Definition: PrimitivePatch.C:310
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:88
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:122
OTstream.H
Foam::mappedPatchBase::facePoint
static pointIndexHit facePoint(const polyMesh &, const label facei, const polyMesh::cellDecomposition)
Get a point on the face given a face decomposition method:
Definition: mappedPatchBase.C:1680
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::patchIdentifier::name
const word & name() const
The patch name.
Definition: patchIdentifier.H:134
Foam::Tuple2::first
const T1 & first() const noexcept
Return first.
Definition: Tuple2.H:118
Foam::PointHit::hit
bool hit() const noexcept
Is there a hit.
Definition: PointHit.H:121
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303
Foam::mappedPatchBase::sampleMode
sampleMode
Mesh items to sample.
Definition: mappedPatchBase.H:120
Foam::mappedPatchBase::communicator
static label communicator(const word &sampleWorld)
Optionally allocate a world-local communicator.
Definition: mappedPatchBase.C:123
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417
Foam::HashSet::set
bool set(const Key &key)
Same as insert (no value to overwrite)
Definition: HashSet.H:187
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:85
Foam::IOobject::MUST_READ
Definition: IOobject.H:120
Foam::labelUIndList
UIndirectList< label > labelUIndList
UIndirectList of labels.
Definition: UIndirectList.H:58
mappedPatchBase.H
Foam::polyMesh::tetBasePtIs
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:892
Foam::mappedPatchBase::samplePatch
const word & samplePatch() const
Patch (only if NEARESTPATCHFACE)
Definition: mappedPatchBaseI.H:68