refinementFeatures.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) 2020-2022 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 "refinementFeatures.H"
30 #include "Time.H"
31 #include "Tuple2.H"
32 #include "DynamicField.H"
33 #include "featureEdgeMesh.H"
34 #include "meshRefinement.H"
35 
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 
38 void Foam::refinementFeatures::read
39 (
40  const objectRegistry& io,
41  const PtrList<dictionary>& featDicts
42 )
43 {
44  forAll(featDicts, featI)
45  {
46  const dictionary& dict = featDicts[featI];
47 
48  fileName featFileName
49  (
50  meshRefinement::get<fileName>
51  (
52  dict,
53  "file",
54  dryRun_,
57  )
58  );
59 
60 
61  // Try reading extendedEdgeMesh first
62 
63  IOobject extFeatObj
64  (
65  featFileName, // name
66  io.time().constant(), // instance
67  "extendedFeatureEdgeMesh", // local
68  io.time(), // registry
71  false
72  );
73 
74  const fileName fName(typeFilePath<extendedFeatureEdgeMesh>(extFeatObj));
75 
76  if (!fName.empty() && extendedEdgeMesh::canRead(fName))
77  {
78  autoPtr<extendedEdgeMesh> eMeshPtr = extendedEdgeMesh::New
79  (
80  fName
81  );
82 
83  if (!dryRun_)
84  {
85  Info<< "Read extendedFeatureEdgeMesh " << extFeatObj.name()
86  << nl << incrIndent;
87  eMeshPtr().writeStats(Info);
88  Info<< decrIndent << endl;
89  }
90 
91  set(featI, new extendedFeatureEdgeMesh(extFeatObj, eMeshPtr()));
92  }
93  else
94  {
95  // Try reading edgeMesh
96 
97  IOobject featObj
98  (
99  featFileName, // name
100  io.time().constant(), // instance
101  "triSurface", // local
102  io.time(), // registry
105  false
106  );
107 
108  const fileName fName(typeFilePath<featureEdgeMesh>(featObj));
109 
110  if (fName.empty())
111  {
113  << "Could not open " << featObj.objectPath()
114  << exit(FatalIOError);
115  }
116 
117  // Read as edgeMesh
118  autoPtr<edgeMesh> eMeshPtr = edgeMesh::New(fName);
119  const edgeMesh& eMesh = eMeshPtr();
120 
121  if (!dryRun_)
122  {
123  Info<< "Read edgeMesh " << featObj.name() << nl
124  << incrIndent;
125  eMesh.writeStats(Info);
126  Info<< decrIndent << endl;
127  }
128 
129  // Analyse for feature points. These are all classified as mixed
130  // points for lack of anything better
131  const labelListList& pointEdges = eMesh.pointEdges();
132 
133  labelList oldToNew(eMesh.points().size(), -1);
134  DynamicField<point> newPoints(eMesh.points().size());
135  forAll(pointEdges, pointi)
136  {
137  if (pointEdges[pointi].size() > 2)
138  {
139  oldToNew[pointi] = newPoints.size();
140  newPoints.append(eMesh.points()[pointi]);
141  }
142  //else if (pointEdges[pointi].size() == 2)
143  //MEJ: do something based on a feature angle?
144  }
145  label nFeatures = newPoints.size();
146  forAll(oldToNew, pointi)
147  {
148  if (oldToNew[pointi] == -1)
149  {
150  oldToNew[pointi] = newPoints.size();
151  newPoints.append(eMesh.points()[pointi]);
152  }
153  }
154 
155 
156  const edgeList& edges = eMesh.edges();
157  edgeList newEdges(edges.size());
158  forAll(edges, edgeI)
159  {
160  const edge& e = edges[edgeI];
161  newEdges[edgeI] = edge
162  (
163  oldToNew[e[0]],
164  oldToNew[e[1]]
165  );
166  }
167 
168  // Construct an extendedEdgeMesh with
169  // - all points on more than 2 edges : mixed feature points
170  // - all edges : external edges
171 
172  extendedEdgeMesh eeMesh
173  (
174  newPoints, // pts
175  newEdges, // eds
176  0, // (point) concaveStart
177  0, // (point) mixedStart
178  nFeatures, // (point) nonFeatureStart
179  edges.size(), // (edge) internalStart
180  edges.size(), // (edge) flatStart
181  edges.size(), // (edge) openStart
182  edges.size(), // (edge) multipleStart
183  vectorField(0), // normals
184  List<extendedEdgeMesh::sideVolumeType>(0),// normalVolumeTypes
185  vectorField(0), // edgeDirections
186  labelListList(0), // normalDirections
187  labelListList(0), // edgeNormals
188  labelListList(0), // featurePointNormals
189  labelListList(0), // featurePointEdges
190  identity(newEdges.size()) // regionEdges
191  );
192 
193  //Info<< "Constructed extendedFeatureEdgeMesh " << featObj.name()
194  // << nl << incrIndent;
195  //eeMesh.writeStats(Info);
196  //Info<< decrIndent << endl;
197 
198  set(featI, new extendedFeatureEdgeMesh(featObj, eeMesh));
199  }
200 
201  const extendedEdgeMesh& eMesh = operator[](featI);
202 
203  if (dict.found("levels"))
204  {
205  List<Tuple2<scalar, label>> distLevels(dict.lookup("levels"));
206 
207  if (dict.size() < 1)
208  {
210  << " : levels should be at least size 1" << endl
211  << "levels : " << dict.lookup("levels")
212  << exit(FatalError);
213  }
214 
215  distances_[featI].setSize(distLevels.size());
216  levels_[featI].setSize(distLevels.size());
217 
218  forAll(distLevels, j)
219  {
220  distances_[featI][j] = distLevels[j].first();
221  levels_[featI][j] = distLevels[j].second();
222 
223  if (levels_[featI][j] < 0)
224  {
226  << "Feature " << featFileName
227  << " has illegal refinement level " << levels_[featI][j]
228  << exit(FatalError);
229  }
230 
231  // Check in incremental order
232  if (j > 0)
233  {
234  if
235  (
236  (distances_[featI][j] <= distances_[featI][j-1])
237  || (levels_[featI][j] > levels_[featI][j-1])
238  )
239  {
241  << " : Refinement should be specified in order"
242  << " of increasing distance"
243  << " (and decreasing refinement level)." << endl
244  << "Distance:" << distances_[featI][j]
245  << " refinementLevel:" << levels_[featI][j]
246  << exit(FatalError);
247  }
248  }
249  }
250  }
251  else
252  {
253  // Look up 'level' for single level
254  levels_[featI] =
255  labelList
256  (
257  1,
258  meshRefinement::get<label>
259  (
260  dict,
261  "level",
262  dryRun_,
264  0
265  )
266  );
267  distances_[featI] = scalarField(1, Zero);
268  }
269 
270  if (!dryRun_)
271  {
272  Info<< "Refinement level according to distance to "
273  << featFileName << " (" << eMesh.points().size() << " points, "
274  << eMesh.edges().size() << " edges)." << endl;
275  forAll(levels_[featI], j)
276  {
277  Info<< " level " << levels_[featI][j]
278  << " for all cells within " << distances_[featI][j]
279  << " metre." << endl;
280  }
281  }
282  }
283 }
284 
285 
286 void Foam::refinementFeatures::buildTrees(const label featI)
287 {
288  const extendedEdgeMesh& eMesh = operator[](featI);
289  const pointField& points = eMesh.points();
290  const edgeList& edges = eMesh.edges();
291 
292  // Calculate bb of all points
293  treeBoundBox bb(points);
294 
295  // Random number generator. Bit dodgy since not exactly random ;-)
296  Random rndGen(65431);
297 
298  // Slightly extended bb. Slightly off-centred just so on symmetric
299  // geometry there are less face/edge aligned items.
300  bb.inflate(rndGen, 1e-4, ROOTVSMALL);
301 
302  edgeTrees_.set
303  (
304  featI,
305  new indexedOctree<treeDataEdge>
306  (
307  treeDataEdge(edges, points), // All edges
308 
309  bb, // overall search domain
310  8, // maxLevel
311  10, // leafsize
312  3.0 // duplicity
313  )
314  );
315 
316 
317  labelList featurePoints(identity(eMesh.nonFeatureStart()));
318 
319  pointTrees_.set
320  (
321  featI,
322  new indexedOctree<treeDataPoint>
323  (
324  treeDataPoint(points, featurePoints),
325 
326  bb, // overall search domain
327  8, // maxLevel
328  10, // leafsize
329  3.0 // duplicity
330  )
331  );
332 }
333 
334 
335 // Find maximum level of a shell.
336 void Foam::refinementFeatures::findHigherLevel
337 (
338  const pointField& pt,
339  const label featI,
340  labelList& maxLevel
341 ) const
342 {
343  const labelList& levels = levels_[featI];
344 
345  const scalarField& distances = distances_[featI];
346 
347  // Collect all those points that have a current maxLevel less than
348  // (any of) the shell. Also collect the furthest distance allowable
349  // to any shell with a higher level.
350 
351  pointField candidates(pt.size());
352  labelList candidateMap(pt.size());
353  scalarField candidateDistSqr(pt.size());
354  label candidateI = 0;
355 
356  forAll(maxLevel, pointi)
357  {
358  forAllReverse(levels, levelI)
359  {
360  if (levels[levelI] > maxLevel[pointi])
361  {
362  candidates[candidateI] = pt[pointi];
363  candidateMap[candidateI] = pointi;
364  candidateDistSqr[candidateI] = sqr(distances[levelI]);
365  candidateI++;
366  break;
367  }
368  }
369  }
370  candidates.setSize(candidateI);
371  candidateMap.setSize(candidateI);
372  candidateDistSqr.setSize(candidateI);
373 
374  // Do the expensive nearest test only for the candidate points.
375  const indexedOctree<treeDataEdge>& tree = edgeTrees_[featI];
376 
377  List<pointIndexHit> nearInfo(candidates.size());
378  forAll(candidates, candidateI)
379  {
380  nearInfo[candidateI] = tree.findNearest
381  (
382  candidates[candidateI],
383  candidateDistSqr[candidateI]
384  );
385  }
386 
387  // Update maxLevel
388  forAll(nearInfo, candidateI)
389  {
390  if (nearInfo[candidateI].hit())
391  {
392  // Check which level it actually is in.
393  label minDistI = findLower
394  (
395  distances,
396  nearInfo[candidateI].point().dist(candidates[candidateI])
397  );
398 
399  label pointi = candidateMap[candidateI];
400 
401  // pt is inbetween shell[minDistI] and shell[minDistI+1]
402  maxLevel[pointi] = levels[minDistI+1];
403  }
404  }
405 }
406 
407 
408 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
409 
412 {
413  if (!regionEdgeTreesPtr_)
414  {
415  regionEdgeTreesPtr_.reset
416  (
417  new PtrList<indexedOctree<treeDataEdge>>(size())
418  );
419  PtrList<indexedOctree<treeDataEdge>>& trees = regionEdgeTreesPtr_();
420 
421  forAll(*this, featI)
422  {
423  const extendedEdgeMesh& eMesh = operator[](featI);
424  const pointField& points = eMesh.points();
425  const edgeList& edges = eMesh.edges();
426 
427  // Calculate bb of all points
428  treeBoundBox bb(points);
429 
430  // Random number generator. Bit dodgy since not exactly random ;-)
431  Random rndGen(65431);
432 
433  // Slightly extended bb. Slightly off-centred just so on symmetric
434  // geometry there are less face/edge aligned items.
435  bb.inflate(rndGen, 1e-4, ROOTVSMALL);
436 
437  trees.set
438  (
439  featI,
440  new indexedOctree<treeDataEdge>
441  (
442  treeDataEdge(edges, points, eMesh.regionEdges()),
443 
444  bb, // overall search domain
445  8, // maxLevel
446  10, // leafsize
447  3.0 // duplicity
448  )
449  );
450  }
451  }
452 
453  return *regionEdgeTreesPtr_;
454 }
455 
456 
457 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
458 
460 (
461  const objectRegistry& io,
462  const PtrList<dictionary>& featDicts,
463  const bool dryRun
464 )
465 :
466  PtrList<extendedFeatureEdgeMesh>(featDicts.size()),
467  distances_(featDicts.size()),
468  levels_(featDicts.size()),
469  edgeTrees_(featDicts.size()),
470  pointTrees_(featDicts.size()),
471  dryRun_(dryRun)
472 {
473  // Read features
474  read(io, featDicts);
475 
476  // Search engines
477  forAll(*this, i)
478  {
479  buildTrees(i);
480  }
481 }
482 
483 
484 //Foam::refinementFeatures::refinementFeatures
485 //(
486 // const objectRegistry& io,
487 // const PtrList<dictionary>& featDicts,
488 // const scalar minCos
489 //)
490 //:
491 // PtrList<extendedFeatureEdgeMesh>(featDicts.size()),
492 // distances_(featDicts.size()),
493 // levels_(featDicts.size()),
494 // edgeTrees_(featDicts.size()),
495 // pointTrees_(featDicts.size())
496 //{
497 // // Read features
498 // read(io, featDicts);
499 //
500 // // Search engines
501 // forAll(*this, i)
502 // {
503 // const edgeMesh& eMesh = operator[](i);
504 // const pointField& points = eMesh.points();
505 // const edgeList& edges = eMesh.edges();
506 // const labelListList& pointEdges = eMesh.pointEdges();
507 //
508 // DynamicList<label> featurePoints;
509 // forAll(pointEdges, pointi)
510 // {
511 // const labelList& pEdges = pointEdges[pointi];
512 // if (pEdges.size() > 2)
513 // {
514 // featurePoints.append(pointi);
515 // }
516 // else if (pEdges.size() == 2)
517 // {
518 // // Check the angle
519 // const edge& e0 = edges[pEdges[0]];
520 // const edge& e1 = edges[pEdges[1]];
521 //
522 // const point& p = points[pointi];
523 // const point& p0 = points[e0.otherVertex(pointi)];
524 // const point& p1 = points[e1.otherVertex(pointi)];
525 //
526 // vector v0 = p-p0;
527 // scalar v0Mag = mag(v0);
528 //
529 // vector v1 = p1-p;
530 // scalar v1Mag = mag(v1);
531 //
532 // if
533 // (
534 // v0Mag > SMALL
535 // && v1Mag > SMALL
536 // && ((v0/v0Mag & v1/v1Mag) < minCos)
537 // )
538 // {
539 // featurePoints.append(pointi);
540 // }
541 // }
542 // }
543 //
544 // Info<< "Detected " << featurePoints.size()
545 // << " featurePoints out of " << points.size()
546 // << " points on feature " << i //eMesh.name()
547 // << " when using feature cos " << minCos << endl;
548 //
549 // buildTrees(i, featurePoints);
550 // }
551 //}
552 
553 
554 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
555 
557 (
558  const scalar maxRatio,
559  const boundBox& meshBb,
560  const bool report,
561  Ostream& os
562 ) const
563 {
564  if (report)
565  {
566  os<< "Checking for size." << endl;
567  }
568 
569  bool hasError = false;
570 
571  forAll(*this, i)
572  {
573  const extendedFeatureEdgeMesh& em = operator[](i);
574  const boundBox bb(em.points(), true);
575 
576  for (label j = i+1; j < size(); j++)
577  {
578  const extendedFeatureEdgeMesh& em2 = operator[](j);
579  const boundBox bb2(em2.points(), true);
580 
581  scalar ratio = bb.mag()/bb2.mag();
582 
583  if (ratio > maxRatio || ratio < 1.0/maxRatio)
584  {
585  hasError = true;
586 
587  if (report)
588  {
589  os << " " << em.name()
590  << " bounds differ from " << em2.name()
591  << " by more than a factor 100:" << nl
592  << " bounding box : " << bb << nl
593  << " bounding box : " << bb2
594  << endl;
595  }
596  }
597  }
598  }
599 
600  forAll(*this, i)
601  {
602  const extendedFeatureEdgeMesh& em = operator[](i);
603  const boundBox bb(em.points(), true);
604  if (!meshBb.contains(bb))
605  {
606  if (report)
607  {
608  os << " " << em.name()
609  << " bounds not fully contained in mesh"<< nl
610  << " bounding box : " << bb << nl
611  << " mesh bounding box : " << meshBb
612  << endl;
613  }
614  }
615  }
616 
617  if (report)
618  {
619  os<< endl;
620  }
621 
622  return returnReduceOr(hasError);
623 }
624 
625 
627 (
628  const pointField& samples,
629  const scalarField& nearestDistSqr,
630  labelList& nearFeature,
631  List<pointIndexHit>& nearInfo,
632  vectorField& nearNormal
633 ) const
634 {
635  nearFeature.setSize(samples.size());
636  nearFeature = -1;
637  nearInfo.setSize(samples.size());
638  nearInfo = pointIndexHit();
639  nearNormal.setSize(samples.size());
640  nearNormal = Zero;
641 
642  forAll(edgeTrees_, featI)
643  {
644  const indexedOctree<treeDataEdge>& tree = edgeTrees_[featI];
645  const treeDataEdge& treeData = tree.shapes();
646 
647  if (!treeData.empty())
648  {
649  forAll(samples, sampleI)
650  {
651  const point& sample = samples[sampleI];
652 
653  scalar distSqr;
654  if (nearInfo[sampleI].hit())
655  {
656  distSqr = nearInfo[sampleI].point().distSqr(sample);
657  }
658  else
659  {
660  distSqr = nearestDistSqr[sampleI];
661  }
662 
663  pointIndexHit info = tree.findNearest(sample, distSqr);
664 
665  if (info.hit())
666  {
667  nearFeature[sampleI] = featI;
668  nearInfo[sampleI] = pointIndexHit
669  (
670  info.hit(),
671  info.point(),
672  treeData.objectIndex(info.index())
673  );
674  nearNormal[sampleI] = treeData.line(info.index()).unitVec();
675  }
676  }
677  }
678  }
679 }
680 
681 
683 (
684  const pointField& samples,
685  const scalarField& nearestDistSqr,
686  labelList& nearFeature,
687  List<pointIndexHit>& nearInfo,
688  vectorField& nearNormal
689 ) const
690 {
691  nearFeature.setSize(samples.size());
692  nearFeature = -1;
693  nearInfo.setSize(samples.size());
694  nearInfo = pointIndexHit();
695  nearNormal.setSize(samples.size());
696  nearNormal = Zero;
697 
698 
699  const PtrList<indexedOctree<treeDataEdge>>& regionTrees =
700  regionEdgeTrees();
701 
702  forAll(regionTrees, featI)
703  {
704  const indexedOctree<treeDataEdge>& regionTree = regionTrees[featI];
705  const treeDataEdge& treeData = regionTree.shapes();
706 
707  forAll(samples, sampleI)
708  {
709  const point& sample = samples[sampleI];
710 
711  scalar distSqr;
712  if (nearInfo[sampleI].hit())
713  {
714  distSqr = nearInfo[sampleI].point().distSqr(sample);
715  }
716  else
717  {
718  distSqr = nearestDistSqr[sampleI];
719  }
720 
721  // Find anything closer than current best
722  pointIndexHit info = regionTree.findNearest(sample, distSqr);
723 
724  if (info.hit())
725  {
726  nearFeature[sampleI] = featI;
727  nearInfo[sampleI] = pointIndexHit
728  (
729  info.hit(),
730  info.point(),
731  treeData.objectIndex(info.index())
732  );
733  nearNormal[sampleI] = treeData.line(info.index()).unitVec();
734  }
735  }
736  }
737 }
738 
739 
740 //void Foam::refinementFeatures::findNearestPoint
741 //(
742 // const pointField& samples,
743 // const scalarField& nearestDistSqr,
744 // labelList& nearFeature,
745 // labelList& nearIndex
746 //) const
747 //{
748 // nearFeature.setSize(samples.size());
749 // nearFeature = -1;
750 // nearIndex.setSize(samples.size());
751 // nearIndex = -1;
752 //
753 // forAll(pointTrees_, featI)
754 // {
755 // const indexedOctree<treeDataPoint>& tree = pointTrees_[featI];
756 //
757 // if (!tree.shapes().empty())
758 // {
759 // forAll(samples, sampleI)
760 // {
761 // const point& sample = samples[sampleI];
762 //
763 // scalar distSqr;
764 // if (nearFeature[sampleI] != -1)
765 // {
766 // const nearTree = pointTrees_[nearFeature[sampleI]];
767 // distSqr = sample.distSqr
768 // (
769 // nearTree.shapes()[nearIndex[sampleI]]
770 // );
771 // }
772 // else
773 // {
774 // distSqr = nearestDistSqr[sampleI];
775 // }
776 //
777 // pointIndexHit info = tree.findNearest(sample, distSqr);
778 //
779 // if (info.hit())
780 // {
781 // nearFeature[sampleI] = featI;
782 // nearIndex[sampleI] = info.index();
783 // }
784 // }
785 // }
786 // }
787 //}
788 
789 
791 (
792  const pointField& samples,
793  const scalarField& nearestDistSqr,
794  labelList& nearFeature,
795  List<pointIndexHit>& nearInfo
796 ) const
797 {
798  nearFeature.setSize(samples.size());
799  nearFeature = -1;
800  nearInfo.setSize(samples.size());
801  nearInfo = pointIndexHit();
802 
803  forAll(pointTrees_, featI)
804  {
805  const indexedOctree<treeDataPoint>& tree = pointTrees_[featI];
806  const auto& treeData = tree.shapes();
807 
808  if (!treeData.empty())
809  {
810  forAll(samples, sampleI)
811  {
812  const point& sample = samples[sampleI];
813 
814  scalar distSqr;
815  if (nearFeature[sampleI] != -1)
816  {
817  distSqr = nearInfo[sampleI].point().distSqr(sample);
818  }
819  else
820  {
821  distSqr = nearestDistSqr[sampleI];
822  }
823 
824  pointIndexHit info = tree.findNearest(sample, distSqr);
825 
826  if (info.hit())
827  {
828  nearFeature[sampleI] = featI;
829  nearInfo[sampleI] = pointIndexHit
830  (
831  info.hit(),
832  info.point(),
833  treeData.objectIndex(info.index())
834  );
835  }
836  }
837  }
838  }
839 }
840 
841 
842 void Foam::refinementFeatures::findHigherLevel
843 (
844  const pointField& pt,
845  const labelList& ptLevel,
846  labelList& maxLevel
847 ) const
848 {
849  // Maximum level of any shell. Start off with level of point.
850  maxLevel = ptLevel;
851 
852  forAll(*this, featI)
853  {
854  findHigherLevel(pt, featI, maxLevel);
855  }
856 }
857 
858 
859 Foam::scalar Foam::refinementFeatures::maxDistance() const
860 {
861  scalar overallMax = -GREAT;
862  forAll(distances_, featI)
863  {
864  overallMax = max(overallMax, max(distances_[featI]));
865  }
866  return overallMax;
867 }
868 
869 
870 // ************************************************************************* //
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:51
const T & operator[](const label i) const
Return const reference to the element.
Definition: UPtrListI.H:234
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value...
static autoPtr< extendedEdgeMesh > New(const fileName &name, const word &fileType)
Select constructed from filename with given file format.
const pointField & points() const noexcept
Return points.
Definition: edgeMeshI.H:92
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
scalar maxDistance() const
Highest distance of all features.
void findNearestPoint(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo) const
Find nearest feature point. Sets.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:150
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
static const fileName null
An empty fileName.
Definition: fileName.H:110
Random rndGen
Definition: createFields.H:23
T & first()
Access first element of the list, position [0].
Definition: UList.H:798
scalarField samples(nIntervals, Zero)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
Definition: pointIndexHit.H:58
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
This class describes the interaction of an object (often a face) and a point. It carries the info of ...
Definition: pointIndexHit.H:44
Ignore writing from objectRegistry::writeObject()
bool checkSizes(const scalar maxRatio, const boundBox &meshBb, const bool report, Ostream &os) const
Check sizes - return true if error and stream to os.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
const point_type & point() const noexcept
Return point, no checks.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
void setSize(const label n)
Alias for resize()
Definition: List.H:289
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
const pointField & points
List< edge > edgeList
A List of edges.
Definition: edgeList.H:60
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:31
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
scalar mag() const
The magnitude/length of the bounding box diagonal.
Definition: boundBoxI.H:191
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:99
Tree tree(triangles.begin(), triangles.end())
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
label index() const noexcept
Return the hit index.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
OBJstream os(runTime.globalPath()/outputName)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:467
bool hit() const noexcept
Is there a hit?
void findNearestRegionEdge(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo, vectorField &nearNormal) const
Find nearest point on nearest region edge. Sets.
vector point
Point is a vector.
Definition: point.H:37
Non-pointer based hierarchical recursive searching.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:607
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
const PtrList< indexedOctree< treeDataEdge > > & regionEdgeTrees() const
void findNearestEdge(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo, vectorField &nearNormal) const
Find nearest point on nearest feature edge. Sets.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:429
List< label > labelList
A List of labels.
Definition: List.H:62
Registry of regIOobjects.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
refinementFeatures(const objectRegistry &io, const PtrList< dictionary > &featDicts, const bool dryRun=false)
Construct from description.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:458
static autoPtr< edgeMesh > New(const fileName &name, const word &fileType)
Read construct from filename with given format.
Definition: edgeMeshNew.C:27
Regular expression.
Definition: keyType.H:83
List< treeBoundBox > meshBb(1, treeBoundBox(coarseMesh.points()).extend(rndGen, 1e-3))
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157