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