triSurface_searchableSurface.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "randomGenerator.H"
29 #include "EdgeMap.H"
30 #include "labelIOField.H"
31 #include "Time.H"
32 #include "PatchTools.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38  namespace searchableSurfaces
39  {
41 
43  (
45  triSurface,
47  );
48 
50  (
52  triSurface,
53  dictionary,
54  triSurfaceMesh,
55  "triSurfaceMesh"
56  );
57  }
58 }
59 
60 
61 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
62 
63 Foam::fileName Foam::searchableSurfaces::triSurface::checkFile
64 (
65  const regIOobject& io,
66  const bool isGlobal
67 )
68 {
69  const fileName fName(io.filePath(isGlobal));
70 
71  if (fName.empty())
72  {
74  << "Cannot find triSurface file starting from "
75  << io.objectPath() << exit(FatalError);
76  }
77 
78  return fName;
79 }
80 
81 
82 Foam::fileName Foam::searchableSurfaces::triSurface::relativeFilePath
83 (
84  const regIOobject& io,
85  const fileName& f,
86  const bool isGlobal
87 )
88 {
89  fileName fName(f);
90  fName.expand();
91  if (!fName.isAbsolute())
92  {
93  // Is the specified file:
94  // - local to the cwd?
95  // - local to the case dir?
96  // - or just another name?
97  fName = fileHandler().filePath(isGlobal, IOobject(io, fName));
98  }
99  return fName;
100 }
101 
102 
103 Foam::fileName Foam::searchableSurfaces::triSurface::checkFile
104 (
105  const regIOobject& io,
106  const dictionary& dict,
107  const bool isGlobal
108 )
109 {
110  fileName dictFName, fName;
111 
112  if (dict.readIfPresent("file", dictFName, false, false))
113  {
114  fName = relativeFilePath(io, dictFName, isGlobal);
115 
116  if (!exists(fName))
117  {
119  << "Cannot find triSurface file " << io.path()/dictFName
120  << exit(FatalError);
121  }
122  }
123  else
124  {
125  fName = io.filePath(isGlobal);
126 
127  if (!exists(fName))
128  {
130  << "Cannot find triSurface file starting from "
131  << io.objectPath() << exit(FatalError);
132  }
133  }
134 
135  return fName;
136 }
137 
138 
139 void Foam::searchableSurfaces::triSurface::scale
140 (
141  const dictionary& dict
142 )
143 {
144  const bool haveScale = dict.found("scale");
145  const bool haveUnits = dict.found("units");
146 
147  if (haveScale && haveUnits)
148  {
150  << "both keywords 'scale' and 'units' defined in dictionary "
151  << dict.name() << exit(FatalIOError);
152  }
153 
154  if (haveScale)
155  {
156  triSurface::scalePoints(dict.lookup<scalar>("scale", units::none));
157  }
158 
159  if (haveUnits)
160  {
161  unitSet units(dimensions::length);
162  units.read(dict.lookup("units"));
163  triSurface::scalePoints(units.toStandard(scalar(1)));
164  }
165 }
166 
167 
168 bool Foam::searchableSurfaces::triSurface::addFaceToEdge
169 (
170  const edge& e,
171  EdgeMap<label>& facesPerEdge
172 )
173 {
174  EdgeMap<label>::iterator eFnd = facesPerEdge.find(e);
175  if (eFnd != facesPerEdge.end())
176  {
177  if (eFnd() == 2)
178  {
179  return false;
180  }
181  eFnd()++;
182  }
183  else
184  {
185  facesPerEdge.insert(e, 1);
186  }
187  return true;
188 }
189 
190 
191 bool Foam::searchableSurfaces::triSurface::isSurfaceClosed() const
192 {
193  const pointField& pts = Foam::triSurface::points();
194 
195  // Construct pointFaces. Let's hope surface has compact point
196  // numbering ...
197  labelListList pointFaces;
198  invertManyToMany(pts.size(), *this, pointFaces);
199 
200  // Loop over all faces surrounding point. Count edges emanating from point.
201  // Every edge should be used by two faces exactly.
202  // To prevent doing work twice per edge only look at edges to higher
203  // point
204  EdgeMap<label> facesPerEdge(100);
205  forAll(pointFaces, pointi)
206  {
207  const labelList& pFaces = pointFaces[pointi];
208 
209  facesPerEdge.clear();
210  forAll(pFaces, i)
211  {
212  const triSurface::FaceType& f =
214  label fp = findIndex(f, pointi);
215 
216  // Something weird: if I expand the code of addFaceToEdge in both
217  // below instances it gives a segmentation violation on some
218  // surfaces. Compiler (4.3.2) problem?
219 
220 
221  // Forward edge
222  label nextPointi = f[f.fcIndex(fp)];
223 
224  if (nextPointi > pointi)
225  {
226  bool okFace = addFaceToEdge
227  (
228  edge(pointi, nextPointi),
229  facesPerEdge
230  );
231 
232  if (!okFace)
233  {
234  return false;
235  }
236  }
237  // Reverse edge
238  label prevPointi = f[f.rcIndex(fp)];
239 
240  if (prevPointi > pointi)
241  {
242  bool okFace = addFaceToEdge
243  (
244  edge(pointi, prevPointi),
245  facesPerEdge
246  );
247 
248  if (!okFace)
249  {
250  return false;
251  }
252  }
253  }
254 
255  // Check for any edges used only once.
256  forAllConstIter(EdgeMap<label>, facesPerEdge, iter)
257  {
258  if (iter() != 2)
259  {
260  return false;
261  }
262  }
263  }
264 
265  return true;
266 }
267 
268 
269 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
270 
272 (
273  const IOobject& io,
274  const Foam::triSurface& s
275 )
276 :
277  searchableSurface(io),
279  (
280  IOobject
281  (
282  io.name(),
283  io.instance(),
284  io.local(),
285  io.db(),
286  io.readOpt(),
287  io.writeOpt(),
288  false // searchableSurface already registered under name
289  )
290  ),
291  Foam::triSurface(s),
293  minQuality_(-1),
294  surfaceClosed_(-1)
295 {
296  const pointField& pts = Foam::triSurface::points();
297 
298  bounds() = boundBox(pts, false);
299 }
300 
301 
303 :
304  // Find instance for triSurface
305  searchableSurface(io),
306  // Reused found instance in objectRegistry
308  (
309  IOobject
310  (
311  io.name(),
312  searchableSurface::instance(),
313  io.local(),
314  io.db(),
315  io.readOpt(),
316  io.writeOpt(),
317  false // searchableSurface already registered under name
318  )
319  ),
321  (
322  checkFile(static_cast<const searchableSurface&>(*this), true)
323  ),
324  triSurfaceRegionSearch(static_cast<const Foam::triSurface&>(*this)),
325  minQuality_(-1),
326  surfaceClosed_(-1)
327 {
328  const pointField& pts = Foam::triSurface::points();
329 
330  bounds() = boundBox(pts, false);
331 }
332 
333 
335 (
336  const IOobject& io,
337  const dictionary& dict
338 )
339 :
340  searchableSurface(io),
341  // Reused found instance in objectRegistry
343  (
344  IOobject
345  (
346  io.name(),
347  searchableSurface::instance(),
348  io.local(),
349  io.db(),
350  io.readOpt(),
351  io.writeOpt(),
352  false // searchableSurface already registered under name
353  )
354  ),
356  (
357  checkFile(static_cast<const searchableSurface&>(*this), dict, true)
358  ),
359  triSurfaceRegionSearch(static_cast<const Foam::triSurface&>(*this), dict),
360  fName_
361  (
362  relativeFilePath
363  (
364  static_cast<const searchableSurface&>(*this),
365  dict.lookup("file", false, false),
366  true
367  )
368  ),
369  minQuality_(-1),
370  surfaceClosed_(-1)
371 {
372  scale(dict);
373 
374  const pointField& pts = Foam::triSurface::points();
375 
376  bounds() = boundBox(pts, false);
377 
378  // Have optional minimum quality for normal calculation
379  if (dict.readIfPresent("minQuality", minQuality_) && minQuality_ > 0)
380  {
382  << " : ignoring triangles with quality < "
383  << minQuality_ << " for normals calculation." << endl;
384  }
385 }
386 
387 
389 (
390  const IOobject& io,
391  const bool isGlobal
392 )
393 :
394  // Find instance for triSurface
395  searchableSurface(io),
396  // Reused found instance in objectRegistry
398  (
399  IOobject
400  (
401  io.name(),
402  searchableSurface::instance(),
403  io.local(),
404  io.db(),
405  io.readOpt(),
406  io.writeOpt(),
407  false // searchableSurface already registered under name
408  )
409  ),
411  (
412  checkFile(static_cast<const searchableSurface&>(*this), isGlobal)
413  ),
414  triSurfaceRegionSearch(static_cast<const Foam::triSurface&>(*this)),
415  minQuality_(-1),
416  surfaceClosed_(-1)
417 {
418  const pointField& pts = Foam::triSurface::points();
419 
420  bounds() = boundBox(pts, false);
421 }
422 
423 
425 (
426  const IOobject& io,
427  const dictionary& dict,
428  const bool isGlobal
429 )
430 :
431  searchableSurface(io),
432  // Reused found instance in objectRegistry
434  (
435  IOobject
436  (
437  io.name(),
438  searchableSurface::instance(),
439  io.local(),
440  io.db(),
441  io.readOpt(),
442  io.writeOpt(),
443  false // searchableSurface already registered under name
444  )
445  ),
447  (
448  checkFile(static_cast<const searchableSurface&>(*this), dict, isGlobal)
449  ),
450  triSurfaceRegionSearch(static_cast<const Foam::triSurface&>(*this), dict),
451  minQuality_(-1),
452  surfaceClosed_(-1)
453 {
454  // Reading from supplied file name instead of objectPath/filePath
455  if (dict.readIfPresent("file", fName_, false, false))
456  {
457  fName_ = relativeFilePath
458  (
459  static_cast<const searchableSurface&>(*this),
460  fName_,
461  isGlobal
462  );
463  }
464 
465  scale(dict);
466 
467  const pointField& pts = Foam::triSurface::points();
468 
469  bounds() = boundBox(pts, false);
470 
471  // Have optional minimum quality for normal calculation
472  if (dict.readIfPresent("minQuality", minQuality_) && minQuality_ > 0)
473  {
475  << " : ignoring triangles with quality < "
476  << minQuality_ << " for normals calculation." << endl;
477  }
478 }
479 
480 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
481 
483 {
484  clearOut();
485 }
486 
487 
489 {
491  edgeTree_.clear();
493 }
494 
495 
496 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
497 
500 {
501  tmp<pointField> tPts(new pointField(8));
502  pointField& pt = tPts.ref();
503 
504  // Use copy to calculate face centres so they don't get stored
506  (
509  ).faceCentres();
510 
511  return tPts;
512 }
513 
514 
516 (
517  pointField& centres,
518  scalarField& radiusSqr
519 ) const
520 {
521  centres = coordinates();
522  radiusSqr.setSize(size());
523  radiusSqr = 0.0;
524 
525  const pointField& pts = Foam::triSurface::points();
526 
527  forAll(*this, facei)
528  {
530  const point& fc = centres[facei];
531  forAll(f, fp)
532  {
533  const point& pt = pts[f[fp]];
534  radiusSqr[facei] = max(radiusSqr[facei], Foam::magSqr(fc-pt));
535  }
536  }
537 
538  // Add a bit to make sure all points are tested inside
539  radiusSqr += Foam::sqr(small);
540 }
541 
542 
545 {
546  return Foam::triSurface::points();
547 }
548 
549 
551 (
552  const boundBox& bb
553 ) const
554 {
555  const indexedOctree<treeDataTriSurface>& octree = tree();
556 
557  labelList indices = octree.findBox(treeBoundBox(bb));
558 
559  return !indices.empty();
560 }
561 
562 
564 (
565  const pointField& newPoints
566 )
567 {
569  edgeTree_.clear();
570  Foam::triSurface::setPoints(newPoints);
571 }
572 
573 
576 {
577  if (edgeTree_.empty())
578  {
579  // Boundary edges
580  labelList bEdges
581  (
583  (
584  nInternalEdges(),
585  nEdges() - nInternalEdges()
586  )
587  );
588 
589  treeBoundBox bb(Zero, Zero);
590 
591  if (bEdges.size())
592  {
593  label nPoints;
595  (
596  *this,
597  bb,
598  nPoints
599  );
600 
601  // Slightly extended bb. Slightly off-centred just so on symmetric
602  // geometry there are less face/edge aligned items.
603  bb = bb.extend(1e-4);
604  }
605 
606  scalar oldTol = indexedOctree<treeDataEdge>::perturbTol();
608 
609  edgeTree_.reset
610  (
612  (
614  (
615  false, // cachebb
616  edges(), // edges
617  localPoints(), // points
618  bEdges // selected edges
619  ),
620  bb, // bb
621  maxTreeDepth(), // maxLevel
622  10, // leafsize
623  3.0 // duplicity
624  )
625  );
626 
628  }
629  return edgeTree_();
630 }
631 
632 
634 {
635  if (regions_.empty())
636  {
637  regions_.setSize(patches().size());
638  forAll(regions_, regionI)
639  {
640  regions_[regionI] = patches()[regionI].name();
641  }
642  }
643  return regions_;
644 }
645 
646 
648 {
649  if (surfaceClosed_ == -1)
650  {
651  if (isSurfaceClosed())
652  {
653  surfaceClosed_ = 1;
654  }
655  else
656  {
657  surfaceClosed_ = 0;
658  }
659  }
660 
661  return surfaceClosed_ == 1;
662 }
663 
664 
666 (
667  const pointField& samples,
668  const scalarField& nearestDistSqr,
669  List<pointIndexHit>& info
670 ) const
671 {
672  triSurfaceSearch::findNearest(samples, nearestDistSqr, info);
673 }
674 
675 
677 (
678  const pointField& samples,
679  const scalarField& nearestDistSqr,
680  const labelList& regionIndices,
681  List<pointIndexHit>& info
682 ) const
683 {
685  (
686  samples,
687  nearestDistSqr,
688  regionIndices,
689  info
690  );
691 }
692 
693 
695 (
696  const pointField& start,
697  const pointField& end,
698  List<pointIndexHit>& info
699 ) const
700 {
701  triSurfaceSearch::findLine(start, end, info);
702 }
703 
704 
706 (
707  const pointField& start,
708  const pointField& end,
709  List<pointIndexHit>& info
710 ) const
711 {
712  triSurfaceSearch::findLineAny(start, end, info);
713 }
714 
715 
717 (
718  const pointField& start,
719  const pointField& end,
721 ) const
722 {
723  triSurfaceSearch::findLineAll(start, end, info);
724 }
725 
726 
728 (
729  const List<pointIndexHit>& info,
731 ) const
732 {
733  region.setSize(info.size());
734  forAll(info, i)
735  {
736  if (info[i].hit())
737  {
738  region[i] = Foam::triSurface::operator[](info[i].index()).region();
739  }
740  else
741  {
742  region[i] = -1;
743  }
744  }
745 }
746 
747 
749 (
750  const List<pointIndexHit>& info,
751  vectorField& normal
752 ) const
753 {
754  const Foam::triSurface& s = *this;
755  const pointField& pts = s.points();
756 
757  normal.setSize(info.size());
758 
759  if (minQuality_ >= 0)
760  {
761  // Make sure we don't use triangles with low quality since
762  // normal is not reliable.
763 
764  const labelListList& faceFaces = s.faceFaces();
765 
766  forAll(info, i)
767  {
768  if (info[i].hit())
769  {
770  label facei = info[i].index();
771  normal[i] = s[facei].area(pts);
772 
773  scalar qual = s[facei].tri(pts).quality();
774 
775  if (qual < minQuality_)
776  {
777  // Search neighbouring triangles
778  const labelList& fFaces = faceFaces[facei];
779 
780  forAll(fFaces, j)
781  {
782  label nbrI = fFaces[j];
783  scalar nbrQual = s[nbrI].tri(pts).quality();
784  if (nbrQual > qual)
785  {
786  qual = nbrQual;
787  normal[i] = s[nbrI].area(pts);
788  }
789  }
790  }
791 
792  normal[i] /= mag(normal[i]) + vSmall;
793  }
794  else
795  {
796  // Set to what?
797  normal[i] = Zero;
798  }
799  }
800  }
801  else
802  {
803  forAll(info, i)
804  {
805  if (info[i].hit())
806  {
807  label facei = info[i].index();
808  // Cached:
809  // normal[i] = faceNormals()[facei];
810 
811  // Uncached
812  normal[i] = s[facei].normal(pts);
813  }
814  else
815  {
816  // Set to what?
817  normal[i] = Zero;
818  }
819  }
820  }
821 }
822 
823 
825 (
826  const pointField& points,
827  List<volumeType>& volType
828 ) const
829 {
830  volType.setSize(points.size());
831 
834 
835  forAll(points, pointi)
836  {
837  const point& pt = points[pointi];
838 
839  if (!tree().bb().contains(pt))
840  {
841  // Have to calculate directly as outside the octree
842  volType[pointi] = tree().shapes().getVolumeType(tree(), pt);
843  }
844  else
845  {
846  // - use cached volume type per each tree node
847  volType[pointi] = tree().getVolumeType(pt);
848  }
849  }
850 
852 }
853 
854 
856 {
857  autoPtr<labelIOField> fldPtr
858  (
859  new labelIOField
860  (
861  IOobject
862  (
863  "values",
866  *this,
869  ),
870  labelField(values)
871  )
872  );
873 
874  // Store field on triMesh
875  fldPtr.ptr()->store();
876 }
877 
878 
880 (
881  const List<pointIndexHit>& info,
882  labelList& values
883 ) const
884 {
885  if (foundObject<labelIOField>("values"))
886  {
887  values.setSize(info.size());
888 
889  const labelIOField& fld = lookupObject<labelIOField>
890  (
891  "values"
892  );
893 
894  forAll(info, i)
895  {
896  if (info[i].hit())
897  {
898  values[i] = fld[info[i].index()];
899  }
900  }
901  }
902 }
903 
904 
906 (
910  const bool write
911 ) const
912 {
913  fileName fullPath;
914  if (fName_.size())
915  {
916  // Override file name
917 
918  fullPath = fName_;
919 
920  fullPath.expand();
921  if (!fullPath.isAbsolute())
922  {
923  // Add directory from regIOobject
924  fullPath = searchableSurface::objectPath().path()/fullPath;
925  }
926  }
927  else
928  {
929  fullPath = searchableSurface::objectPath();
930  }
931 
932  if (!mkDir(fullPath.path()))
933  {
934  return false;
935  }
936 
937  Foam::triSurface::write(fullPath);
938 
939  if (!isFile(fullPath))
940  {
941  return false;
942  }
943 
944  return true;
945 }
946 
947 
948 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
Macros for easy insertion into run-time selection tables.
friend class iterator
Declare friendship with the iterator.
Definition: HashTable.H:194
A primitive field of type <Type> with automated input and output.
Definition: IOField.H:53
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const word & name() const
Return name.
Definition: IOobject.H:307
Version number type.
Definition: IOstream.H:97
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:87
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:194
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
static void calcBounds(const PrimitivePatch< FaceList, PointField > &p, boundBox &bb, label &nPoints)
A list of faces which address into the list of points.
const Field< PointType > & points() const
Return reference to global points.
std::remove_reference< ::Foam::List< labelledTri > >::type::value_type FaceType
A List obtained as a section of another List.
Definition: SubList.H:56
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:325
T & operator[](const label)
Return element of UList.
Definition: UListI.H:167
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
T * ptr()
Return object pointer for reuse.
Definition: autoPtrI.H:90
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:60
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
A class for handling file names.
Definition: fileName.H:82
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:73
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:284
virtual fileName filePath(const bool globalFile, const IOobject &) const =0
Search for an object. globalFile : also check undecomposed case.
Non-pointer based hierarchical recursive searching.
Definition: indexedOctree.H:72
static scalar & perturbTol()
Get the perturbation tolerance.
Triangle with additional region number.
Definition: labelledTri.H:60
Registry of regIOobjects.
const Time & time() const
Return time.
fileName objectPath() const
Return complete path + object name.
Definition: regIOobject.H:155
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
static const word & geometryDir()
Return the geometry directory name.
const boundBox & bounds() const
Return const reference to boundBox.
A surface geometry formed of discrete facets, e.g. triangles and/or quadrilaterals,...
virtual void getVolumeType(const pointField &, List< volumeType > &) const
Determine type (inside/outside/mixed) for point. unknown if.
virtual void findLine(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Find first intersection on segment from start to end.
virtual bool overlaps(const boundBox &bb) const
Does any part of the surface overlap the supplied bound box?
const indexedOctree< treeDataEdge > & edgeTree() const
Demand driven construction of octree for boundary edges.
virtual void findLineAny(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Return any intersection on segment from start to end.
virtual void boundingSpheres(pointField &centres, scalarField &radiusSqr) const
Get bounding spheres (centre and radius squared). Any point.
virtual void setField(const labelList &values)
WIP. Store element-wise field.
virtual void getField(const List< pointIndexHit > &, labelList &) const
WIP. From a set of hits (points and.
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write=true) const
Write using given format, version and compression.
virtual void getNormal(const List< pointIndexHit > &, vectorField &normal) const
From a set of points and indices get the normal.
virtual void getRegion(const List< pointIndexHit > &, labelList &region) const
From a set of points and indices get the region.
virtual const wordList & regions() const
Names of regions.
virtual bool hasVolumeType() const
Whether supports volume type below. I.e. whether is closed.
virtual void findNearest(const pointField &sample, const scalarField &nearestDistSqr, List< pointIndexHit > &) const
virtual tmp< pointField > coordinates() const
Get representative set of element coordinates.
virtual void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit >> &) const
Get all intersections in order from start to end.
virtual void setPoints(const pointField &)
Move points.
virtual tmp< pointField > points() const
Get the points that define the surface.
string & expand(const bool allowEmpty=false)
Expand initial tildes and all occurrences of environment variables.
Definition: string.C:125
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
Standard boundBox + extra functionality for use in octree.
Definition: treeBoundBox.H:90
treeBoundBox extend(const scalar s) const
Return asymmetrically extended bounding box, with guaranteed.
Holds data for octree to work on an edges subset.
Definition: treeDataEdge.H:54
label size() const
Return size.
Helper class to search on triSurface. Creates an octree for each region of the surface and only searc...
void findNearest(const pointField &samples, const scalarField &nearestDistSqr, const labelList &regionIndices, List< pointIndexHit > &info) const
Find the nearest point on the surface out of the regions.
void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit >> &info) const
Calculate all intersections from start to end.
void findLine(const pointField &start, const pointField &end, List< pointIndexHit > &info) const
void findLineAny(const pointField &start, const pointField &end, List< pointIndexHit > &info) const
void findNearest(const pointField &samples, const scalarField &nearestDistSqr, List< pointIndexHit > &info) const
Triangulated surface description with patch information.
Definition: triSurface.H:68
virtual void scalePoints(const scalar)
Scale points. A non-positive factor is ignored.
Definition: triSurface.C:761
triSurface()
Construct null.
Definition: triSurface.C:535
virtual void setPoints(const pointField &)
Move points.
Definition: triSurface.C:748
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
const pointField & points
label nPoints
gmvFile<< "tracers "<< particles.size()<< nl;{ pointField positions(particles.size());label particlei=0;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter) { positions[particlei++]=iter().position(mesh);} for(i=0;i< pTraits< point >::nComponents;i++) { forAll(positions, particlei) { gmvFile<< component(positions[particlei], i)<< ' ';} gmvFile<< nl;}}forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const fvPatchList & patches
const dimensionSet length
addToRunTimeSelectionTable(searchableSurface, box, dictionary)
addBackwardCompatibleToRunTimeSelectionTable(searchableSurface, box, dictionary, searchableBox, "searchableBox")
barycentric coordinates(const polyMesh &mesh, const point &position, const label celli, const label facei, const label faceTrii, const scalar stepFraction)
Return the coordinates given the position and tet topology.
Definition: tracking.C:1258
const unitSet none
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
Namespace for OpenFOAM.
bool isFile(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist as a file in the file system?
Definition: POSIX.C:555
const fileOperation & fileHandler()
Get current file handler.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const zero Zero
Definition: zero.H:97
const doubleScalar e
Definition: doubleScalar.H:106
List< label > labelList
A List of labels.
Definition: labelList.H:56
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:59
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:290
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
bool exists(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist (as directory or file) in the file system?
Definition: POSIX.C:520
messageStream Info
const fvMesh & region(const dictionary &dict)
Cast the give dictionary to the corresponding region fvMesh.
Definition: fvMesh.C:1831
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
Field< label > labelField
Specialisation of Field<T> for label.
Definition: labelField.H:49
IOerror FatalIOError
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
error FatalError
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
void invertManyToMany(const label len, const UList< InList > &, List< OutList > &)
Invert many-to-many.
labelList f(nPoints)
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=*(cellModeller::lookup("hex"));labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells]=cellShape(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< small) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &mergedCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
Definition: readKivaGrid.H:229
dictionary dict
scalarField samples(nIntervals, 0)