polyMeshCheck.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) 2012-2024 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 "primitiveMeshCheck.H"
27 #include "polyMeshCheck.H"
28 #include "unitConversion.H"
29 #include "syncTools.H"
30 
31 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
32 
34 (
35  const polyMesh& mesh,
36  const vectorField& areas,
37  const vectorField& cc
38 )
39 {
40  const labelList& own = mesh.faceOwner();
41  const labelList& nei = mesh.faceNeighbour();
42  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
43 
44  tmp<scalarField> tortho(new scalarField(mesh.nFaces(), 1.0));
45  scalarField& ortho = tortho.ref();
46 
47  // Internal faces
48  forAll(nei, facei)
49  {
50  ortho[facei] = meshCheck::faceOrthogonality
51  (
52  cc[own[facei]],
53  cc[nei[facei]],
54  areas[facei]
55  );
56  }
57 
58 
59  // Coupled faces
60 
61  pointField neighbourCc;
62  syncTools::swapBoundaryCellPositions(mesh, cc, neighbourCc);
63 
64  forAll(pbm, patchi)
65  {
66  const polyPatch& pp = pbm[patchi];
67  if (pp.coupled())
68  {
69  forAll(pp, i)
70  {
71  label facei = pp.start() + i;
72  label bFacei = facei - mesh.nInternalFaces();
73 
74  ortho[facei] = meshCheck::faceOrthogonality
75  (
76  cc[own[facei]],
77  neighbourCc[bFacei],
78  areas[facei]
79  );
80  }
81  }
82  }
83 
84  return tortho;
85 }
86 
87 
89 (
90  const polyMesh& mesh,
91  const pointField& p,
92  const vectorField& fCtrs,
93  const vectorField& fAreas,
94  const vectorField& cellCtrs
95 )
96 {
97  const labelList& own = mesh.faceOwner();
98  const labelList& nei = mesh.faceNeighbour();
99  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
100 
101  tmp<scalarField> tskew(new scalarField(mesh.nFaces()));
102  scalarField& skew = tskew.ref();
103 
104  forAll(nei, facei)
105  {
107  (
108  mesh,
109  p,
110  fCtrs,
111  fAreas,
112 
113  facei,
114  cellCtrs[own[facei]],
115  cellCtrs[nei[facei]]
116  );
117  }
118 
119 
120  // Boundary faces: consider them to have only skewness error.
121  // (i.e. treat as if mirror cell on other side)
122 
123  pointField neighbourCc;
124  syncTools::swapBoundaryCellPositions(mesh, cellCtrs, neighbourCc);
125 
126  forAll(pbm, patchi)
127  {
128  const polyPatch& pp = pbm[patchi];
129  if (pp.coupled())
130  {
131  forAll(pp, i)
132  {
133  const label facei = pp.start() + i;
134  const label bFacei = facei - mesh.nInternalFaces();
135 
137  (
138  mesh,
139  p,
140  fCtrs,
141  fAreas,
142 
143  facei,
144  cellCtrs[own[facei]],
145  neighbourCc[bFacei]
146  );
147  }
148  }
149  else
150  {
151  forAll(pp, i)
152  {
153  const label facei = pp.start() + i;
154 
156  (
157  mesh,
158  p,
159  fCtrs,
160  fAreas,
161 
162  facei,
163  cellCtrs[own[facei]]
164  );
165  }
166  }
167  }
168 
169  return tskew;
170 }
171 
172 
174 (
175  const polyMesh& mesh,
176  const vectorField& fCtrs,
177  const vectorField& fAreas,
178  const vectorField& cellCtrs
179 )
180 {
181  const labelList& own = mesh.faceOwner();
182  const labelList& nei = mesh.faceNeighbour();
183  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
184 
185  tmp<scalarField> tweight(new scalarField(mesh.nFaces(), 1.0));
186  scalarField& weight = tweight.ref();
187 
188  // Internal faces
189  forAll(nei, facei)
190  {
191  const point& fc = fCtrs[facei];
192  const vector& fa = fAreas[facei];
193 
194  const scalar dOwn = mag(fa & (fc-cellCtrs[own[facei]]));
195  const scalar dNei = mag(fa & (cellCtrs[nei[facei]]-fc));
196 
197  weight[facei] = min(dNei,dOwn)/(dNei+dOwn+vSmall);
198  }
199 
200 
201  // Coupled faces
202 
203  pointField neiCc;
204  syncTools::swapBoundaryCellPositions(mesh, cellCtrs, neiCc);
205 
206  forAll(pbm, patchi)
207  {
208  const polyPatch& pp = pbm[patchi];
209  if (pp.coupled())
210  {
211  forAll(pp, i)
212  {
213  const label facei = pp.start() + i;
214  const label bFacei = facei - mesh.nInternalFaces();
215 
216  const point& fc = fCtrs[facei];
217  const vector& fa = fAreas[facei];
218 
219  const scalar dOwn = mag(fa & (fc-cellCtrs[own[facei]]));
220  const scalar dNei = mag(fa & (neiCc[bFacei]-fc));
221 
222  weight[facei] = min(dNei,dOwn)/(dNei+dOwn+vSmall);
223  }
224  }
225  }
226 
227  return tweight;
228 }
229 
230 
232 (
233  const polyMesh& mesh,
234  const scalarField& vol
235 )
236 {
237  const labelList& own = mesh.faceOwner();
238  const labelList& nei = mesh.faceNeighbour();
239  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
240 
241  tmp<scalarField> tratio(new scalarField(mesh.nFaces(), 1.0));
242  scalarField& ratio = tratio.ref();
243 
244  // Internal faces
245  forAll(nei, facei)
246  {
247  const scalar volOwn = vol[own[facei]];
248  const scalar volNei = vol[nei[facei]];
249 
250  ratio[facei] = min(volOwn,volNei)/(max(volOwn, volNei)+vSmall);
251  }
252 
253 
254  // Coupled faces
255 
256  scalarField neiVol;
257  syncTools::swapBoundaryCellList(mesh, vol, neiVol);
258 
259  forAll(pbm, patchi)
260  {
261  const polyPatch& pp = pbm[patchi];
262  if (pp.coupled())
263  {
264  forAll(pp, i)
265  {
266  const label facei = pp.start() + i;
267  const label bFacei = facei - mesh.nInternalFaces();
268 
269  const scalar volOwn = vol[own[facei]];
270  const scalar volNei = neiVol[bFacei];
271 
272  ratio[facei] = min(volOwn,volNei)/(max(volOwn, volNei)+vSmall);
273  }
274  }
275  }
276 
277  return tratio;
278 }
279 
280 
282 (
283  const polyMesh& mesh,
284  const scalar nonOrthThreshold,
285  const bool report,
286  labelHashSet* setPtr
287 )
288 {
289  if (mesh.debug)
290  {
291  InfoInFunction << "Checking mesh non-orthogonality" << endl;
292  }
293 
294  const vectorField& fAreas = mesh.faceAreas();
295  const vectorField& cellCtrs = mesh.cellCentres();
296 
297  // Calculate orthogonality for all internal and coupled boundary faces
298  // (1 for uncoupled boundary faces)
300  (
301  mesh,
302  fAreas,
303  cellCtrs
304  );
305  const scalarField& ortho = tortho.ref();
306 
307  // Severe nonorthogonality threshold
308  const scalar severeNonorthogonalityThreshold = ::cos(nonOrthThreshold);
309 
310 
311  scalar minDDotS = great;
312  scalar sumDDotS = 0.0;
313  label nSummed = 0;
314  label severeNonOrth = 0;
315  label errorNonOrth = 0;
316 
317 
318  // Statistics only for internal and masters of coupled faces
319  PackedBoolList isMasterFace(syncTools::getInternalOrMasterFaces(mesh));
320 
321  forAll(ortho, facei)
322  {
323  if (ortho[facei] < severeNonorthogonalityThreshold)
324  {
325  if (ortho[facei] > small)
326  {
327  if (setPtr)
328  {
329  setPtr->insert(facei);
330  }
331 
332  severeNonOrth++;
333  }
334  else
335  {
336  // Error : non-ortho too large
337  if (setPtr)
338  {
339  setPtr->insert(facei);
340  }
341 
342  errorNonOrth++;
343  }
344  }
345 
346  if (isMasterFace[facei])
347  {
348  minDDotS = min(minDDotS, ortho[facei]);
349  sumDDotS += ortho[facei];
350  nSummed++;
351  }
352  }
353 
354  reduce(minDDotS, minOp<scalar>());
355  reduce(sumDDotS, sumOp<scalar>());
356  reduce(nSummed, sumOp<label>());
357  reduce(severeNonOrth, sumOp<label>());
358  reduce(errorNonOrth, sumOp<label>());
359 
360  if (report)
361  {
362  if (nSummed > 0)
363  {
364  if (report)
365  {
366  Info<< " Mesh non-orthogonality Max: "
367  << radToDeg(::acos(min(1.0, max(-1.0, minDDotS))))
368  << " average: "
369  << radToDeg(::acos(min(1.0, max(-1.0, sumDDotS/nSummed))))
370  << endl;
371  }
372  }
373 
374  if (severeNonOrth > 0)
375  {
376  Info<< " *Number of severely non-orthogonal (> "
377  << radToDeg(nonOrthThreshold) << " degrees) faces: "
378  << severeNonOrth << "." << endl;
379  }
380  }
381 
382  if (errorNonOrth > 0)
383  {
384  if (report)
385  {
386  Info<< " ***Number of non-orthogonality errors: "
387  << errorNonOrth << "." << endl;
388  }
389 
390  return true;
391  }
392  else
393  {
394  if (report)
395  {
396  Info<< " Non-orthogonality check OK." << endl;
397  }
398 
399  return false;
400  }
401 }
402 
403 
405 (
406  const polyMesh& mesh,
407  const scalar skewThreshold,
408  const bool report,
409  labelHashSet* setPtr
410 )
411 {
412  if (mesh.debug)
413  {
414  InfoInFunction << "Checking face skewness" << endl;
415  }
416 
417  const pointField& points = mesh.points();
418  const vectorField& fCtrs = mesh.faceCentres();
419  const vectorField& fAreas = mesh.faceAreas();
420  const vectorField& cellCtrs = mesh.cellCentres();
421 
422  // Warn if the skew correction vector is more than skewWarning times
423  // larger than the face area vector
424 
426  (
427  mesh,
428  points,
429  fCtrs,
430  fAreas,
431  cellCtrs
432  );
433  const scalarField& skew = tskew.ref();
434 
435  scalar maxSkew = max(skew);
436  label nWarnSkew = 0;
437 
438  // Statistics only for all faces except slave coupled faces
439  const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
440 
441  forAll(skew, facei)
442  {
443  // Check if the skewness vector is greater than the PN vector.
444  // This does not cause trouble but is a good indication of a poor mesh.
445  if (skew[facei] > skewThreshold)
446  {
447  if (setPtr)
448  {
449  setPtr->insert(facei);
450  }
451 
452  if (isMasterFace[facei])
453  {
454  nWarnSkew++;
455  }
456  }
457  }
458 
459  reduce(maxSkew, maxOp<scalar>());
460  reduce(nWarnSkew, sumOp<label>());
461 
462  if (nWarnSkew > 0)
463  {
464  if (report)
465  {
466  Info<< " ***Max skewness = " << maxSkew
467  << ", " << nWarnSkew << " highly skew faces detected"
468  " which may impair the quality of the results"
469  << endl;
470  }
471 
472  return true;
473  }
474  else
475  {
476  if (report)
477  {
478  Info<< " Max skewness = " << maxSkew << " OK." << endl;
479  }
480 
481  return false;
482  }
483 }
484 
485 
487 (
488  const polyMesh& mesh,
489  const bool report,
490  const Vector<label>& directions,
491  labelHashSet* setPtr
492 )
493 {
494  // Check 1D/2Dness of edges. Gets passed the non-empty directions and
495  // checks all edges in the mesh whether they:
496  // - have no component in a non-empty direction or
497  // - are only in a single non-empty direction.
498  // Empty direction info is passed in as a vector of labels (synchronised)
499  // which are 1 if the direction is non-empty, 0 if it is.
500 
501  if (mesh.debug)
502  {
503  InfoInFunction << "Checking edge alignment" << endl;
504  }
505 
506  const pointField& p = mesh.points();
507 
508  label nDirs = 0;
509  for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
510  {
511  if (directions[cmpt] == 1)
512  {
513  nDirs++;
514  }
515  else if (directions[cmpt] != 0)
516  {
518  << "directions should contain 0 or 1 but is now " << directions
519  << exit(FatalError);
520  }
521  }
522 
523  if (nDirs == vector::nComponents)
524  {
525  return false;
526  }
527 
528 
529  const faceList& fcs = mesh.faces();
530 
531  EdgeMap<label> edgesInError;
532 
533  forAll(fcs, facei)
534  {
535  const face& f = fcs[facei];
536 
537  forAll(f, fp)
538  {
539  const label p0 = f[fp];
540  const label p1 = f.nextLabel(fp);
541 
542  if (p0 < p1)
543  {
544  vector d(p[p1]-p[p0]);
545  const scalar magD = mag(d);
546 
547  if (magD > rootVSmall)
548  {
549  d /= magD;
550 
551  // Check how many empty directions are used by the edge.
552  label nEmptyDirs = 0;
553  label nNonEmptyDirs = 0;
554  for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
555  {
556  if (mag(d[cmpt]) > 1e-6)
557  {
558  if (directions[cmpt] == 0)
559  {
560  nEmptyDirs++;
561  }
562  else
563  {
564  nNonEmptyDirs++;
565  }
566  }
567  }
568 
569  if (nEmptyDirs == 0)
570  {
571  // Purely in ok directions.
572  }
573  else if (nEmptyDirs == 1)
574  {
575  // Ok if purely in empty directions.
576  if (nNonEmptyDirs > 0)
577  {
578  edgesInError.insert(edge(p0, p1), facei);
579  }
580  }
581  else if (nEmptyDirs > 1)
582  {
583  // Always an error
584  edgesInError.insert(edge(p0, p1), facei);
585  }
586  }
587  }
588  }
589  }
590 
591  label nErrorEdges = returnReduce(edgesInError.size(), sumOp<label>());
592 
593  if (nErrorEdges > 0)
594  {
595  if (report)
596  {
597  Info<< " ***Number of edges not aligned with or perpendicular to "
598  << "non-empty directions: " << nErrorEdges << endl;
599  }
600 
601  if (setPtr)
602  {
603  setPtr->resize(2*edgesInError.size());
604  forAllConstIter(EdgeMap<label>, edgesInError, iter)
605  {
606  setPtr->insert(iter.key()[0]);
607  setPtr->insert(iter.key()[1]);
608  }
609  }
610 
611  return true;
612  }
613  else
614  {
615  if (report)
616  {
617  Info<< " All edges aligned with or perpendicular to "
618  << "non-empty directions." << endl;
619  }
620  return false;
621  }
622 }
623 
624 
626 (
627  const polyMesh& mesh,
628  const bool report,
629  labelHashSet* setPtr
630 )
631 {
632  const vectorField& faceAreas = mesh.faceAreas();
633  const Vector<label>& meshD = mesh.geometricD();
634 
635  const scalar warnDet = 1e-3;
636 
637  if (mesh.debug)
638  {
639  InfoInFunction << "Checking for under-determined cells" << endl;
640  }
641 
643  (
644  mesh,
645  meshD,
646  faceAreas,
647  syncTools::getInternalOrCoupledFaces(mesh)
648  );
649  scalarField& cellDeterminant = tcellDeterminant.ref();
650 
651 
652  label nErrorCells = 0;
653  scalar minDet = min(cellDeterminant);
654  scalar sumDet = sum(cellDeterminant);
655 
656  forAll(cellDeterminant, celli)
657  {
658  if (cellDeterminant[celli] < warnDet)
659  {
660  if (setPtr)
661  {
662  setPtr->insert(celli);
663  }
664 
665  nErrorCells++;
666  }
667  }
668 
669  reduce(nErrorCells, sumOp<label>());
670  reduce(minDet, minOp<scalar>());
671  reduce(sumDet, sumOp<scalar>());
672  label nSummed = returnReduce(cellDeterminant.size(), sumOp<label>());
673 
674  if (report)
675  {
676  if (nSummed > 0)
677  {
678  Info<< " Cell determinant (wellposedness) : minimum: " << minDet
679  << " average: " << sumDet/nSummed
680  << endl;
681  }
682  }
683 
684  if (nErrorCells > 0)
685  {
686  if (report)
687  {
688  Info<< " ***Cells with small determinant (< "
689  << warnDet << ") found, number of cells: "
690  << nErrorCells << endl;
691  }
692 
693  return true;
694  }
695  else
696  {
697  if (report)
698  {
699  Info<< " Cell determinant check OK." << endl;
700  }
701 
702  return false;
703  }
704 
705  return false;
706 }
707 
708 
710 (
711  const polyMesh& mesh,
712  const bool report,
713  const scalar minWeight,
714  labelHashSet* setPtr
715 )
716 {
717  if (mesh.debug)
718  {
719  InfoInFunction << "Checking for low face interpolation weights" << endl;
720  }
721 
722  const vectorField& fCtrs = mesh.faceCentres();
723  const vectorField& fAreas = mesh.faceAreas();
724  const vectorField& cellCtrs = mesh.cellCentres();
725 
727  (
728  mesh,
729  fCtrs,
730  fAreas,
731  cellCtrs
732  );
733  scalarField& faceWght = tfaceWght.ref();
734 
735 
736  label nErrorFaces = 0;
737  scalar minDet = great;
738  scalar sumDet = 0.0;
739  label nSummed = 0;
740 
741  // Statistics only for internal and masters of coupled faces
742  PackedBoolList isMasterFace(syncTools::getInternalOrMasterFaces(mesh));
743 
744  forAll(faceWght, facei)
745  {
746  if (faceWght[facei] < minWeight)
747  {
748  // Note: insert both sides of coupled faces
749  if (setPtr)
750  {
751  setPtr->insert(facei);
752  }
753 
754  nErrorFaces++;
755  }
756 
757  // Note: statistics only on master of coupled faces
758  if (isMasterFace[facei])
759  {
760  minDet = min(minDet, faceWght[facei]);
761  sumDet += faceWght[facei];
762  nSummed++;
763  }
764  }
765 
766  reduce(nErrorFaces, sumOp<label>());
767  reduce(minDet, minOp<scalar>());
768  reduce(sumDet, sumOp<scalar>());
769  reduce(nSummed, sumOp<label>());
770 
771  if (report)
772  {
773  if (nSummed > 0)
774  {
775  Info<< " Face interpolation weight : minimum: " << minDet
776  << " average: " << sumDet/nSummed
777  << endl;
778  }
779  }
780 
781  if (nErrorFaces > 0)
782  {
783  if (report)
784  {
785  Info<< " ***Faces with small interpolation weight (< " << minWeight
786  << ") found, number of faces: "
787  << nErrorFaces << endl;
788  }
789 
790  return true;
791  }
792  else
793  {
794  if (report)
795  {
796  Info<< " Face interpolation weight check OK." << endl;
797  }
798 
799  return false;
800  }
801 
802  return false;
803 }
804 
805 
807 (
808  const polyMesh& mesh,
809  const bool report,
810  const scalar minRatio,
811  labelHashSet* setPtr
812 )
813 {
814  if (mesh.debug)
815  {
816  InfoInFunction << "Checking for volume ratio < " << minRatio << endl;
817  }
818 
819  const scalarField& cellVols = mesh.cellVolumes();
820 
821  tmp<scalarField> tvolRatio = meshCheck::volRatio(mesh, cellVols);
822  scalarField& volRatio = tvolRatio.ref();
823 
824 
825  label nErrorFaces = 0;
826  scalar minDet = great;
827  scalar sumDet = 0.0;
828  label nSummed = 0;
829 
830  // Statistics only for internal and masters of coupled faces
831  PackedBoolList isMasterFace(syncTools::getInternalOrMasterFaces(mesh));
832 
833  forAll(volRatio, facei)
834  {
835  if (volRatio[facei] < minRatio)
836  {
837  // Note: insert both sides of coupled faces
838  if (setPtr)
839  {
840  setPtr->insert(facei);
841  }
842 
843  nErrorFaces++;
844  }
845 
846  // Note: statistics only on master of coupled faces
847  if (isMasterFace[facei])
848  {
849  minDet = min(minDet, volRatio[facei]);
850  sumDet += volRatio[facei];
851  nSummed++;
852  }
853  }
854 
855  reduce(nErrorFaces, sumOp<label>());
856  reduce(minDet, minOp<scalar>());
857  reduce(sumDet, sumOp<scalar>());
858  reduce(nSummed, sumOp<label>());
859 
860  if (report)
861  {
862  if (nSummed > 0)
863  {
864  Info<< " Face volume ratio : minimum: " << minDet
865  << " average: " << sumDet/nSummed
866  << endl;
867  }
868  }
869 
870  if (nErrorFaces > 0)
871  {
872  if (report)
873  {
874  Info<< " ***Faces with small volume ratio (< " << minRatio
875  << ") found, number of faces: "
876  << nErrorFaces << endl;
877  }
878 
879  return true;
880  }
881  else
882  {
883  if (report)
884  {
885  Info<< " Face volume ratio check OK." << endl;
886  }
887 
888  return false;
889  }
890 
891  return false;
892 }
893 
894 
895 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:109
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
void resize(const label newSize)
Resize the hash table for efficiency.
Definition: HashTable.C:506
A bit-packed bool list.
Set of directions for each cell in the mesh. Either uniform and size=1 or one set of directions per c...
Definition: directions.H:67
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:61
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:76
Foam::polyBoundaryMesh.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1326
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1339
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:404
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1345
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1313
const Vector< label > & geometricD() const
Return the vector of geometric directions in mesh.
Definition: polyMesh.C:989
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:70
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
Definition: polyPatch.H:290
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:280
const vectorField & faceCentres() const
const scalarField & cellVolumes() const
const vectorField & cellCentres() const
label nInternalFaces() const
label nFaces() const
const vectorField & faceAreas() const
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:181
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
volScalarField scalarField(fieldObject, mesh)
label patchi
const pointField & points
#define InfoInFunction
Report an information message using Foam::Info.
const dimensionedScalar e
Elementary charge.
bool checkFaceWeight(const polyMesh &mesh, const bool report, const scalar minWeight=0.05, labelHashSet *setPtr=nullptr)
Check for face weights.
tmp< scalarField > faceOrthogonality(const polyMesh &mesh, const vectorField &fAreas, const vectorField &cellCtrs)
Generate orthogonality field. (1 for fully orthogonal, < 1 for.
Definition: polyMeshCheck.C:34
bool checkEdgeAlignment(const polyMesh &mesh, const bool report, const Vector< label > &directions, labelHashSet *setPtr)
Check edge alignment for 1D/2D cases.
tmp< scalarField > faceSkewness(const polyMesh &mesh, const pointField &points, const vectorField &fCtrs, const vectorField &fAreas, const vectorField &cellCtrs)
Generate skewness field.
Definition: polyMeshCheck.C:89
bool checkCellDeterminant(const polyMesh &mesh, const bool report, labelHashSet *setPtr)
bool checkVolRatio(const polyMesh &mesh, const bool report, const scalar minRatio=0.01, labelHashSet *setPtr=nullptr)
Check for neighbouring cell volumes.
scalar boundaryFaceSkewness(const primitiveMesh &mesh, const pointField &p, const vectorField &fCtrs, const vectorField &fAreas, const label facei, const point &ownCc)
Skewness of single boundary face.
tmp< scalarField > cellDeterminant(const primitiveMesh &mesh, const Vector< label > &directions, const vectorField &faceAreas, const PackedBoolList &internalOrCoupledFace)
Generate cell determinant field.
tmp< scalarField > faceWeights(const polyMesh &mesh, const vectorField &fCtrs, const vectorField &fAreas, const vectorField &cellCtrs)
Generate interpolation factors field.
tmp< scalarField > volRatio(const polyMesh &mesh, const scalarField &vol)
Generate volume ratio field.
bool checkFaceOrthogonality(const polyMesh &mesh, const scalar nonOrthThreshold, const bool report=false, labelHashSet *setPtr=nullptr)
Check face orthogonality.
bool checkFaceSkewness(const polyMesh &mesh, const scalar skewThreshold, const bool report=false, labelHashSet *setPtr=nullptr)
Check face skewness.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
scalar radToDeg(const scalar rad)
Convert radians to degrees.
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
messageStream Info
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
dimensioned< scalar > mag(const dimensioned< Type > &)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
error FatalError
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedTensor skew(const dimensionedTensor &dt)
uint8_t direction
Definition: direction.H:45
dimensionedScalar acos(const dimensionedScalar &ds)
labelList f(nPoints)
volScalarField & p
const scalarField & cellVols