meshRefinement.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2021 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 "meshRefinement.H"
30 #include "volMesh.H"
31 #include "volFields.H"
32 #include "surfaceMesh.H"
33 #include "syncTools.H"
34 #include "Time.H"
35 #include "refinementSurfaces.H"
36 #include "refinementFeatures.H"
37 #include "decompositionMethod.H"
38 #include "regionSplit.H"
39 #include "fvMeshDistribute.H"
40 #include "indirectPrimitivePatch.H"
41 #include "polyTopoChange.H"
42 #include "removeCells.H"
43 #include "mapDistributePolyMesh.H"
44 #include "localPointRegion.H"
45 #include "pointMesh.H"
46 #include "pointFields.H"
47 #include "slipPointPatchFields.H"
51 #include "processorPointPatch.H"
52 #include "globalIndex.H"
53 #include "meshTools.H"
54 #include "OFstream.H"
55 #include "Random.H"
56 #include "searchableSurfaces.H"
57 #include "treeBoundBox.H"
59 #include "fvMeshTools.H"
60 #include "motionSmoother.H"
61 #include "faceSet.H"
62 #include "topoDistanceData.H"
63 #include "FaceCellWave.H"
64 
65 // Leak path
66 #include "shortestPathSet.H"
67 #include "meshSearch.H"
68 
69 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
70 
71 namespace Foam
72 {
73  defineTypeNameAndDebug(meshRefinement, 0);
74 }
75 
76 
77 const Foam::Enum
78 <
80 >
82 ({
83  { debugType::MESH, "mesh" },
84  { debugType::OBJINTERSECTIONS, "intersections" },
85  { debugType::FEATURESEEDS, "featureSeeds" },
86  { debugType::ATTRACTION, "attraction" },
87  { debugType::LAYERINFO, "layerInfo" },
88 });
89 
90 
91 //const Foam::Enum
92 //<
93 // Foam::meshRefinement::outputType
94 //>
95 //Foam::meshRefinement::outputTypeNames
96 //({
97 // { outputType::OUTPUTLAYERINFO, "layerInfo" }
98 //});
99 
100 
101 const Foam::Enum
102 <
104 >
106 ({
107  { writeType::WRITEMESH, "mesh" },
108  { writeType::NOWRITEREFINEMENT, "noRefinement" },
109  { writeType::WRITELEVELS, "scalarLevels" },
110  { writeType::WRITELAYERSETS, "layerSets" },
111  { writeType::WRITELAYERFIELDS, "layerFields" },
112 });
113 
114 
115 Foam::meshRefinement::writeType Foam::meshRefinement::writeLevel_;
116 
117 //Foam::meshRefinement::outputType Foam::meshRefinement::outputLevel_;
118 
119 // Inside/outside test for polyMesh:.findCell()
120 // 2.4.x : default = polyMesh::FACE_DIAG_TRIS
121 // 1712 : default = polyMesh::CELL_TETS
122 //
123 // - CELL_TETS is better with concave cells, but much slower.
124 // - use faster method (FACE_DIAG_TRIS) here
125 
128 
129 
130 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
131 
132 void Foam::meshRefinement::calcNeighbourData
133 (
134  labelList& neiLevel,
135  pointField& neiCc
136 ) const
137 {
138  const labelList& cellLevel = meshCutter_.cellLevel();
139  const pointField& cellCentres = mesh_.cellCentres();
140 
141  const label nBoundaryFaces = mesh_.nBoundaryFaces();
142 
143  if (neiLevel.size() != nBoundaryFaces || neiCc.size() != nBoundaryFaces)
144  {
146  << nBoundaryFaces << " neiLevel:" << neiLevel.size()
147  << abort(FatalError);
148  }
149 
150  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
151 
152  labelHashSet addedPatchIDSet(meshedPatches());
153 
154  forAll(patches, patchi)
155  {
156  const polyPatch& pp = patches[patchi];
157 
158  const labelUList& faceCells = pp.faceCells();
159  const vectorField::subField faceCentres = pp.faceCentres();
160  const vectorField::subField faceAreas = pp.faceAreas();
161 
162  label bFacei = pp.start()-mesh_.nInternalFaces();
163 
164  if (pp.coupled())
165  {
166  forAll(faceCells, i)
167  {
168  neiLevel[bFacei] = cellLevel[faceCells[i]];
169  neiCc[bFacei] = cellCentres[faceCells[i]];
170  bFacei++;
171  }
172  }
173  else if (addedPatchIDSet.found(patchi))
174  {
175  // Face was introduced from cell-cell intersection. Try to
176  // reconstruct other side cell(centre). Three possibilities:
177  // - cells same size.
178  // - preserved cell smaller. Not handled.
179  // - preserved cell larger.
180  forAll(faceCells, i)
181  {
182  // Extrapolate the face centre.
183  const vector fn = normalised(faceAreas[i]);
184 
185  label own = faceCells[i];
186  label ownLevel = cellLevel[own];
187  label faceLevel = meshCutter_.faceLevel(pp.start()+i);
188  if (faceLevel < 0)
189  {
190  // Due to e.g. face merging no longer a consistent
191  // refinementlevel of face. Assume same as cell
192  faceLevel = ownLevel;
193  }
194 
195  // Normal distance from face centre to cell centre
196  scalar d = ((faceCentres[i] - cellCentres[own]) & fn);
197  if (faceLevel > ownLevel)
198  {
199  // Other cell more refined. Adjust normal distance
200  d *= 0.5;
201  }
202  neiLevel[bFacei] = faceLevel;
203  // Calculate other cell centre by extrapolation
204  neiCc[bFacei] = faceCentres[i] + d*fn;
205  bFacei++;
206  }
207  }
208  else
209  {
210  forAll(faceCells, i)
211  {
212  neiLevel[bFacei] = cellLevel[faceCells[i]];
213  neiCc[bFacei] = faceCentres[i];
214  bFacei++;
215  }
216  }
217  }
218 
219  // Swap coupled boundaries. Apply separation to cc since is coordinate.
221  syncTools::swapBoundaryFaceList(mesh_, neiLevel);
222 }
223 
224 
225 void Foam::meshRefinement::calcCellCellRays
226 (
227  const pointField& neiCc,
228  const labelList& neiLevel,
229  const labelList& testFaces,
230  pointField& start,
231  pointField& end,
232  labelList& minLevel
233 ) const
234 {
235  const labelList& cellLevel = meshCutter_.cellLevel();
236  const pointField& cellCentres = mesh_.cellCentres();
237 
238 
239  // Mark all non-coupled or coupled+master faces. Leaves only slave of
240  // coupled unset.
241  bitSet isMaster(mesh_.nBoundaryFaces(), true);
242  {
243  for (const polyPatch& pp : mesh_.boundaryMesh())
244  {
245  if (pp.coupled() && !refCast<const coupledPolyPatch>(pp).owner())
246  {
247  isMaster.unset(labelRange(pp.offset(), pp.size()));
248  }
249  }
250  }
251 
252 
253  start.setSize(testFaces.size());
254  end.setSize(testFaces.size());
255  minLevel.setSize(testFaces.size());
256 
257  forAll(testFaces, i)
258  {
259  const label facei = testFaces[i];
260  const label own = mesh_.faceOwner()[facei];
261 
262  if (mesh_.isInternalFace(facei))
263  {
264  const label nei = mesh_.faceNeighbour()[facei];
265 
266  start[i] = cellCentres[own];
267  end[i] = cellCentres[nei];
268  minLevel[i] = min(cellLevel[own], cellLevel[nei]);
269  }
270  else
271  {
272  const label bFacei = facei - mesh_.nInternalFaces();
273 
274  if (isMaster[bFacei])
275  {
276  start[i] = cellCentres[own];
277  end[i] = neiCc[bFacei];
278  }
279  else
280  {
281  // Slave face
282  start[i] = neiCc[bFacei];
283  end[i] = cellCentres[own];
284  }
285  minLevel[i] = min(cellLevel[own], neiLevel[bFacei]);
286  }
287  }
288 
289  // Extend segments a bit
290  {
291  const vectorField smallVec(ROOTSMALL*(end-start));
292  start -= smallVec;
293  end += smallVec;
294  }
295 }
296 
297 
299 {
300  // Stats on edges to test. Count proc faces only once.
301  bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
302 
303  {
304  label nMasterFaces = isMasterFace.count();
305  reduce(nMasterFaces, sumOp<label>());
306 
307  label nChangedFaces = 0;
308  forAll(changedFaces, i)
309  {
310  if (isMasterFace.test(changedFaces[i]))
311  {
312  ++nChangedFaces;
313  }
314  }
315  reduce(nChangedFaces, sumOp<label>());
316 
317  if (!dryRun_)
318  {
319  Info<< "Edge intersection testing:" << nl
320  << " Number of edges : " << nMasterFaces << nl
321  << " Number of edges to retest : " << nChangedFaces
322  << endl;
323  }
324  }
325 
326 
327  // Get boundary face centre and level. Coupled aware.
328  labelList neiLevel(mesh_.nBoundaryFaces());
329  pointField neiCc(mesh_.nBoundaryFaces());
330  calcNeighbourData(neiLevel, neiCc);
331 
332  // Collect segments we want to test for
333  pointField start(changedFaces.size());
334  pointField end(changedFaces.size());
335  {
336  labelList minLevel;
337  calcCellCellRays
338  (
339  neiCc,
340  neiLevel,
341  changedFaces,
342  start,
343  end,
344  minLevel
345  );
346  }
347 
348 
349  // Do tests in one go
350  labelList surfaceHit;
351  {
352  labelList surfaceLevel;
353  surfaces_.findHigherIntersection
354  (
355  shells_,
356  start,
357  end,
358  labelList(start.size(), -1), // accept any intersection
359  surfaceHit,
360  surfaceLevel
361  );
362  }
363 
364  // Keep just surface hit
365  forAll(surfaceHit, i)
366  {
367  surfaceIndex_[changedFaces[i]] = surfaceHit[i];
368  }
369 
370  // Make sure both sides have same information. This should be
371  // case in general since same vectors but just to make sure.
372  syncTools::syncFaceList(mesh_, surfaceIndex_, maxEqOp<label>());
373 
374  label nHits = countHits();
375  label nTotHits = returnReduce(nHits, sumOp<label>());
376 
377 
378  if (!dryRun_)
379  {
380  Info<< " Number of intersected edges : " << nTotHits << endl;
381  }
382 
383  // Set files to same time as mesh
384  setInstance(mesh_.facesInstance());
385 }
386 
387 
388 Foam::labelList Foam::meshRefinement::nearestPatch
389 (
390  const labelList& adaptPatchIDs
391 ) const
392 {
393  // Determine nearest patch for all mesh faces. Used when removing cells
394  // to give some reasonable patch to exposed faces.
395 
396  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
397 
398  labelList nearestAdaptPatch;
399 
400  if (adaptPatchIDs.size())
401  {
402  nearestAdaptPatch.setSize(mesh_.nFaces(), adaptPatchIDs[0]);
403 
404 
405  // Count number of faces in adaptPatchIDs
406  label nFaces = 0;
407  forAll(adaptPatchIDs, i)
408  {
409  const polyPatch& pp = patches[adaptPatchIDs[i]];
410  nFaces += pp.size();
411  }
412 
413  // Field on cells and faces.
414  List<topoDistanceData<label>> cellData(mesh_.nCells());
415  List<topoDistanceData<label>> faceData(mesh_.nFaces());
416 
417  // Start of changes
418  labelList patchFaces(nFaces);
419  List<topoDistanceData<label>> patchData(nFaces);
420  nFaces = 0;
421  forAll(adaptPatchIDs, i)
422  {
423  label patchi = adaptPatchIDs[i];
424  const polyPatch& pp = patches[patchi];
425 
426  forAll(pp, i)
427  {
428  patchFaces[nFaces] = pp.start()+i;
429  patchData[nFaces] = topoDistanceData<label>(0, patchi);
430  nFaces++;
431  }
432  }
433 
434  // Propagate information inwards
435  FaceCellWave<topoDistanceData<label>> deltaCalc
436  (
437  mesh_,
438  patchFaces,
439  patchData,
440  faceData,
441  cellData,
442  mesh_.globalData().nTotalCells()+1
443  );
444 
445  // And extract
446 
447  bool haveWarned = false;
448  forAll(faceData, facei)
449  {
450  if (!faceData[facei].valid(deltaCalc.data()))
451  {
452  if (!haveWarned)
453  {
455  << "Did not visit some faces, e.g. face " << facei
456  << " at " << mesh_.faceCentres()[facei] << endl
457  << "Assigning these faces to patch "
458  << adaptPatchIDs[0]
459  << endl;
460  haveWarned = true;
461  }
462  }
463  else
464  {
465  nearestAdaptPatch[facei] = faceData[facei].data();
466  }
467  }
468  }
469  else
470  {
471  // Use patch 0
472  nearestAdaptPatch.setSize(mesh_.nFaces(), 0);
473  }
474 
475  return nearestAdaptPatch;
476 }
477 
478 
479 Foam::labelList Foam::meshRefinement::nearestIntersection
480 (
481  const labelList& surfacesToTest,
482  const label defaultRegion
483 ) const
484 {
485  // Determine nearest intersection for all mesh faces. Used when removing
486  // cells to give some reasonable patch to exposed faces. Use this
487  // function instead of nearestPatch if you don't have patches yet.
488 
489 
490  // Swap neighbouring cell centres and cell level
491  labelList neiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
492  pointField neiCc(mesh_.nFaces()-mesh_.nInternalFaces());
493  calcNeighbourData(neiLevel, neiCc);
494 
495 
496  // Collect segments
497  // ~~~~~~~~~~~~~~~~
498 
499  const labelList testFaces(intersectedFaces());
500 
501  pointField start(testFaces.size());
502  pointField end(testFaces.size());
503  labelList minLevel(testFaces.size());
504 
505  calcCellCellRays
506  (
507  neiCc,
508  neiLevel,
509  testFaces,
510  start,
511  end,
512  minLevel
513  );
514 
515  // Do tests in one go
516  labelList surface1;
517  List<pointIndexHit> hit1;
518  labelList region1;
519  labelList surface2;
520  List<pointIndexHit> hit2;
521  labelList region2;
522  surfaces_.findNearestIntersection
523  (
524  surfacesToTest,
525  start,
526  end,
527 
528  surface1,
529  hit1,
530  region1,
531  surface2,
532  hit2,
533  region2
534  );
535 
536  labelList nearestRegion(mesh_.nFaces(), defaultRegion);
537 
538  // Field on cells and faces.
539  List<topoDistanceData<label>> cellData(mesh_.nCells());
540  List<topoDistanceData<label>> faceData(mesh_.nFaces());
541 
542  // Start walking from all intersected faces
543  DynamicList<label> patchFaces(start.size());
544  DynamicList<topoDistanceData<label>> patchData(start.size());
545  forAll(start, i)
546  {
547  label facei = testFaces[i];
548  if (surface1[i] != -1)
549  {
550  patchFaces.append(facei);
551  label regioni = surfaces_.globalRegion(surface1[i], region1[i]);
552  patchData.append(topoDistanceData<label>(0, regioni));
553  }
554  else if (surface2[i] != -1)
555  {
556  patchFaces.append(facei);
557  label regioni = surfaces_.globalRegion(surface2[i], region2[i]);
558  patchData.append(topoDistanceData<label>(0, regioni));
559  }
560  }
561 
562  // Propagate information inwards
563  FaceCellWave<topoDistanceData<label>> deltaCalc
564  (
565  mesh_,
566  patchFaces,
567  patchData,
568  faceData,
569  cellData,
570  mesh_.globalData().nTotalCells()+1
571  );
572 
573  // And extract
574 
575  bool haveWarned = false;
576  forAll(faceData, facei)
577  {
578  if (!faceData[facei].valid(deltaCalc.data()))
579  {
580  if (!haveWarned)
581  {
583  << "Did not visit some faces, e.g. face " << facei
584  << " at " << mesh_.faceCentres()[facei] << endl
585  << "Assigning these faces to global region "
586  << defaultRegion << endl;
587  haveWarned = true;
588  }
589  }
590  else
591  {
592  nearestRegion[facei] = faceData[facei].data();
593  }
594  }
595 
596  return nearestRegion;
597 }
598 
599 
601 (
602  const string& msg,
603  const polyMesh& mesh,
604  const List<scalar>& fld
605 )
606 {
607  if (fld.size() != mesh.nPoints())
608  {
610  << msg << endl
611  << "fld size:" << fld.size() << " mesh points:" << mesh.nPoints()
612  << abort(FatalError);
613  }
614 
615  Pout<< "Checking field " << msg << endl;
616  scalarField minFld(fld);
618  (
619  mesh,
620  minFld,
621  minEqOp<scalar>(),
622  GREAT
623  );
624  scalarField maxFld(fld);
626  (
627  mesh,
628  maxFld,
629  maxEqOp<scalar>(),
630  -GREAT
631  );
632  forAll(minFld, pointi)
633  {
634  const scalar& minVal = minFld[pointi];
635  const scalar& maxVal = maxFld[pointi];
636  if (mag(minVal-maxVal) > SMALL)
637  {
638  Pout<< msg << " at:" << mesh.points()[pointi] << nl
639  << " minFld:" << minVal << nl
640  << " maxFld:" << maxVal << nl
641  << endl;
642  }
643  }
644 }
645 
646 
648 (
649  const string& msg,
650  const polyMesh& mesh,
651  const List<point>& fld
652 )
653 {
654  if (fld.size() != mesh.nPoints())
655  {
657  << msg << endl
658  << "fld size:" << fld.size() << " mesh points:" << mesh.nPoints()
659  << abort(FatalError);
660  }
661 
662  Pout<< "Checking field " << msg << endl;
663  pointField minFld(fld);
665  (
666  mesh,
667  minFld,
669  point(GREAT, GREAT, GREAT)
670  );
671  pointField maxFld(fld);
673  (
674  mesh,
675  maxFld,
678  );
679  forAll(minFld, pointi)
680  {
681  const point& minVal = minFld[pointi];
682  const point& maxVal = maxFld[pointi];
683  if (mag(minVal-maxVal) > SMALL)
684  {
685  Pout<< msg << " at:" << mesh.points()[pointi] << nl
686  << " minFld:" << minVal << nl
687  << " maxFld:" << maxVal << nl
688  << endl;
689  }
690  }
691 }
692 
693 
695 {
696  Pout<< "meshRefinement::checkData() : Checking refinement structure."
697  << endl;
698  meshCutter_.checkMesh();
699 
700  Pout<< "meshRefinement::checkData() : Checking refinement levels."
701  << endl;
702  meshCutter_.checkRefinementLevels(1, labelList(0));
703 
704 
705  const label nBnd = mesh_.nBoundaryFaces();
706 
707  Pout<< "meshRefinement::checkData() : Checking synchronization."
708  << endl;
709 
710  // Check face centres
711  {
712  // Boundary face centres
713  pointField::subList boundaryFc
714  (
715  mesh_.faceCentres(),
716  nBnd,
717  mesh_.nInternalFaces()
718  );
719 
720  // Get neighbouring face centres
721  pointField neiBoundaryFc(boundaryFc);
723  (
724  mesh_,
725  neiBoundaryFc,
726  eqOp<point>()
727  );
728 
729  // Compare
730  testSyncBoundaryFaceList
731  (
732  mergeDistance_,
733  "testing faceCentres : ",
734  boundaryFc,
735  neiBoundaryFc
736  );
737  }
738 
739  // Check meshRefinement
740  const labelList& surfIndex = surfaceIndex();
741 
742 
743  {
744  // Get boundary face centre and level. Coupled aware.
745  labelList neiLevel(nBnd);
746  pointField neiCc(nBnd);
747  calcNeighbourData(neiLevel, neiCc);
748 
749  // Collect segments we want to test for
750  pointField start(mesh_.nFaces());
751  pointField end(mesh_.nFaces());
752 
753  forAll(start, facei)
754  {
755  start[facei] = mesh_.cellCentres()[mesh_.faceOwner()[facei]];
756 
757  if (mesh_.isInternalFace(facei))
758  {
759  end[facei] = mesh_.cellCentres()[mesh_.faceNeighbour()[facei]];
760  }
761  else
762  {
763  end[facei] = neiCc[facei-mesh_.nInternalFaces()];
764  }
765  }
766 
767  // Extend segments a bit
768  {
769  const vectorField smallVec(ROOTSMALL*(end-start));
770  start -= smallVec;
771  end += smallVec;
772  }
773 
774 
775  // Do tests in one go
776  labelList surfaceHit;
777  {
778  labelList surfaceLevel;
779  surfaces_.findHigherIntersection
780  (
781  shells_,
782  start,
783  end,
784  labelList(start.size(), -1), // accept any intersection
785  surfaceHit,
786  surfaceLevel
787  );
788  }
789  // Get the coupled hit
790  labelList neiHit
791  (
793  (
794  surfaceHit,
795  nBnd,
796  mesh_.nInternalFaces()
797  )
798  );
799  syncTools::swapBoundaryFaceList(mesh_, neiHit);
800 
801  // Check
802  forAll(surfaceHit, facei)
803  {
804  if (surfIndex[facei] != surfaceHit[facei])
805  {
806  if (mesh_.isInternalFace(facei))
807  {
809  << "Internal face:" << facei
810  << " fc:" << mesh_.faceCentres()[facei]
811  << " cached surfaceIndex_:" << surfIndex[facei]
812  << " current:" << surfaceHit[facei]
813  << " ownCc:"
814  << mesh_.cellCentres()[mesh_.faceOwner()[facei]]
815  << " neiCc:"
816  << mesh_.cellCentres()[mesh_.faceNeighbour()[facei]]
817  << endl;
818  }
819  else if
820  (
821  surfIndex[facei]
822  != neiHit[facei-mesh_.nInternalFaces()]
823  )
824  {
826  << "Boundary face:" << facei
827  << " fc:" << mesh_.faceCentres()[facei]
828  << " cached surfaceIndex_:" << surfIndex[facei]
829  << " current:" << surfaceHit[facei]
830  << " ownCc:"
831  << mesh_.cellCentres()[mesh_.faceOwner()[facei]]
832  << " neiCc:"
833  << neiCc[facei-mesh_.nInternalFaces()]
834  << " end:" << end[facei]
835  << " ownLevel:"
836  << meshCutter_.cellLevel()[mesh_.faceOwner()[facei]]
837  << " faceLevel:"
838  << meshCutter_.faceLevel(facei)
839  << endl;
840  }
841  }
842  }
843  }
844  {
845  labelList::subList boundarySurface
846  (
847  surfaceIndex_,
848  mesh_.nBoundaryFaces(),
849  mesh_.nInternalFaces()
850  );
851 
852  labelList neiBoundarySurface(boundarySurface);
854  (
855  mesh_,
856  neiBoundarySurface
857  );
858 
859  // Compare
860  testSyncBoundaryFaceList
861  (
862  0, // tolerance
863  "testing surfaceIndex() : ",
864  boundarySurface,
865  neiBoundarySurface
866  );
867  }
868 
869 
870  // Find duplicate faces
871  Pout<< "meshRefinement::checkData() : Counting duplicate faces."
872  << endl;
873 
874  labelList duplicateFace
875  (
877  (
878  mesh_,
879  identity(mesh_.nBoundaryFaces(), mesh_.nInternalFaces())
880  )
881  );
882 
883  // Count
884  {
885  label nDup = 0;
886 
887  forAll(duplicateFace, i)
888  {
889  if (duplicateFace[i] != -1)
890  {
891  nDup++;
892  }
893  }
894  nDup /= 2; // will have counted both faces of duplicate
895  Pout<< "meshRefinement::checkData() : Found " << nDup
896  << " duplicate pairs of faces." << endl;
897  }
898 }
899 
900 
902 {
903  meshCutter_.setInstance(inst);
904  surfaceIndex_.instance() = inst;
905 }
906 
907 
909 (
910  const labelList& cellsToRemove,
911  const labelList& exposedFaces,
912  const labelList& exposedPatchIDs,
913  removeCells& cellRemover
914 )
915 {
916  polyTopoChange meshMod(mesh_);
917 
918  // Arbitrary: put exposed faces into last patch.
919  cellRemover.setRefinement
920  (
921  cellsToRemove,
922  exposedFaces,
923  exposedPatchIDs,
924  meshMod
925  );
926 
927  // Change the mesh (no inflation)
928  autoPtr<mapPolyMesh> mapPtr = meshMod.changeMesh(mesh_, false, true);
929  mapPolyMesh& map = *mapPtr;
930 
931  // Update fields
932  mesh_.updateMesh(map);
933 
934  // Move mesh (since morphing might not do this)
935  if (map.hasMotionPoints())
936  {
937  mesh_.movePoints(map.preMotionPoints());
938  }
939  else
940  {
941  // Delete mesh volumes. No other way to do this?
942  mesh_.clearOut();
943  }
944 
945  // Reset the instance for if in overwrite mode
946  mesh_.setInstance(timeName());
947  setInstance(mesh_.facesInstance());
948 
949  // Update local mesh data
950  cellRemover.updateMesh(map);
951 
952  // Update intersections. Recalculate intersections for exposed faces.
953  labelList newExposedFaces = renumber
954  (
955  map.reverseFaceMap(),
956  exposedFaces
957  );
958 
959  //Pout<< "removeCells : updating intersections for "
960  // << newExposedFaces.size() << " newly exposed faces." << endl;
961 
962  updateMesh(map, newExposedFaces);
963 
964  return mapPtr;
965 }
966 
967 
969 (
970  const labelList& splitFaces,
971  const labelPairList& splits,
972  //const List<Pair<point>>& splitPoints,
973  polyTopoChange& meshMod
974 ) const
975 {
976  forAll(splitFaces, i)
977  {
978  label facei = splitFaces[i];
979  const face& f = mesh_.faces()[facei];
980 
981  // Split as start and end index in face
982  const labelPair& split = splits[i];
983 
984  label nVerts = split[1]-split[0];
985  if (nVerts < 0)
986  {
987  nVerts += f.size();
988  }
989  nVerts += 1;
990 
991 
992  // Split into f0, f1
993  face f0(nVerts);
994 
995  label fp = split[0];
996  forAll(f0, i)
997  {
998  f0[i] = f[fp];
999  fp = f.fcIndex(fp);
1000  }
1001 
1002  face f1(f.size()-f0.size()+2);
1003  fp = split[1];
1004  forAll(f1, i)
1005  {
1006  f1[i] = f[fp];
1007  fp = f.fcIndex(fp);
1008  }
1009 
1010 
1011  // Determine face properties
1012  label own = mesh_.faceOwner()[facei];
1013  label nei = -1;
1014  label patchi = -1;
1015  if (facei >= mesh_.nInternalFaces())
1016  {
1017  patchi = mesh_.boundaryMesh().whichPatch(facei);
1018  }
1019  else
1020  {
1021  nei = mesh_.faceNeighbour()[facei];
1022  }
1023 
1024  label zonei = mesh_.faceZones().whichZone(facei);
1025  bool zoneFlip = false;
1026  if (zonei != -1)
1027  {
1028  const faceZone& fz = mesh_.faceZones()[zonei];
1029  zoneFlip = fz.flipMap()[fz.whichFace(facei)];
1030  }
1031 
1032 
1033  if (debug)
1034  {
1035  Pout<< "face:" << facei << " verts:" << f
1036  << " split into f0:" << f0
1037  << " f1:" << f1 << endl;
1038  }
1039 
1040  // Change/add faces
1041  meshMod.modifyFace
1042  (
1043  f0, // modified face
1044  facei, // label of face
1045  own, // owner
1046  nei, // neighbour
1047  false, // face flip
1048  patchi, // patch for face
1049  zonei, // zone for face
1050  zoneFlip // face flip in zone
1051  );
1052 
1053  meshMod.addFace
1054  (
1055  f1, // modified face
1056  own, // owner
1057  nei, // neighbour
1058  -1, // master point
1059  -1, // master edge
1060  facei, // master face
1061  false, // face flip
1062  patchi, // patch for face
1063  zonei, // zone for face
1064  zoneFlip // face flip in zone
1065  );
1066 
1067 
1069  //meshMod.modifyPoint
1070  //(
1071  // f[split[0]],
1072  // splitPoints[i][0],
1073  // -1,
1074  // true
1075  //);
1076  //meshMod.modifyPoint
1077  //(
1078  // f[split[1]],
1079  // splitPoints[i][1],
1080  // -1,
1081  // true
1082  //);
1083  }
1084 }
1085 
1086 
1089  const labelList& splitFaces,
1090  const labelPairList& splits,
1091  const dictionary& motionDict,
1092 
1093  labelList& duplicateFace,
1094  List<labelPair>& baffles
1095 )
1096 {
1097  label nSplit = returnReduce(splitFaces.size(), sumOp<label>());
1098  Info<< nl
1099  << "Splitting " << nSplit
1100  << " faces across diagonals" << "." << nl << endl;
1101 
1102  // To undo: store original faces
1103  faceList originalFaces(UIndirectList<face>(mesh_.faces(), splitFaces));
1104  labelPairList facePairs(splitFaces.size(), labelPair(-1, -1));
1105 
1106 
1107  {
1108  polyTopoChange meshMod(mesh_);
1109  meshMod.setCapacity
1110  (
1111  meshMod.points().size(),
1112  meshMod.faces().size()+splitFaces.size(),
1113  mesh_.nCells()
1114  );
1115 
1116  // Insert the mesh changes
1117  doSplitFaces(splitFaces, splits, meshMod);
1118 
1119  // Change the mesh (no inflation)
1120  autoPtr<mapPolyMesh> mapPtr = meshMod.changeMesh(mesh_, false, true);
1121  mapPolyMesh& map = *mapPtr;
1122 
1123  // Update fields
1124  mesh_.updateMesh(map);
1125 
1126  // Move mesh (since morphing might not do this)
1127  if (map.hasMotionPoints())
1128  {
1129  mesh_.movePoints(map.preMotionPoints());
1130  }
1131 
1132  // Reset the instance for if in overwrite mode
1133  mesh_.setInstance(timeName());
1134  setInstance(mesh_.facesInstance());
1135 
1136 
1137  // Update local mesh data
1138  // ~~~~~~~~~~~~~~~~~~~~~~
1139 
1140  forAll(originalFaces, i)
1141  {
1142  inplaceRenumber(map.reversePointMap(), originalFaces[i]);
1143  }
1144 
1145  {
1146  Map<label> splitFaceToIndex(2*splitFaces.size());
1147  forAll(splitFaces, i)
1148  {
1149  splitFaceToIndex.insert(splitFaces[i], i);
1150  }
1151 
1152  forAll(map.faceMap(), facei)
1153  {
1154  label oldFacei = map.faceMap()[facei];
1155 
1156  const auto oldFaceFnd = splitFaceToIndex.cfind(oldFacei);
1157 
1158  if (oldFaceFnd.found())
1159  {
1160  labelPair& twoFaces = facePairs[oldFaceFnd.val()];
1161  if (twoFaces[0] == -1)
1162  {
1163  twoFaces[0] = facei;
1164  }
1165  else if (twoFaces[1] == -1)
1166  {
1167  twoFaces[1] = facei;
1168  }
1169  else
1170  {
1172  << "problem: twoFaces:" << twoFaces
1173  << exit(FatalError);
1174  }
1175  }
1176  }
1177  }
1178 
1179 
1180  // Update baffle data
1181  // ~~~~~~~~~~~~~~~~~~
1182 
1183  if (duplicateFace.size())
1184  {
1186  (
1187  map.faceMap(),
1188  label(-1),
1189  duplicateFace
1190  );
1191  }
1192 
1193  const labelList& oldToNewFaces = map.reverseFaceMap();
1194  forAll(baffles, i)
1195  {
1196  labelPair& baffle = baffles[i];
1197  baffle.first() = oldToNewFaces[baffle.first()];
1198  baffle.second() = oldToNewFaces[baffle.second()];
1199 
1200  if (baffle.first() == -1 || baffle.second() == -1)
1201  {
1203  << "Removed baffle : faces:" << baffle
1204  << exit(FatalError);
1205  }
1206  }
1207 
1208 
1209  // Update intersections
1210  // ~~~~~~~~~~~~~~~~~~~~
1211 
1212  {
1213  DynamicList<label> changedFaces(facePairs.size());
1214  forAll(facePairs, i)
1215  {
1216  changedFaces.append(facePairs[i].first());
1217  changedFaces.append(facePairs[i].second());
1218  }
1219 
1220  // Update intersections on changed faces
1221  updateMesh(map, growFaceCellFace(changedFaces));
1222  }
1223  }
1224 
1225 
1226 
1227  // Undo loop
1228  // ~~~~~~~~~
1229  // Maintains two bits of information:
1230  // facePairs : two faces originating from the same face
1231  // originalFaces : original face in current vertices
1232 
1233 
1234  for (label iteration = 0; iteration < 100; iteration++)
1235  {
1236  Info<< nl
1237  << "Undo iteration " << iteration << nl
1238  << "----------------" << endl;
1239 
1240 
1241  // Check mesh for errors
1242  // ~~~~~~~~~~~~~~~~~~~~~
1243 
1244  faceSet errorFaces(mesh_, "errorFaces", mesh_.nBoundaryFaces());
1245  bool hasErrors = motionSmoother::checkMesh
1246  (
1247  false, // report
1248  mesh_,
1249  motionDict,
1250  errorFaces,
1251  dryRun_
1252  );
1253  if (!hasErrors)
1254  {
1255  break;
1256  }
1257 
1258  // Extend faces
1259  {
1260  const labelList grownFaces(growFaceCellFace(errorFaces));
1261  errorFaces.clear();
1262  errorFaces.insert(grownFaces);
1263  }
1264 
1265 
1266  // Merge face pairs
1267  // ~~~~~~~~~~~~~~~~
1268  // (if one of the faces is in the errorFaces set)
1269 
1270  polyTopoChange meshMod(mesh_);
1271 
1272  // Indices (in facePairs) of merged faces
1273  labelHashSet mergedIndices(facePairs.size());
1274  forAll(facePairs, index)
1275  {
1276  const labelPair& twoFaces = facePairs[index];
1277 
1278  if
1279  (
1280  errorFaces.found(twoFaces.first())
1281  || errorFaces.found(twoFaces.second())
1282  )
1283  {
1284  const face& originalFace = originalFaces[index];
1285 
1286 
1287  // Determine face properties
1288  label own = mesh_.faceOwner()[twoFaces[0]];
1289  label nei = -1;
1290  label patchi = -1;
1291  if (twoFaces[0] >= mesh_.nInternalFaces())
1292  {
1293  patchi = mesh_.boundaryMesh().whichPatch(twoFaces[0]);
1294  }
1295  else
1296  {
1297  nei = mesh_.faceNeighbour()[twoFaces[0]];
1298  }
1299 
1300  label zonei = mesh_.faceZones().whichZone(twoFaces[0]);
1301  bool zoneFlip = false;
1302  if (zonei != -1)
1303  {
1304  const faceZone& fz = mesh_.faceZones()[zonei];
1305  zoneFlip = fz.flipMap()[fz.whichFace(twoFaces[0])];
1306  }
1307 
1308  // Modify first face
1309  meshMod.modifyFace
1310  (
1311  originalFace, // modified face
1312  twoFaces[0], // label of face
1313  own, // owner
1314  nei, // neighbour
1315  false, // face flip
1316  patchi, // patch for face
1317  zonei, // zone for face
1318  zoneFlip // face flip in zone
1319  );
1320  // Merge second face into first
1321  meshMod.removeFace(twoFaces[1], twoFaces[0]);
1322 
1323  mergedIndices.insert(index);
1324  }
1325  }
1326 
1327  label n = returnReduce(mergedIndices.size(), sumOp<label>());
1328 
1329  Info<< "Detected " << n
1330  << " split faces that will be restored to their original faces."
1331  << nl << endl;
1332 
1333  if (n == 0)
1334  {
1335  // Nothing to be restored
1336  break;
1337  }
1338 
1339  nSplit -= n;
1340 
1341 
1342  // Change the mesh (no inflation)
1343  autoPtr<mapPolyMesh> mapPtr = meshMod.changeMesh(mesh_, false, true);
1344  mapPolyMesh& map = *mapPtr;
1345 
1346  // Update fields
1347  mesh_.updateMesh(map);
1348 
1349  // Move mesh (since morphing might not do this)
1350  if (map.hasMotionPoints())
1351  {
1352  mesh_.movePoints(map.preMotionPoints());
1353  }
1354 
1355  // Reset the instance for if in overwrite mode
1356  mesh_.setInstance(timeName());
1357  setInstance(mesh_.facesInstance());
1358 
1359 
1360  // Update local mesh data
1361  // ~~~~~~~~~~~~~~~~~~~~~~
1362 
1363  {
1364  const labelList& oldToNewFaces = map.reverseFaceMap();
1365  const labelList& oldToNewPoints = map.reversePointMap();
1366 
1367  // Compact out merged faces
1368  DynamicList<label> changedFaces(mergedIndices.size());
1369 
1370  label newIndex = 0;
1371  forAll(facePairs, index)
1372  {
1373  const labelPair& oldSplit = facePairs[index];
1374  label new0 = oldToNewFaces[oldSplit[0]];
1375  label new1 = oldToNewFaces[oldSplit[1]];
1376 
1377  if (!mergedIndices.found(index))
1378  {
1379  // Faces still split
1380  if (new0 < 0 || new1 < 0)
1381  {
1383  << "Problem: oldFaces:" << oldSplit
1384  << " newFaces:" << labelPair(new0, new1)
1385  << exit(FatalError);
1386  }
1387 
1388  facePairs[newIndex] = labelPair(new0, new1);
1389  originalFaces[newIndex] = renumber
1390  (
1391  oldToNewPoints,
1392  originalFaces[index]
1393  );
1394  newIndex++;
1395  }
1396  else
1397  {
1398  // Merged face. Only new0 kept.
1399  if (new0 < 0 || new1 == -1)
1400  {
1402  << "Problem: oldFaces:" << oldSplit
1403  << " newFace:" << labelPair(new0, new1)
1404  << exit(FatalError);
1405  }
1406  changedFaces.append(new0);
1407  }
1408  }
1409 
1410  facePairs.setSize(newIndex);
1411  originalFaces.setSize(newIndex);
1412 
1413 
1414  // Update intersections
1415  updateMesh(map, growFaceCellFace(changedFaces));
1416  }
1417 
1418  // Update baffle data
1419  // ~~~~~~~~~~~~~~~~~~
1420  {
1421  if (duplicateFace.size())
1422  {
1424  (
1425  map.faceMap(),
1426  label(-1),
1427  duplicateFace
1428  );
1429  }
1430 
1431  const labelList& reverseFaceMap = map.reverseFaceMap();
1432  forAll(baffles, i)
1433  {
1434  labelPair& baffle = baffles[i];
1435  baffle.first() = reverseFaceMap[baffle.first()];
1436  baffle.second() = reverseFaceMap[baffle.second()];
1437 
1438  if (baffle.first() == -1 || baffle.second() == -1)
1439  {
1441  << "Removed baffle : faces:" << baffle
1442  << exit(FatalError);
1443  }
1444  }
1445  }
1446 
1447  }
1448 
1449  return nSplit;
1450 }
1451 
1452 
1453 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
1454 
1455 Foam::meshRefinement::meshRefinement
1457  fvMesh& mesh,
1458  const scalar mergeDistance,
1459  const bool overwrite,
1460  const refinementSurfaces& surfaces,
1461  const refinementFeatures& features,
1462  const shellSurfaces& shells,
1463  const shellSurfaces& limitShells,
1464  const labelUList& checkFaces,
1465  const bool dryRun
1466 )
1467 :
1468  mesh_(mesh),
1469  mergeDistance_(mergeDistance),
1470  overwrite_(overwrite),
1471  oldInstance_(mesh.pointsInstance()),
1472  surfaces_(surfaces),
1473  features_(features),
1474  shells_(shells),
1475  limitShells_(limitShells),
1476  dryRun_(dryRun),
1477  meshCutter_
1478  (
1479  mesh,
1480  false // do not try to read history.
1481  ),
1482  surfaceIndex_
1483  (
1484  IOobject
1485  (
1486  "surfaceIndex",
1487  mesh_.facesInstance(),
1489  mesh_,
1492  false
1493  ),
1494  labelList(mesh_.nFaces(), -1)
1495  ),
1496  userFaceData_(0)
1497 {
1498  // recalculate intersections for all faces
1499  updateIntersections(checkFaces);
1500 }
1501 
1502 
1503 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1504 
1506 {
1507  if (surfaceIndex_.size() != mesh_.nFaces())
1508  {
1509  const_cast<meshRefinement&>(*this).updateIntersections
1510  (
1511  identity(mesh_.nFaces())
1512  );
1513  }
1514  return surfaceIndex_;
1515 }
1516 
1517 
1519 {
1520  if (surfaceIndex_.size() != mesh_.nFaces())
1521  {
1522  updateIntersections(identity(mesh_.nFaces()));
1523  }
1524  return surfaceIndex_;
1525 }
1526 
1527 
1529 {
1530  // Stats on edges to test. Count proc faces only once.
1531  bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
1532 
1533  label nHits = 0;
1534 
1535  const labelList& surfIndex = surfaceIndex();
1536 
1537  forAll(surfIndex, facei)
1538  {
1539  if (surfIndex[facei] >= 0 && isMasterFace.test(facei))
1540  {
1541  ++nHits;
1542  }
1543  }
1544  return nHits;
1545 }
1546 
1547 
1550  const bool keepZoneFaces,
1551  const bool keepBaffles,
1552  const scalarField& cellWeights,
1553  decompositionMethod& decomposer,
1554  fvMeshDistribute& distributor
1555 )
1556 {
1558 
1559  if (Pstream::parRun())
1560  {
1561  // Wanted distribution
1563 
1564 
1565  // Faces where owner and neighbour are not 'connected' so can
1566  // go to different processors.
1567  boolList blockedFace;
1568  label nUnblocked = 0;
1569 
1570  // Faces that move as block onto single processor
1571  PtrList<labelList> specifiedProcessorFaces;
1572  labelList specifiedProcessor;
1573 
1574  // Pairs of baffles
1575  List<labelPair> couples;
1576 
1577  // Constraints from decomposeParDict
1578  decomposer.setConstraints
1579  (
1580  mesh_,
1581  blockedFace,
1582  specifiedProcessorFaces,
1583  specifiedProcessor,
1584  couples
1585  );
1586 
1587 
1588  if (keepZoneFaces || keepBaffles)
1589  {
1590  if (keepZoneFaces)
1591  {
1592  // Determine decomposition to keep/move surface zones
1593  // on one processor. The reason is that snapping will make these
1594  // into baffles, move and convert them back so if they were
1595  // proc boundaries after baffling&moving the points might be no
1596  // longer synchronised so recoupling will fail. To prevent this
1597  // keep owner&neighbour of such a surface zone on the same
1598  // processor.
1599 
1600  const faceZoneMesh& fZones = mesh_.faceZones();
1601  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
1602 
1603  // Get faces whose owner and neighbour should stay together,
1604  // i.e. they are not 'blocked'.
1605 
1606  forAll(fZones, zonei)
1607  {
1608  const faceZone& fZone = fZones[zonei];
1609 
1610  forAll(fZone, i)
1611  {
1612  label facei = fZone[i];
1613  if (blockedFace[facei])
1614  {
1615  if
1616  (
1617  mesh_.isInternalFace(facei)
1618  || pbm[pbm.whichPatch(facei)].coupled()
1619  )
1620  {
1621  blockedFace[facei] = false;
1622  nUnblocked++;
1623  }
1624  }
1625  }
1626  }
1627 
1628 
1629  // If the faceZones are not synchronised the blockedFace
1630  // might not be synchronised. If you are sure the faceZones
1631  // are synchronised remove below check.
1633  (
1634  mesh_,
1635  blockedFace,
1636  andEqOp<bool>() // combine operator
1637  );
1638  }
1639  reduce(nUnblocked, sumOp<label>());
1640 
1641  if (keepZoneFaces)
1642  {
1643  Info<< "Found " << nUnblocked
1644  << " zoned faces to keep together." << endl;
1645  }
1646 
1647 
1648  // Extend un-blockedFaces with any cyclics
1649  {
1650  boolList separatedCoupledFace(mesh_.nFaces(), false);
1651  selectSeparatedCoupledFaces(separatedCoupledFace);
1652 
1653  label nSeparated = 0;
1654  forAll(separatedCoupledFace, facei)
1655  {
1656  if (separatedCoupledFace[facei])
1657  {
1658  if (blockedFace[facei])
1659  {
1660  blockedFace[facei] = false;
1661  nSeparated++;
1662  }
1663  }
1664  }
1665  reduce(nSeparated, sumOp<label>());
1666  Info<< "Found " << nSeparated
1667  << " separated coupled faces to keep together." << endl;
1668 
1669  nUnblocked += nSeparated;
1670  }
1671 
1672 
1673  if (keepBaffles)
1674  {
1675  const label nBnd = mesh_.nBoundaryFaces();
1676 
1677  labelList coupledFace(mesh_.nFaces(), -1);
1678  {
1679  // Get boundary baffles that need to stay together
1680  List<labelPair> allCouples
1681  (
1683  );
1684 
1685  // Merge with any couples from
1686  // decompositionMethod::setConstraints
1687  forAll(couples, i)
1688  {
1689  const labelPair& baffle = couples[i];
1690  coupledFace[baffle.first()] = baffle.second();
1691  coupledFace[baffle.second()] = baffle.first();
1692  }
1693  forAll(allCouples, i)
1694  {
1695  const labelPair& baffle = allCouples[i];
1696  coupledFace[baffle.first()] = baffle.second();
1697  coupledFace[baffle.second()] = baffle.first();
1698  }
1699  }
1700 
1701  couples.setSize(nBnd);
1702  label nCpl = 0;
1703  forAll(coupledFace, facei)
1704  {
1705  if (coupledFace[facei] != -1 && facei < coupledFace[facei])
1706  {
1707  couples[nCpl++] = labelPair(facei, coupledFace[facei]);
1708  }
1709  }
1710  couples.setSize(nCpl);
1711  }
1712  label nCouples = returnReduce(couples.size(), sumOp<label>());
1713 
1714  if (keepBaffles)
1715  {
1716  Info<< "Found " << nCouples << " baffles to keep together."
1717  << endl;
1718  }
1719  }
1720 
1721 
1722  // Make sure blockedFace not set on couples
1723  forAll(couples, i)
1724  {
1725  const labelPair& baffle = couples[i];
1726  blockedFace[baffle.first()] = false;
1727  blockedFace[baffle.second()] = false;
1728  }
1729 
1730  distribution = decomposer.decompose
1731  (
1732  mesh_,
1733  cellWeights,
1734  blockedFace,
1735  specifiedProcessorFaces,
1736  specifiedProcessor,
1737  couples // explicit connections
1738  );
1739 
1740  if (debug)
1741  {
1742  labelList nProcCells(distributor.countCells(distribution));
1743  Pout<< "Wanted distribution:" << nProcCells << endl;
1744 
1746  Pstream::listCombineScatter(nProcCells);
1747 
1748  Pout<< "Wanted resulting decomposition:" << endl;
1749  forAll(nProcCells, proci)
1750  {
1751  Pout<< " " << proci << '\t' << nProcCells[proci] << endl;
1752  }
1753  Pout<< endl;
1754  }
1755 
1756  // Do actual sending/receiving of mesh
1757  map = distributor.distribute(distribution);
1758 
1759  // Update numbering of meshRefiner
1760  distribute(map());
1761 
1762  // Set correct instance (for if overwrite)
1763  mesh_.setInstance(timeName());
1764  setInstance(mesh_.facesInstance());
1765 
1766 
1767  if (debug && keepZoneFaces)
1768  {
1769  const faceZoneMesh& fZones = mesh_.faceZones();
1770  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
1771 
1772  // Check that faceZone faces are indeed internal
1773  forAll(fZones, zonei)
1774  {
1775  const faceZone& fZone = fZones[zonei];
1776 
1777  forAll(fZone, i)
1778  {
1779  label facei = fZone[i];
1780  label patchi = pbm.whichPatch(facei);
1781 
1782  if (patchi >= 0 && pbm[patchi].coupled())
1783  {
1785  << "Face at " << mesh_.faceCentres()[facei]
1786  << " on zone " << fZone.name()
1787  << " is on coupled patch " << pbm[patchi].name()
1788  << endl;
1789  }
1790  }
1791  }
1792  }
1793  }
1794 
1795  return map;
1796 }
1797 
1798 
1800 {
1801  label nBoundaryFaces = 0;
1802 
1803  const labelList& surfIndex = surfaceIndex();
1804 
1805  forAll(surfIndex, facei)
1806  {
1807  if (surfIndex[facei] != -1)
1808  {
1809  nBoundaryFaces++;
1810  }
1811  }
1812 
1813  labelList surfaceFaces(nBoundaryFaces);
1814  nBoundaryFaces = 0;
1815 
1816  forAll(surfIndex, facei)
1817  {
1818  if (surfIndex[facei] != -1)
1819  {
1820  surfaceFaces[nBoundaryFaces++] = facei;
1821  }
1822  }
1823  return surfaceFaces;
1824 }
1825 
1826 
1828 {
1829  const faceList& faces = mesh_.faces();
1830 
1831  // Mark all points on faces that will become baffles
1832  bitSet isBoundaryPoint(mesh_.nPoints());
1833  label nBoundaryPoints = 0;
1834 
1835  const labelList& surfIndex = surfaceIndex();
1836 
1837  forAll(surfIndex, facei)
1838  {
1839  if (surfIndex[facei] != -1)
1840  {
1841  const face& f = faces[facei];
1842 
1843  forAll(f, fp)
1844  {
1845  if (isBoundaryPoint.set(f[fp]))
1846  {
1847  nBoundaryPoints++;
1848  }
1849  }
1850  }
1851  }
1852 
1854  //labelList adaptPatchIDs(meshedPatches());
1855  //forAll(adaptPatchIDs, i)
1856  //{
1857  // label patchi = adaptPatchIDs[i];
1858  //
1859  // if (patchi != -1)
1860  // {
1861  // const polyPatch& pp = mesh_.boundaryMesh()[patchi];
1862  //
1863  // label facei = pp.start();
1864  //
1865  // forAll(pp, i)
1866  // {
1867  // const face& f = faces[facei];
1868  //
1869  // forAll(f, fp)
1870  // {
1871  // if (isBoundaryPoint.set(f[fp]))
1872  // nBoundaryPoints++;
1873  // }
1874  // }
1875  // facei++;
1876  // }
1877  // }
1878  //}
1879 
1880 
1881  // Pack
1882  labelList boundaryPoints(nBoundaryPoints);
1883  nBoundaryPoints = 0;
1884  forAll(isBoundaryPoint, pointi)
1885  {
1886  if (isBoundaryPoint.test(pointi))
1887  {
1888  boundaryPoints[nBoundaryPoints++] = pointi;
1889  }
1890  }
1891 
1892  return boundaryPoints;
1893 }
1894 
1895 
1896 //- Create patch from set of patches
1899  const polyMesh& mesh,
1900  const labelList& patchIDs
1901 )
1902 {
1904 
1905  // Count faces.
1906  label nFaces = 0;
1907 
1908  forAll(patchIDs, i)
1909  {
1910  const polyPatch& pp = patches[patchIDs[i]];
1911 
1912  nFaces += pp.size();
1913  }
1914 
1915  // Collect faces.
1916  labelList addressing(nFaces);
1917  nFaces = 0;
1918 
1919  forAll(patchIDs, i)
1920  {
1921  const polyPatch& pp = patches[patchIDs[i]];
1922 
1923  label meshFacei = pp.start();
1924 
1925  forAll(pp, i)
1926  {
1927  addressing[nFaces++] = meshFacei++;
1928  }
1929  }
1930 
1932  (
1933  IndirectList<face>(mesh.faces(), addressing),
1934  mesh.points()
1935  );
1936 }
1937 
1938 
1941  const pointMesh& pMesh,
1942  const labelList& adaptPatchIDs
1943 )
1944 {
1945  const polyMesh& mesh = pMesh();
1946 
1947  // Construct displacement field.
1948  const pointBoundaryMesh& pointPatches = pMesh.boundary();
1949 
1950  wordList patchFieldTypes
1951  (
1952  pointPatches.size(),
1953  slipPointPatchVectorField::typeName
1954  );
1955 
1956  forAll(adaptPatchIDs, i)
1957  {
1958  patchFieldTypes[adaptPatchIDs[i]] =
1959  fixedValuePointPatchVectorField::typeName;
1960  }
1961 
1962  forAll(pointPatches, patchi)
1963  {
1964  if (isA<processorPointPatch>(pointPatches[patchi]))
1965  {
1966  patchFieldTypes[patchi] = calculatedPointPatchVectorField::typeName;
1967  }
1968  else if (isA<cyclicPointPatch>(pointPatches[patchi]))
1969  {
1970  patchFieldTypes[patchi] = cyclicSlipPointPatchVectorField::typeName;
1971  }
1972  }
1973 
1974  // Note: time().timeName() instead of meshRefinement::timeName() since
1975  // postprocessable field.
1977  (
1978  IOobject
1979  (
1980  "pointDisplacement",
1981  mesh.time().timeName(),
1982  mesh,
1985  ),
1986  pMesh,
1988  patchFieldTypes
1989  );
1990 }
1991 
1992 
1994 {
1995  const faceZoneMesh& fZones = mesh.faceZones();
1996 
1997  // Check any zones are present anywhere and in same order
1998 
1999  {
2000  List<wordList> zoneNames(Pstream::nProcs());
2001  zoneNames[Pstream::myProcNo()] = fZones.names();
2002  Pstream::gatherList(zoneNames);
2003  Pstream::scatterList(zoneNames);
2004  // All have same data now. Check.
2005  forAll(zoneNames, proci)
2006  {
2007  if (proci != Pstream::myProcNo())
2008  {
2009  if (zoneNames[proci] != zoneNames[Pstream::myProcNo()])
2010  {
2012  << "faceZones are not synchronised on processors." << nl
2013  << "Processor " << proci << " has faceZones "
2014  << zoneNames[proci] << nl
2015  << "Processor " << Pstream::myProcNo()
2016  << " has faceZones "
2017  << zoneNames[Pstream::myProcNo()] << nl
2018  << exit(FatalError);
2019  }
2020  }
2021  }
2022  }
2023 
2024  // Check that coupled faces are present on both sides.
2025 
2026  labelList faceToZone(mesh.nBoundaryFaces(), -1);
2027 
2028  forAll(fZones, zonei)
2029  {
2030  const faceZone& fZone = fZones[zonei];
2031 
2032  forAll(fZone, i)
2033  {
2034  label bFacei = fZone[i]-mesh.nInternalFaces();
2035 
2036  if (bFacei >= 0)
2037  {
2038  if (faceToZone[bFacei] == -1)
2039  {
2040  faceToZone[bFacei] = zonei;
2041  }
2042  else if (faceToZone[bFacei] == zonei)
2043  {
2045  << "Face " << fZone[i] << " in zone "
2046  << fZone.name()
2047  << " is twice in zone!"
2048  << abort(FatalError);
2049  }
2050  else
2051  {
2053  << "Face " << fZone[i] << " in zone "
2054  << fZone.name()
2055  << " is also in zone "
2056  << fZones[faceToZone[bFacei]].name()
2057  << abort(FatalError);
2058  }
2059  }
2060  }
2061  }
2062 
2063  labelList neiFaceToZone(faceToZone);
2064  syncTools::swapBoundaryFaceList(mesh, neiFaceToZone);
2065 
2066  forAll(faceToZone, i)
2067  {
2068  if (faceToZone[i] != neiFaceToZone[i])
2069  {
2071  << "Face " << mesh.nInternalFaces()+i
2072  << " is in zone " << faceToZone[i]
2073  << ", its coupled face is in zone " << neiFaceToZone[i]
2074  << abort(FatalError);
2075  }
2076  }
2077 }
2078 
2079 
2082  const polyMesh& mesh,
2083  const bitSet& isMasterEdge,
2084  const labelList& meshPoints,
2085  const edgeList& edges,
2086  scalarField& edgeWeights,
2087  scalarField& invSumWeight
2088 )
2089 {
2090  const pointField& pts = mesh.points();
2091 
2092  // Calculate edgeWeights and inverse sum of edge weights
2093  edgeWeights.setSize(isMasterEdge.size());
2094  invSumWeight.setSize(meshPoints.size());
2095 
2096  forAll(edges, edgei)
2097  {
2098  const edge& e = edges[edgei];
2099  scalar eMag = max
2100  (
2101  SMALL,
2102  mag
2103  (
2104  pts[meshPoints[e[1]]]
2105  - pts[meshPoints[e[0]]]
2106  )
2107  );
2108  edgeWeights[edgei] = 1.0/eMag;
2109  }
2110 
2111  // Sum per point all edge weights
2112  weightedSum
2113  (
2114  mesh,
2115  isMasterEdge,
2116  meshPoints,
2117  edges,
2118  edgeWeights,
2119  scalarField(meshPoints.size(), 1.0), // data
2120  invSumWeight
2121  );
2122 
2123  // Inplace invert
2124  forAll(invSumWeight, pointi)
2125  {
2126  scalar w = invSumWeight[pointi];
2127 
2128  if (w > 0.0)
2129  {
2130  invSumWeight[pointi] = 1.0/w;
2131  }
2132  }
2133 }
2134 
2135 
2138  fvMesh& mesh,
2139  const label insertPatchi,
2140  const word& patchName,
2141  const dictionary& patchDict
2142 )
2143 {
2144  // Clear local fields and e.g. polyMesh parallelInfo.
2145  mesh.clearOut();
2146 
2147  polyBoundaryMesh& polyPatches =
2148  const_cast<polyBoundaryMesh&>(mesh.boundaryMesh());
2149  fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh.boundary());
2150 
2151  label patchi = polyPatches.size();
2152 
2153  // Add polyPatch at the end
2154  polyPatches.setSize(patchi+1);
2155  polyPatches.set
2156  (
2157  patchi,
2159  (
2160  patchName,
2161  patchDict,
2162  insertPatchi,
2163  polyPatches
2164  )
2165  );
2166  fvPatches.setSize(patchi+1);
2167  fvPatches.set
2168  (
2169  patchi,
2170  fvPatch::New
2171  (
2172  polyPatches[patchi], // point to newly added polyPatch
2173  mesh.boundary()
2174  )
2175  );
2176 
2177  addPatchFields<volScalarField>
2178  (
2179  mesh,
2181  );
2182  addPatchFields<volVectorField>
2183  (
2184  mesh,
2186  );
2187  addPatchFields<volSphericalTensorField>
2188  (
2189  mesh,
2191  );
2192  addPatchFields<volSymmTensorField>
2193  (
2194  mesh,
2196  );
2197  addPatchFields<volTensorField>
2198  (
2199  mesh,
2201  );
2202 
2203  // Surface fields
2204 
2205  addPatchFields<surfaceScalarField>
2206  (
2207  mesh,
2209  );
2210  addPatchFields<surfaceVectorField>
2211  (
2212  mesh,
2214  );
2215  addPatchFields<surfaceSphericalTensorField>
2216  (
2217  mesh,
2219  );
2220  addPatchFields<surfaceSymmTensorField>
2221  (
2222  mesh,
2224  );
2225  addPatchFields<surfaceTensorField>
2226  (
2227  mesh,
2229  );
2230  return patchi;
2231 }
2232 
2233 
2236  fvMesh& mesh,
2237  const word& patchName,
2238  const dictionary& patchInfo
2239 )
2240 {
2241  polyBoundaryMesh& polyPatches =
2242  const_cast<polyBoundaryMesh&>(mesh.boundaryMesh());
2243  fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh.boundary());
2244 
2245  const label patchi = polyPatches.findPatchID(patchName);
2246  if (patchi != -1)
2247  {
2248  // Already there
2249  return patchi;
2250  }
2251 
2252 
2253  label insertPatchi = polyPatches.size();
2254  label startFacei = mesh.nFaces();
2255 
2256  forAll(polyPatches, patchi)
2257  {
2258  const polyPatch& pp = polyPatches[patchi];
2259 
2260  if (isA<processorPolyPatch>(pp))
2261  {
2262  insertPatchi = patchi;
2263  startFacei = pp.start();
2264  break;
2265  }
2266  }
2267 
2268  dictionary patchDict(patchInfo);
2269  patchDict.set("nFaces", 0);
2270  patchDict.set("startFace", startFacei);
2271 
2272  // Below is all quite a hack. Feel free to change once there is a better
2273  // mechanism to insert and reorder patches.
2274 
2275  label addedPatchi = appendPatch(mesh, insertPatchi, patchName, patchDict);
2276 
2277 
2278  // Create reordering list
2279  // patches before insert position stay as is
2280  labelList oldToNew(addedPatchi+1);
2281  for (label i = 0; i < insertPatchi; i++)
2282  {
2283  oldToNew[i] = i;
2284  }
2285  // patches after insert position move one up
2286  for (label i = insertPatchi; i < addedPatchi; i++)
2287  {
2288  oldToNew[i] = i+1;
2289  }
2290  // appended patch gets moved to insert position
2291  oldToNew[addedPatchi] = insertPatchi;
2292 
2293  // Shuffle into place
2294  polyPatches.reorder(oldToNew, true);
2295  fvPatches.reorder(oldToNew);
2296 
2297  reorderPatchFields<volScalarField>(mesh, oldToNew);
2298  reorderPatchFields<volVectorField>(mesh, oldToNew);
2299  reorderPatchFields<volSphericalTensorField>(mesh, oldToNew);
2300  reorderPatchFields<volSymmTensorField>(mesh, oldToNew);
2301  reorderPatchFields<volTensorField>(mesh, oldToNew);
2302  reorderPatchFields<surfaceScalarField>(mesh, oldToNew);
2303  reorderPatchFields<surfaceVectorField>(mesh, oldToNew);
2304  reorderPatchFields<surfaceSphericalTensorField>(mesh, oldToNew);
2305  reorderPatchFields<surfaceSymmTensorField>(mesh, oldToNew);
2306  reorderPatchFields<surfaceTensorField>(mesh, oldToNew);
2307 
2308  return insertPatchi;
2309 }
2310 
2311 
2314  const word& name,
2315  const dictionary& patchInfo
2316 )
2317 {
2318  label meshedi = meshedPatches_.find(name);
2319 
2320  if (meshedi != -1)
2321  {
2322  // Already there. Get corresponding polypatch
2323  return mesh_.boundaryMesh().findPatchID(name);
2324  }
2325  else
2326  {
2327  // Add patch
2328  label patchi = addPatch(mesh_, name, patchInfo);
2329 
2330 // dictionary patchDict(patchInfo);
2331 // patchDict.set("nFaces", 0);
2332 // patchDict.set("startFace", 0);
2333 // autoPtr<polyPatch> ppPtr
2334 // (
2335 // polyPatch::New
2336 // (
2337 // name,
2338 // patchDict,
2339 // 0,
2340 // mesh_.boundaryMesh()
2341 // )
2342 // );
2343 // label patchi = fvMeshTools::addPatch
2344 // (
2345 // mesh_,
2346 // ppPtr(),
2347 // dictionary(), // optional field values
2348 // calculatedFvPatchField<scalar>::typeName,
2349 // true
2350 // );
2351 
2352  // Store
2353  meshedPatches_.append(name);
2354 
2355  // Clear patch based addressing
2356  faceToCoupledPatch_.clear();
2357 
2358  return patchi;
2359  }
2360 }
2361 
2362 
2364 {
2365  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
2366 
2367  DynamicList<label> patchIDs(meshedPatches_.size());
2368  forAll(meshedPatches_, i)
2369  {
2370  label patchi = patches.findPatchID(meshedPatches_[i]);
2371 
2372  if (patchi == -1)
2373  {
2375  << "Problem : did not find patch " << meshedPatches_[i]
2376  << endl << "Valid patches are " << patches.names()
2377  << endl; //abort(FatalError);
2378  }
2379  else if (!polyPatch::constraintType(patches[patchi].type()))
2380  {
2381  patchIDs.append(patchi);
2382  }
2383  }
2384 
2385  return patchIDs;
2386 }
2387 
2388 
2391  const word& fzName,
2392  const word& masterPatch,
2393  const word& slavePatch,
2394  const surfaceZonesInfo::faceZoneType& fzType
2395 )
2396 {
2397  label zonei = surfaceZonesInfo::addFaceZone
2398  (
2399  fzName, //name
2400  labelList(0), //addressing
2401  boolList(0), //flipmap
2402  mesh_
2403  );
2404 
2405  faceZoneToMasterPatch_.insert(fzName, masterPatch);
2406  faceZoneToSlavePatch_.insert(fzName, slavePatch);
2407  faceZoneToType_.insert(fzName, fzType);
2408 
2409  return zonei;
2410 }
2411 
2412 
2415  const word& fzName,
2416  label& masterPatchID,
2417  label& slavePatchID,
2419 ) const
2420 {
2421  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
2422 
2423  if (!faceZoneToMasterPatch_.found(fzName))
2424  {
2425  return false;
2426  }
2427  else
2428  {
2429  const word& masterName = faceZoneToMasterPatch_[fzName];
2430  masterPatchID = pbm.findPatchID(masterName);
2431 
2432  const word& slaveName = faceZoneToSlavePatch_[fzName];
2433  slavePatchID = pbm.findPatchID(slaveName);
2434 
2435  fzType = faceZoneToType_[fzName];
2436 
2437  return true;
2438  }
2439 }
2440 
2441 
2443 {
2444  for (const polyPatch& pp : mesh_.boundaryMesh())
2445  {
2446  // Check all coupled. Avoid using .coupled() so we also pick up AMI.
2447  const auto* cpp = isA<coupledPolyPatch>(pp);
2448 
2449  if (cpp && (cpp->separated() || !cpp->parallel()))
2450  {
2451  SubList<bool>(selected, pp.size(), pp.start()) = true;
2452  }
2453  }
2454 }
2455 
2456 
2459  const polyMesh& mesh,
2460  const labelList& cellToRegion,
2461  const vector& perturbVec,
2462  const point& p
2463 )
2464 {
2465  label regioni = -1;
2466 
2467  // Force calculation of base points (needs to be synchronised)
2468  (void)mesh.tetBasePtIs();
2469 
2470  label celli = mesh.findCell(p, findCellMode);
2471  if (celli != -1)
2472  {
2473  regioni = cellToRegion[celli];
2474  }
2475  reduce(regioni, maxOp<label>());
2476 
2477  if (regioni == -1)
2478  {
2479  // See if we can perturb a bit
2480  celli = mesh.findCell(p+perturbVec, findCellMode);
2481  if (celli != -1)
2482  {
2483  regioni = cellToRegion[celli];
2484  }
2485  reduce(regioni, maxOp<label>());
2486  }
2487  return regioni;
2488 }
2489 
2490 
2491 // Modify cellRegion to be consistent with locationsInMesh.
2492 // - all regions not in locationsInMesh are set to -1
2493 // - check that all regions inside locationsOutsideMesh are set to -1
2496  const polyMesh& mesh,
2497  const vector& perturbVec,
2498  const pointField& locationsInMesh,
2499  const pointField& locationsOutsideMesh,
2500  const bool exitIfLeakPath,
2501  const writer<scalar>& leakPathFormatter,
2502  const label nRegions,
2503  labelList& cellRegion,
2504  const boolList& blockedFace
2505 )
2506 {
2507  bitSet insideCell(mesh.nCells());
2508 
2509  // Mark all cells reachable from locationsInMesh
2510  labelList insideRegions(locationsInMesh.size());
2511  forAll(insideRegions, i)
2512  {
2513  // Find the region containing the point
2514  label regioni = findRegion
2515  (
2516  mesh,
2517  cellRegion,
2518  perturbVec,
2519  locationsInMesh[i]
2520  );
2521 
2522  insideRegions[i] = regioni;
2523 
2524  // Mark all cells in the region as being inside
2525  forAll(cellRegion, celli)
2526  {
2527  if (cellRegion[celli] == regioni)
2528  {
2529  insideCell.set(celli);
2530  }
2531  }
2532  }
2533 
2534 
2535 
2536  // Check that all the locations outside the
2537  // mesh do not conflict with those inside
2538  forAll(locationsOutsideMesh, i)
2539  {
2540  // Find the region containing the point
2541  label regioni = findRegion
2542  (
2543  mesh,
2544  cellRegion,
2545  perturbVec,
2546  locationsOutsideMesh[i]
2547  );
2548 
2549  if (regioni != -1)
2550  {
2551  // Do a quick check for locationsOutsideMesh overlapping with
2552  // inside ones.
2553  label index = insideRegions.find(regioni);
2554  if (index != -1)
2555  {
2556  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
2557 
2558  fileName outputDir;
2559  if (Pstream::master())
2560  {
2561  outputDir =
2562  (
2563  mesh.time().globalPath()
2565  / mesh.pointsInstance()
2566  );
2567  outputDir.clean(); // Remove unneeded ".."
2568  mkDir(outputDir);
2569  }
2570 
2571 
2572  // Write the leak path
2573 
2574  meshSearch searchEngine(mesh);
2575  shortestPathSet leakPath
2576  (
2577  "leakPath",
2578  mesh,
2579  searchEngine,
2581  false, //true,
2582  50, // tbd. Number of iterations
2583  pbm.groupPatchIDs()["wall"],
2584  locationsInMesh,
2585  locationsOutsideMesh,
2586  blockedFace
2587  );
2588 
2589  // Split leak path according to segment. Note: segment index
2590  // is global (= index in locationsInsideMesh)
2591  List<pointList> segmentPoints;
2592  List<scalarList> segmentDist;
2593  {
2594  label nSegments = 0;
2595  if (leakPath.segments().size())
2596  {
2597  nSegments = max(leakPath.segments())+1;
2598  }
2599  reduce(nSegments, maxOp<label>());
2600 
2601  labelList nElemsPerSegment(nSegments, Zero);
2602  for (label segmenti : leakPath.segments())
2603  {
2604  nElemsPerSegment[segmenti]++;
2605  }
2606  segmentPoints.setSize(nElemsPerSegment.size());
2607  segmentDist.setSize(nElemsPerSegment.size());
2608  forAll(nElemsPerSegment, i)
2609  {
2610  segmentPoints[i].setSize(nElemsPerSegment[i]);
2611  segmentDist[i].setSize(nElemsPerSegment[i]);
2612  }
2613  nElemsPerSegment = 0;
2614 
2615  forAll(leakPath, elemi)
2616  {
2617  label segmenti = leakPath.segments()[elemi];
2618  pointList& points = segmentPoints[segmenti];
2619  scalarList& dist = segmentDist[segmenti];
2620  label& n = nElemsPerSegment[segmenti];
2621 
2622  points[n] = leakPath[elemi];
2623  dist[n] = leakPath.curveDist()[elemi];
2624  n++;
2625  }
2626  }
2627 
2628  PtrList<coordSet> allLeakPaths(segmentPoints.size());
2629  forAll(allLeakPaths, segmenti)
2630  {
2631  // Collect data from all processors
2632  List<pointList> gatheredPts(Pstream::nProcs());
2633  gatheredPts[Pstream::myProcNo()] =
2634  std::move(segmentPoints[segmenti]);
2635  Pstream::gatherList(gatheredPts);
2636 
2637  List<scalarList> gatheredDist(Pstream::nProcs());
2638  gatheredDist[Pstream::myProcNo()] =
2639  std::move(segmentDist[segmenti]);
2640  Pstream::gatherList(gatheredDist);
2641 
2642  // Combine processor lists into one big list.
2643  pointList allPts
2644  (
2645  ListListOps::combine<pointList>
2646  (
2647  gatheredPts, accessOp<pointList>()
2648  )
2649  );
2650  scalarList allDist
2651  (
2652  ListListOps::combine<scalarList>
2653  (
2654  gatheredDist, accessOp<scalarList>()
2655  )
2656  );
2657 
2658  // Sort according to curveDist
2659  labelList indexSet(Foam::sortedOrder(allDist));
2660 
2661  allLeakPaths.set
2662  (
2663  segmenti,
2664  new coordSet
2665  (
2666  leakPath.name(),
2667  leakPath.axis(),
2668  pointList(allPts, indexSet),
2669  //scalarList(allDist, indexSet)
2670  scalarList(allPts.size(), scalar(segmenti))
2671  )
2672  );
2673  }
2674 
2675  fileName fName;
2676  if (Pstream::master())
2677  {
2678  List<List<scalarField>> allLeakData(1);
2679  List<scalarField>& varData = allLeakData[0];
2680  varData.setSize(allLeakPaths.size());
2681  forAll(allLeakPaths, segmenti)
2682  {
2683  varData[segmenti] = allLeakPaths[segmenti].curveDist();
2684  }
2685 
2686  const wordList valueSetNames(1, "leakPath");
2687 
2688  fName =
2689  outputDir
2690  /leakPathFormatter.getFileName
2691  (
2692  allLeakPaths[0],
2693  valueSetNames
2694  );
2695 
2696  // Note scope to force writing to finish before
2697  // FatalError exit
2698  OFstream ofs(fName);
2699  if (ofs.opened())
2700  {
2701  leakPathFormatter.write
2702  (
2703  true, // write tracks
2704  List<scalarField>(), // times
2705  allLeakPaths,
2706  valueSetNames,
2707  allLeakData,
2708  ofs
2709  );
2710  }
2711  }
2712 
2713  Pstream::scatter(fName);
2714 
2715  if (exitIfLeakPath)
2716  {
2718  << "Location in mesh " << locationsInMesh[index]
2719  << " is inside same mesh region " << regioni
2720  << " as one of the locations outside mesh "
2721  << locationsOutsideMesh
2722  << nl << " Dumped leak path to " << fName
2723  << exit(FatalError);
2724  }
2725  else
2726  {
2728  << "Location in mesh " << locationsInMesh[index]
2729  << " is inside same mesh region " << regioni
2730  << " as one of the locations outside mesh "
2731  << locationsOutsideMesh
2732  << nl << "Dumped leak path to " << fName << endl;
2733  }
2734  }
2735  }
2736  }
2737 
2738 
2739  label nRemove = 0;
2740 
2741  // Now update cellRegion to -1 for unreachable cells
2742  forAll(insideCell, celli)
2743  {
2744  if (!insideCell.test(celli))
2745  {
2746  cellRegion[celli] = -1;
2747  ++nRemove;
2748  }
2749  else if (cellRegion[celli] == -1)
2750  {
2751  ++nRemove;
2752  }
2753  }
2754 
2755  return nRemove;
2756 }
2757 
2758 
2761  const labelList& globalToMasterPatch,
2762  const labelList& globalToSlavePatch,
2763  const pointField& locationsInMesh,
2764  const pointField& locationsOutsideMesh,
2765  const bool exitIfLeakPath,
2766  const writer<scalar>& leakPathFormatter
2767 )
2768 {
2769  // Force calculation of face decomposition (used in findCell)
2770  (void)mesh_.tetBasePtIs();
2771 
2772  // Determine connected regions. regionSplit is the labelList with the
2773  // region per cell.
2774 
2775  boolList blockedFace(mesh_.nFaces(), false);
2776  selectSeparatedCoupledFaces(blockedFace);
2777 
2778  regionSplit cellRegion(mesh_, blockedFace);
2779 
2780  label nRemove = findRegions
2781  (
2782  mesh_,
2783  mergeDistance_ * vector::one, // perturbVec
2784  locationsInMesh,
2785  locationsOutsideMesh,
2786  exitIfLeakPath,
2787  leakPathFormatter,
2788  cellRegion.nRegions(),
2789  cellRegion,
2790  blockedFace
2791  );
2792 
2793  // Subset
2794  // ~~~~~~
2795 
2796  // Get cells to remove
2797  DynamicList<label> cellsToRemove(nRemove);
2798  forAll(cellRegion, celli)
2799  {
2800  if (cellRegion[celli] == -1)
2801  {
2802  cellsToRemove.append(celli);
2803  }
2804  }
2805  cellsToRemove.shrink();
2806 
2807  label nTotCellsToRemove = returnReduce
2808  (
2809  cellsToRemove.size(),
2810  sumOp<label>()
2811  );
2812 
2813 
2814  autoPtr<mapPolyMesh> mapPtr;
2815  if (nTotCellsToRemove > 0)
2816  {
2817  label nCellsToKeep =
2818  mesh_.globalData().nTotalCells()
2819  - nTotCellsToRemove;
2820 
2821  Info<< "Keeping all cells containing points " << locationsInMesh << endl
2822  << "Selected for keeping : "
2823  << nCellsToKeep
2824  << " cells." << endl;
2825 
2826 
2827  // Remove cells
2828  removeCells cellRemover(mesh_);
2829 
2830  labelList exposedFaces(cellRemover.getExposedFaces(cellsToRemove));
2831  labelList exposedPatch;
2832 
2833  label nExposedFaces = returnReduce(exposedFaces.size(), sumOp<label>());
2834  if (nExposedFaces)
2835  {
2836  // FatalErrorInFunction
2837  // << "Removing non-reachable cells should only expose"
2838  // << " boundary faces" << nl
2839  // << "ExposedFaces:" << exposedFaces << abort(FatalError);
2840 
2841  // Patch for exposed faces for lack of anything sensible.
2842  label defaultPatch = 0;
2843  if (globalToMasterPatch.size())
2844  {
2845  defaultPatch = globalToMasterPatch[0];
2846  }
2847 
2849  << "Removing non-reachable cells exposes "
2850  << nExposedFaces << " internal or coupled faces." << endl
2851  << " These get put into patch " << defaultPatch << endl;
2852  exposedPatch.setSize(exposedFaces.size(), defaultPatch);
2853  }
2854 
2855  mapPtr = doRemoveCells
2856  (
2857  cellsToRemove,
2858  exposedFaces,
2859  exposedPatch,
2860  cellRemover
2861  );
2862  }
2863  return mapPtr;
2864 }
2865 
2866 
2868 {
2869  // mesh_ already distributed; distribute my member data
2870 
2871  // surfaceQueries_ ok.
2872 
2873  // refinement
2874  meshCutter_.distribute(map);
2875 
2876  // surfaceIndex is face data.
2877  map.distributeFaceData(surfaceIndex_);
2878 
2879  // faceToPatch (baffles that were on coupled faces) is not maintained
2880  // (since baffling also disconnects points)
2881  faceToCoupledPatch_.clear();
2882 
2883  // maintainedFaces are indices of faces.
2884  forAll(userFaceData_, i)
2885  {
2886  map.distributeFaceData(userFaceData_[i].second());
2887  }
2888 
2889  // Redistribute surface and any fields on it.
2890  {
2891  Random rndGen(653213);
2892 
2893  // Get local mesh bounding box. Single box for now.
2895  treeBoundBox& bb = meshBb[0];
2896  bb = treeBoundBox(mesh_.points());
2897  bb = bb.extend(rndGen, 1e-4);
2898 
2899  // Distribute all geometry (so refinementSurfaces and shellSurfaces)
2900  searchableSurfaces& geometry =
2901  const_cast<searchableSurfaces&>(surfaces_.geometry());
2902 
2903  forAll(geometry, i)
2904  {
2906  autoPtr<mapDistribute> pointMap;
2907  geometry[i].distribute
2908  (
2909  meshBb,
2910  false, // do not keep outside triangles
2911  faceMap,
2912  pointMap
2913  );
2914 
2915  if (faceMap)
2916  {
2917  // (ab)use the instance() to signal current modification time
2918  geometry[i].instance() = geometry[i].time().timeName();
2919  }
2920 
2921  faceMap.clear();
2922  pointMap.clear();
2923  }
2924  }
2925 }
2926 
2927 
2930  const mapPolyMesh& map,
2931  const labelList& changedFaces
2932 )
2933 {
2934  Map<label> dummyMap(0);
2935 
2936  updateMesh(map, changedFaces, dummyMap, dummyMap, dummyMap);
2937 }
2938 
2939 
2942  const labelList& pointsToStore,
2943  const labelList& facesToStore,
2944  const labelList& cellsToStore
2945 )
2946 {
2947  // For now only meshCutter has storable/retrievable data.
2948  meshCutter_.storeData
2949  (
2950  pointsToStore,
2951  facesToStore,
2952  cellsToStore
2953  );
2954 }
2955 
2956 
2959  const mapPolyMesh& map,
2960  const labelList& changedFaces,
2961  const Map<label>& pointsToRestore,
2962  const Map<label>& facesToRestore,
2963  const Map<label>& cellsToRestore
2964 )
2965 {
2966  // For now only meshCutter has storable/retrievable data.
2967 
2968  // Update numbering of cells/vertices.
2969  meshCutter_.updateMesh
2970  (
2971  map,
2972  pointsToRestore,
2973  facesToRestore,
2974  cellsToRestore
2975  );
2976 
2977  // Update surfaceIndex
2978  updateList(map.faceMap(), label(-1), surfaceIndex_);
2979 
2980  // Update faceToCoupledPatch_
2981  {
2982  Map<label> newFaceToPatch(faceToCoupledPatch_.size());
2983  forAllConstIters(faceToCoupledPatch_, iter)
2984  {
2985  const label newFacei = map.reverseFaceMap()[iter.key()];
2986 
2987  if (newFacei >= 0)
2988  {
2989  newFaceToPatch.insert(newFacei, iter.val());
2990  }
2991  }
2992  faceToCoupledPatch_.transfer(newFaceToPatch);
2993  }
2994 
2995 
2996  // Update cached intersection information
2997  updateIntersections(changedFaces);
2998 
2999  // Update maintained faces
3000  forAll(userFaceData_, i)
3001  {
3002  labelList& data = userFaceData_[i].second();
3003 
3004  if (userFaceData_[i].first() == KEEPALL)
3005  {
3006  // extend list with face-from-face data
3007  updateList(map.faceMap(), label(-1), data);
3008  }
3009  else if (userFaceData_[i].first() == MASTERONLY)
3010  {
3011  // keep master only
3012  labelList newFaceData(map.faceMap().size(), -1);
3013 
3014  forAll(newFaceData, facei)
3015  {
3016  label oldFacei = map.faceMap()[facei];
3017 
3018  if (oldFacei >= 0 && map.reverseFaceMap()[oldFacei] == facei)
3019  {
3020  newFaceData[facei] = data[oldFacei];
3021  }
3022  }
3023  data.transfer(newFaceData);
3024  }
3025  else
3026  {
3027  // remove any face that has been refined i.e. referenced more than
3028  // once.
3029 
3030  // 1. Determine all old faces that get referenced more than once.
3031  // These get marked with -1 in reverseFaceMap
3032  labelList reverseFaceMap(map.reverseFaceMap());
3033 
3034  forAll(map.faceMap(), facei)
3035  {
3036  label oldFacei = map.faceMap()[facei];
3037 
3038  if (oldFacei >= 0)
3039  {
3040  if (reverseFaceMap[oldFacei] != facei)
3041  {
3042  // facei is slave face. Mark old face.
3043  reverseFaceMap[oldFacei] = -1;
3044  }
3045  }
3046  }
3047 
3048  // 2. Map only faces with intact reverseFaceMap
3049  labelList newFaceData(map.faceMap().size(), -1);
3050  forAll(newFaceData, facei)
3051  {
3052  label oldFacei = map.faceMap()[facei];
3053 
3054  if (oldFacei >= 0)
3055  {
3056  if (reverseFaceMap[oldFacei] == facei)
3057  {
3058  newFaceData[facei] = data[oldFacei];
3059  }
3060  }
3061  }
3062  data.transfer(newFaceData);
3063  }
3064  }
3065 }
3066 
3067 
3069 {
3070  bool writeOk = mesh_.write();
3071 
3072  // Make sure that any distributed surfaces (so ones which probably have
3073  // been changed) get written as well.
3074  // Note: should ideally have some 'modified' flag to say whether it
3075  // has been changed or not.
3076  searchableSurfaces& geometry =
3077  const_cast<searchableSurfaces&>(surfaces_.geometry());
3078 
3079  forAll(geometry, i)
3080  {
3081  searchableSurface& s = geometry[i];
3082 
3083  // Check if instance() of surface is not constant or system.
3084  // Is good hint that surface is distributed.
3085  if
3086  (
3087  s.instance() != s.time().system()
3088  && s.instance() != s.time().caseSystem()
3089  && s.instance() != s.time().constant()
3090  && s.instance() != s.time().caseConstant()
3091  )
3092  {
3093  // Make sure it gets written to current time, not constant.
3094  s.instance() = s.time().timeName();
3095  writeOk = writeOk && s.write();
3096  }
3097  }
3098 
3099  return writeOk;
3100 }
3101 
3102 
3105  const polyMesh& mesh,
3106  const labelList& meshPoints
3107 )
3108 {
3109  const globalIndex globalPoints(meshPoints.size());
3110 
3111  labelList myPoints
3112  (
3113  identity(globalPoints.localSize(), globalPoints.localStart())
3114  );
3115 
3117  (
3118  mesh,
3119  meshPoints,
3120  myPoints,
3121  minEqOp<label>(),
3122  labelMax
3123  );
3124 
3125 
3126  bitSet isPatchMasterPoint(meshPoints.size());
3127  forAll(meshPoints, pointi)
3128  {
3129  if (myPoints[pointi] == globalPoints.toGlobal(pointi))
3130  {
3131  isPatchMasterPoint.set(pointi);
3132  }
3133  }
3134 
3135  return isPatchMasterPoint;
3136 }
3137 
3138 
3141  const polyMesh& mesh,
3142  const labelList& meshEdges
3143 )
3144 {
3145  const globalIndex globalEdges(meshEdges.size());
3146 
3147  labelList myEdges
3148  (
3149  identity(globalEdges.localSize(), globalEdges.localStart())
3150  );
3151 
3153  (
3154  mesh,
3155  meshEdges,
3156  myEdges,
3157  minEqOp<label>(),
3158  labelMax
3159  );
3160 
3161 
3162  bitSet isMasterEdge(meshEdges.size());
3163  forAll(meshEdges, edgei)
3164  {
3165  if (myEdges[edgei] == globalEdges.toGlobal(edgei))
3166  {
3167  isMasterEdge.set(edgei);
3168  }
3169  }
3170 
3171  return isMasterEdge;
3172 }
3173 
3174 
3175 void Foam::meshRefinement::printMeshInfo(const bool debug, const string& msg)
3176 const
3177 {
3178  const globalMeshData& pData = mesh_.globalData();
3179 
3180  if (debug)
3181  {
3182  Pout<< msg.c_str()
3183  << " : cells(local):" << mesh_.nCells()
3184  << " faces(local):" << mesh_.nFaces()
3185  << " points(local):" << mesh_.nPoints()
3186  << endl;
3187  }
3188 
3189  {
3190  bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
3191  label nMasterFaces = isMasterFace.count();
3192 
3193  bitSet isMeshMasterPoint(syncTools::getMasterPoints(mesh_));
3194  label nMasterPoints = isMeshMasterPoint.count();
3195 
3196  Info<< msg.c_str()
3197  << " : cells:" << pData.nTotalCells()
3198  << " faces:" << returnReduce(nMasterFaces, sumOp<label>())
3199  << " points:" << returnReduce(nMasterPoints, sumOp<label>())
3200  << endl;
3201  }
3202 
3203 
3204  //if (debug)
3205  {
3206  const labelList& cellLevel = meshCutter_.cellLevel();
3207 
3208  labelList nCells(gMax(cellLevel)+1, Zero);
3209 
3210  forAll(cellLevel, celli)
3211  {
3212  nCells[cellLevel[celli]]++;
3213  }
3214 
3217 
3218  Info<< "Cells per refinement level:" << endl;
3219  forAll(nCells, leveli)
3220  {
3221  Info<< " " << leveli << '\t' << nCells[leveli]
3222  << endl;
3223  }
3224  }
3225 }
3226 
3227 
3229 {
3230  if (overwrite_ && mesh_.time().timeIndex() == 0)
3231  {
3232  return oldInstance_;
3233  }
3234 
3235  return mesh_.time().timeName();
3236 }
3237 
3238 
3240 {
3241  // Note: use time().timeName(), not meshRefinement::timeName()
3242  // so as to dump the fields to 0, not to constant.
3243  {
3244  volScalarField volRefLevel
3245  (
3246  IOobject
3247  (
3248  "cellLevel",
3249  mesh_.time().timeName(),
3250  mesh_,
3253  false
3254  ),
3255  mesh_,
3257  zeroGradientFvPatchScalarField::typeName
3258  );
3259 
3260  const labelList& cellLevel = meshCutter_.cellLevel();
3261 
3262  forAll(volRefLevel, celli)
3263  {
3264  volRefLevel[celli] = cellLevel[celli];
3265  }
3266 
3267  volRefLevel.write();
3268  }
3269 
3270  // Dump pointLevel
3271  {
3272  const pointMesh& pMesh = pointMesh::New(mesh_);
3273 
3274  pointScalarField pointRefLevel
3275  (
3276  IOobject
3277  (
3278  "pointLevel",
3279  mesh_.time().timeName(),
3280  mesh_,
3283  false
3284  ),
3285  pMesh,
3287  );
3288 
3289  const labelList& pointLevel = meshCutter_.pointLevel();
3290 
3291  forAll(pointRefLevel, pointi)
3292  {
3293  pointRefLevel[pointi] = pointLevel[pointi];
3294  }
3295 
3296  pointRefLevel.write();
3297  }
3298 }
3299 
3300 
3302 {
3303  {
3304  OFstream str(prefix + "_edges.obj");
3305  label verti = 0;
3306  Pout<< "meshRefinement::dumpIntersections :"
3307  << " Writing cellcentre-cellcentre intersections to file "
3308  << str.name() << endl;
3309 
3310 
3311  // Redo all intersections
3312  // ~~~~~~~~~~~~~~~~~~~~~~
3313 
3314  // Get boundary face centre and level. Coupled aware.
3315  labelList neiLevel(mesh_.nBoundaryFaces());
3316  pointField neiCc(mesh_.nBoundaryFaces());
3317  calcNeighbourData(neiLevel, neiCc);
3318 
3319  labelList intersectionFaces(intersectedFaces());
3320 
3321  // Collect segments we want to test for
3322  pointField start(intersectionFaces.size());
3323  pointField end(intersectionFaces.size());
3324  {
3325  labelList minLevel;
3326  calcCellCellRays
3327  (
3328  neiCc,
3329  labelList(neiCc.size(), -1),
3330  intersectionFaces,
3331  start,
3332  end,
3333  minLevel
3334  );
3335  }
3336 
3337 
3338  // Do tests in one go
3339  labelList surfaceHit;
3340  List<pointIndexHit> surfaceHitInfo;
3341  surfaces_.findAnyIntersection
3342  (
3343  start,
3344  end,
3345  surfaceHit,
3346  surfaceHitInfo
3347  );
3348 
3349  forAll(intersectionFaces, i)
3350  {
3351  if (surfaceHit[i] != -1)
3352  {
3353  meshTools::writeOBJ(str, start[i]);
3354  verti++;
3355  meshTools::writeOBJ(str, surfaceHitInfo[i].hitPoint());
3356  verti++;
3357  meshTools::writeOBJ(str, end[i]);
3358  verti++;
3359  str << "l " << verti-2 << ' ' << verti-1 << nl
3360  << "l " << verti-1 << ' ' << verti << nl;
3361  }
3362  }
3363  }
3364 
3365  Pout<< endl;
3366 }
3367 
3368 
3371  const debugType debugFlags,
3372  const writeType writeFlags,
3373  const fileName& prefix
3374 ) const
3375 {
3376  if (writeFlags & WRITEMESH)
3377  {
3378  write();
3379  }
3380 
3381  if (writeFlags && !(writeFlags & NOWRITEREFINEMENT))
3382  {
3383  meshCutter_.write();
3384 
3385  // Force calculation before writing
3386  (void)surfaceIndex();
3387  surfaceIndex_.write();
3388  }
3389 
3390  if (writeFlags & WRITELEVELS)
3391  {
3392  dumpRefinementLevel();
3393  }
3394 
3395  if ((debugFlags & OBJINTERSECTIONS) && prefix.size())
3396  {
3397  dumpIntersections(prefix);
3398  }
3399 }
3400 
3401 
3403 {
3404  IOobject io
3405  (
3406  "dummy",
3407  mesh.facesInstance(),
3408  mesh.meshSubDir,
3409  mesh
3410  );
3411  fileName setsDir(io.path());
3412 
3413  if (topoSet::debug) DebugVar(setsDir);
3414 
3415  // Remove local files
3416  if (exists(setsDir/"surfaceIndex"))
3417  {
3418  rm(setsDir/"surfaceIndex");
3419  }
3420 
3421  // Remove other files
3423 }
3424 
3425 
3427 {
3428  return writeLevel_;
3429 }
3430 
3431 
3433 {
3434  writeLevel_ = flags;
3435 }
3436 
3437 
3438 //Foam::meshRefinement::outputType Foam::meshRefinement::outputLevel()
3439 //{
3440 // return outputLevel_;
3441 //}
3442 //
3443 //
3444 //void Foam::meshRefinement::outputLevel(const outputType flags)
3445 //{
3446 // outputLevel_ = flags;
3447 //}
3448 
3449 
3452  const dictionary& dict,
3453  const word& keyword,
3454  const bool noExit,
3455  enum keyType::option matchOpt
3456 )
3457 {
3458  const auto finder(dict.csearch(keyword, matchOpt));
3459 
3460  if (!finder.good())
3461  {
3462  auto& err = FatalIOErrorInFunction(dict);
3463 
3464  err << "Entry '" << keyword << "' not found in dictionary "
3465  << dict.name() << nl;
3466 
3467  if (noExit)
3468  {
3469  return dictionary::null;
3470  }
3471  else
3472  {
3473  err << exit(FatalIOError);
3474  }
3475  }
3476 
3477  return finder.dict();
3478 }
3479 
3480 
3483  const dictionary& dict,
3484  const word& keyword,
3485  const bool noExit,
3486  enum keyType::option matchOpt
3487 )
3488 {
3489  const auto finder(dict.csearch(keyword, matchOpt));
3490 
3491  if (!finder.good())
3492  {
3493  auto& err = FatalIOErrorInFunction(dict);
3494 
3495  err << "Entry '" << keyword << "' not found in dictionary "
3496  << dict.name() << nl;
3497 
3498  if (noExit)
3499  {
3500  // Fake entry
3501  return dict.first()->stream();
3502  }
3503  else
3504  {
3505  err << exit(FatalIOError);
3506  }
3507  }
3508 
3509  return finder.ref().stream();
3510 }
3511 
3512 
3513 // ************************************************************************* //
processorPointPatch.H
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::Pair::second
const T & second() const noexcept
Return second element, which is also the last element.
Definition: PairI.H:122
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
volFields.H
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::syncTools::syncEdgeList
static void syncEdgeList(const polyMesh &mesh, List< T > &edgeValues, const CombineOp &cop, const T &nullValue, const TransformOp &top, const FlipOp &fop)
Synchronize values on all mesh edges.
Definition: syncToolsTemplates.C:800
Foam::fvMeshDistribute::countCells
static labelList countCells(const labelList &)
Helper function: count cells per processor in wanted distribution.
Definition: fvMeshDistribute.C:1852
Foam::Random
Random number generator.
Definition: Random.H:59
Foam::maxOp
Definition: ops.H:223
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1069
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
meshTools.H
Foam::scalarList
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:64
Foam::distribution
Accumulating histogram of values. Specified bin resolution automatic generation of bins.
Definition: distribution.H:61
topoDistanceData.H
Foam::treeBoundBox::extend
treeBoundBox extend(Random &rndGen, const scalar s) const
Return slightly wider bounding box.
Definition: treeBoundBoxI.H:325
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:194
Foam::polyMesh::FACE_DIAG_TRIS
Definition: polyMesh.H:107
Foam::pointMesh::boundary
const pointBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: pointMesh.H:109
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::one
static const Vector< scalar > one
Definition: VectorSpace.H:116
Foam::exists
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: MSwindows.C:625
Foam::polyMesh::cellDecomposition
cellDecomposition
Enumeration defining the decomposition of the cell for.
Definition: polyMesh.H:100
Foam::globalPoints
Calculates points shared by more than two processor patches or cyclic patches.
Definition: globalPoints.H:102
Foam::surfaceZonesInfo::faceZoneType
faceZoneType
What to do with faceZone faces.
Definition: surfaceZonesInfo.H:86
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::meshRefinement::dumpIntersections
void dumpIntersections(const fileName &prefix) const
Debug: Write intersection information to OBJ format.
Definition: meshRefinement.C:3301
Foam::accessOp
Definition: UList.H:668
Foam::labelMax
constexpr label labelMax
Definition: label.H:61
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::hexRef8::cellLevel
const labelIOList & cellLevel() const
Definition: hexRef8.H:397
Foam::meshSearch
Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search.
Definition: meshSearch.H:60
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::faceZone::flipMap
const boolList & flipMap() const noexcept
Return face flip map.
Definition: faceZone.H:272
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
Foam::meshRefinement::splitMeshRegions
autoPtr< mapPolyMesh > splitMeshRegions(const labelList &globalToMasterPatch, const labelList &globalToSlavePatch, const pointField &locationsInMesh, const pointField &locationsOutsideMesh, const bool exitIfLeakPath, const writer< scalar > &leakPathFormatter)
Split mesh. Keep part containing point. Return empty map if.
Definition: meshRefinement.C:2760
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
Foam::meshRefinement::findRegion
static label findRegion(const polyMesh &, const labelList &cellRegion, const vector &perturbVec, const point &p)
Find region point is in. Uses optional perturbation to re-test.
Definition: meshRefinement.C:2458
cyclicSlipPointPatchFields.H
Foam::OFstream::name
virtual const fileName & name() const
Read/write access to the name of the stream.
Definition: OSstream.H:107
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:52
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::meshRefinement::intersectedPoints
labelList intersectedPoints() const
Get points on surfaces with intersection and boundary faces.
Definition: meshRefinement.C:1827
Foam::meshRefinement::lookup
static ITstream & lookup(const dictionary &dict, const word &keyword, const bool noExit, enum keyType::option matchOpt=keyType::REGEX)
Wrapper around dictionary::lookup which does not exit.
Definition: meshRefinement.C:3482
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::removeCells
Given list of cells to remove, insert all the topology changes.
Definition: removeCells.H:63
Foam::DynamicList< label >
calculatedPointPatchFields.H
Foam::polyTopoChange::points
const DynamicList< point > & points() const
Points. Shrunk after constructing mesh (or calling of compact())
Definition: polyTopoChange.H:450
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
Definition: gatherScatterList.C:215
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:54
volMesh.H
globalIndex.H
Foam::polyTopoChange::addFace
label addFace(const face &f, const label own, const label nei, const label masterPointID, const label masterEdgeID, const label masterFaceID, const bool flipFaceFlux, const label patchID, const label zoneID, const bool zoneFlip)
Add face to cells. Return new face label.
Definition: polyTopoChange.C:2747
Foam::treeBoundBox
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:86
Foam::meshRefinement::writeLevel
static writeType writeLevel()
Get/set write level.
Definition: meshRefinement.C:3426
Foam::meshRefinement::intersectedFaces
labelList intersectedFaces() const
Get faces with intersection.
Definition: meshRefinement.C:1799
Foam::meshRefinement::printMeshInfo
void printMeshInfo(const bool, const string &) const
Print some mesh stats.
Definition: meshRefinement.C:3175
Foam::meshRefinement::addFaceZone
label addFaceZone(const word &fzName, const word &masterPatch, const word &slavePatch, const surfaceZonesInfo::faceZoneType &fzType)
Add/lookup faceZone and update information. Return index of.
Definition: meshRefinement.C:2390
Foam::polyMesh::meshSubDir
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:321
Foam::polyBoundaryMesh::groupPatchIDs
const HashTable< labelList > & groupPatchIDs() const
The patch indices per patch group.
Definition: polyBoundaryMesh.C:481
motionSmoother.H
polyTopoChange.H
Foam::andEqOp
Definition: ops.H:85
Foam::MeshObject< polyMesh, UpdateableMeshObject, pointMesh >::New
static const pointMesh & New(const polyMesh &mesh, Args &&... args)
Get existing or create a new MeshObject.
Definition: MeshObject.C:48
Foam::polyBoundaryMesh::reorder
void reorder(const labelUList &oldToNew, const bool validBoundary)
Reorders patches. Ordering does not have to be done in.
Definition: polyBoundaryMesh.C:1214
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
localPointRegion.H
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:99
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::meshRefinement::countHits
label countHits() const
Count number of intersections (local)
Definition: meshRefinement.C:1528
Foam::fvPatch::New
static autoPtr< fvPatch > New(const polyPatch &, const fvBoundaryMesh &)
Return a pointer to a new patch created on freestore from polyPatch.
Definition: fvPatchNew.C:35
Foam::meshRefinement::subDict
static const dictionary & subDict(const dictionary &dict, const word &keyword, const bool noExit, enum keyType::option matchOpt=keyType::REGEX)
Wrapper around dictionary::subDict which does not exit.
Definition: meshRefinement.C:3451
Foam::writer::write
virtual void write(const coordSet &, const wordList &, const List< const Field< Type > * > &, Ostream &) const =0
General entry point for writing.
Foam::syncTools::getMasterPoints
static bitSet getMasterPoints(const polyMesh &mesh)
Definition: syncTools.C:68
Foam::polyMesh::facesInstance
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:852
Foam::removeCells::updateMesh
void updateMesh(const mapPolyMesh &)
Force recalculation of locally stored data on topological change.
Definition: removeCells.H:131
Foam::bitSet::set
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:574
Foam::Map< label >
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::syncTools::swapBoundaryFaceList
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues)
Swap coupled boundary face values. Uses eqOp.
Definition: syncTools.H:445
Foam::meshRefinement::splitFacesUndo
label splitFacesUndo(const labelList &splitFaces, const labelPairList &splits, const dictionary &motionDict, labelList &duplicateFace, List< labelPair > &baffles)
Split faces along diagonal. Maintain mesh quality. Return.
Definition: meshRefinement.C:1088
Foam::faceSet
A list of face labels.
Definition: faceSet.H:51
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:150
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:65
Foam::rm
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: MSwindows.C:1004
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:175
Foam::FatalIOError
IOerror FatalIOError
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::motionSmootherAlgo::checkMesh
static bool checkMesh(const bool report, const polyMesh &mesh, const dictionary &dict, labelHashSet &wrongFaces, const bool dryRun=false)
Check mesh with mesh settings in dict. Collects incorrect faces.
Definition: motionSmootherAlgoCheck.C:462
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::PtrList::set
const T * set(const label i) const
Return const pointer to element (can be nullptr),.
Definition: PtrList.H:138
decompositionMethod.H
Foam::mapPolyMesh::preMotionPoints
const pointField & preMotionPoints() const
Pre-motion point positions.
Definition: mapPolyMesh.H:613
Foam::syncTools::getMasterFaces
static bitSet getMasterFaces(const polyMesh &mesh)
Definition: syncTools.C:126
Foam::dictionary::set
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:780
meshBb
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(rndGen, 1e-3))
removeCells.H
refinementFeatures.H
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::hexRef8::removeFiles
static void removeFiles(const polyMesh &)
Helper: remove all relevant files from mesh instance.
Definition: hexRef8.C:5715
Foam::decompositionMethod::setConstraints
void setConstraints(const polyMesh &mesh, boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections) const
Helper: extract constraints:
Definition: decompositionMethod.C:1217
Foam::bitSet::test
bool test(const label pos) const
Test value at specified position, never auto-vivify entries.
Definition: bitSetI.H:520
Foam::dictionary::name
const fileName & name() const noexcept
The dictionary name.
Definition: dictionaryI.H:48
Foam::HashSet< label, Hash< label > >
syncTools.H
Foam::meshRefinement::removeFiles
static void removeFiles(const polyMesh &)
Helper: remove all relevant files from mesh instance.
Definition: meshRefinement.C:3402
Foam::bitSet::count
unsigned int count(const bool on=true) const
Count number of bits set.
Definition: bitSetI.H:499
Foam::meshRefinement::addPatch
static label addPatch(fvMesh &, const word &name, const dictionary &)
Helper:add patch to mesh. Update all registered fields.
Definition: meshRefinement.C:2235
Foam::meshRefinement::doSplitFaces
void doSplitFaces(const labelList &splitFaces, const labelPairList &splits, polyTopoChange &meshMod) const
Split faces into two.
Definition: meshRefinement.C:969
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
Foam::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:61
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::meshRefinement::updateList
static void updateList(const labelList &newToOld, const T &nullValue, List< T > &elems)
Helper: reorder list according to map.
Definition: meshRefinementTemplates.C:38
Foam::polyBoundaryMesh::names
wordList names() const
Return a list of patch names.
Definition: polyBoundaryMesh.C:555
Foam::syncTools::syncPointList
static void syncPointList(const polyMesh &mesh, List< T > &pointValues, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
Definition: syncToolsTemplates.C:721
Foam::removeCells::setRefinement
void setRefinement(const bitSet &removedCell, const labelUList &facesToExpose, const labelUList &patchIDs, polyTopoChange &) const
Play commands into polyTopoChange to remove cells.
Definition: removeCells.C:201
Foam::dictionary::transfer
void transfer(dictionary &dict)
Transfer the contents of the argument and annul the argument.
Definition: dictionary.C:866
Foam::sumOp
Definition: ops.H:213
Foam::primitiveMesh::nPoints
label nPoints() const noexcept
Number of mesh points.
Definition: primitiveMeshI.H:37
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::minEqOp
Definition: ops.H:81
OFstream.H
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::dimensionedVector
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
Definition: dimensionedVector.H:50
Foam::dictionary::null
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
Definition: dictionary.H:392
Foam::polyTopoChange::setCapacity
void setCapacity(const label nPoints, const label nFaces, const label nCells)
Definition: polyTopoChange.C:2449
Foam::meshRefinement::getMasterEdges
static bitSet getMasterEdges(const polyMesh &mesh, const labelList &meshEdges)
Determine master edge for subset of edges. If coupled.
Definition: meshRefinement.C:3140
Foam::fvBoundaryMesh
Foam::fvBoundaryMesh.
Definition: fvBoundaryMesh.H:57
Foam::writer::getFileName
virtual fileName getFileName(const coordSet &, const wordList &) const =0
Generate file name with correct extension.
Foam::meshRefinement::doRemoveCells
autoPtr< mapPolyMesh > doRemoveCells(const labelList &cellsToRemove, const labelList &exposedFaces, const labelList &exposedPatchIDs, removeCells &cellRemover)
Remove cells. Put exposedFaces into exposedPatchIDs.
Definition: meshRefinement.C:909
Foam::labelPair
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:54
Foam::meshRefinement::calculateEdgeWeights
static void calculateEdgeWeights(const polyMesh &mesh, const bitSet &isMasterEdge, const labelList &meshPoints, const edgeList &edges, scalarField &edgeWeights, scalarField &invSumWeight)
Helper: calculate edge weights (1/length)
Definition: meshRefinement.C:2081
Foam::polyMesh::pointsInstance
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:846
searchableSurfaces.H
mapDistributePolyMesh.H
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::syncTools::syncFaceList
static void syncFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop)
Synchronize values on all mesh faces.
Definition: syncTools.H:396
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::shellSurfaces
Encapsulates queries for volume refinement ('refine all cells within shell').
Definition: shellSurfaces.H:57
Foam::meshRefinement::timeName
word timeName() const
Definition: meshRefinement.C:3228
Foam::Field< vector >
Foam::polyPatch::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:315
Foam::polyTopoChange::faces
const DynamicList< face > & faces() const
Definition: polyTopoChange.H:455
Foam::meshRefinement::checkCoupledFaceZones
static void checkCoupledFaceZones(const polyMesh &)
Helper function: check that face zones are synced.
Definition: meshRefinement.C:1993
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:52
Foam::faceZone
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:64
treeBoundBox.H
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
refinementSurfaces.H
Foam::meshRefinement::surfaceIndex
const labelList & surfaceIndex() const
Per start-end edge the index of the surface hit.
Definition: meshRefinement.C:1505
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::meshRefinement::appendPatch
static label appendPatch(fvMesh &, const label insertPatchi, const word &, const dictionary &)
Helper:append patch to end of mesh.
Definition: meshRefinement.C:2137
Foam::meshRefinement::findRegions
static label findRegions(const polyMesh &, const vector &perturbVec, const pointField &locationsInMesh, const pointField &locationsOutsideMesh, const bool exitIfLeakPath, const writer< scalar > &leakPathFormatter, const label nRegions, labelList &cellRegion, const boolList &blockedFace)
Find regions points are in.
Definition: meshRefinement.C:2495
Foam::searchableSurface
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Definition: searchableSurface.H:69
Foam::meshRefinement::meshedPatches
labelList meshedPatches() const
Get patchIDs for patches added in addMeshedPatch.
Definition: meshRefinement.C:2363
Foam::polyTopoChange::modifyFace
void modifyFace(const face &f, const label facei, const label own, const label nei, const bool flipFaceFlux, const label patchID, const label zoneID, const bool zoneFlip)
Modify vertices or cell of face.
Definition: polyTopoChange.C:2811
faceSet.H
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:456
findCellMode
static const Foam::polyMesh::cellDecomposition findCellMode(Foam::polyMesh::FACE_DIAG_TRIS)
regionSplit.H
Foam::dictionary::csearch
const_searcher csearch(const word &keyword, enum keyType::option=keyType::REGEX) const
Search dictionary for given keyword.
Definition: dictionarySearch.C:265
Foam::IndirectList
A List with indirect addressing.
Definition: IndirectList.H:56
Foam::IOstream::opened
bool opened() const noexcept
True if stream has been opened.
Definition: IOstream.H:221
Foam::PtrList::setSize
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:151
Foam::primitiveMesh::nBoundaryFaces
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces)
Definition: primitiveMeshI.H:84
Foam::ZoneMesh< faceZone, polyMesh >
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:486
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:42
Foam::polyBoundaryMesh::whichPatch
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Definition: polyBoundaryMesh.C:812
Foam::regionSplit
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
Definition: regionSplit.H:140
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
Foam::regionSplit::nRegions
label nRegions() const
Return total number of regions.
Definition: regionSplit.H:294
slipPointPatchFields.H
Foam::functionObject::outputPrefix
static word outputPrefix
Directory prefix.
Definition: functionObject.H:376
Foam::polyBoundaryMesh::findPatchID
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
Definition: polyBoundaryMesh.C:765
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
fld
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputLagrangian.H:23
Foam::polyPatch::constraintType
static bool constraintType(const word &pt)
Return true if the given type is a constraint type.
Definition: polyPatch.C:277
Foam::syncTools::swapBoundaryFacePositions
static void swapBoundaryFacePositions(const polyMesh &mesh, UList< point > &positions)
Swap coupled positions. Uses eqOp.
Definition: syncTools.H:461
Foam::meshRefinement::distribute
void distribute(const mapDistributePolyMesh &)
Update local numbering for mesh redistribution.
Definition: meshRefinement.C:2867
Foam::polyTopoChange::changeMesh
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, const labelUList &patchMap, const bool inflate, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
Definition: polyTopoChange.C:2980
indirectPrimitivePatch.H
Foam::maxMagSqrEqOp
Definition: ops.H:83
timeName
word timeName
Definition: getTimeIndex.H:3
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::meshRefinement::writeTypeNames
static const Enum< writeType > writeTypeNames
Definition: meshRefinement.H:121
Foam::shortestPathSet
Finds shortest path (in terms of cell centres) to walk on mesh from any point in insidePoints to any ...
Definition: shortestPathSet.H:115
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::eqOp
Definition: ops.H:71
surfaceMesh.H
Foam::globalMeshData
Various mesh related information for a parallel run. Upon construction, constructs all info using par...
Definition: globalMeshData.H:107
Foam::polyPatch::New
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return pointer to a new patch created on freestore from components.
Definition: polyPatchNew.C:35
Foam::meshRefinement::makePatch
static autoPtr< indirectPrimitivePatch > makePatch(const polyMesh &, const labelList &)
Create patch from set of patches.
Definition: meshRefinement.C:1898
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
meshRefinement.H
Foam::decompositionMethod
Abstract base class for domain decomposition.
Definition: decompositionMethod.H:51
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::writer< scalar >
Foam::localPointRegion::findDuplicateFaces
static labelList findDuplicateFaces(const primitiveMesh &, const labelList &)
Helper routine to find baffles (two boundary faces using the.
Definition: localPointRegion.C:544
Foam::coordSet
Holds list of sampling positions.
Definition: coordSet.H:53
Foam::mapDistributePolyMesh::distributeFaceData
void distributeFaceData(List< T > &lst) const
Distribute list of face data.
Definition: mapDistributePolyMesh.H:249
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
Foam::calculatedFvPatchField
This boundary condition is not designed to be evaluated; it is assmued that the value is assigned via...
Definition: calculatedFvPatchField.H:66
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::pointMesh
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:51
Foam::faceZone::whichFace
label whichFace(const label globalCellID) const
Helper function to re-direct to zone::localID(...)
Definition: faceZone.C:372
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::meshRefinement::updateMesh
void updateMesh(const mapPolyMesh &, const labelList &changedFaces)
Update for external change to mesh. changedFaces are in new mesh.
Definition: meshRefinement.C:2929
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:361
Foam::polyTopoChange::removeFace
void removeFace(const label facei, const label mergeFacei)
Remove/merge face.
Definition: polyTopoChange.C:2848
Foam::meshRefinement::balance
autoPtr< mapDistributePolyMesh > balance(const bool keepZoneFaces, const bool keepBaffles, const scalarField &cellWeights, decompositionMethod &decomposer, fvMeshDistribute &distributor)
Redecompose according to cell count.
Definition: meshRefinement.C:1549
Foam::maxEqOp
Definition: ops.H:80
fixedValuePointPatchFields.H
Random.H
Foam::ZoneMesh::names
wordList names() const
A list of the zone names.
Definition: ZoneMesh.C:305
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::meshRefinement::setInstance
void setInstance(const fileName &)
Set instance of all local IOobjects.
Definition: meshRefinement.C:901
Foam::pointBoundaryMesh
Foam::pointBoundaryMesh.
Definition: pointBoundaryMesh.H:56
Foam::mapPolyMesh::reverseFaceMap
const labelList & reverseFaceMap() const
Reverse face map.
Definition: mapPolyMesh.H:501
Foam::normalised
VectorSpace< Form, Cmpt, Ncmpts > normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:487
Foam::meshRefinement::selectSeparatedCoupledFaces
void selectSeparatedCoupledFaces(boolList &) const
Select coupled faces that are not collocated.
Definition: meshRefinement.C:2442
Foam::Pstream::listCombineGather
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
Definition: combineGatherScatter.C:290
Foam::fvMesh::boundary
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:685
Foam::IOobject::name
const word & name() const noexcept
Return name.
Definition: IOobjectI.H:65
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::polyMesh::findCell
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition: polyMesh.C:1507
Foam::renumber
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:37
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:84
shortestPathSet.H
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:52
Foam::decompositionMethod::decompose
virtual labelList decompose(const pointField &points, const scalarField &pointWeights) const
Return the wanted processor number for every coordinate.
Definition: decompositionMethod.C:1325
fvMeshDistribute.H
meshSearch.H
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:463
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Pair< label >
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::coordSet::coordFormatNames
static const Enum< coordFormat > coordFormatNames
String representation of coordFormat enum.
Definition: coordSet.H:72
Foam::zoneIdentifier::name
const word & name() const noexcept
The zone name.
Definition: zoneIdentifier.H:123
fvMeshTools.H
Foam::refinementFeatures
Encapsulates queries for features.
Definition: refinementFeatures.H:53
f
labelList f(nPoints)
Foam::mapPolyMesh::reversePointMap
const labelList & reversePointMap() const
Reverse point map.
Definition: mapPolyMesh.H:469
Foam::Vector< scalar >
Foam::meshRefinement::writeType
writeType
Enumeration for what to write. Used as a bit-pattern.
Definition: meshRefinement.H:112
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const noexcept
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List< label >
Foam::coordSet::coordFormat::DISTANCE
Foam::searchableSurfaces
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
Definition: searchableSurfaces.H:92
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::PackedList::size
label size() const noexcept
Number of entries.
Definition: PackedListI.H:377
Foam::meshRefinement::checkData
void checkData()
Debugging: check that all faces still obey start()>end()
Definition: meshRefinement.C:694
Foam::meshRefinement
Helper class which maintains intersections of (changing) mesh with (static) surfaces.
Definition: meshRefinement.H:85
FaceCellWave.H
Foam::UList< label >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::meshRefinement::write
bool write() const
Write mesh and all data.
Definition: meshRefinement.C:3068
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::tmp::New
static tmp< T > New(Args &&... args)
Construct tmp of T with forwarding arguments.
Foam::meshRefinement::addMeshedPatch
label addMeshedPatch(const word &name, const dictionary &)
Add patch originating from meshing. Update meshedPatches_.
Definition: meshRefinement.C:2313
Foam::meshRefinement::storeData
void storeData(const labelList &pointsToStore, const labelList &facesToStore, const labelList &cellsToStore)
Signal points/face/cells for which to store data.
Definition: meshRefinement.C:2941
Foam::fvMeshDistribute::distribute
autoPtr< mapDistributePolyMesh > distribute(const labelList &dist)
Send cells to neighbours according to distribution.
Definition: fvMeshDistribute.C:1876
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::mapPolyMesh::faceMap
const labelList & faceMap() const
Old face map.
Definition: mapPolyMesh.H:410
Foam::meshRefinement::testSyncPointList
static void testSyncPointList(const string &msg, const polyMesh &mesh, const List< scalar > &fld)
Definition: meshRefinement.C:601
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:36
Foam::autoPtr::clear
void clear() noexcept
Same as reset(nullptr)
Definition: autoPtr.H:176
split
static bool split(const std::string &line, std::string &key, std::string &val)
Definition: cpuInfo.C:39
Foam::mapPolyMesh
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:161
Foam::mapPolyMesh::hasMotionPoints
bool hasMotionPoints() const
Has valid preMotionPoints?
Definition: mapPolyMesh.H:619
Foam::TimePaths::globalPath
fileName globalPath() const
Return global path for the case.
Definition: TimePathsI.H:80
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::fileName::clean
static bool clean(std::string &str)
Definition: fileName.C:199
rndGen
Random rndGen
Definition: createFields.H:23
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:280
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::zero
static const Vector< scalar > zero
Definition: VectorSpace.H:115
Foam::UIndirectList
A List with indirect addressing.
Definition: faMatrix.H:60
Foam::globalMeshData::nTotalCells
label nTotalCells() const noexcept
Return total number of cells in decomposed mesh.
Definition: globalMeshData.H:371
Foam::Field< vector >::subField
SubField< vector > subField
Declare type of subField.
Definition: Field.H:89
Foam::primitiveMesh::nFaces
label nFaces() const noexcept
Number of mesh faces.
Definition: primitiveMeshI.H:90
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:473
Foam::meshRefinement::updateIntersections
void updateIntersections(const labelList &changedFaces)
Find any intersection of surface. Store in surfaceIndex_.
Definition: meshRefinement.C:298
Foam::plusEqOp
Definition: ops.H:72
Foam::sortedOrder
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
coupled
bool coupled(solutionDict.getOrDefault("coupledEnergyField", false))
Foam::pointList
List< point > pointList
A List of points.
Definition: pointList.H:64
Foam::hexRef8::faceLevel
label faceLevel(const label facei) const
Gets level such that the face has four points <= level.
Definition: hexRef8.C:799
Foam::mapDistributePolyMesh
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Definition: mapDistributePolyMesh.H:66
Foam::Pstream::listCombineScatter
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Definition: combineGatherScatter.C:432
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
Foam::meshRefinement::debugTypeNames
static const Enum< debugType > debugTypeNames
Definition: meshRefinement.H:101
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:188
Foam::minMagSqrEqOp
Definition: ops.H:82
Foam::refinementSurfaces
Container for data on surfaces used for surface-driven refinement. Contains all the data about the le...
Definition: refinementSurfaces.H:63
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
DebugVar
#define DebugVar(var)
Report a variable name and value.
Definition: messageStream.H:404
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
zeroGradientFvPatchFields.H
Foam::meshRefinement::makeDisplacementField
static tmp< pointVectorField > makeDisplacementField(const pointMesh &pMesh, const labelList &adaptPatchIDs)
Helper function to make a pointVectorField with correct.
Definition: meshRefinement.C:1940
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::syncTools::syncBoundaryFacePositions
static void syncBoundaryFacePositions(const polyMesh &mesh, UList< point > &positions, const CombineOp &cop)
Synchronize locations on boundary faces only.
Definition: syncTools.H:378
Foam::fvMeshDistribute
Sends/receives parts of mesh+fvfields to neighbouring processors. Used in load balancing.
Definition: fvMeshDistribute.H:70
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:55
pointFields.H
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:592
pointMesh.H
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:445
Foam::meshRefinement::getMasterPoints
static bitSet getMasterPoints(const polyMesh &mesh, const labelList &meshPoints)
Determine master point for subset of points. If coupled.
Definition: meshRefinement.C:3104
Foam::meshRefinement::getFaceZoneInfo
bool getFaceZoneInfo(const word &fzName, label &masterPatchID, label &slavePatchID, surfaceZonesInfo::faceZoneType &fzType) const
Lookup faceZone information. Return false if no information.
Definition: meshRefinement.C:2414
Foam::localPointRegion::findDuplicateFacePairs
static labelPairList findDuplicateFacePairs(const polyMesh &)
Helper routine to find all baffles (two boundary faces.
Definition: localPointRegion.C:625
Foam::dimless
const dimensionSet dimless
Dimensionless.
Definition: dimensionSets.C:189
Foam::keyType::option
option
Enumeration for the data type and search/match modes (bitmask)
Definition: keyType.H:78
Foam::fvMesh::clearOut
void clearOut()
Clear all geometry and addressing.
Definition: fvMesh.C:239
Foam::removeCells::getExposedFaces
labelList getExposedFaces(const bitSet &removedCell) const
Get labels of faces exposed after cells removal.
Definition: removeCells.C:97
Foam::meshRefinement::dumpRefinementLevel
void dumpRefinementLevel() const
Write refinement level as volScalarFields for postprocessing.
Definition: meshRefinement.C:3239
Foam::meshRefinement::debugType
debugType
Enumeration for what to debug. Used as a bit-pattern.
Definition: meshRefinement.H:92
Foam::surfaceZonesInfo::addFaceZone
static label addFaceZone(const word &name, const labelList &addressing, const boolList &flipMap, polyMesh &mesh)
Definition: surfaceZonesInfo.C:510
Foam::polyMesh::tetBasePtIs
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:892