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