triSurface.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 
26 #include "triSurface.H"
27 #include "demandDrivenData.H"
28 #include "IFstream.H"
29 #include "OFstream.H"
30 #include "Time.H"
31 #include "boundBox.H"
32 #include "SortableList.H"
33 #include "PackedBoolList.H"
34 #include "plane.H"
35 #include "tensor2D.H"
36 #include "symmTensor2D.H"
37 #include "transform.H"
38 #include "OSspecific.H"
39 #include "scalarMatrices.H"
40 
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
46 }
47 
48 
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
50 
52 {
53  fileName foamName(d.caseName() + ".ftr");
54 
55  // Search back through the time directories list to find the time
56  // closest to and lower than current time
57 
58  instantList ts = d.times();
59  label i;
60 
61  for (i=ts.size()-1; i>=0; i--)
62  {
63  if (ts[i].value() <= d.userTimeValue())
64  {
65  break;
66  }
67  }
68 
69  // Noting that the current directory has already been searched
70  // for mesh data, start searching from the previously stored time directory
71 
72  if (i>=0)
73  {
74  for (label j=i; j>=0; j--)
75  {
76  if (isFile(d.path()/ts[j].name()/typeName/foamName))
77  {
78  if (debug)
79  {
80  Pout<< " triSurface::triSurfInstance(const Time& d)"
81  << "reading " << foamName
82  << " from " << ts[j].name()/typeName
83  << endl;
84  }
85 
86  return ts[j].name();
87  }
88  }
89  }
90 
91  if (debug)
92  {
93  Pout<< " triSurface::triSurfInstance(const Time& d)"
94  << "reading " << foamName
95  << " from constant/" << endl;
96  }
97  return d.constant();
98 }
99 
100 
101 Foam::List<Foam::labelledTri> Foam::triSurface::convertToTri
102 (
103  const faceList& faces,
104  const label defaultRegion
105 )
106 {
107  List<labelledTri> triFaces(faces.size());
108 
109  forAll(triFaces, facei)
110  {
111  const face& f = faces[facei];
112 
113  if (f.size() != 3)
114  {
116  << "Face at position " << facei
117  << " does not have three vertices:" << f
118  << abort(FatalError);
119  }
120 
121  labelledTri& tri = triFaces[facei];
122 
123  tri[0] = f[0];
124  tri[1] = f[1];
125  tri[2] = f[2];
126  tri.region() = defaultRegion;
127  }
128 
129  return triFaces;
130 }
131 
132 
133 Foam::List<Foam::labelledTri> Foam::triSurface::convertToTri
134 (
135  const triFaceList& faces,
136  const label defaultRegion
137 )
138 {
139  List<labelledTri> triFaces(faces.size());
140 
141  forAll(triFaces, facei)
142  {
143  const triFace& f = faces[facei];
144 
145  labelledTri& tri = triFaces[facei];
146 
147  tri[0] = f[0];
148  tri[1] = f[1];
149  tri[2] = f[2];
150  tri.region() = defaultRegion;
151  }
152 
153  return triFaces;
154 }
155 
156 
157 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
158 
159 void Foam::triSurface::printTriangle
160 (
161  Ostream& os,
162  const string& pre,
163  const labelledTri& f,
164  const pointField& points
165 )
166 {
167  os
168  << pre.c_str() << "vertex numbers:"
169  << f[0] << ' ' << f[1] << ' ' << f[2] << endl
170  << pre.c_str() << "vertex coords :"
171  << points[f[0]] << ' ' << points[f[1]] << ' ' << points[f[2]]
172  << pre.c_str() << "region :" << f.region() << endl
173  << endl;
174 }
175 
176 
177 Foam::string Foam::triSurface::getLineNoComment(IFstream& is)
178 {
179  string line;
180  do
181  {
182  is.getLine(line);
183  }
184  while ((line.empty() || line[0] == '#') && is.good());
185 
186  return line;
187 }
188 
189 
190 Foam::scalar Foam::triSurface::pointNormalWeight
191 (
192  const triFace& f,
193  const label pi,
194  const vector& fa,
195  const pointField& points
196 ) const
197 {
198  const label index = findIndex(f, pi);
199 
200  if (index == -1)
201  {
203  << "Point not in face" << abort(FatalError);
204  }
205 
206  const vector e1 = points[f[index]] - points[f[f.fcIndex(index)]];
207  const vector e2 = points[f[index]] - points[f[f.rcIndex(index)]];
208 
209  return mag(fa)/(magSqr(e1)*magSqr(e2) + vSmall);
210 }
211 
212 
213 Foam::tmp<Foam::vectorField> Foam::triSurface::weightedPointNormals() const
214 {
215  // Weighted average of normals of faces attached to the vertex
216  // Weight = fA / (mag(e0)^2 * mag(e1)^2);
217 
218  tmp<vectorField> tpointNormals
219  (
220  new vectorField(nPoints(), Zero)
221  );
222  vectorField& pointNormals = tpointNormals.ref();
223 
224  const pointField& points = this->points();
225  const labelListList& pointFaces = this->pointFaces();
226  const labelList& meshPoints = this->meshPoints();
227 
228  forAll(pointFaces, pi)
229  {
230  const labelList& pFaces = pointFaces[pi];
231 
232  forAll(pFaces, fi)
233  {
234  const label facei = pFaces[fi];
235  const triFace& f = operator[](facei);
236 
237  const vector fa = f.area(points);
238  const scalar weight =
239  pointNormalWeight(f, meshPoints[pi], fa, points);
240 
241  pointNormals[pi] += weight*fa;
242  }
243 
244  pointNormals[pi] /= mag(pointNormals[pi]) + vSmall;
245  }
246 
247  return tpointNormals;
248 }
249 
250 
251 Foam::tmp<Foam::triadField> Foam::triSurface::pointCoordSys
252 (
253  const vectorField& pointNormals
254 ) const
255 {
256  tmp<triadField> tpointCoordSys(new triadField(nPoints()));
257  triadField& pointCoordSys = tpointCoordSys.ref();
258 
259  const pointField& points = this->points();
260  const labelList& meshPoints = this->meshPoints();
261 
262  forAll(meshPoints, pi)
263  {
264  const point& pt = points[meshPoints[pi]];
265  const vector& normal = pointNormals[pi];
266 
267  if (mag(normal) < small)
268  {
269  pointCoordSys[pi] = triad::unset;
270  continue;
271  }
272 
273  plane p(pt, normal);
274 
275  // Pick a point in plane
276  vector dir1 = pt - p.aPoint();
277  dir1 /= mag(dir1);
278 
279  vector dir2 = dir1 ^ normal;
280  dir2 /= mag(dir2);
281 
282  pointCoordSys[pi] = triad(dir1, dir2, normal);
283  }
284 
285  return pointCoordSys;
286 }
287 
288 
289 bool Foam::triSurface::read(Istream& is)
290 {
291  is >> patches_ >> storedPoints() >> storedFaces();
292 
293  return true;
294 }
295 
296 
297 bool Foam::triSurface::read
298 (
299  const fileName& name,
300  const word& ext,
301  const bool check
302 )
303 {
304  if (check && !exists(name))
305  {
307  << "Cannot read " << name << exit(FatalError);
308  }
309 
310  if (ext == "gz")
311  {
312  fileName unzipName = name.lessExt();
313 
314  // Do not check for existence. Let IFstream do the unzipping.
315  return read(unzipName, unzipName.ext(), false);
316  }
317  else if (ext == "ftr")
318  {
319  return read(IFstream(name)());
320  }
321  else if (ext == "stl")
322  {
323  return readSTL(name);
324  }
325  else if (ext == "stlb")
326  {
327  return readSTLBINARY(name);
328  }
329  else if (ext == "gts")
330  {
331  return readGTS(name);
332  }
333  else if (ext == "obj")
334  {
335  return readOBJ(name);
336  }
337  else if (ext == "off")
338  {
339  return readOFF(name);
340  }
341  else if (ext == "tri")
342  {
343  return readTRI(name);
344  }
345  else if (ext == "ac")
346  {
347  return readAC(name);
348  }
349  else if (ext == "nas")
350  {
351  return readNAS(name);
352  }
353  else if (ext == "vtk")
354  {
355  return readVTK(name);
356  }
357  else
358  {
360  << "unknown file extension " << ext
361  << ". Supported extensions are '.ftr', '.stl', '.stlb', '.gts'"
362  << ", '.obj', '.ac', '.off', '.nas', '.tri' and '.vtk'"
363  << exit(FatalError);
364 
365  return false;
366  }
367 }
368 
369 
370 void Foam::triSurface::write
371 (
372  const fileName& name,
373  const word& ext,
374  const bool sort
375 ) const
376 {
377  if (ext == "ftr")
378  {
379  return write(OFstream(name)());
380  }
381  else if (ext == "stl")
382  {
383  return writeSTLASCII(sort, OFstream(name)());
384  }
385  else if (ext == "stlb")
386  {
387  ofstream outFile(name.c_str(), std::ios::binary);
388 
389  writeSTLBINARY(outFile);
390  }
391  else if (ext == "gts")
392  {
393  return writeGTS(sort, OFstream(name)());
394  }
395  else if (ext == "obj")
396  {
397  writeOBJ(sort, OFstream(name)());
398  }
399  else if (ext == "off")
400  {
401  writeOFF(sort, OFstream(name)());
402  }
403  else if (ext == "vtk")
404  {
405  writeVTK(sort, OFstream(name)());
406  }
407  else if (ext == "tri")
408  {
409  writeTRI(sort, OFstream(name)());
410  }
411  else if (ext == "ac")
412  {
413  writeAC(OFstream(name)());
414  }
415  else if (ext == "smesh")
416  {
417  writeSMESH(sort, OFstream(name)());
418  }
419  else
420  {
422  << "unknown file extension " << ext
423  << " for file " << name
424  << ". Supported extensions are '.ftr', '.stl', '.stlb', "
425  << "'.gts', '.obj', '.vtk'"
426  << ", '.off', '.dx', '.smesh', '.ac' and '.tri'"
427  << exit(FatalError);
428  }
429 }
430 
431 
432 Foam::surfacePatchList Foam::triSurface::calcPatches(labelList& faceMap) const
433 {
434  // Sort according to region numbers of labelledTri
435  SortableList<label> sortedRegion(size());
436 
437  forAll(sortedRegion, facei)
438  {
439  sortedRegion[facei] = operator[](facei).region();
440  }
441  sortedRegion.sort();
442 
443  faceMap = sortedRegion.indices();
444 
445  // Extend regions
446  label maxRegion = patches_.size()-1; // for non-compacted regions
447 
448  if (faceMap.size())
449  {
450  maxRegion = max
451  (
452  maxRegion,
453  operator[](faceMap.last()).region()
454  );
455  }
456 
457  // Get new region list
458  surfacePatchList newPatches(maxRegion + 1);
459 
460  // Fill patch sizes
461  forAll(*this, facei)
462  {
463  label region = operator[](facei).region();
464 
465  newPatches[region].size()++;
466  }
467 
468 
469  // Fill rest of patch info
470 
471  label startFacei = 0;
472  forAll(newPatches, newPatchi)
473  {
474  surfacePatch& newPatch = newPatches[newPatchi];
475 
476  newPatch.index() = newPatchi;
477 
478  label oldPatchi = newPatchi;
479 
480  // start of patch
481  newPatch.start() = startFacei;
482 
483 
484  // Take over any information from existing patches
485  if ((oldPatchi < patches_.size()) && (patches_[oldPatchi].name() != ""))
486  {
487  newPatch.name() = patches_[oldPatchi].name();
488  }
489  else
490  {
491  newPatch.name() = word("patch") + name(newPatchi);
492  }
493 
494  if
495  (
496  (oldPatchi < patches_.size())
497  && (patches_[oldPatchi].geometricType() != "")
498  )
499  {
500  newPatch.geometricType() = patches_[oldPatchi].geometricType();
501  }
502  else
503  {
504  newPatch.geometricType() = "empty";
505  }
506 
507  startFacei += newPatch.size();
508  }
509 
510  return newPatches;
511 }
512 
513 
514 void Foam::triSurface::setDefaultPatches()
515 {
517 
518  // Get names, types and sizes
519  surfacePatchList newPatches(calcPatches(faceMap));
520 
521  // Take over names and types (but not size)
522  patches_.setSize(newPatches.size());
523 
524  forAll(newPatches, patchi)
525  {
526  patches_[patchi].index() = patchi;
527  patches_[patchi].name() = newPatches[patchi].name();
528  patches_[patchi].geometricType() = newPatches[patchi].geometricType();
529  }
530 }
531 
532 
533 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
534 
536 :
537  triSurfacePointMesh(*this),
539  patches_(0),
540  sortedEdgeFacesPtr_(nullptr),
541  edgeOwnerPtr_(nullptr)
542 {}
543 
544 
546 (
547  const List<labelledTri>& triangles,
549  const pointField& points
550 )
551 :
552  triSurfacePointMesh(*this),
553  ParentType(triangles, points),
554  patches_(patches),
555  sortedEdgeFacesPtr_(nullptr),
556  edgeOwnerPtr_(nullptr)
557 {}
558 
559 
561 (
562  List<labelledTri>& triangles,
565  const bool reuse
566 )
567 :
568  triSurfacePointMesh(*this),
569  ParentType(triangles, points, reuse),
570  patches_(patches),
571  sortedEdgeFacesPtr_(nullptr),
572  edgeOwnerPtr_(nullptr)
573 {}
574 
575 
577 (
578  List<labelledTri>&& triangles,
581 )
582 :
583  triSurfacePointMesh(*this),
584  ParentType(move(triangles), move(points)),
585  patches_(patches),
586  sortedEdgeFacesPtr_(nullptr),
587  edgeOwnerPtr_(nullptr)
588 {}
589 
590 
592 (
593  const List<labelledTri>& triangles,
594  const pointField& points
595 )
596 :
597  triSurfacePointMesh(*this),
598  ParentType(triangles, points),
599  patches_(),
600  sortedEdgeFacesPtr_(nullptr),
601  edgeOwnerPtr_(nullptr)
602 {
603  setDefaultPatches();
604 }
605 
606 
608 (
609  const triFaceList& triangles,
610  const pointField& points
611 )
612 :
613  triSurfacePointMesh(*this),
614  ParentType(convertToTri(triangles, 0), points),
615  patches_(),
616  sortedEdgeFacesPtr_(nullptr),
617  edgeOwnerPtr_(nullptr)
618 {
619  setDefaultPatches();
620 }
621 
622 
624 :
625  triSurfacePointMesh(*this),
627  patches_(),
628  sortedEdgeFacesPtr_(nullptr),
629  edgeOwnerPtr_(nullptr)
630 {
631  word ext = name.ext();
632 
633  read(name, ext);
634 
635  setDefaultPatches();
636 }
637 
638 
640 :
641  triSurfacePointMesh(*this),
643  patches_(),
644  sortedEdgeFacesPtr_(nullptr),
645  edgeOwnerPtr_(nullptr)
646 {
647  read(is);
648 
649  setDefaultPatches();
650 }
651 
652 
654 :
655  triSurfacePointMesh(*this),
657  patches_(),
658  sortedEdgeFacesPtr_(nullptr),
659  edgeOwnerPtr_(nullptr)
660 {
661  fileName foamFile(d.caseName() + ".ftr");
662 
663  fileName foamPath(d.path()/triSurfInstance(d)/typeName/foamFile);
664 
665  IFstream foamStream(foamPath);
666 
667  read(foamStream);
668 
669  setDefaultPatches();
670 }
671 
672 
674 :
675  triSurfacePointMesh(*this),
676  ParentType(ts, ts.points()),
677  patches_(ts.patches()),
678  sortedEdgeFacesPtr_(nullptr),
679  edgeOwnerPtr_(nullptr)
680 {}
681 
682 
684 :
685  triSurfacePointMesh(*this),
686  ParentType(move(ts), move(ts.points())),
687  patches_(move(ts.patches())),
688  sortedEdgeFacesPtr_(nullptr),
689  edgeOwnerPtr_(nullptr)
690 {}
691 
692 
693 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
694 
696 {
697  clearOut();
698 }
699 
700 
701 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
702 
704 {
705  ParentType::clearTopology();
706  deleteDemandDrivenData(sortedEdgeFacesPtr_);
707  deleteDemandDrivenData(edgeOwnerPtr_);
708 }
709 
710 
712 {
713  ParentType::clearPatchMeshAddr();
714 }
715 
716 
718 {
719  ParentType::clearOut();
720 
721  clearTopology();
722  clearPatchMeshAddr();
723 }
724 
725 
727 {
728  if (!sortedEdgeFacesPtr_)
729  {
730  calcSortedEdgeFaces();
731  }
732 
733  return *sortedEdgeFacesPtr_;
734 }
735 
736 
738 {
739  if (!edgeOwnerPtr_)
740  {
741  calcEdgeOwner();
742  }
743 
744  return *edgeOwnerPtr_;
745 }
746 
747 
749 {
750  // Remove all geometry dependent data
751  deleteDemandDrivenData(sortedEdgeFacesPtr_);
752 
753  // Adapt for new point position
754  ParentType::clearGeom();
755 
756  // Copy new points
757  storedPoints() = newPoints;
758 }
759 
760 
761 void Foam::triSurface::scalePoints(const scalar scaleFactor)
762 {
763  // avoid bad scaling
764  if (scaleFactor > 0 && scaleFactor != 1.0)
765  {
766  // Remove all geometry dependent data
767  clearTopology();
768 
769  // Adapt for new point position
770  ParentType::clearGeom();
771 
772  storedPoints() *= scaleFactor;
773  }
774 }
775 
776 
777 void Foam::triSurface::checkTriangles(const bool verbose)
778 {
779  // Simple check on indices ok.
780  const label maxPointi = points().size() - 1;
781 
782  forAll(*this, facei)
783  {
784  const triSurface::FaceType& f = (*this)[facei];
785 
786  forAll(f, fp)
787  {
788  if (f[fp] < 0 || f[fp] > maxPointi)
789  {
791  << "triangle " << f
792  << " uses point indices outside point range 0.."
793  << maxPointi
794  << exit(FatalError);
795  }
796  }
797  }
798 
799  // Two phase process
800  // 1. mark invalid faces
801  // 2. pack
802  // Done to keep numbering constant in phase 1
803 
804  // List of valid triangles
805  boolList valid(size(), true);
806  bool hasInvalid = false;
807 
808  forAll(*this, facei)
809  {
810  const labelledTri& f = (*this)[facei];
811 
812  if ((f[0] == f[1]) || (f[0] == f[2]) || (f[1] == f[2]))
813  {
814  // 'degenerate' triangle check
815  valid[facei] = false;
816  hasInvalid = true;
817 
818  if (verbose)
819  {
821  << "triangle " << facei
822  << " does not have three unique vertices:\n";
823  printTriangle(Warning, " ", f, points());
824  }
825  }
826  else
827  {
828  // duplicate triangle check
829  const labelList& fEdges = faceEdges()[facei];
830 
831  // Check if faceNeighbours use same points as this face.
832  // Note: discards normal information - sides of baffle are merged.
833 
834  forAll(fEdges, fp)
835  {
836  const labelList& eFaces = edgeFaces()[fEdges[fp]];
837 
838  forAll(eFaces, i)
839  {
840  label neighbour = eFaces[i];
841 
842  if (neighbour > facei)
843  {
844  // lower numbered faces already checked
845  const labelledTri& n = (*this)[neighbour];
846 
847  if
848  (
849  ((f[0] == n[0]) || (f[0] == n[1]) || (f[0] == n[2]))
850  && ((f[1] == n[0]) || (f[1] == n[1]) || (f[1] == n[2]))
851  && ((f[2] == n[0]) || (f[2] == n[1]) || (f[2] == n[2]))
852  )
853  {
854  valid[facei] = false;
855  hasInvalid = true;
856 
857  if (verbose)
858  {
860  << "triangles share the same vertices:\n"
861  << " face 1 :" << facei << endl;
862  printTriangle(Warning, " ", f, points());
863 
864  Warning
865  << endl
866  << " face 2 :"
867  << neighbour << endl;
868  printTriangle(Warning, " ", n, points());
869  }
870 
871  break;
872  }
873  }
874  }
875  }
876  }
877  }
878 
879  if (hasInvalid)
880  {
881  // Pack
882  label newFacei = 0;
883  forAll(*this, facei)
884  {
885  if (valid[facei])
886  {
887  const labelledTri& f = (*this)[facei];
888  (*this)[newFacei++] = f;
889  }
890  }
891 
892  if (verbose)
893  {
895  << "Removing " << size() - newFacei
896  << " illegal faces." << endl;
897  }
898  (*this).setSize(newFacei);
899 
900  // Topology can change because of renumbering
901  clearOut();
902  }
903 }
904 
905 
906 void Foam::triSurface::checkEdges(const bool verbose)
907 {
908  const labelListList& eFaces = edgeFaces();
909 
910  forAll(eFaces, edgeI)
911  {
912  const labelList& myFaces = eFaces[edgeI];
913 
914  if (myFaces.empty())
915  {
917  << "Edge " << edgeI << " with vertices " << edges()[edgeI]
918  << " has no edgeFaces"
919  << exit(FatalError);
920  }
921  else if (myFaces.size() > 2 && verbose)
922  {
924  << "Edge " << edgeI << " with vertices " << edges()[edgeI]
925  << " has more than 2 faces connected to it : " << myFaces
926  << endl;
927  }
928  }
929 }
930 
931 
932 void Foam::triSurface::cleanup(const bool verbose)
933 {
934  // Merge points (already done for STL, TRI)
935  stitchTriangles(small, verbose);
936 
937  // Merging points might have changed geometric factors
938  clearOut();
939 
940  checkTriangles(verbose);
941 
942  checkEdges(verbose);
943 }
944 
945 
947 (
948  const boolList& borderEdge,
949  const label facei,
950  const label currentZone,
952 ) const
953 {
954  // List of faces whose faceZone has been set.
955  labelList changedFaces(1, facei);
956 
957  while (true)
958  {
959  // Pick up neighbours of changedFaces
960  DynamicList<label> newChangedFaces(2*changedFaces.size());
961 
962  forAll(changedFaces, i)
963  {
964  label facei = changedFaces[i];
965 
966  const labelList& fEdges = faceEdges()[facei];
967 
968  forAll(fEdges, i)
969  {
970  label edgeI = fEdges[i];
971 
972  if (!borderEdge[edgeI])
973  {
974  const labelList& eFaces = edgeFaces()[edgeI];
975 
976  forAll(eFaces, j)
977  {
978  label nbrFacei = eFaces[j];
979 
980  if (faceZone[nbrFacei] == -1)
981  {
982  faceZone[nbrFacei] = currentZone;
983  newChangedFaces.append(nbrFacei);
984  }
985  else if (faceZone[nbrFacei] != currentZone)
986  {
988  << "Zones " << faceZone[nbrFacei]
989  << " at face " << nbrFacei
990  << " connects to zone " << currentZone
991  << " at face " << facei
992  << abort(FatalError);
993  }
994  }
995  }
996  }
997  }
998 
999  if (newChangedFaces.empty())
1000  {
1001  break;
1002  }
1003 
1004  changedFaces.transfer(newChangedFaces);
1005  }
1006 }
1007 
1008 
1010 (
1011  const boolList& borderEdge,
1013 ) const
1014 {
1015  faceZone.setSize(size());
1016  faceZone = -1;
1017 
1018  if (borderEdge.size() != nEdges())
1019  {
1021  << "borderEdge boolList not same size as number of edges" << endl
1022  << "borderEdge:" << borderEdge.size() << endl
1023  << "nEdges :" << nEdges()
1024  << exit(FatalError);
1025  }
1026 
1027  label zoneI = 0;
1028 
1029  for (label startFacei = 0;; zoneI++)
1030  {
1031  // Find first non-coloured face
1032  for (; startFacei < size(); startFacei++)
1033  {
1034  if (faceZone[startFacei] == -1)
1035  {
1036  break;
1037  }
1038  }
1039 
1040  if (startFacei >= size())
1041  {
1042  break;
1043  }
1044 
1045  faceZone[startFacei] = zoneI;
1046 
1047  markZone(borderEdge, startFacei, zoneI, faceZone);
1048  }
1049 
1050  return zoneI;
1051 }
1052 
1053 
1055 (
1056  const boolList& include,
1057  labelList& pointMap,
1059 ) const
1060 {
1061  const List<labelledTri>& locFaces = localFaces();
1062 
1063  label facei = 0;
1064  label pointi = 0;
1065 
1066  faceMap.setSize(locFaces.size());
1067 
1068  pointMap.setSize(nPoints());
1069 
1070  boolList pointHad(nPoints(), false);
1071 
1072  forAll(include, oldFacei)
1073  {
1074  if (include[oldFacei])
1075  {
1076  // Store new faces compact
1077  faceMap[facei++] = oldFacei;
1078 
1079  // Renumber labels for face
1080  const triSurface::FaceType& f = locFaces[oldFacei];
1081 
1082  forAll(f, fp)
1083  {
1084  label labI = f[fp];
1085  if (!pointHad[labI])
1086  {
1087  pointHad[labI] = true;
1088  pointMap[pointi++] = labI;
1089  }
1090  }
1091  }
1092  }
1093 
1094  // Trim
1095  faceMap.setSize(facei);
1096  pointMap.setSize(pointi);
1097 }
1098 
1099 
1101 (
1102  const boolList& include,
1103  labelList& pointMap,
1105 ) const
1106 {
1107  const pointField& locPoints = localPoints();
1108  const List<labelledTri>& locFaces = localFaces();
1109 
1110  // Fill pointMap, faceMap
1111  subsetMeshMap(include, pointMap, faceMap);
1112 
1113 
1114  // Create compact coordinate list and forward mapping array
1115  pointField newPoints(pointMap.size());
1116  labelList oldToNew(locPoints.size());
1117  forAll(pointMap, pointi)
1118  {
1119  newPoints[pointi] = locPoints[pointMap[pointi]];
1120  oldToNew[pointMap[pointi]] = pointi;
1121  }
1122 
1123  // Renumber triangle node labels and compact
1124  List<labelledTri> newTriangles(faceMap.size());
1125 
1126  forAll(faceMap, facei)
1127  {
1128  // Get old vertex labels
1129  const labelledTri& tri = locFaces[faceMap[facei]];
1130 
1131  newTriangles[facei][0] = oldToNew[tri[0]];
1132  newTriangles[facei][1] = oldToNew[tri[1]];
1133  newTriangles[facei][2] = oldToNew[tri[2]];
1134  newTriangles[facei].region() = tri.region();
1135  }
1136 
1137  // Construct subsurface
1138  return triSurface(newTriangles, patches(), newPoints, true);
1139 }
1140 
1141 
1143 {
1144  faceList faces(size());
1145 
1146  forAll(*this, facei)
1147  {
1148  faces[facei] = operator[](facei).triFaceFace();
1149  }
1150 
1151  return faces;
1152 }
1153 
1154 
1156 {
1157  // Curvature calculation is an implementation of the algorithm from:
1158  // "Estimating Curvatures and their Derivatives on Triangle Meshes"
1159  // by S. Rusinkiewicz
1160 
1161  const pointField& points = this->points();
1162  const labelList& meshPoints = this->meshPoints();
1163  const Map<label>& meshPointMap = this->meshPointMap();
1164 
1165  const vectorField pointNormals
1166  (
1167  this->weightedPointNormals()
1168  );
1169 
1170  const triadField pointCoordSys
1171  (
1172  this->pointCoordSys(pointNormals)
1173  );
1174 
1175  tmp<scalarField> tcurvaturePointField(new scalarField(nPoints(), 0.0));
1176  scalarField& curvaturePointField = tcurvaturePointField.ref();
1177 
1178  List<symmTensor2D> pointFundamentalTensors(nPoints(), Zero);
1179  scalarList accumulatedWeights(nPoints(), 0.0);
1180 
1181  forAll(*this, fi)
1182  {
1183  const triFace& f = operator[](fi);
1184  const edgeList fEdges = f.edges();
1185 
1186  // Calculate the edge vectors and the normal differences
1187  vectorField edgeVectors(f.size(), Zero);
1188  vectorField normalDifferences(f.size(), Zero);
1189 
1190  forAll(fEdges, feI)
1191  {
1192  const edge& e = fEdges[feI];
1193 
1194  edgeVectors[feI] = e.vec(points);
1195  normalDifferences[feI] =
1196  pointNormals[meshPointMap[e[0]]]
1197  - pointNormals[meshPointMap[e[1]]];
1198  }
1199 
1200  // Set up a local coordinate system for the face
1201  const vector& e0 = edgeVectors[0];
1202  const vector eN = f.area(points);
1203  const vector e1 = (e0 ^ eN);
1204 
1205  if (magSqr(eN) < rootVSmall)
1206  {
1207  continue;
1208  }
1209 
1210  triad faceCoordSys(e0, e1, eN);
1211  faceCoordSys.normalise();
1212 
1213  // Construct the matrix to solve
1215  scalarDiagonalMatrix Z(3, 0);
1216 
1217  // Least Squares
1218  for (label i = 0; i < 3; ++i)
1219  {
1220  const scalar x = edgeVectors[i] & faceCoordSys[0];
1221  const scalar y = edgeVectors[i] & faceCoordSys[1];
1222 
1223  T(0, 0) += sqr(x);
1224  T(1, 0) += x*y;
1225  T(1, 1) += sqr(x) + sqr(y);
1226  T(2, 1) += x*y;
1227  T(2, 2) += sqr(y);
1228 
1229  const scalar dndx = normalDifferences[i] & faceCoordSys[0];
1230  const scalar dndy = normalDifferences[i] & faceCoordSys[1];
1231 
1232  Z[0] += dndx*x;
1233  Z[1] += dndx*y + dndy*x;
1234  Z[2] += dndy*y;
1235  }
1236 
1237  // Perform Cholesky decomposition and back substitution.
1238  // Decomposed matrix is in T and solution is in Z.
1239  LUsolve(T, Z);
1240  const symmTensor2D secondFundamentalTensor(Z[0], Z[1], Z[2]);
1241 
1242  // Loop over the face points adding the contribution of the face
1243  // curvature to the points.
1244  forAll(f, fpi)
1245  {
1246  const label patchPointIndex = meshPointMap[f[fpi]];
1247 
1248  const triad& ptCoordSys = pointCoordSys[patchPointIndex];
1249 
1250  if (!ptCoordSys.set())
1251  {
1252  continue;
1253  }
1254 
1255  // Rotate faceCoordSys to ptCoordSys
1256  const tensor rotTensor = rotationTensor
1257  (
1258  ptCoordSys[2],
1259  faceCoordSys[2]
1260  );
1261  const triad rotatedFaceCoordSys = rotTensor & tensor(faceCoordSys);
1262 
1263  // Project the face curvature onto the point plane
1264 
1265  const vector2D cmp1
1266  (
1267  ptCoordSys[0] & rotatedFaceCoordSys[0],
1268  ptCoordSys[0] & rotatedFaceCoordSys[1]
1269  );
1270  const vector2D cmp2
1271  (
1272  ptCoordSys[1] & rotatedFaceCoordSys[0],
1273  ptCoordSys[1] & rotatedFaceCoordSys[1]
1274  );
1275 
1276  const tensor2D projTensor
1277  (
1278  cmp1,
1279  cmp2
1280  );
1281 
1282  const symmTensor2D projectedFundamentalTensor
1283  (
1284  projTensor.x() & (secondFundamentalTensor & projTensor.x()),
1285  projTensor.x() & (secondFundamentalTensor & projTensor.y()),
1286  projTensor.y() & (secondFundamentalTensor & projTensor.y())
1287  );
1288 
1289  // Calculate weight
1290  const scalar weight = pointNormalWeight
1291  (
1292  f,
1293  meshPoints[patchPointIndex],
1294  f.area(points),
1295  points
1296  );
1297 
1298  // Sum contribution of face to this point
1299  pointFundamentalTensors[patchPointIndex] +=
1300  weight*projectedFundamentalTensor;
1301 
1302  accumulatedWeights[patchPointIndex] += weight;
1303  }
1304  }
1305 
1306  forAll(curvaturePointField, pi)
1307  {
1308  pointFundamentalTensors[pi] /= (accumulatedWeights[pi] + small);
1309 
1310  const vector2D principalCurvatures =
1311  eigenValues(pointFundamentalTensors[pi]);
1312 
1313  // scalar curvature =
1314  // (principalCurvatures[0] + principalCurvatures[1])/2;
1315  const scalar curvature = max
1316  (
1317  mag(principalCurvatures[0]),
1318  mag(principalCurvatures[1])
1319  );
1320  // scalar curvature = principalCurvatures[0]*principalCurvatures[1];
1321 
1322  curvaturePointField[meshPoints[pi]] = curvature;
1323  }
1324 
1325  return tcurvaturePointField;
1326 }
1327 
1328 
1329 void Foam::triSurface::write
1330 (
1331  const fileName& name,
1332  const bool sortByRegion
1333 ) const
1334 {
1335  write(name, name.ext(), sortByRegion);
1336 }
1337 
1338 
1339 void Foam::triSurface::write(Ostream& os) const
1340 {
1341  os << patches() << endl;
1342 
1343  // Note: Write with global point numbering
1344  os << points() << nl
1345  << static_cast<const List<labelledTri>&>(*this) << endl;
1346 
1347  // Check state of Ostream
1348  os.check("triSurface::write(Ostream&)");
1349 }
1350 
1351 
1352 void Foam::triSurface::write(const Time& d) const
1353 {
1354  fileName foamFile(d.caseName() + ".ftr");
1355 
1356  fileName foamPath(d.path()/triSurfInstance(d)/typeName/foamFile);
1357 
1358  OFstream foamStream(foamPath);
1359 
1360  write(foamStream);
1361 }
1362 
1363 
1365 {
1366  // Unfortunately nPoints constructs meshPoints() so do compact version
1367  // ourselves.
1368  PackedBoolList pointIsUsed(points().size());
1369 
1370  label nPoints = 0;
1372 
1373  forAll(*this, facei)
1374  {
1375  const triSurface::FaceType& f = operator[](facei);
1376 
1377  forAll(f, fp)
1378  {
1379  label pointi = f[fp];
1380  if (pointIsUsed.set(pointi, 1))
1381  {
1382  bb.min() = ::Foam::min(bb.min(), points()[pointi]);
1383  bb.max() = ::Foam::max(bb.max(), points()[pointi]);
1384  nPoints++;
1385  }
1386  }
1387  }
1388 
1389  os << indent << "Triangles : " << size() << endl
1390  << indent << "Vertices : " << nPoints << endl
1391  << indent << "Bounding Box : " << bb << endl;
1392 }
1393 
1394 
1395 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1396 
1398 {
1400  clearOut();
1401  storedPoints() = ts.points();
1402  patches_ = ts.patches();
1403 }
1404 
1405 
1407 {
1408  List<labelledTri>::operator=(move(ts));
1409  clearOut();
1410  storedPoints() = move(ts.points());
1411  patches_ = move(ts.patches());
1412 }
1413 
1414 
1415 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1416 
1418 {
1419  sm.write(os);
1420  return os;
1421 }
1422 
1423 
1424 // ************************************************************************* //
scalar y
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
Input from file stream.
Definition: IFstream.H:85
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:108
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void operator=(const UList< T > &)
Assignment to UList operator. Takes linear time.
Definition: List.C:376
void setSize(const label)
Reset size of List.
Definition: List.C:281
Output to file stream.
Definition: OFstream.H:87
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A bit-packed bool list.
void set(const PackedList< 1 > &)
Set specified bits.
const Field< PointType > & points() const
Return reference to global points.
std::remove_reference< ::Foam::List< labelledTri > >::type::value_type FaceType
Templated 2D symmetric tensor derived from VectorSpace adding construction from 4 components,...
Definition: SymmTensor2D.H:56
A templated 2D square symmetric matrix of objects of <T>, where the n x n matrix dimension is known a...
Templated 2D tensor derived from VectorSpace adding construction from 4 components,...
Definition: Tensor2D.H:59
Vector2D< Cmpt > y() const
Definition: Tensor2DI.H:106
Vector2D< Cmpt > x() const
Definition: Tensor2DI.H:100
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
instantList times() const
Search the case for valid time directories.
Definition: Time.C:659
fileName path() const
Explicitly inherit path from TimePaths to disambiguate from.
Definition: TimePaths.H:138
scalar userTimeValue() const
Return current user time value.
Definition: Time.C:838
const fileName & caseName() const
Explicitly inherit caseName from TimePaths to disambiguate from.
Definition: TimePaths.H:106
label rcIndex(const label i) const
Return the reverse circular index, i.e. the previous index.
Definition: UListI.H:65
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Definition: UListI.H:58
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:325
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:60
const point & min() const
Minimum point defining the bounding box.
Definition: boundBoxI.H:88
const point & max() const
Maximum point defining the bounding box.
Definition: boundBoxI.H:94
static const boundBox invertedBox
A very large inverted boundBox: min/max == +/- vGreat.
Definition: boundBox.H:80
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:61
Named list of face indices representing a sub-set of the mesh faces.
Definition: faceZone.H:66
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:76
A class for handling file names.
Definition: fileName.H:82
label size() const
Return fvMesh size.
Definition: fvMesh.H:468
Triangle with additional region number.
Definition: labelledTri.H:60
label region() const
Return region label.
Definition: labelledTriI.H:68
Motion of the mesh specified as a list of pointMeshMovers.
A class for handling character strings derived from std::string.
Definition: string.H:79
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
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition: triFace.H:71
triSurface point mesh for fields on triSurface points
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
static fileName triSurfInstance(const Time &)
Name of triSurface directory to use.
Definition: triSurface.C:51
triSurface()
Construct null.
Definition: triSurface.C:535
triSurface subsetMesh(const boolList &include, labelList &pointMap, labelList &faceMap) const
Return new surface. Returns pointMap, faceMap from.
Definition: triSurface.C:1101
label markZones(const boolList &borderEdge, labelList &faceZone) const
(size and) fills faceZone with zone of face. Zone is area
Definition: triSurface.C:1010
tmp< scalarField > curvature() const
Return the curvature of surface at the points.
Definition: triSurface.C:1155
void operator=(const triSurface &)
Definition: triSurface.C:1397
void cleanup(const bool verbose)
Remove non-valid triangles.
Definition: triSurface.C:932
void clearTopology()
Definition: triSurface.C:703
const geometricSurfacePatchList & patches() const
Definition: triSurface.H:320
void checkTriangles(const bool verbose)
Check/remove duplicate/degenerate triangles.
Definition: triSurface.C:777
void checkEdges(const bool verbose)
Check triply (or more) connected edges.
Definition: triSurface.C:906
void markZone(const boolList &borderEdge, const label facei, const label currentZone, labelList &faceZone) const
Fill faceZone with currentZone for every face reachable.
Definition: triSurface.C:947
void writeStats(Ostream &) const
Write some statistics.
Definition: triSurface.C:1364
faceList faces() const
Return the list of triangles as a faceList.
Definition: triSurface.C:1142
const labelList & edgeOwner() const
If 2 face neighbours: label of face where ordering of edge.
Definition: triSurface.C:737
void subsetMeshMap(const boolList &include, labelList &pointMap, labelList &faceMap) const
'Create' sub mesh, including only faces for which
Definition: triSurface.C:1055
void clearPatchMeshAddr()
Definition: triSurface.C:711
const labelListList & sortedEdgeFaces() const
Return edge-face addressing sorted (for edges with more than.
Definition: triSurface.C:726
virtual ~triSurface()
Destructor.
Definition: triSurface.C:695
virtual void setPoints(const pointField &)
Move points.
Definition: triSurface.C:748
Representation of a 3D Cartesian coordinate system as a Vector of vectors.
Definition: triad.H:68
static const triad unset
Definition: triad.H:99
bool set(const direction d) const
Is the vector in the direction d set.
Definition: triadI.H:61
void normalise()
Normalise each set axis vector to have a unit magnitude.
Definition: triadI.H:111
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
const pointField & points
label nPoints
const fvPatchList & patches
#define WarningInFunction
Report a warning using Foam::Warning.
bool valid(const PtrList< ModelType > &l)
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
Definition: meshTools.C:203
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
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
bool read(const char *, int32_t &)
Definition: int32IO.C:85
tensor rotationTensor(const vector &n1, const vector &n2)
Rotational transformation tensor from unit vector n1 to n2.
Definition: transform.H:47
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
Tensor< scalar > tensor
Tensor of scalars.
Definition: tensor.H:51
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
void eigenValues(pointPatchField< vector > &, const pointPatchField< tensor > &)
void deleteDemandDrivenData(DataType *&dataPtr)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
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
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
vector point
Point is a vector.
Definition: point.H:41
Field< triad > triadField
Specialisation of Field<T> for triad.
Definition: triadField.H:49
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
List< triFace > triFaceList
list of triFaces
Definition: triFaceList.H:42
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
void sort(UList< T > &)
Definition: UList.C:115
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Field< vector > vectorField
Specialisation of Field<T> for vector.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
void writeVTK(OFstream &os, const Type &value)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
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,.
Ostream & operator<<(Ostream &os, const fvConstraints &constraints)
error FatalError
void LUsolve(scalarSquareMatrix &matrix, List< Type > &source)
Solve the matrix using LU decomposition with pivoting.
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:243
void T(GeometricField< Type, GeoMesh, PrimitiveField1 > &gf, const GeometricField< Type, GeoMesh, PrimitiveField2 > &gf1)
static const char nl
Definition: Ostream.H:297
List< surfacePatch > surfacePatchList
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
messageStream Warning
face triFace(3)
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
volScalarField & p
3D tensor transformation operations.