searchableSurfaces.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-2017 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 "searchableSurfaces.H"
31 #include "ListOps.H"
32 #include "Time.H"
33 #include "DynamicField.H"
34 #include "PatchTools.H"
35 #include "triSurfaceMesh.H"
36 
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41  defineTypeNameAndDebug(searchableSurfaces, 0);
42 }
43 
44 
45 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
46 
47 bool Foam::searchableSurfaces::connected
48 (
49  const triSurface& s,
50  const label edgeI,
51  const pointIndexHit& hit
52 )
53 {
54  const edge& e = s.edges()[edgeI];
55  const labelList& mp = s.meshPoints();
56  const edge meshE(mp[e[0]], mp[e[1]]);
57 
58  const triFace& f = s[hit.index()];
59 
60  forAll(f, i)
61  {
62  if (meshE.otherVertex(f[i]) != -1)
63  {
64  return true;
65  }
66  }
67 
68  // Account for triangle intersection routine going wrong for
69  // lines in same plane as triangle. Tbd!
70 
71  vector eVec(meshE.vec(s.points()));
72  scalar magEVec(mag(eVec));
73  if (magEVec > ROOTVSMALL)
74  {
75  vector n(f.areaNormal(s.points()));
76  scalar magArea(mag(n));
77  if (magArea > ROOTVSMALL)
78  {
79  n /= magArea;
80  if (mag(n&(eVec/magEVec)) < SMALL)
81  {
82  // Bad intersection
83  return true;
84  }
85  else
86  {
87  return false;
88  }
89  }
90  }
91 
92  return true;
93 }
94 
95 
96 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
97 
98 Foam::searchableSurfaces::searchableSurfaces(const label size)
99 :
100  PtrList<searchableSurface>(size),
101  regionNames_(size),
102  allSurfaces_(identity(size))
103 {}
104 
105 
106 //Foam::searchableSurfaces::searchableSurfaces
107 //(
108 // const IOobject& io,
109 // const PtrList<dictionary>& dicts
110 //)
111 //:
112 // PtrList<searchableSurface>(dicts.size()),
113 // regionNames_(dicts.size()),
114 // allSurfaces_(identity(dicts.size()))
115 //{
116 // forAll(dicts, surfI)
117 // {
118 // const dictionary& dict = dicts[surfI];
119 //
120 // // Make IOobject with correct name
121 // autoPtr<IOobject> namedIO(io.clone());
122 // namedIO().rename(dict.get<word>("name"));
123 //
124 // // Create and hook surface
125 // set
126 // (
127 // surfI,
128 // searchableSurface::New
129 // (
130 // dict.get<word>("type"),
131 // namedIO(),
132 // dict
133 // )
134 // );
135 // const searchableSurface& s = operator[](surfI);
136 //
137 // // Construct default region names by prepending surface name
138 // // to region name.
139 // const wordList& localNames = s.regions();
140 //
141 // wordList globalNames(localNames.size());
142 // forAll(localNames, regionI)
143 // {
144 // globalNames[regionI] = s.name() + '_' + localNames[regionI];
145 // }
146 //
147 // // See if dictionary provides any global region names.
148 // if (dict.found("regions"))
149 // {
150 // const dictionary& regionsDict = dict.subDict("regions");
151 //
152 // for (const entry& dEntry : regionsDict)
153 // {
154 // if (dEntry.isDict())
155 // {
156 // const word& key = dEntry.keyword();
157 // const dictionary& regionDict = dEntry.dict();
158 //
159 // label index = localNames.find(key);
160 //
161 // if (index == -1)
162 // {
163 // FatalErrorInFunction
164 // << "Unknown region name " << key
165 // << " for surface " << s.name() << endl
166 // << "Valid region names are " << localNames
167 // << exit(FatalError);
168 // }
169 //
170 // globalNames[index] = regionDict.get<word>("name");
171 // }
172 // }
173 // }
174 //
175 // // Now globalNames contains the names of the regions.
176 // Info<< "Surface:" << s.name() << " has regions:"
177 // << endl;
178 // forAll(globalNames, regionI)
179 // {
180 // Info<< " " << globalNames[regionI] << endl;
181 // }
182 //
183 // // Create reverse lookup
184 // forAll(globalNames, regionI)
185 // {
186 // regionNames_.insert
187 // (
188 // globalNames[regionI],
189 // labelPair(surfI, regionI)
190 // );
191 // }
192 // }
193 //}
194 
195 
196 Foam::searchableSurfaces::searchableSurfaces
197 (
198  const IOobject& io,
199  const dictionary& topDict,
200  const bool singleRegionName
201 )
202 :
203  PtrList<searchableSurface>(topDict.size()),
204  names_(topDict.size()),
205  regionNames_(topDict.size()),
206  allSurfaces_(identity(topDict.size()))
207 {
208  label surfI = 0;
209 
210  for (const entry& dEntry : topDict)
211  {
212  if (!dEntry.isDict())
213  {
215  << "Found non-dictionary entry " << dEntry
216  << " in top-level dictionary " << topDict
217  << exit(FatalError);
218  }
219 
220  const word& key = dEntry.keyword();
221  const dictionary& dict = topDict.subDict(key);
222 
223  names_[surfI] = dict.getOrDefault<word>("name", key);
224 
225  // Make IOobject with correct name
226  autoPtr<IOobject> namedIO(io.clone());
227  // Note: we would like to e.g. register triSurface 'sphere.stl' as
228  // 'sphere'. Unfortunately
229  // no support for having object read from different location than
230  // their object name. Maybe have stlTriSurfaceMesh which appends .stl
231  // when reading/writing?
232  namedIO().rename(key); // names_[surfI]
233 
234  // Create and hook surface
235  set
236  (
237  surfI,
239  (
240  dict.get<word>("type"),
241  namedIO(),
242  dict
243  )
244  );
245  const searchableSurface& s = operator[](surfI);
246 
247  // Construct default region names by prepending surface name
248  // to region name.
249  const wordList& localNames = s.regions();
250 
251  wordList& rNames = regionNames_[surfI];
252  rNames.setSize(localNames.size());
253 
254  if (singleRegionName && localNames.size() == 1)
255  {
256  rNames[0] = names_[surfI];
257  }
258  else
259  {
260  forAll(localNames, regionI)
261  {
262  rNames[regionI] = names_[surfI] + '_' + localNames[regionI];
263  }
264  }
265 
266  // See if dictionary provides any global region names.
267  if (dict.found("regions"))
268  {
269  const dictionary& regionsDict = dict.subDict("regions");
270 
271  for (const entry& dEntry : regionsDict)
272  {
273  if (dEntry.isDict())
274  {
275  const word& key = dEntry.keyword();
276  const dictionary& regionDict = dEntry.dict();
277 
278  label index = localNames.find(key);
279 
280  if (index == -1)
281  {
283  << "Unknown region name " << key
284  << " for surface " << s.name() << nl
285  << "Valid region names are " << localNames
286  << endl
287  << exit(FatalError);
288  }
289 
290  rNames[index] = regionDict.get<word>("name");
291  }
292  }
293  }
294 
295  surfI++;
296  }
297 
298  // Trim (not really necessary since we don't allow non-dictionary entries)
300  names_.setSize(surfI);
301  regionNames_.setSize(surfI);
302  allSurfaces_.setSize(surfI);
303 }
304 
305 
306 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
307 
309 (
310  const word& wantedName
311 ) const
312 {
313  return names_.find(wantedName);
314 }
315 
316 
318 (
319  const word& surfaceName,
320  const word& regionName
321 ) const
322 {
323  const label surfaceIndex = findSurfaceID(surfaceName);
324 
325  return this->operator[](surfaceIndex).regions().find(regionName);
326 }
327 
328 
329 // Find any intersection
331 (
332  const pointField& start,
333  const pointField& end,
334  labelList& hitSurfaces,
335  List<pointIndexHit>& hitInfo
336 ) const
337 {
339  (
340  *this,
341  allSurfaces_,
342  start,
343  end,
344  hitSurfaces,
345  hitInfo
346  );
347 }
348 
349 
351 (
352  const pointField& start,
353  const pointField& end,
354  labelListList& hitSurfaces,
355  List<List<pointIndexHit>>& hitInfo
356 ) const
357 {
359  (
360  *this,
361  allSurfaces_,
362  start,
363  end,
364  hitSurfaces,
365  hitInfo
366  );
367 }
368 
369 
370 //Find intersections of edge nearest to both endpoints.
372 (
373  const pointField& start,
374  const pointField& end,
375  labelList& surface1,
376  List<pointIndexHit>& hit1,
377  labelList& surface2,
378  List<pointIndexHit>& hit2
379 ) const
380 {
382  (
383  *this,
384  allSurfaces_,
385  start,
386  end,
387  surface1,
388  hit1,
389  surface2,
390  hit2
391  );
392 }
393 
394 
396 (
397  const pointField& samples,
398  const scalarField& nearestDistSqr,
399  labelList& nearestSurfaces,
400  List<pointIndexHit>& nearestInfo
401 ) const
402 {
404  (
405  *this,
406  allSurfaces_,
407  samples,
408  nearestDistSqr,
409  nearestSurfaces,
410  nearestInfo
411  );
412 }
413 
414 
416 (
417  const labelListList& regionIndices,
418  const pointField& samples,
419  const scalarField& nearestDistSqr,
420  labelList& nearestSurfaces,
421  List<pointIndexHit>& nearestInfo
422 ) const
423 {
425  (
426  *this,
427  allSurfaces_,
428  regionIndices,
429 
430  samples,
431  nearestDistSqr,
432 
433  nearestSurfaces,
434  nearestInfo
435  );
436 }
437 
438 
440 {
442  (
443  *this,
444  allSurfaces_
445  );
446 }
447 
448 
449 bool Foam::searchableSurfaces::checkClosed(const bool report) const
450 {
451  if (report)
452  {
453  Info<< "Checking for closedness." << endl;
454  }
455 
456  bool hasError = false;
457 
458  forAll(*this, surfI)
459  {
460  if (!operator[](surfI).hasVolumeType())
461  {
462  hasError = true;
463 
464  if (report)
465  {
466  Info<< " " << names()[surfI]
467  << " : not closed" << endl;
468  }
469 
470  if (isA<triSurface>(operator[](surfI)))
471  {
472  const triSurface& s = dynamic_cast<const triSurface&>
473  (
474  operator[](surfI)
475  );
476  const labelListList& edgeFaces = s.edgeFaces();
477 
478  label nSingleEdges = 0;
479  forAll(edgeFaces, edgeI)
480  {
481  if (edgeFaces[edgeI].size() == 1)
482  {
483  nSingleEdges++;
484  }
485  }
486 
487  label nMultEdges = 0;
488  forAll(edgeFaces, edgeI)
489  {
490  if (edgeFaces[edgeI].size() > 2)
491  {
492  nMultEdges++;
493  }
494  }
495 
496  if (report && (nSingleEdges != 0 || nMultEdges != 0))
497  {
498  Info<< " connected to one face : "
499  << nSingleEdges << nl
500  << " connected to >2 faces : "
501  << nMultEdges << endl;
502  }
503  }
504  }
505  }
506 
507  if (report)
508  {
509  Info<< endl;
510  }
511 
512  return returnReduce(hasError, orOp<bool>());
513 }
514 
515 
517 {
518  if (report)
519  {
520  Info<< "Checking for normal orientation." << endl;
521  }
522 
523  bool hasError = false;
524 
525  forAll(*this, surfI)
526  {
527  if (isA<triSurface>(operator[](surfI)))
528  {
529  const triSurface& s = dynamic_cast<const triSurface&>
530  (
531  operator[](surfI)
532  );
533 
534  labelHashSet borderEdge(s.size()/1000);
535  PatchTools::checkOrientation(s, false, &borderEdge);
536  // Colour all faces into zones using borderEdge
537  labelList normalZone;
538  label nZones = PatchTools::markZones(s, borderEdge, normalZone);
539  if (nZones > 1)
540  {
541  hasError = true;
542 
543  if (report)
544  {
545  Info<< " " << names()[surfI]
546  << " : has multiple orientation zones ("
547  << nZones << ")" << endl;
548  }
549  }
550  }
551  }
552 
553  if (report)
554  {
555  Info<< endl;
556  }
557 
558  return returnReduce(hasError, orOp<bool>());
559 }
560 
561 
563 (
564  const scalar maxRatio,
565  const bool report
566 ) const
567 {
568  if (report)
569  {
570  Info<< "Checking for size." << endl;
571  }
572 
573  bool hasError = false;
574 
575  forAll(*this, i)
576  {
577  const boundBox& bb = operator[](i).bounds();
578 
579  for (label j = i+1; j < size(); j++)
580  {
581  scalar ratio = bb.mag()/operator[](j).bounds().mag();
582 
583  if (ratio > maxRatio || ratio < 1.0/maxRatio)
584  {
585  hasError = true;
586 
587  if (report)
588  {
589  Info<< " " << names()[i]
590  << " bounds differ from " << names()[j]
591  << " by more than a factor 100:" << nl
592  << " bounding box : " << bb << nl
593  << " bounding box : " << operator[](j).bounds()
594  << endl;
595  }
596  break;
597  }
598  }
599  }
600 
601  if (report)
602  {
603  Info<< endl;
604  }
605 
606  return returnReduce(hasError, orOp<bool>());
607 }
608 
609 
611 (
612  const scalar tolerance,
613  const autoPtr<writer<scalar>>& setWriter,
614  const bool report
615 ) const
616 {
617  if (report)
618  {
619  Info<< "Checking for intersection." << endl;
620  }
621 
622  //cpuTime timer;
623 
624  bool hasError = false;
625 
626  forAll(*this, i)
627  {
628  if (isA<triSurfaceMesh>(operator[](i)))
629  {
630  const triSurfaceMesh& s0 = dynamic_cast<const triSurfaceMesh&>
631  (
632  operator[](i)
633  );
634  const edgeList& edges0 = s0.edges();
635  const pointField& localPoints0 = s0.localPoints();
636 
637  // Collect all the edge vectors
638  pointField start(edges0.size());
639  pointField end(edges0.size());
640  forAll(edges0, edgeI)
641  {
642  const edge& e = edges0[edgeI];
643  start[edgeI] = localPoints0[e[0]];
644  end[edgeI] = localPoints0[e[1]];
645  }
646 
647  // Test all other surfaces for intersection
648  forAll(*this, j)
649  {
650  List<pointIndexHit> hits;
651 
652  //if (i == j)
653  //{
654  // // Slightly shorten the edges to prevent finding lots of
655  // // intersections. The fast triangle intersection routine
656  // // has problems with rays passing through a point of the
657  // // triangle. Now done in 'connected' routine. Tbd.
658  // vectorField d
659  // (
660  // max(tolerance, 10*s0.tolerance())
661  // *(end-start)
662  // );
663  // start += d;
664  // end -= d;
665  //}
666 
667  operator[](j).findLineAny(start, end, hits);
668 
669  label nHits = 0;
670  DynamicField<point> intersections(edges0.size()/100);
671  DynamicField<scalar> intersectionEdge(intersections.capacity());
672 
673  forAll(hits, edgeI)
674  {
675  if
676  (
677  hits[edgeI].hit()
678  && (i != j || !connected(s0, edgeI, hits[edgeI]))
679  )
680  {
681  intersections.append(hits[edgeI].hitPoint());
682  intersectionEdge.append(1.0*edgeI);
683  nHits++;
684  }
685  }
686 
687  // tdb. What about distributedTriSurfaceMesh?
688  //reduce(nHits, sumOp<label>());
689 
690  if (nHits > 0)
691  {
692  if (report)
693  {
694  Info<< " " << names()[i]
695  << " intersects " << names()[j]
696  << " at " << nHits
697  << " locations."
698  << endl;
699 
700  if (setWriter)
701  {
702  scalarField dist(mag(intersections));
703  coordSet track
704  (
705  names()[i] + '_' + names()[j],
706  "xyz",
707  std::move(intersections),
708  std::move(dist)
709  );
710  wordList valueSetNames(1, "edgeIndex");
711  List<const scalarField*> valueSets
712  (
713  1,
714  &intersectionEdge
715  );
716 
717  fileName fName
718  (
719  setWriter().getFileName(track, valueSetNames)
720  );
721  Info<< " Writing intersection locations to "
722  << fName << endl;
723  OFstream os
724  (
725  s0.searchableSurface::time().path()
726  /fName
727  );
728  setWriter().write
729  (
730  track,
731  valueSetNames,
732  valueSets,
733  os
734  );
735  }
736  }
737 
738  hasError = true;
739  break;
740  }
741  }
742  }
743  }
744 
745  if (report)
746  {
747  Info<< endl;
748  }
749 
750  return returnReduce(hasError, orOp<bool>());
751 }
752 
753 
755 (
756  const scalar minQuality,
757  const bool report
758 ) const
759 {
760  if (report)
761  {
762  Info<< "Checking for triangle quality." << endl;
763  }
764 
765  bool hasError = false;
766 
767  forAll(*this, surfI)
768  {
769  if (isA<triSurface>(operator[](surfI)))
770  {
771  const triSurface& s = dynamic_cast<const triSurface&>
772  (
773  operator[](surfI)
774  );
775 
776  label nBadTris = 0;
777  forAll(s, facei)
778  {
779  const labelledTri& f = s[facei];
780 
781  scalar q = triPointRef
782  (
783  s.points()[f[0]],
784  s.points()[f[1]],
785  s.points()[f[2]]
786  ).quality();
787 
788  if (q < minQuality)
789  {
790  nBadTris++;
791  }
792  }
793 
794  if (nBadTris > 0)
795  {
796  hasError = true;
797 
798  if (report)
799  {
800  Info<< " " << names()[surfI]
801  << " : has " << nBadTris << " bad quality triangles "
802  << " (quality < " << minQuality << ")" << endl;
803  }
804  }
805  }
806  }
807 
808  if (report)
809  {
810  Info<< endl;
811  }
812 
813  return returnReduce(hasError, orOp<bool>());
814 
815 }
816 
817 
818 // Check all surfaces. Return number of failures.
820 (
821  const bool report
822 ) const
823 {
824  label noFailedChecks = 0;
825 
826  if (checkClosed(report))
827  {
828  noFailedChecks++;
829  }
830 
831  if (checkNormalOrientation(report))
832  {
833  noFailedChecks++;
834  }
835  return noFailedChecks;
836 }
837 
838 
840 (
841  const scalar maxRatio,
842  const scalar tol,
843  const autoPtr<writer<scalar>>& setWriter,
844  const scalar minQuality,
845  const bool report
846 ) const
847 {
848  label noFailedChecks = 0;
849 
850  if (maxRatio > 0 && checkSizes(maxRatio, report))
851  {
852  noFailedChecks++;
853  }
854 
855  if (checkIntersection(tol, setWriter, report))
856  {
857  noFailedChecks++;
858  }
859 
860  if (checkQuality(minQuality, report))
861  {
862  noFailedChecks++;
863  }
864 
865  return noFailedChecks;
866 }
867 
868 
870 (
871  const List<wordList>& patchTypes,
872  Ostream& os
873 ) const
874 {
875  Info<< "Statistics." << endl;
876  forAll(*this, surfI)
877  {
878  Info<< " " << names()[surfI] << ':' << endl;
879 
880  const searchableSurface& s = operator[](surfI);
881 
882  Info<< " type : " << s.type() << nl
883  << " size : " << s.globalSize() << nl;
884  if (isA<triSurfaceMesh>(s))
885  {
886  const triSurfaceMesh& ts = dynamic_cast<const triSurfaceMesh&>(s);
887  Info<< " edges : " << ts.nEdges() << nl
888  << " points : " << ts.points()().size() << nl;
889  }
890  Info<< " bounds : " << s.bounds() << nl
891  << " closed : " << Switch(s.hasVolumeType()) << endl;
892 
893  if (patchTypes.size() && patchTypes[surfI].size() >= 1)
894  {
895  wordList unique(wordHashSet(patchTypes[surfI]).sortedToc());
896  Info<< " patches : ";
897  forAll(unique, i)
898  {
899  Info<< unique[i];
900  if (i < unique.size()-1)
901  {
902  Info<< ',';
903  }
904  }
905  Info<< endl;
906  }
907  }
908  Info<< endl;
909 }
910 
911 
912 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
913 
914 const Foam::searchableSurface& Foam::searchableSurfaces::operator[]
915 (
916  const word& surfName
917 ) const
918 {
919  const label surfI = findSurfaceID(surfName);
920 
921  if (surfI < 0)
922  {
924  << "Surface named " << surfName << " not found." << nl
925  << "Available surface names: " << names_ << endl
926  << abort(FatalError);
927  }
928 
929  return operator[](surfI);
930 }
931 
932 
933 Foam::searchableSurface& Foam::searchableSurfaces::operator[]
934 (
935  const word& surfName
936 )
937 {
938  const label surfI = findSurfaceID(surfName);
939 
940  if (surfI < 0)
941  {
943  << "Surface named " << surfName << " not found." << nl
944  << "Available surface names: " << names_ << endl
945  << abort(FatalError);
946  }
947 
948  return operator[](surfI);
949 }
950 
951 
952 // ************************************************************************* //
nZones
label nZones
Definition: interpolatedFaces.H:24
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:67
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::constant::atomic::mp
const dimensionedScalar mp
Proton mass.
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:77
Foam::boundBox::mag
scalar mag() const
The magnitude of the bounding box span.
Definition: boundBoxI.H:133
Foam::BitOps::set
void set(List< bool > &bools, const labelRange &range)
Set the specified range 'on' in a boolList.
Definition: BitOps.C:37
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
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::PrimitivePatch::edges
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
Definition: PrimitivePatch.C:183
PatchTools.H
Foam::searchableSurfaces::checkIntersection
bool checkIntersection(const scalar tol, const autoPtr< writer< scalar >> &, const bool report) const
Do surfaces self-intersect or intersect others.
Definition: searchableSurfaces.C:611
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: dictionaryI.H:87
Foam::searchableSurfaces::checkQuality
bool checkQuality(const scalar minQuality, const bool report) const
Check triangle quality.
Definition: searchableSurfaces.C:755
Foam::searchableSurfaces::findNearestIntersection
void findNearestIntersection(const pointField &start, const pointField &end, labelList &surface1, List< pointIndexHit > &hit1, labelList &surface2, List< pointIndexHit > &hit2) const
Definition: searchableSurfaces.C:372
Foam::PrimitivePatch::nEdges
label nEdges() const
Number of edges in patch.
Definition: PrimitivePatch.H:322
Foam::searchableSurfaces::checkTopology
label checkTopology(const bool report) const
All topological checks. Return number of failed checks.
Definition: searchableSurfaces.C:820
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::searchableSurfacesQueries::findAnyIntersection
static void findAnyIntersection(const PtrList< searchableSurface > &, const labelList &surfacesToTest, const pointField &start, const pointField &end, labelList &surfaces, List< pointIndexHit > &)
Find any intersection. Return hit point information and.
Definition: searchableSurfacesQueries.C:122
Foam::glTF::key
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:108
Foam::triSurfaceMesh
IOoject and searching on triSurface.
Definition: triSurfaceMesh.H:106
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::searchableSurfaces::writeStats
void writeStats(const List< wordList > &, Ostream &) const
Write some stats.
Definition: searchableSurfaces.C:870
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::HashSet< label, Hash< label > >
Foam::OBJstream::write
virtual Ostream & write(const char c)
Write character.
Definition: OBJstream.C:78
searchableSurfacesQueries.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
patchTypes
wordList patchTypes(nPatches)
Foam::DynamicField
Dynamically sized Field.
Definition: DynamicField.H:49
searchableSurfaces.H
n
label n
Definition: TABSMDCalcMethod2.H:31
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::searchableSurfaces::findAnyIntersection
void findAnyIntersection(const pointField &start, const pointField &end, labelList &surfaces, List< pointIndexHit > &) const
Find any intersection. Return hit point information and.
Definition: searchableSurfaces.C:331
Foam::searchableSurfaces::bounds
boundBox bounds() const
Calculate bounding box.
Definition: searchableSurfaces.C:439
Foam::searchableSurfacesQueries::findNearestIntersection
static void findNearestIntersection(const PtrList< searchableSurface > &allSurfaces, const labelList &surfacesToTest, const pointField &start, const pointField &end, labelList &surface1, List< pointIndexHit > &hit1, labelList &surface2, List< pointIndexHit > &hit2)
Find intersections of edge nearest to both endpoints.
Definition: searchableSurfacesQueries.C:262
Foam::Field< vector >
Foam::searchableSurfaces::checkClosed
bool checkClosed(const bool report) const
Are all surfaces closed and manifold.
Definition: searchableSurfaces.C:449
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:76
Foam::searchableSurfaces::findNearest
void findNearest(const pointField &, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &) const
Find nearest. Return -1 (and a miss()) or surface and nearest.
Definition: searchableSurfaces.C:396
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::searchableSurface
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Definition: searchableSurface.H:69
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:460
Foam::PtrList::setSize
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:151
samples
scalarField samples(nIntervals, Zero)
Foam::IOobject::clone
autoPtr< IOobject > clone() const
Clone.
Definition: IOobject.H:468
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
Foam::searchableSurfaces::findSurfaceRegionID
label findSurfaceRegionID(const word &surfaceName, const word &regionName) const
Definition: searchableSurfaces.C:318
Foam::searchableSurfaces::findSurfaceID
label findSurfaceID(const word &name) const
Find index of surface. Return -1 if not found.
Definition: searchableSurfaces.C:309
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:123
os
OBJstream os(runTime.globalPath()/outputName)
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::writer< scalar >
Foam::coordSet
Holds list of sampling positions.
Definition: coordSet.H:53
Foam::triSurfaceMesh::points
virtual tmp< pointField > points() const
Get the points that define the surface.
Definition: triSurfaceMesh.C:596
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
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::searchableSurfaces::checkSizes
bool checkSizes(const scalar maxRatio, const bool report) const
Are all bounding boxes of similar size.
Definition: searchableSurfaces.C:563
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:359
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::searchableSurfaces::checkGeometry
label checkGeometry(const scalar maxRatio, const scalar tolerance, const autoPtr< writer< scalar >> &setWriter, const scalar minQuality, const bool report) const
All geometric checks. Return number of failed checks.
Definition: searchableSurfaces.C:840
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
DynamicField.H
Foam::searchableSurfacesQueries::bounds
static boundBox bounds(const PtrList< searchableSurface > &allSurfaces, const labelUList &surfacesToTest)
Find the boundBox of the selected surfaces.
Definition: searchableSurfacesQueries.C:697
Foam::pointIndexHit
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
Definition: pointIndexHit.H:46
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::List< word >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
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::searchableSurfaces::checkNormalOrientation
bool checkNormalOrientation(const bool report) const
Are all (triangulated) surfaces consistent normal orientation.
Definition: searchableSurfaces.C:516
Foam::labelledTri
A triFace with additional (region) index.
Definition: labelledTri.H:57
Foam::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
Foam::searchableSurfacesQueries::findAllIntersections
static void findAllIntersections(const PtrList< searchableSurface > &, const labelList &surfacesToTest, const pointField &start, const pointField &end, labelListList &surfaces, List< List< pointIndexHit >> &surfaceHits)
Find all intersections in order from start to end. Returns for.
Definition: searchableSurfacesQueries.C:183
Foam::wordHashSet
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
Definition: HashSet.H:77
Foam::PatchTools::markZones
static label markZones(const PrimitivePatch< FaceList, PointField > &, const BoolListType &borderEdge, labelList &faceZone)
Size and fills faceZone with zone of face.
ListOps.H
Various functions to operate on Lists.
Foam::PatchTools::checkOrientation
static bool checkOrientation(const PrimitivePatch< FaceList, PointField > &, const bool report=false, labelHashSet *marked=0)
Check for orientation issues.
Definition: PatchToolsCheck.C:36
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::orOp
Definition: ops.H:234
Foam::PtrListOps::names
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Foam::IOobject::path
fileName path() const
The complete path.
Definition: IOobject.C:511
triSurfaceMesh.H
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::searchableSurfaces::findAllIntersections
void findAllIntersections(const pointField &start, const pointField &end, labelListList &surfaces, List< List< pointIndexHit >> &) const
Find all intersections in order from start to end. Returns for.
Definition: searchableSurfaces.C:351
triFace
face triFace(3)
Foam::searchableSurfacesQueries::findNearest
static void findNearest(const PtrList< searchableSurface > &, const labelList &surfacesToTest, const pointField &, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &)
Find nearest. Return -1 (and a miss()) or surface and nearest.
Definition: searchableSurfacesQueries.C:349
Foam::triPointRef
triangle< point, const point & > triPointRef
A triangle using referred points.
Definition: triangle.H:71