oldCyclicPolyPatch.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-2016 OpenFOAM Foundation
9  Copyright (C) 2019 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 "oldCyclicPolyPatch.H"
31 #include "polyBoundaryMesh.H"
32 #include "polyMesh.H"
33 #include "demandDrivenData.H"
34 #include "OFstream.H"
35 #include "patchZones.H"
36 #include "matchPoints.H"
37 #include "Time.H"
38 #include "transformList.H"
39 #include "cyclicPolyPatch.H"
40 
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45  defineTypeNameAndDebug(oldCyclicPolyPatch, 0);
46 
47  addToRunTimeSelectionTable(polyPatch, oldCyclicPolyPatch, word);
48  addToRunTimeSelectionTable(polyPatch, oldCyclicPolyPatch, dictionary);
49 }
50 
51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
52 
53 Foam::pointField Foam::oldCyclicPolyPatch::calcFaceCentres
54 (
55  const UList<face>& faces,
56  const pointField& points
57 )
58 {
59  pointField ctrs(faces.size());
60 
61  forAll(faces, facei)
62  {
63  ctrs[facei] = faces[facei].centre(points);
64  }
65 
66  return ctrs;
67 }
68 
69 
70 Foam::pointField Foam::oldCyclicPolyPatch::getAnchorPoints
71 (
72  const UList<face>& faces,
73  const pointField& points
74 )
75 {
76  pointField anchors(faces.size());
77 
78  forAll(faces, facei)
79  {
80  anchors[facei] = points[faces[facei][0]];
81  }
82 
83  return anchors;
84 }
85 
86 
87 Foam::label Foam::oldCyclicPolyPatch::findMaxArea
88 (
89  const pointField& points,
90  const faceList& faces
91 )
92 {
93  label maxI = -1;
94  scalar maxAreaSqr = -GREAT;
95 
96  forAll(faces, facei)
97  {
98  scalar areaSqr = magSqr(faces[facei].areaNormal(points));
99 
100  if (maxAreaSqr < areaSqr)
101  {
102  maxAreaSqr = areaSqr;
103  maxI = facei;
104  }
105  }
106  return maxI;
107 }
108 
109 
110 bool Foam::oldCyclicPolyPatch::getGeometricHalves
111 (
112  const primitivePatch& pp,
113  labelList& half0ToPatch,
114  labelList& half1ToPatch
115 ) const
116 {
117  // Get geometric zones of patch by looking at normals.
118  // Method 1: any edge with sharpish angle is edge between two halves.
119  // (this will handle e.g. wedge geometries).
120  // Also two fully disconnected regions will be handled this way.
121  // Method 2: sort faces into two halves based on face normal.
122 
123  // Calculate normals
124  const vectorField& faceNormals = pp.faceNormals();
125 
126  // Find edges with sharp angles.
127  boolList regionEdge(pp.nEdges(), false);
128 
129  const labelListList& edgeFaces = pp.edgeFaces();
130 
131  label nRegionEdges = 0;
132 
133  forAll(edgeFaces, edgeI)
134  {
135  const labelList& eFaces = edgeFaces[edgeI];
136 
137  // Check manifold edges for sharp angle.
138  // (Non-manifold already handled by patchZones)
139  if (eFaces.size() == 2)
140  {
141  if ((faceNormals[eFaces[0]] & faceNormals[eFaces[1]])< featureCos_)
142  {
143  regionEdge[edgeI] = true;
144 
145  nRegionEdges++;
146  }
147  }
148  }
149 
150 
151  // For every face determine zone it is connected to (without crossing
152  // any regionEdge)
153  patchZones ppZones(pp, regionEdge);
154 
155  if (debug)
156  {
157  Pout<< "oldCyclicPolyPatch::getGeometricHalves : "
158  << "Found " << nRegionEdges << " edges on patch " << name()
159  << " where the cos of the angle between two connected faces"
160  << " was less than " << featureCos_ << nl
161  << "Patch divided by these and by single sides edges into "
162  << ppZones.nZones() << " parts." << endl;
163 
164 
165  // Dumping zones to obj files.
166 
167  labelList nZoneFaces(ppZones.nZones());
168 
169  for (label zoneI = 0; zoneI < ppZones.nZones(); zoneI++)
170  {
171  OFstream stream
172  (
173  boundaryMesh().mesh().time().path()
174  /name()+"_zone_"+Foam::name(zoneI)+".obj"
175  );
176  Pout<< "oldCyclicPolyPatch::getGeometricHalves : Writing zone "
177  << zoneI << " face centres to OBJ file " << stream.name()
178  << endl;
179 
180  labelList zoneFaces(findIndices(ppZones, zoneI));
181 
182  forAll(zoneFaces, i)
183  {
184  writeOBJ(stream, pp[zoneFaces[i]].centre(pp.points()));
185  }
186 
187  nZoneFaces[zoneI] = zoneFaces.size();
188  }
189  }
190 
191 
192  if (ppZones.nZones() == 2)
193  {
194  half0ToPatch = findIndices(ppZones, 0);
195  half1ToPatch = findIndices(ppZones, 1);
196  }
197  else
198  {
199  if (debug)
200  {
201  Pout<< "oldCyclicPolyPatch::getGeometricHalves :"
202  << " falling back to face-normal comparison" << endl;
203  }
204  label n0Faces = 0;
205  half0ToPatch.setSize(pp.size());
206 
207  label n1Faces = 0;
208  half1ToPatch.setSize(pp.size());
209 
210  // Compare to face 0 normal.
211  forAll(faceNormals, facei)
212  {
213  if ((faceNormals[facei] & faceNormals[0]) > 0)
214  {
215  half0ToPatch[n0Faces++] = facei;
216  }
217  else
218  {
219  half1ToPatch[n1Faces++] = facei;
220  }
221  }
222  half0ToPatch.setSize(n0Faces);
223  half1ToPatch.setSize(n1Faces);
224 
225  if (debug)
226  {
227  Pout<< "oldCyclicPolyPatch::getGeometricHalves :"
228  << " Number of faces per zone:("
229  << n0Faces << ' ' << n1Faces << ')' << endl;
230  }
231  }
232 
233  if (half0ToPatch.size() != half1ToPatch.size())
234  {
235  fileName casePath(boundaryMesh().mesh().time().path());
236 
237  // Dump halves
238  {
239  fileName nm0(casePath/name()+"_half0_faces.obj");
240  Pout<< "oldCyclicPolyPatch::getGeometricHalves : Writing half0"
241  << " faces to OBJ file " << nm0 << endl;
242  writeOBJ(nm0, UIndirectList<face>(pp, half0ToPatch)(), pp.points());
243 
244  fileName nm1(casePath/name()+"_half1_faces.obj");
245  Pout<< "oldCyclicPolyPatch::getGeometricHalves : Writing half1"
246  << " faces to OBJ file " << nm1 << endl;
247  writeOBJ(nm1, UIndirectList<face>(pp, half1ToPatch)(), pp.points());
248  }
249 
250  // Dump face centres
251  {
252  OFstream str0(casePath/name()+"_half0.obj");
253  Pout<< "oldCyclicPolyPatch::getGeometricHalves : Writing half0"
254  << " face centres to OBJ file " << str0.name() << endl;
255 
256  forAll(half0ToPatch, i)
257  {
258  writeOBJ(str0, pp[half0ToPatch[i]].centre(pp.points()));
259  }
260 
261  OFstream str1(casePath/name()+"_half1.obj");
262  Pout<< "oldCyclicPolyPatch::getGeometricHalves : Writing half1"
263  << " face centres to OBJ file " << str1.name() << endl;
264  forAll(half1ToPatch, i)
265  {
266  writeOBJ(str1, pp[half1ToPatch[i]].centre(pp.points()));
267  }
268  }
269 
271  << "Patch " << name() << " gets decomposed in two zones of"
272  << "inequal size: " << half0ToPatch.size()
273  << " and " << half1ToPatch.size() << endl
274  << "This means that the patch is either not two separate regions"
275  << " or one region where the angle between the different regions"
276  << " is not sufficiently sharp." << endl
277  << "Please adapt the featureCos setting." << endl
278  << "Continuing with incorrect face ordering from now on!" << endl;
279 
280  return false;
281  }
282 
283  return true;
284 }
285 
286 
287 void Foam::oldCyclicPolyPatch::getCentresAndAnchors
288 (
289  const primitivePatch& pp,
290  const faceList& half0Faces,
291  const faceList& half1Faces,
292 
293  pointField& ppPoints,
294  pointField& half0Ctrs,
295  pointField& half1Ctrs,
296  pointField& anchors0,
297  scalarField& tols
298 ) const
299 {
300  // Get geometric data on both halves.
301  half0Ctrs = calcFaceCentres(half0Faces, pp.points());
302  anchors0 = getAnchorPoints(half0Faces, pp.points());
303  half1Ctrs = calcFaceCentres(half1Faces, pp.points());
304 
305  switch (transform())
306  {
307  case ROTATIONAL:
308  {
309  label face0 = getConsistentRotationFace(half0Ctrs);
310  label face1 = getConsistentRotationFace(half1Ctrs);
311 
312  const vector n0 =
313  normalised
314  (
315  (half0Ctrs[face0] - rotationCentre_) ^ rotationAxis_
316  );
317 
318  const vector n1 =
319  normalised
320  (
321  (half1Ctrs[face1] - rotationCentre_) ^ -rotationAxis_
322  );
323 
324  if (debug)
325  {
326  Pout<< "oldCyclicPolyPatch::getCentresAndAnchors :"
327  << " Specified rotation :"
328  << " n0:" << n0 << " n1:" << n1 << endl;
329  }
330 
331  // Rotation (around origin)
332  const tensor reverseT(rotationTensor(n0, -n1));
333 
334  // Rotation
335  forAll(half0Ctrs, facei)
336  {
337  half0Ctrs[facei] = Foam::transform(reverseT, half0Ctrs[facei]);
338  anchors0[facei] = Foam::transform(reverseT, anchors0[facei]);
339  }
340 
341  ppPoints = Foam::transform(reverseT, pp.points());
342 
343  break;
344  }
345  //- Problem: usually specified translation is not accurate enough
346  //- To get proper match so keep automatic determination over here.
347  //case TRANSLATIONAL:
348  //{
349  // // Transform 0 points.
350  //
351  // if (debug)
352  // {
353  // Pout<< "oldCyclicPolyPatch::getCentresAndAnchors :"
354  // << "Specified translation : " << separationVector_
355  // << endl;
356  // }
357  //
358  // half0Ctrs += separationVector_;
359  // anchors0 += separationVector_;
360  // break;
361  //}
362  default:
363  {
364  // Assumes that cyclic is planar. This is also the initial
365  // condition for patches without faces.
366 
367  // Determine the face with max area on both halves. These
368  // two faces are used to determine the transformation tensors
369  label max0I = findMaxArea(pp.points(), half0Faces);
370  const vector n0 = half0Faces[max0I].unitNormal(pp.points());
371 
372  label max1I = findMaxArea(pp.points(), half1Faces);
373  const vector n1 = half1Faces[max1I].unitNormal(pp.points());
374 
375  if (mag(n0 & n1) < 1-matchTolerance())
376  {
377  if (debug)
378  {
379  Pout<< "oldCyclicPolyPatch::getCentresAndAnchors :"
380  << " Detected rotation :"
381  << " n0:" << n0 << " n1:" << n1 << endl;
382  }
383 
384  // Rotation (around origin)
385  const tensor reverseT(rotationTensor(n0, -n1));
386 
387  // Rotation
388  forAll(half0Ctrs, facei)
389  {
390  half0Ctrs[facei] = Foam::transform
391  (
392  reverseT,
393  half0Ctrs[facei]
394  );
395  anchors0[facei] = Foam::transform
396  (
397  reverseT,
398  anchors0[facei]
399  );
400  }
401  ppPoints = Foam::transform(reverseT, pp.points());
402  }
403  else
404  {
405  // Parallel translation. Get average of all used points.
406 
407  primitiveFacePatch half0(half0Faces, pp.points());
408  const pointField& half0Pts = half0.localPoints();
409  const point ctr0(sum(half0Pts)/half0Pts.size());
410 
411  primitiveFacePatch half1(half1Faces, pp.points());
412  const pointField& half1Pts = half1.localPoints();
413  const point ctr1(sum(half1Pts)/half1Pts.size());
414 
415  if (debug)
416  {
417  Pout<< "oldCyclicPolyPatch::getCentresAndAnchors :"
418  << " Detected translation :"
419  << " n0:" << n0 << " n1:" << n1
420  << " ctr0:" << ctr0 << " ctr1:" << ctr1 << endl;
421  }
422 
423  half0Ctrs += ctr1 - ctr0;
424  anchors0 += ctr1 - ctr0;
425  ppPoints = pp.points() + ctr1 - ctr0;
426  }
427  break;
428  }
429  }
430 
431 
432  // Calculate typical distance per face
433  tols = matchTolerance()*calcFaceTol(half1Faces, pp.points(), half1Ctrs);
434 }
435 
436 
437 bool Foam::oldCyclicPolyPatch::matchAnchors
438 (
439  const bool report,
440  const primitivePatch& pp,
441  const labelList& half0ToPatch,
442  const pointField& anchors0,
443 
444  const labelList& half1ToPatch,
445  const faceList& half1Faces,
446  const labelList& from1To0,
447 
448  const scalarField& tols,
449 
451  labelList& rotation
452 ) const
453 {
454  // Set faceMap such that half0 faces get first and corresponding half1
455  // faces last.
456 
457  forAll(half0ToPatch, half0Facei)
458  {
459  // Label in original patch
460  label patchFacei = half0ToPatch[half0Facei];
461 
462  faceMap[patchFacei] = half0Facei;
463 
464  // No rotation
465  rotation[patchFacei] = 0;
466  }
467 
468  bool fullMatch = true;
469 
470  forAll(from1To0, half1Facei)
471  {
472  label patchFacei = half1ToPatch[half1Facei];
473 
474  // This face has to match the corresponding one on half0.
475  label half0Facei = from1To0[half1Facei];
476 
477  label newFacei = half0Facei + pp.size()/2;
478 
479  faceMap[patchFacei] = newFacei;
480 
481  // Rotate patchFacei such that its f[0] aligns with that of
482  // the corresponding face
483  // (which after shuffling will be at position half0Facei)
484 
485  const point& wantedAnchor = anchors0[half0Facei];
486 
487  rotation[newFacei] = getRotation
488  (
489  pp.points(),
490  half1Faces[half1Facei],
491  wantedAnchor,
492  tols[half1Facei]
493  );
494 
495  if (rotation[newFacei] == -1)
496  {
497  fullMatch = false;
498 
499  if (report)
500  {
501  const face& f = half1Faces[half1Facei];
503  << "Patch:" << name() << " : "
504  << "Cannot find point on face " << f
505  << " with vertices:"
506  << UIndirectList<point>(pp.points(), f)
507  << " that matches point " << wantedAnchor
508  << " when matching the halves of cyclic patch " << name()
509  << endl
510  << "Continuing with incorrect face ordering from now on!"
511  << endl;
512  }
513  }
514  }
515  return fullMatch;
516 }
517 
518 
519 Foam::label Foam::oldCyclicPolyPatch::getConsistentRotationFace
520 (
521  const pointField& faceCentres
522 ) const
523 {
524  const scalarField magRadSqr
525  (
526  magSqr((faceCentres - rotationCentre_) ^ rotationAxis_)
527  );
528  scalarField axisLen
529  (
530  (faceCentres - rotationCentre_) & rotationAxis_
531  );
532  axisLen = axisLen - min(axisLen);
533  const scalarField magLenSqr
534  (
535  magRadSqr + axisLen*axisLen
536  );
537 
538  label rotFace = -1;
539  scalar maxMagLenSqr = -GREAT;
540  scalar maxMagRadSqr = -GREAT;
541  forAll(faceCentres, i)
542  {
543  if (magLenSqr[i] >= maxMagLenSqr)
544  {
545  if (magRadSqr[i] > maxMagRadSqr)
546  {
547  rotFace = i;
548  maxMagLenSqr = magLenSqr[i];
549  maxMagRadSqr = magRadSqr[i];
550  }
551  }
552  }
553 
554  if (debug)
555  {
556  Info<< "getConsistentRotationFace(const pointField&)" << nl
557  << " rotFace = " << rotFace << nl
558  << " point = " << faceCentres[rotFace] << endl;
559  }
560 
561  return rotFace;
562 }
563 
564 
565 // * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
566 
568 (
569  const word& name,
570  const label size,
571  const label start,
572  const label index,
573  const polyBoundaryMesh& bm,
574  const word& patchType,
576 )
577 :
578  coupledPolyPatch(name, size, start, index, bm, patchType, transform),
579  featureCos_(0.9),
580  rotationAxis_(Zero),
581  rotationCentre_(Zero),
582  separationVector_(Zero)
583 {}
584 
585 
587 (
588  const word& name,
589  const dictionary& dict,
590  const label index,
591  const polyBoundaryMesh& bm,
592  const word& patchType
593 )
594 :
595  coupledPolyPatch(name, dict, index, bm, patchType),
596  featureCos_(0.9),
597  rotationAxis_(Zero),
598  rotationCentre_(Zero),
599  separationVector_(Zero)
600 {
601  if (dict.found("neighbourPatch"))
602  {
604  << "Found \"neighbourPatch\" entry when reading cyclic patch "
605  << name << endl
606  << "Is this mesh already with split cyclics?" << endl
607  << "If so run a newer version that supports it"
608  << ", if not comment out the \"neighbourPatch\" entry and re-run"
609  << exit(FatalIOError);
610  }
611 
612  dict.readIfPresent("featureCos", featureCos_);
613 
614  switch (transform())
615  {
616  case ROTATIONAL:
617  {
618  dict.readEntry("rotationAxis", rotationAxis_);
619  dict.readEntry("rotationCentre", rotationCentre_);
620  break;
621  }
622  case TRANSLATIONAL:
623  {
624  dict.readEntry("separationVector", separationVector_);
625  break;
626  }
627  default:
628  {
629  // no additional info required
630  }
631  }
632 }
633 
634 
636 (
637  const oldCyclicPolyPatch& pp,
638  const polyBoundaryMesh& bm
639 )
640 :
641  coupledPolyPatch(pp, bm),
642  featureCos_(pp.featureCos_),
643  rotationAxis_(pp.rotationAxis_),
644  rotationCentre_(pp.rotationCentre_),
645  separationVector_(pp.separationVector_)
646 {}
647 
648 
650 (
651  const oldCyclicPolyPatch& pp,
652  const polyBoundaryMesh& bm,
653  const label index,
654  const label newSize,
655  const label newStart
656 )
657 :
658  coupledPolyPatch(pp, bm, index, newSize, newStart),
659  featureCos_(pp.featureCos_),
660  rotationAxis_(pp.rotationAxis_),
661  rotationCentre_(pp.rotationCentre_),
662  separationVector_(pp.separationVector_)
663 {}
664 
665 
666 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
667 
669 {}
670 
671 
672 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
673 
675 {
677 }
678 
679 
681 (
682  const primitivePatch& referPatch,
683  const pointField& thisCtrs,
684  const vectorField& thisAreas,
685  const pointField& thisCc,
686  const pointField& nbrCtrs,
687  const vectorField& nbrAreas,
688  const pointField& nbrCc
689 )
690 {}
691 
692 
694 {}
695 
696 
698 (
699  PstreamBuffers& pBufs,
700  const pointField& p
701 )
702 {
704 }
705 
706 
708 (
709  PstreamBuffers& pBufs,
710  const pointField& p
711 )
712 {
713  polyPatch::movePoints(pBufs, p);
714 }
715 
716 
718 {
720 }
721 
722 
724 {
725  polyPatch::updateMesh(pBufs);
726 }
727 
728 
730 (
732  const primitivePatch& pp
733 ) const
734 {}
735 
736 
737 // Return new ordering. Ordering is -faceMap: for every face index
738 // the new face -rotation:for every new face the clockwise shift
739 // of the original face. Return false if nothing changes (faceMap
740 // is identity, rotation is 0)
742 (
744  const primitivePatch& pp,
746  labelList& rotation
747 ) const
748 {
749  faceMap.setSize(pp.size());
750  faceMap = -1;
751 
752  rotation.setSize(pp.size());
753  rotation = 0;
754 
755  if (pp.empty())
756  {
757  // No faces, nothing to change.
758  return false;
759  }
760 
761  if (pp.size()&1)
762  {
764  << "Size of cyclic " << name() << " should be a multiple of 2"
765  << ". It is " << pp.size() << abort(FatalError);
766  }
767 
768  label halfSize = pp.size()/2;
769 
770  // Supplied primitivePatch already with new points.
771  // Cyclics are limited to one transformation tensor
772  // currently anyway (i.e. straight plane) so should not be too big a
773  // problem.
774 
775 
776  // Indices of faces on half0
777  labelList half0ToPatch;
778  // Indices of faces on half1
779  labelList half1ToPatch;
780 
781 
782  // 1. Test if already correctly oriented by starting from trivial ordering.
783  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
784 
785  half0ToPatch = identity(halfSize);
786  half1ToPatch = half0ToPatch + halfSize;
787 
788  // Get faces
789  faceList half0Faces(UIndirectList<face>(pp, half0ToPatch));
790  faceList half1Faces(UIndirectList<face>(pp, half1ToPatch));
791 
792  // Get geometric quantities
793  pointField half0Ctrs, half1Ctrs, anchors0, ppPoints;
794  scalarField tols;
795  getCentresAndAnchors
796  (
797  pp,
798  half0Faces,
799  half1Faces,
800 
801  ppPoints,
802  half0Ctrs,
803  half1Ctrs,
804  anchors0,
805  tols
806  );
807 
808  // Geometric match of face centre vectors
809  labelList from1To0;
810  bool matchedAll = matchPoints
811  (
812  half1Ctrs,
813  half0Ctrs,
814  tols,
815  false,
816  from1To0
817  );
818 
819  if (debug)
820  {
821  Pout<< "oldCyclicPolyPatch::order : test if already ordered:"
822  << matchedAll << endl;
823 
824  // Dump halves
825  fileName nm0("match1_"+name()+"_half0_faces.obj");
826  Pout<< "oldCyclicPolyPatch::order : Writing half0"
827  << " faces to OBJ file " << nm0 << endl;
828  writeOBJ(nm0, half0Faces, ppPoints);
829 
830  fileName nm1("match1_"+name()+"_half1_faces.obj");
831  Pout<< "oldCyclicPolyPatch::order : Writing half1"
832  << " faces to OBJ file " << nm1 << endl;
833  writeOBJ(nm1, half1Faces, pp.points());
834 
835  OFstream ccStr
836  (
837  boundaryMesh().mesh().time().path()
838  /"match1_"+ name() + "_faceCentres.obj"
839  );
840  Pout<< "oldCyclicPolyPatch::order : "
841  << "Dumping currently found cyclic match as lines between"
842  << " corresponding face centres to file " << ccStr.name()
843  << endl;
844 
845  // Recalculate untransformed face centres
846  //pointField rawHalf0Ctrs = calcFaceCentres(half0Faces, pp.points());
847  label vertI = 0;
848 
849  forAll(half1Ctrs, i)
850  {
851  //if (from1To0[i] != -1)
852  {
853  // Write edge between c1 and c0
854  //const point& c0 = rawHalf0Ctrs[from1To0[i]];
855  //const point& c0 = half0Ctrs[from1To0[i]];
856  const point& c0 = half0Ctrs[i];
857  const point& c1 = half1Ctrs[i];
858  writeOBJ(ccStr, c0, c1, vertI);
859  }
860  }
861  }
862 
863 
864  // 2. Ordered in pairs (so 0,1 coupled and 2,3 etc.)
865  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
866 
867  if (!matchedAll)
868  {
869  label facei = 0;
870  for (label i = 0; i < halfSize; i++)
871  {
872  half0ToPatch[i] = facei++;
873  half1ToPatch[i] = facei++;
874  }
875 
876  // And redo all matching
877  half0Faces = UIndirectList<face>(pp, half0ToPatch);
878  half1Faces = UIndirectList<face>(pp, half1ToPatch);
879 
880  getCentresAndAnchors
881  (
882  pp,
883  half0Faces,
884  half1Faces,
885 
886  ppPoints,
887  half0Ctrs,
888  half1Ctrs,
889  anchors0,
890  tols
891  );
892 
893  // Geometric match of face centre vectors
894  matchedAll = matchPoints
895  (
896  half1Ctrs,
897  half0Ctrs,
898  tols,
899  false,
900  from1To0
901  );
902 
903  if (debug)
904  {
905  Pout<< "oldCyclicPolyPatch::order : test if pairwise ordered:"
906  << matchedAll << endl;
907  // Dump halves
908  fileName nm0("match2_"+name()+"_half0_faces.obj");
909  Pout<< "oldCyclicPolyPatch::order : Writing half0"
910  << " faces to OBJ file " << nm0 << endl;
911  writeOBJ(nm0, half0Faces, ppPoints);
912 
913  fileName nm1("match2_"+name()+"_half1_faces.obj");
914  Pout<< "oldCyclicPolyPatch::order : Writing half1"
915  << " faces to OBJ file " << nm1 << endl;
916  writeOBJ(nm1, half1Faces, pp.points());
917 
918  OFstream ccStr
919  (
920  boundaryMesh().mesh().time().path()
921  /"match2_"+name()+"_faceCentres.obj"
922  );
923  Pout<< "oldCyclicPolyPatch::order : "
924  << "Dumping currently found cyclic match as lines between"
925  << " corresponding face centres to file " << ccStr.name()
926  << endl;
927 
928  // Recalculate untransformed face centres
929  label vertI = 0;
930 
931  forAll(half1Ctrs, i)
932  {
933  if (from1To0[i] != -1)
934  {
935  // Write edge between c1 and c0
936  const point& c0 = half0Ctrs[from1To0[i]];
937  const point& c1 = half1Ctrs[i];
938  writeOBJ(ccStr, c0, c1, vertI);
939  }
940  }
941  }
942  }
943 
944 
945  // 3. Baffles(coincident faces) converted into cyclics (e.g. jump)
946  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
947 
948  if (!matchedAll)
949  {
950  label baffleI = 0;
951 
952  forAll(pp, facei)
953  {
954  const face& f = pp.localFaces()[facei];
955  const labelList& pFaces = pp.pointFaces()[f[0]];
956 
957  label matchedFacei = -1;
958 
959  forAll(pFaces, i)
960  {
961  label otherFacei = pFaces[i];
962 
963  if (otherFacei > facei)
964  {
965  const face& otherF = pp.localFaces()[otherFacei];
966 
967  // Note: might pick up two similar oriented faces
968  // (but that is illegal anyway)
969  if (f == otherF)
970  {
971  matchedFacei = otherFacei;
972  break;
973  }
974  }
975  }
976 
977  if (matchedFacei != -1)
978  {
979  half0ToPatch[baffleI] = facei;
980  half1ToPatch[baffleI] = matchedFacei;
981  baffleI++;
982  }
983  }
984 
985  if (baffleI == halfSize)
986  {
987  // And redo all matching
988  half0Faces = UIndirectList<face>(pp, half0ToPatch);
989  half1Faces = UIndirectList<face>(pp, half1ToPatch);
990 
991  getCentresAndAnchors
992  (
993  pp,
994  half0Faces,
995  half1Faces,
996 
997  ppPoints,
998  half0Ctrs,
999  half1Ctrs,
1000  anchors0,
1001  tols
1002  );
1003 
1004  // Geometric match of face centre vectors
1005  matchedAll = matchPoints
1006  (
1007  half1Ctrs,
1008  half0Ctrs,
1009  tols,
1010  false,
1011  from1To0
1012  );
1013 
1014  if (debug)
1015  {
1016  Pout<< "oldCyclicPolyPatch::order : test if baffles:"
1017  << matchedAll << endl;
1018  // Dump halves
1019  fileName nm0("match3_"+name()+"_half0_faces.obj");
1020  Pout<< "oldCyclicPolyPatch::order : Writing half0"
1021  << " faces to OBJ file " << nm0 << endl;
1022  writeOBJ(nm0, half0Faces, ppPoints);
1023 
1024  fileName nm1("match3_"+name()+"_half1_faces.obj");
1025  Pout<< "oldCyclicPolyPatch::order : Writing half1"
1026  << " faces to OBJ file " << nm1 << endl;
1027  writeOBJ(nm1, half1Faces, pp.points());
1028 
1029  OFstream ccStr
1030  (
1031  boundaryMesh().mesh().time().path()
1032  /"match3_"+ name() + "_faceCentres.obj"
1033  );
1034  Pout<< "oldCyclicPolyPatch::order : "
1035  << "Dumping currently found cyclic match as lines between"
1036  << " corresponding face centres to file " << ccStr.name()
1037  << endl;
1038 
1039  // Recalculate untransformed face centres
1040  label vertI = 0;
1041 
1042  forAll(half1Ctrs, i)
1043  {
1044  if (from1To0[i] != -1)
1045  {
1046  // Write edge between c1 and c0
1047  const point& c0 = half0Ctrs[from1To0[i]];
1048  const point& c1 = half1Ctrs[i];
1049  writeOBJ(ccStr, c0, c1, vertI);
1050  }
1051  }
1052  }
1053  }
1054  }
1055 
1056 
1057  // 4. Automatic geometric ordering
1058  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1059 
1060  if (!matchedAll)
1061  {
1062  // Split faces according to feature angle or topology
1063  bool okSplit = getGeometricHalves(pp, half0ToPatch, half1ToPatch);
1064 
1065  if (!okSplit)
1066  {
1067  // Did not split into two equal parts.
1068  return false;
1069  }
1070 
1071  // And redo all matching
1072  half0Faces = UIndirectList<face>(pp, half0ToPatch);
1073  half1Faces = UIndirectList<face>(pp, half1ToPatch);
1074 
1075  getCentresAndAnchors
1076  (
1077  pp,
1078  half0Faces,
1079  half1Faces,
1080 
1081  ppPoints,
1082  half0Ctrs,
1083  half1Ctrs,
1084  anchors0,
1085  tols
1086  );
1087 
1088  // Geometric match of face centre vectors
1089  matchedAll = matchPoints
1090  (
1091  half1Ctrs,
1092  half0Ctrs,
1093  tols,
1094  false,
1095  from1To0
1096  );
1097 
1098  if (debug)
1099  {
1100  Pout<< "oldCyclicPolyPatch::order : automatic ordering result:"
1101  << matchedAll << endl;
1102  // Dump halves
1103  fileName nm0("match4_"+name()+"_half0_faces.obj");
1104  Pout<< "oldCyclicPolyPatch::order : Writing half0"
1105  << " faces to OBJ file " << nm0 << endl;
1106  writeOBJ(nm0, half0Faces, ppPoints);
1107 
1108  fileName nm1("match4_"+name()+"_half1_faces.obj");
1109  Pout<< "oldCyclicPolyPatch::order : Writing half1"
1110  << " faces to OBJ file " << nm1 << endl;
1111  writeOBJ(nm1, half1Faces, pp.points());
1112 
1113  OFstream ccStr
1114  (
1115  boundaryMesh().mesh().time().path()
1116  /"match4_"+ name() + "_faceCentres.obj"
1117  );
1118  Pout<< "oldCyclicPolyPatch::order : "
1119  << "Dumping currently found cyclic match as lines between"
1120  << " corresponding face centres to file " << ccStr.name()
1121  << endl;
1122 
1123  // Recalculate untransformed face centres
1124  label vertI = 0;
1125 
1126  forAll(half1Ctrs, i)
1127  {
1128  if (from1To0[i] != -1)
1129  {
1130  // Write edge between c1 and c0
1131  const point& c0 = half0Ctrs[from1To0[i]];
1132  const point& c1 = half1Ctrs[i];
1133  writeOBJ(ccStr, c0, c1, vertI);
1134  }
1135  }
1136  }
1137  }
1138 
1139 
1140  if (!matchedAll || debug)
1141  {
1142  // Dump halves
1143  fileName nm0(name()+"_half0_faces.obj");
1144  Pout<< "oldCyclicPolyPatch::order : Writing half0"
1145  << " faces to OBJ file " << nm0 << endl;
1146  writeOBJ(nm0, half0Faces, pp.points());
1147 
1148  fileName nm1(name()+"_half1_faces.obj");
1149  Pout<< "oldCyclicPolyPatch::order : Writing half1"
1150  << " faces to OBJ file " << nm1 << endl;
1151  writeOBJ(nm1, half1Faces, pp.points());
1152 
1153  OFstream ccStr
1154  (
1155  boundaryMesh().mesh().time().path()
1156  /name() + "_faceCentres.obj"
1157  );
1158  Pout<< "oldCyclicPolyPatch::order : "
1159  << "Dumping currently found cyclic match as lines between"
1160  << " corresponding face centres to file " << ccStr.name()
1161  << endl;
1162 
1163  // Recalculate untransformed face centres
1164  //pointField rawHalf0Ctrs = calcFaceCentres(half0Faces, pp.points());
1165  label vertI = 0;
1166 
1167  forAll(half1Ctrs, i)
1168  {
1169  if (from1To0[i] != -1)
1170  {
1171  // Write edge between c1 and c0
1172  //const point& c0 = rawHalf0Ctrs[from1To0[i]];
1173  const point& c0 = half0Ctrs[from1To0[i]];
1174  const point& c1 = half1Ctrs[i];
1175  writeOBJ(ccStr, c0, c1, vertI);
1176  }
1177  }
1178  }
1179 
1180 
1181  if (!matchedAll)
1182  {
1184  << "Patch:" << name() << " : "
1185  << "Cannot match vectors to faces on both sides of patch" << endl
1186  << " Perhaps your faces do not match?"
1187  << " The obj files written contain the current match." << endl
1188  << " Continuing with incorrect face ordering from now on!"
1189  << endl;
1190 
1191  return false;
1192  }
1193 
1194 
1195  // Set faceMap such that half0 faces get first and corresponding half1
1196  // faces last.
1197  matchAnchors
1198  (
1199  true, // report if anchor matching error
1200  pp,
1201  half0ToPatch,
1202  anchors0,
1203  half1ToPatch,
1204  half1Faces,
1205  from1To0,
1206  tols,
1207  faceMap,
1208  rotation
1209  );
1210 
1211  // Return false if no change necessary, true otherwise.
1212 
1213  forAll(faceMap, facei)
1214  {
1215  if (faceMap[facei] != facei || rotation[facei] != 0)
1216  {
1217  return true;
1218  }
1219  }
1220 
1221  return false;
1222 }
1223 
1224 
1226 {
1227  // Replacement of polyPatch::write to write 'cyclic' instead of type():
1228  os.writeEntry("type", cyclicPolyPatch::typeName);
1230  os.writeEntry("nFaces", size());
1231  os.writeEntry("startFace", start());
1232 
1233 
1234  os.writeEntry("featureCos", featureCos_);
1235  switch (transform())
1236  {
1237  case ROTATIONAL:
1238  {
1239  os.writeEntry("rotationAxis", rotationAxis_);
1240  os.writeEntry("rotationCentre", rotationCentre_);
1241  break;
1242  }
1243  case TRANSLATIONAL:
1244  {
1245  os.writeEntry("separationVector", separationVector_);
1246  break;
1247  }
1248  default:
1249  {
1250  // no additional info to write
1251  }
1252  }
1253 
1255  << "Please run foamUpgradeCyclics to convert these old-style"
1256  << " cyclics into two separate cyclics patches."
1257  << endl;
1258 }
1259 
1260 
1261 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::oldCyclicPolyPatch::updateMesh
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
Definition: oldCyclicPolyPatch.C:723
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::PrimitivePatch::pointFaces
const labelListList & pointFaces() const
Return point-face addressing.
Definition: PrimitivePatch.C:281
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::oldCyclicPolyPatch::initGeometry
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
Definition: oldCyclicPolyPatch.C:674
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::oldCyclicPolyPatch::write
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
Definition: oldCyclicPolyPatch.C:1225
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::polyPatch::movePoints
virtual void movePoints(PstreamBuffers &, const pointField &p)
Correct patches after moving points.
Definition: polyPatch.C:61
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
cyclicPolyPatch.H
Foam::primitiveFacePatch
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
A PrimitivePatch with List storage for the faces, const reference for the point field.
Definition: primitiveFacePatch.H:51
Foam::oldCyclicPolyPatch::movePoints
virtual void movePoints(PstreamBuffers &, const pointField &)
Correct patches after moving points.
Definition: oldCyclicPolyPatch.C:708
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
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: dictionary.C:364
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:87
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:69
Foam::FatalIOError
IOerror FatalIOError
Foam::oldCyclicPolyPatch::initMovePoints
virtual void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
Definition: oldCyclicPolyPatch.C:698
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::coupledPolyPatch
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
Definition: coupledPolyPatch.H:53
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:519
polyMesh.H
Foam::polyPatch::updateMesh
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
Definition: polyPatch.C:67
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::oldCyclicPolyPatch::~oldCyclicPolyPatch
virtual ~oldCyclicPolyPatch()
Definition: oldCyclicPolyPatch.C:668
OFstream.H
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
oldCyclicPolyPatch.H
Foam::oldCyclicPolyPatch::order
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
Definition: oldCyclicPolyPatch.C:742
matchPoints.H
Determine correspondence between points. See below.
Foam::polyPatch::initUpdateMesh
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
Definition: polyPatch.H:117
Foam::constant::physicoChemical::c1
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
pFaces
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::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, &oldCyclicPolyPatch::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:235
faceNormals
surfaceVectorField faceNormals(mesh.Sf()/mesh.magSf())
Foam::Field< vector >
Foam::polyPatch::initMovePoints
virtual void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
Definition: polyPatch.H:110
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
patchZones.H
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::OSstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:107
SeriousErrorInFunction
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
Definition: messageStream.H:281
Foam::dictionary::readEntry
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
Definition: dictionaryTemplates.C:314
Foam::polyPatch::initGeometry
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
Definition: polyPatch.H:102
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:121
Foam::PrimitivePatch::points
const Field< point_type > & points() const
Return reference to global points.
Definition: PrimitivePatch.H:305
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::oldCyclicPolyPatch::initOrder
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
Definition: oldCyclicPolyPatch.C:730
Foam::PrimitivePatch::localFaces
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
Definition: PrimitivePatch.C:297
Foam::oldCyclicPolyPatch::initUpdateMesh
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
Definition: oldCyclicPolyPatch.C:717
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::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::normalised
VectorSpace< Form, Cmpt, Ncmpts > normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:483
Time.H
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
Foam::oldCyclicPolyPatch
'old' style cyclic polyPatch with all faces in single patch. Does ordering but cannot be used to run....
Definition: oldCyclicPolyPatch.H:54
Foam::oldCyclicPolyPatch::calcGeometry
virtual void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
Definition: oldCyclicPolyPatch.C:693
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::nl
constexpr char nl
Definition: Ostream.H:385
f
labelList f(nPoints)
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::Vector< scalar >
Foam::List< label >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
points
const pointField & points
Definition: gmvOutputHeader.H:1
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::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
polyBoundaryMesh.H
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:232
Foam::UIndirectList
A List with indirect addressing.
Definition: faMatrix.H:60
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:62
Foam::patchIdentifier::write
void write(Ostream &os) const
Definition: patchIdentifier.C:96
Foam::primitivePatch
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
Definition: primitivePatch.H:51
Foam::findIndices
labelList findIndices(const ListType &input, typename ListType::const_reference val, label start=0)
Linear search to find all occurrences of given element.
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::rotationTensor
tensor rotationTensor(const vector &n1, const vector &n2)
Rotational transformation tensor from vector n1 to n2.
Definition: transform.H:51
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::coupledPolyPatch::transformType
transformType
Definition: coupledPolyPatch.H:59
transformList.H
Spatial transformation functions for list of values and primitive fields.
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::matchPoints
bool matchPoints(const UList< point > &pts0, const UList< point > &pts1, const UList< scalar > &matchDistance, const bool verbose, labelList &from0To1, const point &origin=point::zero)
Determine correspondence between pointFields. Gets passed.
Definition: matchPoints.C:36
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303
Foam::tensor
Tensor< scalar > tensor
Tensor of scalars, i.e. Tensor<scalar>.
Definition: symmTensor.H:61
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:85
Foam::oldCyclicPolyPatch::oldCyclicPolyPatch
oldCyclicPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm, const word &patchType, const transformType transform=UNKNOWN)
Construct from components.
Definition: oldCyclicPolyPatch.C:568