autoDensity.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) 2012-2016 OpenFOAM Foundation
9  Copyright (C) 2018-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 "autoDensity.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 defineTypeNameAndDebug(autoDensity, 0);
41 (
42  initialPointsMethod,
43  autoDensity,
44  dictionary
45 );
46 
47 
48 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 
50 void Foam::autoDensity::writeOBJ
51 (
52  const treeBoundBox& bb,
53  fileName name
54 ) const
55 {
56  OFstream str(time().path()/name + ".obj");
57 
58  Pout<< "Writing " << str.name() << endl;
59 
60  pointField bbPoints(bb.points());
61 
62  for (const point& pt : bbPoints)
63  {
64  meshTools::writeOBJ(str, pt);
65  }
66 
67  for (const edge& e : treeBoundBox::edges)
68  {
69  str << "l " << e[0] + 1 << ' ' << e[1] + 1 << nl;
70  }
71 }
72 
73 
74 bool Foam::autoDensity::combinedOverlaps(const treeBoundBox& box) const
75 {
76  if (Pstream::parRun())
77  {
78  return
79  decomposition().overlapsThisProcessor(box)
80  || geometryToConformTo().overlaps(box);
81  }
82 
83  return geometryToConformTo().overlaps(box);
84 }
85 
86 
87 bool Foam::autoDensity::combinedInside(const point& p) const
88 {
89  if (Pstream::parRun())
90  {
91  return
92  decomposition().positionOnThisProcessor(p)
93  && geometryToConformTo().inside(p);
94  }
95 
96  return geometryToConformTo().inside(p);
97 }
98 
99 
100 Foam::Field<bool> Foam::autoDensity::combinedWellInside
101 (
102  const pointField& pts,
103  const scalarField& sizes
104 ) const
105 {
106  if (!Pstream::parRun())
107  {
108  return geometryToConformTo().wellInside
109  (
110  pts,
111  minimumSurfaceDistanceCoeffSqr_*sqr(sizes)
112  );
113  }
114 
115  Field<bool> inside(pts.size(), true);
116 
117  // Perform AND operation between testing the surfaces and the previous
118  // field, i.e the parallel result, or in serial, with true.
119 
120  Field<bool> insideA
121  (
122  geometryToConformTo().wellInside
123  (
124  pts,
125  minimumSurfaceDistanceCoeffSqr_*sqr(sizes)
126  )
127  );
128 
129  Field<bool> insideB
130  (
131  decomposition().positionOnThisProcessor(pts)
132  );
133 
134  // inside = insideA && insideB;
135 
136  // Pout<< insideA << nl << insideB << endl;
137 
138  forAll(inside, i)
139  {
140  // if (inside[i] != (insideA[i] && insideB[i]))
141  // {
142  // Pout<< i << " not equal " << " "
143  // << pts[i] << " " << sizes[i] << " "
144  // << insideA[i] << " "
145  // << insideB[i] << " "
146  // << inside[i]
147  // << endl;
148  // }
149 
150  inside[i] = (insideA[i] && insideB[i]);
151  }
152 
153  return inside;
154 }
155 
156 
157 bool Foam::autoDensity::combinedWellInside
158 (
159  const point& p,
160  scalar size
161 ) const
162 {
163  bool inside = true;
164 
165  if (Pstream::parRun())
166  {
167  inside = decomposition().positionOnThisProcessor(p);
168  }
169 
170  // Perform AND operation between testing the surfaces and the previous
171  // result, i.e the parallel result, or in serial, with true.
172  inside =
173  inside
174  && geometryToConformTo().wellInside
175  (
176  p,
177  minimumSurfaceDistanceCoeffSqr_*sqr(size)
178  );
179 
180  return inside;
181 }
182 
183 
184 Foam::label Foam::autoDensity::recurseAndFill
185 (
186  DynamicList<Vb::Point>& initialPoints,
187  const treeBoundBox& bb,
188  label levelLimit,
189  word recursionName
190 ) const
191 {
192  label treeDepth = 0;
193 
194  for (direction i = 0; i < 8; i++)
195  {
196  treeBoundBox subBB = bb.subBbox(i);
197 
198  word newName = recursionName + "_" + Foam::name(i);
199 
200  conformalVoronoiMesh::timeCheck(time(), newName, debug);
201 
202  if (combinedOverlaps(subBB))
203  {
204  if (levelLimit > 0)
205  {
206  treeDepth =
207  max
208  (
209  treeDepth,
210  recurseAndFill
211  (
212  initialPoints,
213  subBB,
214  levelLimit - 1,
215  newName
216  )
217  );
218  }
219  else
220  {
221  if (debug)
222  {
223  writeOBJ
224  (
225  subBB,
226  word(newName + "_overlap")
227  );
228 
229  Pout<< newName + "_overlap " << subBB << endl;
230  }
231 
232  if (!fillBox(initialPoints, subBB, true))
233  {
234  treeDepth =
235  max
236  (
237  treeDepth,
238  recurseAndFill
239  (
240  initialPoints,
241  subBB,
242  levelLimit - 1,
243  newName
244  )
245  );
246  }
247  }
248  }
249  else if (combinedInside(subBB.centre()))
250  {
251  if (debug)
252  {
253  writeOBJ
254  (
255  subBB,
256  newName + "_inside"
257  );
258 
259  Pout<< newName + "_inside " << subBB << endl;
260  }
261 
262  if (!fillBox(initialPoints, subBB, false))
263  {
264  treeDepth =
265  max
266  (
267  treeDepth,
268  recurseAndFill
269  (
270  initialPoints,
271  subBB,
272  levelLimit - 1,
273  newName
274  )
275  );
276  }
277  }
278  else
279  {
280  if (debug)
281  {
282  writeOBJ
283  (
284  subBB,
285  newName + "_outside"
286  );
287  }
288  }
289  }
290 
291  return treeDepth + 1;
292 }
293 
294 
295 bool Foam::autoDensity::fillBox
296 (
297  DynamicList<Vb::Point>& initialPoints,
298  const treeBoundBox& bb,
299  bool overlapping
300 ) const
301 {
302  const conformationSurfaces& geometry = geometryToConformTo();
303 
304  label initialSize = initialPoints.size();
305 
306  scalar maxCellSize = -GREAT;
307 
308  scalar minCellSize = GREAT;
309 
310  scalar maxDensity = 1/pow3(minCellSize);
311 
312  scalar volumeAdded = 0.0;
313 
314  const point& min = bb.min();
315 
316  vector span = bb.span();
317 
318  scalar totalVolume = bb.volume();
319 
320  label trialPoints = 0;
321 
322  bool wellInside = false;
323 
324  if (!overlapping)
325  {
326  // Check the nearest point on the surface to the box, if it is far
327  // enough away, then the surface sampling of the box can be skipped.
328  // Checking if the nearest piece of surface is at least 1.5*bb.span away
329  // from the bb.centre()
330 
331  pointIndexHit surfHit;
332  label hitSurface;
333 
334  geometry.findSurfaceNearest
335  (
336  bb.centre(),
337  2.25*magSqr(span),
338  surfHit,
339  hitSurface
340  );
341 
342  if (!surfHit.hit())
343  {
344  if (debug)
345  {
346  Pout<< "box wellInside, no need to sample surface." << endl;
347  }
348 
349  wellInside = true;
350  }
351  }
352 
353  if (!overlapping && !wellInside)
354  {
355  // If this is an inside box then it is possible to fill points very
356  // close to the boundary, to prevent this, check the corners and sides
357  // of the box so ensure that they are "wellInside". If not, set as an
358  // overlapping box.
359 
360  pointField corners(bb.points());
361 
362  scalarField cornerSizes = cellShapeControls().cellSize(corners);
363 
364  Field<bool> insideCorners = combinedWellInside(corners, cornerSizes);
365 
366  // Pout<< corners << nl << cornerSizes << nl << insideCorners << endl;
367 
368  forAll(insideCorners, i)
369  {
370  // Use the sizes to improve the min/max cell size estimate
371  scalar s = cornerSizes[i];
372 
373  if (s > maxCellSize)
374  {
375  maxCellSize = s;
376  }
377 
378  if (s < minCellSize)
379  {
380  minCellSize = max(s, minCellSizeLimit_);
381  }
382 
383  if (maxCellSize/minCellSize > maxSizeRatio_)
384  {
385  if (debug)
386  {
387  Pout<< "Abort fill at corner sample stage,"
388  << " minCellSize " << minCellSize
389  << " maxCellSize " << maxCellSize
390  << " maxSizeRatio " << maxCellSize/minCellSize
391  << endl;
392  }
393 
394  return false;
395  }
396 
397  if (!insideCorners[i])
398  {
399  // If one or more corners is not "wellInside", then treat this
400  // as an overlapping box.
401 
402  if (debug)
403  {
404  Pout<< "Inside box found to have some non-wellInside "
405  << "corners, using overlapping fill."
406  << endl;
407  }
408 
409  overlapping = true;
410 
411  break;
412  }
413  }
414 
415  if (!overlapping)
416  {
417  vector delta = span/(surfRes_ - 1);
418 
419  label nLine = 6*(surfRes_ - 2);
420 
421  pointField linePoints(nLine, Zero);
422 
423  scalarField lineSizes(nLine, Zero);
424 
425  for (label i = 0; i < surfRes_; i++)
426  {
427  label lPI = 0;
428 
429  for (label j = 1; j < surfRes_ - 1 ; j++)
430  {
431  linePoints[lPI++] =
432  min
433  + vector(0, delta.y()*i, delta.z()*j);
434 
435  linePoints[lPI++] =
436  min
437  + vector
438  (
439  delta.x()*(surfRes_ - 1),
440  delta.y()*i,
441  delta.z()*j
442  );
443 
444  linePoints[lPI++] =
445  min
446  + vector(delta.x()*j, 0, delta.z()*i);
447 
448  linePoints[lPI++] =
449  min
450  + vector
451  (
452  delta.x()*j,
453  delta.y()*(surfRes_ - 1),
454  delta.z()*i
455  );
456 
457  linePoints[lPI++] =
458  min
459  + vector(delta.x()*i, delta.y()*j, 0);
460 
461  linePoints[lPI++] =
462  min
463  + vector
464  (
465  delta.x()*i,
466  delta.y()*j,
467  delta.z()*(surfRes_ - 1)
468  );
469  }
470 
471  lineSizes = cellShapeControls().cellSize(linePoints);
472 
473  Field<bool> insideLines = combinedWellInside
474  (
475  linePoints,
476  lineSizes
477  );
478 
479  forAll(insideLines, i)
480  {
481  // Use the sizes to improve the min/max cell size estimate
482  scalar s = lineSizes[i];
483 
484  if (s > maxCellSize)
485  {
486  maxCellSize = s;
487  }
488 
489  if (s < minCellSize)
490  {
491  minCellSize = max(s, minCellSizeLimit_);
492  }
493 
494  if (maxCellSize/minCellSize > maxSizeRatio_)
495  {
496  if (debug)
497  {
498  Pout<< "Abort fill at surface sample stage, "
499  << " minCellSize " << minCellSize
500  << " maxCellSize " << maxCellSize
501  << " maxSizeRatio " << maxCellSize/minCellSize
502  << endl;
503  }
504 
505  return false;
506  }
507 
508  if (!insideLines[i])
509  {
510  // If one or more surface points is not "wellInside",
511  // then treat this as an overlapping box.
512  overlapping = true;
513 
514  if (debug)
515  {
516  Pout<< "Inside box found to have some non-"
517  << "wellInside surface points, using "
518  << "overlapping fill."
519  << endl;
520  }
521 
522  break;
523  }
524  }
525  }
526  }
527  }
528 
529  if (overlapping)
530  {
531  // Sample the box to find an estimate of the min size, and a volume
532  // estimate when overlapping == true.
533 
534  pointField samplePoints
535  (
536  volRes_*volRes_*volRes_,
537  Zero
538  );
539 
540  vector delta = span/volRes_;
541 
542  label pI = 0;
543 
544  for (label i = 0; i < volRes_; i++)
545  {
546  for (label j = 0; j < volRes_; j++)
547  {
548  for (label k = 0; k < volRes_; k++)
549  {
550  // Perturb the points to avoid creating degenerate positions
551  // in the Delaunay tessellation.
552 
553  samplePoints[pI++] =
554  min
555  + vector
556  (
557  delta.x()
558  *(i + 0.5 + 0.1*(rndGen().sample01<scalar>() - 0.5)),
559  delta.y()
560  *(j + 0.5 + 0.1*(rndGen().sample01<scalar>() - 0.5)),
561  delta.z()
562  *(k + 0.5 + 0.1*(rndGen().sample01<scalar>() - 0.5))
563  );
564  }
565  }
566  }
567 
568  // Randomise the order of the points to (potentially) improve the speed
569  // of assessing the density ratio, and prevent a box being filled from a
570  // corner when only some these points are required.
571  shuffle(samplePoints);
572 
573  scalarField sampleSizes = cellShapeControls().cellSize(samplePoints);
574 
575  Field<bool> insidePoints = combinedWellInside
576  (
577  samplePoints,
578  sampleSizes
579  );
580 
581  label nInside = 0;
582 
583  forAll(insidePoints, i)
584  {
585  if (insidePoints[i])
586  {
587  nInside++;
588 
589  scalar s = sampleSizes[i];
590 
591  if (s > maxCellSize)
592  {
593  maxCellSize = s;
594  }
595 
596  if (s < minCellSize)
597  {
598  minCellSize = max(s, minCellSizeLimit_);
599  }
600 
601  if (maxCellSize/minCellSize > maxSizeRatio_)
602  {
603  if (debug)
604  {
605  Pout<< "Abort fill at sample stage,"
606  << " minCellSize " << minCellSize
607  << " maxCellSize " << maxCellSize
608  << " maxSizeRatio " << maxCellSize/minCellSize
609  << endl;
610  }
611 
612  return false;
613  }
614  }
615  }
616 
617  if (nInside == 0)
618  {
619  if (debug)
620  {
621  Pout<< "No sample points found inside box" << endl;
622  }
623 
624  return true;
625  }
626 
627  if (debug)
628  {
629  Pout<< scalar(nInside)/scalar(samplePoints.size())
630  << " full overlapping box" << endl;
631  }
632 
633  totalVolume *= scalar(nInside)/scalar(samplePoints.size());
634 
635  if (debug)
636  {
637  Pout<< "Total volume to fill = " << totalVolume << endl;
638  }
639 
640  // Using the sampledPoints as the first test locations as they are
641  // randomly shuffled, but uniformly sampling space and have wellInside
642  // and size data already
643 
644  maxDensity = 1/pow3(max(minCellSize, SMALL));
645 
646  forAll(insidePoints, i)
647  {
648  if (insidePoints[i])
649  {
650  trialPoints++;
651 
652  const point& p = samplePoints[i];
653 
654  scalar localSize = sampleSizes[i];
655 
656  scalar localDensity = 1/pow3(localSize);
657 
658  // No need to look at max/min cell size here, already handled
659  // by sampling
660 
661  // Accept possible placements proportional to the relative
662  // local density
663 
664  // TODO - is there a lot of cost in the 1/density calc? Could
665  // assess on
666  // (1/maxDensity)/(1/localDensity) = minVolume/localVolume
667  if (localDensity/maxDensity > rndGen().sample01<scalar>())
668  {
669  scalar localVolume = 1/localDensity;
670 
671  if (volumeAdded + localVolume > totalVolume)
672  {
673  // Add the final box with a probability of to the ratio
674  // of the remaining volume to the volume to be added,
675  // i.e. insert a box of volume 0.5 into a remaining
676  // volume of 0.1 20% of the time.
677  scalar addProbability =
678  (totalVolume - volumeAdded)/localVolume;
679 
680  scalar r = rndGen().sample01<scalar>();
681 
682  if (debug)
683  {
684  Pout<< "totalVolume " << totalVolume << nl
685  << "volumeAdded " << volumeAdded << nl
686  << "localVolume " << localVolume << nl
687  << "addProbability " << addProbability << nl
688  << "random " << r
689  << endl;
690  }
691 
692  if (addProbability > r)
693  {
694  // Place this volume before finishing filling this
695  // box
696 
697  // Pout<< "Final volume probability break accept"
698  // << endl;
699 
700  initialPoints.append
701  (
702  Vb::Point(p.x(), p.y(), p.z())
703  );
704 
705  volumeAdded += localVolume;
706  }
707 
708  break;
709  }
710 
711  initialPoints.append(Vb::Point(p.x(), p.y(), p.z()));
712 
713  volumeAdded += localVolume;
714  }
715  }
716  }
717  }
718 
719  if (volumeAdded < totalVolume)
720  {
721  if (debug)
722  {
723  Pout<< "Adding random points, remaining volume "
724  << totalVolume - volumeAdded
725  << endl;
726  }
727 
728  maxDensity = 1/pow3(max(minCellSize, SMALL));
729 
730  while (true)
731  {
732  trialPoints++;
733 
734  point p = min + cmptMultiply(span, rndGen().sample01<vector>());
735 
736  scalar localSize = cellShapeControls().cellSize(p);
737 
738  bool insidePoint = false;
739 
740  if (!overlapping)
741  {
742  insidePoint = true;
743  }
744  else
745  {
746  // Determine if the point is "wellInside" the domain
747  insidePoint = combinedWellInside(p, localSize);
748  }
749 
750  if (insidePoint)
751  {
752  if (localSize > maxCellSize)
753  {
754  maxCellSize = localSize;
755  }
756 
757  if (localSize < minCellSize)
758  {
759  minCellSize = max(localSize, minCellSizeLimit_);
760 
761  localSize = minCellSize;
762 
763  // 1/(minimum cell size)^3, gives the maximum permissible
764  // point density
765  maxDensity = 1/pow3(max(minCellSize, SMALL));
766  }
767 
768  if (maxCellSize/minCellSize > maxSizeRatio_)
769  {
770  if (debug)
771  {
772  Pout<< "Abort fill at random fill stage,"
773  << " minCellSize " << minCellSize
774  << " maxCellSize " << maxCellSize
775  << " maxSizeRatio " << maxCellSize/minCellSize
776  << endl;
777  }
778 
779  // Discard any points already filled into this box by
780  // setting size of initialPoints back to its starting value
781  initialPoints.resize(initialSize);
782 
783  return false;
784  }
785 
786  scalar localDensity = 1/pow3(max(localSize, SMALL));
787 
788  // Accept possible placements proportional to the relative local
789  // density
790  if (localDensity/maxDensity > rndGen().sample01<scalar>())
791  {
792  scalar localVolume = 1/localDensity;
793 
794  if (volumeAdded + localVolume > totalVolume)
795  {
796  // Add the final box with a probability of to the ratio
797  // of the remaining volume to the volume to be added,
798  // i.e. insert a box of volume 0.5 into a remaining
799  // volume of 0.1 20% of the time.
800  scalar addProbability =
801  (totalVolume - volumeAdded)/localVolume;
802 
803  scalar r = rndGen().sample01<scalar>();
804 
805  if (debug)
806  {
807  Pout<< "totalVolume " << totalVolume << nl
808  << "volumeAdded " << volumeAdded << nl
809  << "localVolume " << localVolume << nl
810  << "addProbability " << addProbability << nl
811  << "random " << r
812  << endl;
813  }
814 
815  if (addProbability > r)
816  {
817  // Place this volume before finishing filling this
818  // box
819 
820  // Pout<< "Final volume probability break accept"
821  // << endl;
822 
823  initialPoints.append
824  (
825  Vb::Point(p.x(), p.y(), p.z())
826  );
827 
828  volumeAdded += localVolume;
829  }
830 
831  break;
832  }
833 
834  initialPoints.append(Vb::Point(p.x(), p.y(), p.z()));
835 
836  volumeAdded += localVolume;
837  }
838  }
839  }
840  }
841 
842  globalTrialPoints_ += trialPoints;
843 
844  if (debug)
845  {
846  Pout<< trialPoints
847  << " locations queried, " << initialPoints.size() - initialSize
848  << " points placed, ("
849  << scalar(initialPoints.size() - initialSize)
850  /scalar(max(trialPoints, 1))
851  << " success rate)." << nl
852  << "minCellSize " << minCellSize
853  << ", maxCellSize " << maxCellSize
854  << ", ratio " << maxCellSize/minCellSize
855  << nl << endl;
856  }
857 
858  return true;
859 }
860 
861 
862 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
863 
865 (
866  const dictionary& initialPointsDict,
867  const Time& runTime,
868  Random& rndGen,
869  const conformationSurfaces& geometryToConformTo,
870  const cellShapeControl& cellShapeControls,
871  const autoPtr<backgroundMeshDecomposition>& decomposition
872 )
873 :
874  initialPointsMethod
875  (
876  typeName,
877  initialPointsDict,
878  runTime,
879  rndGen,
880  geometryToConformTo,
881  cellShapeControls,
882  decomposition
883  ),
884  globalTrialPoints_(0),
885  minCellSizeLimit_
886  (
887  detailsDict().getOrDefault<scalar>("minCellSizeLimit", 0)
888  ),
889  minLevels_(detailsDict().get<label>("minLevels")),
890  maxSizeRatio_(detailsDict().get<scalar>("maxSizeRatio")),
891  volRes_(detailsDict().get<label>("sampleResolution")),
892  surfRes_
893  (
894  detailsDict().getOrDefault<label>("surfaceSampleResolution", volRes_)
895  )
896 {
897  if (maxSizeRatio_ <= 1.0)
898  {
899  maxSizeRatio_ = 2.0;
900 
902  << "The maxSizeRatio must be greater than one to be sensible, "
903  << "setting to " << maxSizeRatio_
904  << endl;
905  }
906 }
907 
908 
909 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
910 
911 List<Vb::Point> autoDensity::initialPoints() const
912 {
913  treeBoundBox hierBB;
914 
915  // Pick up the bounds of this processor, or the whole geometry, depending
916  // on whether this is a parallel run.
917  if (Pstream::parRun())
918  {
919  hierBB = decomposition().procBounds();
920  }
921  else
922  {
923  // Extend the global box to move it off large plane surfaces
925  (
926  rndGen(),
927  1e-6
928  );
929  }
930 
931  DynamicList<Vb::Point> initialPoints;
932 
933  Info<< nl << " " << typeName << endl;
934 
935  if (debug)
936  {
937  Pout<< " Filling box " << hierBB << endl;
938  }
939 
940  label treeDepth = recurseAndFill
941  (
943  hierBB,
944  minLevels_ - 1,
945  "recursionBox"
946  );
947 
948  initialPoints.shrink();
949 
950  label nInitialPoints = initialPoints.size();
951 
952  if (Pstream::parRun())
953  {
954  reduce(nInitialPoints, sumOp<label>());
955  reduce(globalTrialPoints_, sumOp<label>());
956  }
957 
959  << indent << nInitialPoints << " points placed" << nl
960  << indent << globalTrialPoints_ << " locations queried" << nl
961  << indent
962  << scalar(nInitialPoints)/scalar(max(globalTrialPoints_, 1))
963  << " success rate" << nl
964  << indent
965  << returnReduce(treeDepth, maxOp<label>())
966  << " levels of recursion (maximum)"
967  << decrIndent << decrIndent
968  << endl;
969 
970  return initialPoints;
971 }
972 
973 
974 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
975 
976 } // End namespace Foam
977 
978 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::treeBoundBox::extend
treeBoundBox extend(Random &rndGen, const scalar s) const
Return slightly wider bounding box.
Definition: treeBoundBoxI.H:325
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::initialPointsMethod::decomposition
const backgroundMeshDecomposition & decomposition() const
Definition: initialPointsMethod.H:186
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
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
Foam::cmptMultiply
dimensioned< Type > cmptMultiply(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
CGAL::indexedVertex::Point
Vb::Point Point
Definition: indexedVertex.H:135
Foam::Random::sample01
Type sample01()
Return a sample whose components lie in the range [0,1].
Definition: RandomTemplates.C:36
Foam::conformalVoronoiMesh::timeCheck
static void timeCheck(const Time &runTime, const string &description=string::null, const bool check=true)
Write the elapsedCpuTime and memory usage, with an optional.
Foam::autoDensity::initialPoints
virtual List< Vb::Point > initialPoints() const
Return the initial points for the conformalVoronoiMesh.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::treeBoundBox::edges
static const edgeList edges
Edge to point addressing.
Definition: treeBoundBox.H:154
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::incrIndent
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:346
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
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::initialPointsMethod::geometryToConformTo
const conformationSurfaces & geometryToConformTo() const
Definition: initialPointsMethod.H:176
Foam::Field< bool >
Foam::pow3
dimensionedScalar pow3(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:89
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::OSstream::name
virtual const fileName & name() const
Get the name of the stream.
Definition: OSstream.H:107
delta
scalar delta
Definition: LISASMDCalcMethod2.H:8
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
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::decrIndent
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:353
Foam::indent
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:339
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::conformationSurfaces::globalBounds
const treeBoundBox & globalBounds() const
Return the global bounds.
Definition: conformationSurfacesI.H:75
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:404
Foam::shuffle
void shuffle(UList< T > &a)
Definition: UList.C:289
Foam::initialPointsMethod::rndGen
Random & rndGen() const
Definition: initialPointsMethod.H:171
Foam::backgroundMeshDecomposition::procBounds
const treeBoundBox & procBounds() const
Return the boundBox of this processor.
Definition: backgroundMeshDecompositionI.H:44
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
autoDensity.H
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Foam::direction
uint8_t direction
Definition: direction.H:52
Foam::PtrListOps::get
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
insidePoints
insidePoints((1 2 3))
rndGen
Random rndGen
Definition: createFields.H:23
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::autoDensity::autoDensity
autoDensity(const dictionary &initialPointsDict, const Time &runTime, Random &rndGen, const conformationSurfaces &geometryToConformTo, const cellShapeControl &cellShapeControls, const autoPtr< backgroundMeshDecomposition > &decomposition)
Construct from components.
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328