shellSurfaces.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-2015 OpenFOAM Foundation
9  Copyright (C) 2015-2018 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 "shellSurfaces.H"
30 #include "searchableSurface.H"
31 #include "boundBox.H"
32 #include "triSurfaceMesh.H"
33 #include "refinementSurfaces.H"
34 #include "searchableSurfaces.H"
35 #include "orientedSurface.H"
36 #include "pointIndexHit.H"
37 #include "volumeType.H"
38 
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 
41 const Foam::Enum
42 <
44 >
45 Foam::shellSurfaces::refineModeNames_
46 ({
47  { refineMode::INSIDE, "inside" },
48  { refineMode::OUTSIDE, "outside" },
49  { refineMode::DISTANCE, "distance" },
50 });
51 
52 
53 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
54 
55 void Foam::shellSurfaces::setAndCheckLevels
56 (
57  const label shellI,
58  const List<Tuple2<scalar, label>>& distLevels
59 )
60 {
61  const searchableSurface& shell = allGeometry_[shells_[shellI]];
62 
63  if (modes_[shellI] != DISTANCE && distLevels.size() != 1)
64  {
66  << "For refinement mode "
67  << refineModeNames_[modes_[shellI]]
68  << " specify only one distance+level."
69  << " (its distance gets discarded)"
70  << exit(FatalError);
71  }
72  // Extract information into separate distance and level
73  distances_[shellI].setSize(distLevels.size());
74  levels_[shellI].setSize(distLevels.size());
75 
76  forAll(distLevels, j)
77  {
78  distances_[shellI][j] = distLevels[j].first();
79  levels_[shellI][j] = distLevels[j].second();
80 
81  if (levels_[shellI][j] < -1)
82  {
84  << "Shell " << shell.name()
85  << " has illegal refinement level "
86  << levels_[shellI][j]
87  << exit(FatalError);
88  }
89 
90 
91  // Check in incremental order
92  if (j > 0)
93  {
94  if
95  (
96  (distances_[shellI][j] <= distances_[shellI][j-1])
97  || (levels_[shellI][j] > levels_[shellI][j-1])
98  )
99  {
101  << "For refinement mode "
102  << refineModeNames_[modes_[shellI]]
103  << " : Refinement should be specified in order"
104  << " of increasing distance"
105  << " (and decreasing refinement level)." << endl
106  << "Distance:" << distances_[shellI][j]
107  << " refinementLevel:" << levels_[shellI][j]
108  << exit(FatalError);
109  }
110  }
111  }
112 
113  if (modes_[shellI] == DISTANCE)
114  {
115  if (!dryRun_)
116  {
117  Info<< "Refinement level according to distance to "
118  << shell.name() << endl;
119  forAll(levels_[shellI], j)
120  {
121  Info<< " level " << levels_[shellI][j]
122  << " for all cells within " << distances_[shellI][j]
123  << " metre." << endl;
124  }
125  }
126  }
127  else
128  {
129  if (!shell.hasVolumeType())
130  {
132  << "Shell " << shell.name()
133  << " does not support testing for "
134  << refineModeNames_[modes_[shellI]] << endl
135  << "Probably it is not closed."
136  << exit(FatalError);
137  }
138 
139  if (!dryRun_)
140  {
141  if (modes_[shellI] == INSIDE)
142  {
143  Info<< "Refinement level " << levels_[shellI][0]
144  << " for all cells inside " << shell.name() << endl;
145  }
146  else
147  {
148  Info<< "Refinement level " << levels_[shellI][0]
149  << " for all cells outside " << shell.name() << endl;
150  }
151  }
152  }
153 }
154 
155 
156 void Foam::shellSurfaces::checkGapLevels
157 (
158  const dictionary& shellDict,
159  const label shellI,
160  const List<FixedList<label, 3>>& levels
161 )
162 {
163  const searchableSurface& shell = allGeometry_[shells_[shellI]];
164 
165  forAll(levels, regionI)
166  {
167  const FixedList<label, 3>& info = levels[regionI];
168 
169  if (info[2] > 0)
170  {
171  if (modes_[shellI] == DISTANCE)
172  {
173  FatalIOErrorInFunction(shellDict)
174  << "'gapLevel' specification cannot be used with mode "
175  << refineModeNames_[DISTANCE]
176  << " for shell " << shell.name()
177  << exit(FatalIOError);
178  }
179  }
180  }
181 
182  // Hardcode for region 0
183  if (levels[0][0] > 0)
184  {
185  Info<< "Refinement level up to " << levels[0][2]
186  << " for all cells in gaps for shell "
187  << shell.name() << endl;
188  }
189 }
190 
191 
192 
193 // Specifically orient triSurfaces using a calculated point outside.
194 // Done since quite often triSurfaces not of consistent orientation which
195 // is (currently) necessary for sideness calculation
196 void Foam::shellSurfaces::orient()
197 {
198  // Determine outside point.
199  boundBox overallBb = boundBox::invertedBox;
200 
201  bool hasSurface = false;
202 
203  forAll(shells_, shellI)
204  {
205  const searchableSurface& s = allGeometry_[shells_[shellI]];
206 
207  if (modes_[shellI] != DISTANCE && isA<triSurfaceMesh>(s))
208  {
209  const triSurfaceMesh& shell = refCast<const triSurfaceMesh>(s);
210 
211  if (shell.triSurface::size())
212  {
213  hasSurface = true;
214  // Assume surface is compact!
215  overallBb.add(shell.points());
216  }
217  }
218  }
219 
220  if (hasSurface)
221  {
222  const point outsidePt = overallBb.max() + overallBb.span();
223 
224  //Info<< "Using point " << outsidePt << " to orient shells" << endl;
225 
226  forAll(shells_, shellI)
227  {
228  const searchableSurface& s = allGeometry_[shells_[shellI]];
229 
230  if (modes_[shellI] != DISTANCE && isA<triSurfaceMesh>(s))
231  {
232  triSurfaceMesh& shell = const_cast<triSurfaceMesh&>
233  (
234  refCast<const triSurfaceMesh>(s)
235  );
236 
237  // Flip surface so outsidePt is outside.
238  bool anyFlipped = orientedSurface::orient
239  (
240  shell,
241  outsidePt,
242  true
243  );
244 
245  if (anyFlipped && !dryRun_)
246  {
247  // orientedSurface will have done a clearOut of the surface.
248  // we could do a clearout of the triSurfaceMeshes::trees()
249  // but these aren't affected by orientation
250  // (except for cached
251  // sideness which should not be set at this point.
252  // !!Should check!)
253 
254  Info<< "shellSurfaces : Flipped orientation of surface "
255  << s.name()
256  << " so point " << outsidePt << " is outside." << endl;
257  }
258  }
259  }
260  }
261 }
262 
263 
264 // Find maximum level of a shell.
265 void Foam::shellSurfaces::findHigherLevel
266 (
267  const pointField& pt,
268  const label shellI,
269  labelList& maxLevel
270 ) const
271 {
272  const labelList& levels = levels_[shellI];
273 
274  if (modes_[shellI] == DISTANCE)
275  {
276  // Distance mode.
277 
278  const scalarField& distances = distances_[shellI];
279 
280  // Collect all those points that have a current maxLevel less than
281  // (any of) the shell. Also collect the furthest distance allowable
282  // to any shell with a higher level.
283 
284  pointField candidates(pt.size());
285  labelList candidateMap(pt.size());
286  scalarField candidateDistSqr(pt.size());
287  label candidateI = 0;
288 
289  forAll(maxLevel, pointi)
290  {
291  forAllReverse(levels, levelI)
292  {
293  if (levels[levelI] > maxLevel[pointi])
294  {
295  candidates[candidateI] = pt[pointi];
296  candidateMap[candidateI] = pointi;
297  candidateDistSqr[candidateI] = sqr(distances[levelI]);
298  candidateI++;
299  break;
300  }
301  }
302  }
303  candidates.setSize(candidateI);
304  candidateMap.setSize(candidateI);
305  candidateDistSqr.setSize(candidateI);
306 
307  // Do the expensive nearest test only for the candidate points.
308  List<pointIndexHit> nearInfo;
309  allGeometry_[shells_[shellI]].findNearest
310  (
311  candidates,
312  candidateDistSqr,
313  nearInfo
314  );
315 
316  // Update maxLevel
317  forAll(nearInfo, i)
318  {
319  if (nearInfo[i].hit())
320  {
321  // Check which level it actually is in.
322  label minDistI = findLower
323  (
324  distances,
325  mag(nearInfo[i].hitPoint()-candidates[i])
326  );
327 
328  label pointi = candidateMap[i];
329 
330  // pt is inbetween shell[minDistI] and shell[minDistI+1]
331  maxLevel[pointi] = levels[minDistI+1];
332  }
333  }
334  }
335  else
336  {
337  // Inside/outside mode
338 
339  // Collect all those points that have a current maxLevel less than the
340  // shell.
341 
342  pointField candidates(pt.size());
343  labelList candidateMap(pt.size());
344  label candidateI = 0;
345 
346  forAll(maxLevel, pointi)
347  {
348  if (levels[0] > maxLevel[pointi])
349  {
350  candidates[candidateI] = pt[pointi];
351  candidateMap[candidateI] = pointi;
352  candidateI++;
353  }
354  }
355  candidates.setSize(candidateI);
356  candidateMap.setSize(candidateI);
357 
358  // Do the expensive nearest test only for the candidate points.
359  List<volumeType> volType;
360  allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
361 
362  forAll(volType, i)
363  {
364  label pointi = candidateMap[i];
365 
366  if
367  (
368  (
369  modes_[shellI] == INSIDE
370  && volType[i] == volumeType::INSIDE
371  )
372  || (
373  modes_[shellI] == OUTSIDE
374  && volType[i] == volumeType::OUTSIDE
375  )
376  )
377  {
378  maxLevel[pointi] = levels[0];
379  }
380  }
381  }
382 }
383 
384 
385 void Foam::shellSurfaces::findHigherGapLevel
386 (
387  const pointField& pt,
388  const labelList& ptLevel,
389  const label shellI,
390  labelList& gapShell,
391  List<FixedList<label, 3>>& gapInfo,
392  List<volumeType>& gapMode
393 ) const
394 {
395  //TBD: hardcoded for region 0 information
396  const FixedList<label, 3>& info = extendedGapLevel_[shellI][0];
397  volumeType mode = extendedGapMode_[shellI][0];
398 
399  if (info[2] == 0)
400  {
401  return;
402  }
403 
404 
405  // Collect all those points that have a current maxLevel less than the
406  // shell.
407 
408  labelList candidateMap(pt.size());
409  label candidateI = 0;
410 
411  forAll(ptLevel, pointI)
412  {
413  if (ptLevel[pointI] >= info[1] && ptLevel[pointI] < info[2])
414  {
415  candidateMap[candidateI++] = pointI;
416  }
417  }
418  candidateMap.setSize(candidateI);
419 
420  // Do the expensive nearest test only for the candidate points.
421  List<volumeType> volType;
422  allGeometry_[shells_[shellI]].getVolumeType
423  (
424  pointField(pt, candidateMap),
425  volType
426  );
427 
428  forAll(volType, i)
429  {
430  label pointI = candidateMap[i];
431 
432  bool isInside = (volType[i] == volumeType::INSIDE);
433 
434  if
435  (
436  (
437  (modes_[shellI] == INSIDE && isInside)
438  || (modes_[shellI] == OUTSIDE && !isInside)
439  )
440  && info[2] > gapInfo[pointI][2]
441  )
442  {
443  gapShell[pointI] = shellI;
444  gapInfo[pointI] = info;
445  gapMode[pointI] = mode;
446  }
447  }
448 }
449 
450 
451 void Foam::shellSurfaces::findLevel
452 (
453  const pointField& pt,
454  const label shellI,
455  labelList& minLevel,
456  labelList& shell
457 ) const
458 {
459  const labelList& levels = levels_[shellI];
460 
461  if (modes_[shellI] == DISTANCE)
462  {
463  // Distance mode.
464 
465  const scalarField& distances = distances_[shellI];
466 
467  // Collect all those points that have a current level equal/greater
468  // (any of) the shell. Also collect the furthest distance allowable
469  // to any shell with a higher level.
470 
471  pointField candidates(pt.size());
472  labelList candidateMap(pt.size());
473  scalarField candidateDistSqr(pt.size());
474  label candidateI = 0;
475 
476  forAll(shell, pointI)
477  {
478  if (shell[pointI] == -1)
479  {
480  forAllReverse(levels, levelI)
481  {
482  if (levels[levelI] <= minLevel[pointI])
483  {
484  candidates[candidateI] = pt[pointI];
485  candidateMap[candidateI] = pointI;
486  candidateDistSqr[candidateI] = sqr(distances[levelI]);
487  candidateI++;
488  break;
489  }
490  }
491  }
492  }
493  candidates.setSize(candidateI);
494  candidateMap.setSize(candidateI);
495  candidateDistSqr.setSize(candidateI);
496 
497  // Do the expensive nearest test only for the candidate points.
498  List<pointIndexHit> nearInfo;
499  allGeometry_[shells_[shellI]].findNearest
500  (
501  candidates,
502  candidateDistSqr,
503  nearInfo
504  );
505 
506  // Update maxLevel
507  forAll(nearInfo, i)
508  {
509  if (nearInfo[i].hit())
510  {
511  // Check which level it actually is in.
512  label minDistI = findLower
513  (
514  distances,
515  mag(nearInfo[i].hitPoint()-candidates[i])
516  );
517 
518  label pointI = candidateMap[i];
519 
520  // pt is inbetween shell[minDistI] and shell[minDistI+1]
521  shell[pointI] = shellI;
522  minLevel[pointI] = levels[minDistI+1];
523  }
524  }
525  }
526  else
527  {
528  // Inside/outside mode
529 
530  // Collect all those points that have a current maxLevel less than the
531  // shell.
532 
533  pointField candidates(pt.size());
534  labelList candidateMap(pt.size());
535  label candidateI = 0;
536 
537  forAll(shell, pointI)
538  {
539  if (shell[pointI] == -1 && levels[0] <= minLevel[pointI])
540  {
541  candidates[candidateI] = pt[pointI];
542  candidateMap[candidateI] = pointI;
543  candidateI++;
544  }
545  }
546  candidates.setSize(candidateI);
547  candidateMap.setSize(candidateI);
548 
549  // Do the expensive nearest test only for the candidate points.
550  List<volumeType> volType;
551  allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
552 
553  forAll(volType, i)
554  {
555  if
556  (
557  (
558  modes_[shellI] == INSIDE
559  && volType[i] == volumeType::INSIDE
560  )
561  || (
562  modes_[shellI] == OUTSIDE
563  && volType[i] == volumeType::OUTSIDE
564  )
565  )
566  {
567  label pointI = candidateMap[i];
568  shell[pointI] = shellI;
569  minLevel[pointI] = levels[0];
570  }
571  }
572  }
573 }
574 
575 
576 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
577 
579 (
580  const searchableSurfaces& allGeometry,
581  const dictionary& shellsDict,
582  const bool dryRun
583 )
584 :
585  allGeometry_(allGeometry),
586  dryRun_(dryRun)
587 {
588  // Wilcard specification : loop over all surfaces and try to find a match.
589 
590  // Count number of shells.
591  label shellI = 0;
592  for (const word& geomName : allGeometry_.names())
593  {
594  if (shellsDict.found(geomName))
595  {
596  ++shellI;
597  }
598  }
599 
600 
601  // Size lists
602  shells_.setSize(shellI);
603  modes_.setSize(shellI);
604  distances_.setSize(shellI);
605  levels_.setSize(shellI);
606  dirLevels_.setSize(shellI);
607  smoothDirection_.setSize(shellI);
608  nSmoothExpansion_.setSize(shellI);
609  nSmoothPosition_.setSize(shellI);
610 
611  extendedGapLevel_.setSize(shellI);
612  extendedGapMode_.setSize(shellI);
613 
614  FixedList<label, 3> nullGapLevel;
615  nullGapLevel[0] = 0;
616  nullGapLevel[1] = 0;
617  nullGapLevel[2] = 0;
618 
619 
620  wordHashSet unmatchedKeys(shellsDict.toc());
621  shellI = 0;
622 
623  forAll(allGeometry_.names(), geomI)
624  {
625  const word& geomName = allGeometry_.names()[geomI];
626 
627  const entry* eptr = shellsDict.findEntry(geomName, keyType::REGEX);
628 
629  if (eptr)
630  {
631  const dictionary& dict = eptr->dict();
632  unmatchedKeys.erase(eptr->keyword());
633 
634  shells_[shellI] = geomI;
635  modes_[shellI] = refineModeNames_.get("mode", dict);
636 
637  // Read pairs of distance+level
638  setAndCheckLevels(shellI, dict.lookup("levels"));
639 
640 
641  // Directional refinement
642  // ~~~~~~~~~~~~~~~~~~~~~~
643 
644  dirLevels_[shellI] = Tuple2<labelPair,labelVector>
645  (
648  );
649  const entry* levelPtr =
650  dict.findEntry("levelIncrement", keyType::REGEX);
651 
652  if (levelPtr)
653  {
654  // Do reading ourselves since using labelPair would require
655  // additional bracket pair
656  Istream& is = levelPtr->stream();
657 
658  is.readBegin("levelIncrement");
659  is >> dirLevels_[shellI].first().first()
660  >> dirLevels_[shellI].first().second()
661  >> dirLevels_[shellI].second();
662  is.readEnd("levelIncrement");
663 
664  if (modes_[shellI] == INSIDE)
665  {
666  if (!dryRun_)
667  {
668  Info<< "Additional directional refinement level"
669  << " for all cells inside " << geomName << endl;
670  }
671  }
672  else if (modes_[shellI] == OUTSIDE)
673  {
674  if (!dryRun_)
675  {
676  Info<< "Additional directional refinement level"
677  << " for all cells outside " << geomName << endl;
678  }
679  }
680  else
681  {
682  FatalIOErrorInFunction(shellsDict)
683  << "Unsupported mode "
684  << refineModeNames_[modes_[shellI]]
685  << exit(FatalIOError);
686  }
687  }
688 
689  // Directional smoothing
690  // ~~~~~~~~~~~~~~~~~~~~~
691 
692  nSmoothExpansion_[shellI] = 0;
693  nSmoothPosition_[shellI] = 0;
694  smoothDirection_[shellI] =
695  dict.lookupOrDefault("smoothDirection", vector::zero);
696 
697  if (smoothDirection_[shellI] != vector::zero)
698  {
699  dict.readEntry("nSmoothExpansion", nSmoothExpansion_[shellI]);
700  dict.readEntry("nSmoothPosition", nSmoothPosition_[shellI]);
701  }
702 
703 
704  // Gap specification
705  // ~~~~~~~~~~~~~~~~~
706 
707 
708  // Shell-wide gap level specification
709  const searchableSurface& surface = allGeometry_[geomI];
710  const wordList& regionNames = surface.regions();
711 
712  FixedList<label, 3> gapSpec
713  (
715  (
716  "gapLevel",
717  nullGapLevel
718  )
719  );
720  extendedGapLevel_[shellI].setSize(regionNames.size());
721  extendedGapLevel_[shellI] = gapSpec;
722 
723  extendedGapMode_[shellI].setSize(regionNames.size());
724  extendedGapMode_[shellI] =
725  volumeType("gapMode", dict, volumeType::MIXED);
726 
727 
728  // Override on a per-region basis?
729 
730  if (dict.found("regions"))
731  {
732  const dictionary& regionsDict = dict.subDict("regions");
733  forAll(regionNames, regionI)
734  {
735  if (regionsDict.found(regionNames[regionI]))
736  {
737  // Get the dictionary for region
738  const dictionary& regionDict = regionsDict.subDict
739  (
740  regionNames[regionI]
741  );
742  FixedList<label, 3> gapSpec
743  (
744  regionDict.lookupOrDefault
745  (
746  "gapLevel",
747  nullGapLevel
748  )
749  );
750  extendedGapLevel_[shellI][regionI] = gapSpec;
751 
752  extendedGapMode_[shellI][regionI] =
753  volumeType
754  (
755  "gapMode",
756  regionDict,
758  );
759  }
760  }
761  }
762 
763  checkGapLevels(dict, shellI, extendedGapLevel_[shellI]);
764 
765  shellI++;
766  }
767  }
768 
769  if (unmatchedKeys.size() > 0)
770  {
771  IOWarningInFunction(shellsDict)
772  << "Not all entries in refinementRegions dictionary were used."
773  << " The following entries were not used : "
774  << unmatchedKeys.sortedToc()
775  << endl;
776  }
777 
778  // Orient shell surfaces before any searching is done. Note that this
779  // only needs to be done for inside or outside. Orienting surfaces
780  // constructs lots of addressing which we want to avoid.
781  orient();
782 }
783 
784 
785 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
786 
787 // Highest shell level
789 {
790  label overallMax = 0;
791  forAll(levels_, shellI)
792  {
793  overallMax = max(overallMax, max(levels_[shellI]));
794  }
795  return overallMax;
796 }
797 
798 
800 {
801  labelList surfaceMax(extendedGapLevel_.size(), Zero);
802 
803  forAll(extendedGapLevel_, shelli)
804  {
805  const List<FixedList<label, 3>>& levels = extendedGapLevel_[shelli];
806  forAll(levels, i)
807  {
808  surfaceMax[shelli] = max(surfaceMax[shelli], levels[i][2]);
809  }
810  }
811  return surfaceMax;
812 }
813 
814 
816 {
817  labelPairList levels(dirLevels_.size());
818  forAll(dirLevels_, shelli)
819  {
820  levels[shelli] = dirLevels_[shelli].first();
821  }
822  return levels;
823 }
824 
825 
827 {
828  return nSmoothExpansion_;
829 }
830 
831 
833 {
834  return smoothDirection_;
835 }
836 
837 
839 {
840  return nSmoothPosition_;
841 }
842 
843 
844 void Foam::shellSurfaces::findHigherLevel
845 (
846  const pointField& pt,
847  const labelList& ptLevel,
848  labelList& maxLevel
849 ) const
850 {
851  // Maximum level of any shell. Start off with level of point.
852  maxLevel = ptLevel;
853 
854  forAll(shells_, shelli)
855  {
856  findHigherLevel(pt, shelli, maxLevel);
857  }
858 }
859 
860 
861 void Foam::shellSurfaces::findHigherGapLevel
862 (
863  const pointField& pt,
864  const labelList& ptLevel,
865  labelList& gapShell,
866  List<FixedList<label, 3>>& gapInfo,
867  List<volumeType>& gapMode
868 ) const
869 {
870  gapShell.setSize(pt.size());
871  gapShell = -1;
872 
873  FixedList<label, 3> nullGapLevel;
874  nullGapLevel[0] = 0;
875  nullGapLevel[1] = 0;
876  nullGapLevel[2] = 0;
877 
878  gapInfo.setSize(pt.size());
879  gapInfo = nullGapLevel;
880 
881  gapMode.setSize(pt.size());
882  gapMode = volumeType::MIXED;
883 
884  forAll(shells_, shelli)
885  {
886  findHigherGapLevel(pt, ptLevel, shelli, gapShell, gapInfo, gapMode);
887  }
888 }
889 
890 
891 void Foam::shellSurfaces::findHigherGapLevel
892 (
893  const pointField& pt,
894  const labelList& ptLevel,
895  List<FixedList<label, 3>>& gapInfo,
896  List<volumeType>& gapMode
897 ) const
898 {
899  labelList gapShell;
900  findHigherGapLevel(pt, ptLevel, gapShell, gapInfo, gapMode);
901 }
902 
903 
904 void Foam::shellSurfaces::findLevel
905 (
906  const pointField& pt,
907  const labelList& ptLevel,
908  labelList& shell
909 ) const
910 {
911  shell.setSize(pt.size());
912  shell = -1;
913 
914  labelList minLevel(ptLevel);
915 
916  forAll(shells_, shelli)
917  {
918  findLevel(pt, shelli, minLevel, shell);
919  }
920 }
921 
922 
924 (
925  const pointField& pt,
926  const labelList& ptLevel,
927  const labelList& dirLevel, // directional level
928  const direction dir,
929  labelList& shell
930 ) const
931 {
932  shell.setSize(pt.size());
933  shell = -1;
934 
935  List<volumeType> volType;
936 
937  // Current back to original
938  DynamicList<label> candidateMap(pt.size());
939 
940  forAll(shells_, shelli)
941  {
942  if (modes_[shelli] == INSIDE || modes_[shelli] == OUTSIDE)
943  {
944  const labelPair& selectLevels = dirLevels_[shelli].first();
945  const label addLevel = dirLevels_[shelli].second()[dir];
946 
947  // Collect the cells that are of the right original level
948  candidateMap.clear();
949  forAll(ptLevel, celli)
950  {
951  label level = ptLevel[celli];
952 
953  if
954  (
955  level >= selectLevels.first()
956  && level <= selectLevels.second()
957  && dirLevel[celli] < level+addLevel
958  )
959  {
960  candidateMap.append(celli);
961  }
962  }
963 
964  // Do geometric test
965  pointField candidatePt(pt, candidateMap);
966  allGeometry_[shells_[shelli]].getVolumeType(candidatePt, volType);
967 
968  // Extract selected cells
969  forAll(candidateMap, i)
970  {
971  if
972  (
973  (
974  modes_[shelli] == INSIDE
975  && volType[i] == volumeType::INSIDE
976  )
977  || (
978  modes_[shelli] == OUTSIDE
979  && volType[i] == volumeType::OUTSIDE
980  )
981  )
982  {
983  shell[candidateMap[i]] = shelli;
984  }
985  }
986  }
987  }
988 }
989 
990 
991 // ************************************************************************* //
shellSurfaces.H
Foam::Pair::second
const T & second() const noexcept
Return second element, which is also the last element.
Definition: PairI.H:122
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::shellSurfaces::refineMode
refineMode
Volume refinement controls.
Definition: shellSurfaces.H:64
Foam::nearInfo
Tuple2< scalar, label > nearInfo
Private class for finding nearest.
Definition: sampledTriSurfaceMesh.C:67
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:51
pointIndexHit.H
Foam::shellSurfaces::smoothDirection
const vectorField & smoothDirection() const
Per shell the smoothing direction.
Definition: shellSurfaces.C:832
Foam::labelMax
constexpr label labelMax
Definition: label.H:65
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::entry::stream
virtual ITstream & stream() const =0
Return token stream, if entry is a primitive entry.
s
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;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
searchableSurface.H
Foam::entry::keyword
const keyType & keyword() const
Return keyword.
Definition: entry.H:187
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
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:359
Foam::boundBox::invertedBox
static const boundBox invertedBox
A large inverted boundBox: min/max == +/- ROOTVGREAT.
Definition: boundBox.H:86
Foam::shellSurfaces::DISTANCE
Definition: shellSurfaces.H:68
Foam::shellSurfaces::maxGapLevel
labelList maxGapLevel() const
Highest shell gap level.
Definition: shellSurfaces.C:799
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:182
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::dictionary::lookupOrDefault
T lookupOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.H:1241
Foam::Istream::readEnd
bool readEnd(const char *funcName)
End read of data chunk, ends with ')'.
Definition: Istream.C:127
Foam::HashSet< word >
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::Istream::readBegin
bool readBegin(const char *funcName)
Begin read of data chunk, starts with '('.
Definition: Istream.C:109
Foam::labelPair
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:54
Foam::mode
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
Definition: MSwindows.C:564
searchableSurfaces.H
volumeType.H
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::volumeType
An enumeration wrapper for classification of a location as being inside/outside of a volume.
Definition: volumeType.H:60
Foam::Field< vector >
Foam::findLower
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Foam::searchableSurface::regions
virtual const wordList & regions() const =0
Names of regions.
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
refinementSurfaces.H
Foam::searchableSurface
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Definition: searchableSurface.H:69
Foam::volumeType::MIXED
A location that is partly inside and outside.
Definition: volumeType.H:70
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:523
Foam::shellSurfaces::directionalSelectLevel
labelPairList directionalSelectLevel() const
Min and max cell level for directional refinement.
Definition: shellSurfaces.C:815
Foam::dictionary::readEntry
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
Definition: dictionaryTemplates.C:314
Foam::shellSurfaces::shellSurfaces
shellSurfaces(const searchableSurfaces &allGeometry, const dictionary &shellsDict, const bool dryRun=false)
Construct from geometry and dictionary.
Definition: shellSurfaces.C:579
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
Foam::dictionary::lookup
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.C:419
dict
dictionary dict
Definition: searchingEngine.H:14
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::FixedList::setSize
void setSize(const label n)
Dummy setSize function, to make FixedList consistent with List.
Definition: FixedListI.H:323
Foam::entry::dict
virtual const dictionary & dict() const =0
Return dictionary, if entry is a dictionary.
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
boundBox.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:54
Foam::VectorSpace::max
static const Form max
Definition: VectorSpace.H:117
Foam::ILList::erase
bool erase(T *item)
Remove the specified element from the list and delete it.
Definition: ILList.C:97
Foam::shellSurfaces::findDirectionalLevel
void findDirectionalLevel(const pointField &pt, const labelList &ptLevel, const labelList &dirLevel, const direction dir, labelList &shell) const
Find any shell (or -1) with higher wanted directional level.
Definition: shellSurfaces.C:924
Foam::List< word >
Foam::searchableSurfaces
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
Definition: searchableSurfaces.H:92
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::FixedList< label, 3 >
Foam::dictionary::findEntry
entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find for an entry (non-const access) with the given keyword.
Definition: dictionary.C:369
Foam::keyType::REGEX
Regular expression.
Definition: keyType.H:74
Foam::direction
uint8_t direction
Definition: direction.H:47
Foam::volumeType::INSIDE
A location inside the volume.
Definition: volumeType.H:68
Foam::labelMin
constexpr label labelMin
Definition: label.H:64
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:303
Foam::VectorSpace< Vector< label >, label, 3 >::zero
static const Vector< label > zero
Definition: VectorSpace.H:115
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:375
Foam::shellSurfaces::nSmoothPosition
const labelList & nSmoothPosition() const
Per shell the positional smoothing iterations.
Definition: shellSurfaces.C:838
Foam::orientedSurface::orient
static bool orient(triSurface &, const point &, const bool orientOutside)
Flip faces such that normals are consistent with point:
Definition: orientedSurface.C:448
Foam::dictionary::toc
wordList toc() const
Return the table of contents.
Definition: dictionary.C:665
Foam::shellSurfaces::nSmoothExpansion
const labelList & nSmoothExpansion() const
Per shell the directional smoothing iterations.
Definition: shellSurfaces.C:826
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:306
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::point
vector point
Point is a vector.
Definition: point.H:43
Foam::shellSurfaces::INSIDE
Definition: shellSurfaces.H:66
Foam::shellSurfaces::maxLevel
label maxLevel() const
Highest shell level.
Definition: shellSurfaces.C:788
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
triSurfaceMesh.H
orientedSurface.H
Foam::volumeType::OUTSIDE
A location outside the volume.
Definition: volumeType.H:69