splitMeshRegions.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  splitMeshRegions
29 
30 Group
31  grpMeshManipulationUtilities
32 
33 Description
34  Splits mesh into multiple regions.
35 
36  Each region is defined as a domain whose cells can all be reached by
37  cell-face-cell walking without crossing
38  - boundary faces
39  - additional faces from faceset (-blockedFaces faceSet).
40  - any face between differing cellZones (-cellZones)
41 
42  Output is:
43  - volScalarField with regions as different scalars (-detectOnly)
44  or
45  - mesh with multiple regions and mapped patches. These patches
46  either cover the whole interface between two region (default) or
47  only part according to faceZones (-useFaceZones)
48  or
49  - mesh with cells put into cellZones (-makeCellZones)
50 
51  Note:
52  - cellZonesOnly does not do a walk and uses the cellZones only. Use
53  this if you don't mind having disconnected domains in a single region.
54  This option requires all cells to be in one (and one only) cellZone.
55 
56  - cellZonesFileOnly behaves like -cellZonesOnly but reads the cellZones
57  from the specified file. This allows one to explicitly specify the region
58  distribution and still have multiple cellZones per region.
59 
60  - prefixRegion prefixes all normal patches with region name (interface
61  (patches already have region name prefix)
62 
63  - Should work in parallel.
64  cellZones can differ on either side of processor boundaries in which case
65  the faces get moved from processor patch to directMapped patch. Not
66  the faces get moved from processor patch to mapped patch. Not
67  very well tested.
68 
69  - If a cell zone gets split into more than one region it can detect
70  the largest matching region (-sloppyCellZones). This will accept any
71  region that covers more than 50% of the zone. It has to be a subset
72  so cannot have any cells in any other zone.
73 
74  - If explicitly a single region has been selected (-largestOnly or
75  -insidePoint) its region name will be either
76  - name of a cellZone it matches to or
77  - "largestOnly" respectively "insidePoint" or
78  - polyMesh::defaultRegion if additionally -overwrite
79  (so it will overwrite the input mesh!)
80 
81  - writes maps like decomposePar back to original mesh:
82  - pointRegionAddressing : for every point in this region the point in
83  the original mesh
84  - cellRegionAddressing : ,, cell ,, cell ,,
85  - faceRegionAddressing : ,, face ,, face in
86  the original mesh + 'turning index'. For a face in the same orientation
87  this is the original facelabel+1, for a turned face this is -facelabel-1
88  - boundaryRegionAddressing : for every patch in this region the
89  patch in the original mesh (or -1 if added patch)
90 
91 \*---------------------------------------------------------------------------*/
92 
93 #include "SortableList.H"
94 #include "argList.H"
95 #include "regionSplit.H"
96 #include "fvMeshSubset.H"
97 #include "IOobjectList.H"
98 #include "volFields.H"
99 #include "faceSet.H"
100 #include "cellSet.H"
101 #include "polyTopoChange.H"
102 #include "removeCells.H"
103 #include "edgeHashes.H"
104 #include "syncTools.H"
105 #include "ReadFields.H"
106 #include "mappedWallPolyPatch.H"
107 #include "fvMeshTools.H"
109 #include "processorMeshes.H"
110 
111 using namespace Foam;
112 
113 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
114 
115 // Prepend prefix to selected patches.
116 void renamePatches
117 (
118  fvMesh& mesh,
119  const word& prefix,
120  const labelList& patchesToRename
121 )
122 {
123  polyBoundaryMesh& polyPatches =
124  const_cast<polyBoundaryMesh&>(mesh.boundaryMesh());
125  forAll(patchesToRename, i)
126  {
127  label patchi = patchesToRename[i];
128  polyPatch& pp = polyPatches[patchi];
129 
130  if (isA<coupledPolyPatch>(pp))
131  {
133  << "Encountered coupled patch " << pp.name()
134  << ". Will only rename the patch itself,"
135  << " not any referred patches."
136  << " This might have to be done by hand."
137  << endl;
138  }
139 
140  pp.name() = prefix + '_' + pp.name();
141  }
142  // Recalculate any demand driven data (e.g. group to name lookup)
143  polyPatches.updateMesh();
144 }
145 
146 
147 template<class GeoField>
148 void subsetVolFields
149 (
150  const fvMesh& mesh,
151  const fvMesh& subMesh,
152  const labelList& cellMap,
153  const labelList& faceMap,
154  const labelHashSet& addedPatches
155 )
156 {
157  const labelList patchMap(identity(mesh.boundaryMesh().size()));
158 
160  (
161  mesh.objectRegistry::lookupClass<GeoField>()
162  );
163  forAllConstIters(fields, iter)
164  {
165  const GeoField& fld = *iter.val();
166 
167  Info<< "Mapping field " << fld.name() << endl;
168 
169  tmp<GeoField> tSubFld
170  (
172  (
173  fld,
174  subMesh,
175  patchMap,
176  cellMap,
177  faceMap
178  )
179  );
180 
181  // Hack: set value to 0 for introduced patches (since don't
182  // get initialised.
183  forAll(tSubFld().boundaryField(), patchi)
184  {
185  if (addedPatches.found(patchi))
186  {
187  tSubFld.ref().boundaryFieldRef()[patchi] ==
188  typename GeoField::value_type(Zero);
189  }
190  }
191 
192  // Store on subMesh
193  GeoField* subFld = tSubFld.ptr();
194  subFld->rename(fld.name());
195  subFld->writeOpt() = IOobject::AUTO_WRITE;
196  subFld->store();
197  }
198 }
199 
200 
201 template<class GeoField>
202 void subsetSurfaceFields
203 (
204  const fvMesh& mesh,
205  const fvMesh& subMesh,
206  const labelList& cellMap,
207  const labelList& faceMap,
208  const labelHashSet& addedPatches
209 )
210 {
211  const labelList patchMap(identity(mesh.boundaryMesh().size()));
212 
214  (
215  mesh.objectRegistry::lookupClass<GeoField>()
216  );
217  forAllConstIters(fields, iter)
218  {
219  const GeoField& fld = *iter.val();
220 
221  Info<< "Mapping field " << fld.name() << endl;
222 
223  tmp<GeoField> tSubFld
224  (
226  (
227  fld,
228  subMesh,
229  patchMap,
230  cellMap,
231  faceMap
232  )
233  );
234 
235  // Hack: set value to 0 for introduced patches (since don't
236  // get initialised.
237  forAll(tSubFld().boundaryField(), patchi)
238  {
239  if (addedPatches.found(patchi))
240  {
241  tSubFld.ref().boundaryFieldRef()[patchi] ==
242  typename GeoField::value_type(Zero);
243  }
244  }
245 
246  // Store on subMesh
247  GeoField* subFld = tSubFld.ptr();
248  subFld->rename(fld.name());
249  subFld->writeOpt() = IOobject::AUTO_WRITE;
250  subFld->store();
251  }
252 }
253 
254 // Select all cells not in the region
255 labelList getNonRegionCells(const labelList& cellRegion, const label regionI)
256 {
257  DynamicList<label> nonRegionCells(cellRegion.size());
258  forAll(cellRegion, celli)
259  {
260  if (cellRegion[celli] != regionI)
261  {
262  nonRegionCells.append(celli);
263  }
264  }
265  return nonRegionCells.shrink();
266 }
267 
268 
269 void addToInterface
270 (
271  const polyMesh& mesh,
272  const label zoneID,
273  const label ownRegion,
274  const label neiRegion,
275  EdgeMap<Map<label>>& regionsToSize
276 )
277 {
279  (
280  min(ownRegion, neiRegion),
281  max(ownRegion, neiRegion)
282  );
283 
284  auto iter = regionsToSize.find(interface);
285 
286  if (iter.found())
287  {
288  // Check if zone present
289  auto zoneIter = iter().find(zoneID);
290  if (zoneIter.found())
291  {
292  // Found zone. Increment count.
293  ++(*zoneIter);
294  }
295  else
296  {
297  // New or no zone. Insert with count 1.
298  iter().insert(zoneID, 1);
299  }
300  }
301  else
302  {
303  // Create new interface of size 1.
304  Map<label> zoneToSize;
305  zoneToSize.insert(zoneID, 1);
306  regionsToSize.insert(interface, zoneToSize);
307  }
308 }
309 
310 
311 // Get region-region interface name and sizes.
312 // Returns interfaces as straight list for looping in identical order.
313 void getInterfaceSizes
314 (
315  const polyMesh& mesh,
316  const bool useFaceZones,
317  const labelList& cellRegion,
318  const wordList& regionNames,
319 
320  edgeList& interfaces,
321  List<Pair<word>>& interfaceNames,
322  labelList& interfaceSizes,
323  labelList& faceToInterface
324 )
325 {
326  // From region-region to faceZone (or -1) to number of faces.
327 
328  EdgeMap<Map<label>> regionsToSize;
329 
330 
331  // Internal faces
332  // ~~~~~~~~~~~~~~
333 
334  forAll(mesh.faceNeighbour(), facei)
335  {
336  label ownRegion = cellRegion[mesh.faceOwner()[facei]];
337  label neiRegion = cellRegion[mesh.faceNeighbour()[facei]];
338 
339  if (ownRegion != neiRegion)
340  {
341  addToInterface
342  (
343  mesh,
344  (useFaceZones ? mesh.faceZones().whichZone(facei) : -1),
345  ownRegion,
346  neiRegion,
347  regionsToSize
348  );
349  }
350  }
351 
352  // Boundary faces
353  // ~~~~~~~~~~~~~~
354 
355  // Neighbour cellRegion.
356  labelList coupledRegion(mesh.nBoundaryFaces());
357 
358  forAll(coupledRegion, i)
359  {
360  label celli = mesh.faceOwner()[i+mesh.nInternalFaces()];
361  coupledRegion[i] = cellRegion[celli];
362  }
363  syncTools::swapBoundaryFaceList(mesh, coupledRegion);
364 
365  forAll(coupledRegion, i)
366  {
367  label facei = i+mesh.nInternalFaces();
368  label ownRegion = cellRegion[mesh.faceOwner()[facei]];
369  label neiRegion = coupledRegion[i];
370 
371  if (ownRegion != neiRegion)
372  {
373  addToInterface
374  (
375  mesh,
376  (useFaceZones ? mesh.faceZones().whichZone(facei) : -1),
377  ownRegion,
378  neiRegion,
379  regionsToSize
380  );
381  }
382  }
383 
384 
385  if (Pstream::parRun())
386  {
387  if (Pstream::master())
388  {
389  // Receive and add to my sizes
390  for
391  (
392  int slave=Pstream::firstSlave();
393  slave<=Pstream::lastSlave();
394  slave++
395  )
396  {
397  IPstream fromSlave(Pstream::commsTypes::blocking, slave);
398 
399  EdgeMap<Map<label>> slaveSizes(fromSlave);
400 
401  forAllConstIters(slaveSizes, slaveIter)
402  {
403  const Map<label>& slaveInfo = *slaveIter;
404 
405  auto masterIter = regionsToSize.find(slaveIter.key());
406 
407  if (masterIter.found())
408  {
409  // Same inter-region
410  Map<label>& masterInfo = *masterIter;
411 
412  forAllConstIters(slaveInfo, iter)
413  {
414  const label zoneID = iter.key();
415  const label slaveSize = iter.val();
416 
417  auto zoneIter = masterInfo.find(zoneID);
418  if (zoneIter.found())
419  {
420  *zoneIter += slaveSize;
421  }
422  else
423  {
424  masterInfo.insert(zoneID, slaveSize);
425  }
426  }
427  }
428  else
429  {
430  regionsToSize.insert(slaveIter.key(), slaveInfo);
431  }
432  }
433  }
434  }
435  else
436  {
437  // Send to master
438  {
439  OPstream toMaster
440  (
443  );
444  toMaster << regionsToSize;
445  }
446  }
447  }
448 
449  // Rework
450 
451  Pstream::scatter(regionsToSize);
452 
453 
454 
455  // Now we have the global sizes of all inter-regions.
456  // Invert this on master and distribute.
457  label nInterfaces = 0;
458  forAllConstIters(regionsToSize, iter)
459  {
460  const Map<label>& info = iter.val();
461  nInterfaces += info.size();
462  }
463 
464  interfaces.setSize(nInterfaces);
465  interfaceNames.setSize(nInterfaces);
466  interfaceSizes.setSize(nInterfaces);
467  EdgeMap<Map<label>> regionsToInterface(nInterfaces);
468 
469  nInterfaces = 0;
470  forAllConstIters(regionsToSize, iter)
471  {
472  const edge& e = iter.key();
473  const Map<label>& info = iter.val();
474 
475  const word& name0 = regionNames[e[0]];
476  const word& name1 = regionNames[e[1]];
477 
478  forAllConstIters(info, infoIter)
479  {
480  interfaces[nInterfaces] = iter.key();
481  label zoneID = infoIter.key();
482  if (zoneID == -1)
483  {
484  interfaceNames[nInterfaces] = Pair<word>
485  (
486  name0 + "_to_" + name1,
487  name1 + "_to_" + name0
488  );
489  }
490  else
491  {
492  const word& zoneName = mesh.faceZones()[zoneID].name();
493  interfaceNames[nInterfaces] = Pair<word>
494  (
495  zoneName + "_" + name0 + "_to_" + name1,
496  zoneName + "_" + name1 + "_to_" + name0
497  );
498  }
499  interfaceSizes[nInterfaces] = infoIter();
500 
501  if (regionsToInterface.found(e))
502  {
503  regionsToInterface[e].insert(zoneID, nInterfaces);
504  }
505  else
506  {
507  Map<label> zoneAndInterface;
508  zoneAndInterface.insert(zoneID, nInterfaces);
509  regionsToInterface.insert(e, zoneAndInterface);
510  }
511  nInterfaces++;
512  }
513  }
514 
515 
516  // Now all processor have consistent interface information
517 
518  Pstream::scatter(interfaces);
519  Pstream::scatter(interfaceNames);
520  Pstream::scatter(interfaceSizes);
521  Pstream::scatter(regionsToInterface);
522 
523  // Mark all inter-region faces.
524  faceToInterface.setSize(mesh.nFaces(), -1);
525 
526  forAll(mesh.faceNeighbour(), facei)
527  {
528  label ownRegion = cellRegion[mesh.faceOwner()[facei]];
529  label neiRegion = cellRegion[mesh.faceNeighbour()[facei]];
530 
531  if (ownRegion != neiRegion)
532  {
533  label zoneID = -1;
534  if (useFaceZones)
535  {
536  zoneID = mesh.faceZones().whichZone(facei);
537  }
538 
540  (
541  min(ownRegion, neiRegion),
542  max(ownRegion, neiRegion)
543  );
544 
545  faceToInterface[facei] = regionsToInterface[interface][zoneID];
546  }
547  }
548  forAll(coupledRegion, i)
549  {
550  label facei = i+mesh.nInternalFaces();
551  label ownRegion = cellRegion[mesh.faceOwner()[facei]];
552  label neiRegion = coupledRegion[i];
553 
554  if (ownRegion != neiRegion)
555  {
556  label zoneID = -1;
557  if (useFaceZones)
558  {
559  zoneID = mesh.faceZones().whichZone(facei);
560  }
561 
563  (
564  min(ownRegion, neiRegion),
565  max(ownRegion, neiRegion)
566  );
567 
568  faceToInterface[facei] = regionsToInterface[interface][zoneID];
569  }
570  }
571 }
572 
573 
574 // Create mesh for region.
575 autoPtr<mapPolyMesh> createRegionMesh
576 (
577  const fvMesh& mesh,
578  // Region info
579  const labelList& cellRegion,
580  const label regionI,
581  const word& regionName,
582  // Interface info
583  const labelList& interfacePatches,
584  const labelList& faceToInterface,
585 
586  autoPtr<fvMesh>& newMesh
587 )
588 {
589  // Create dummy system/fv*
591 
592  // Neighbour cellRegion.
593  labelList coupledRegion(mesh.nBoundaryFaces());
594 
595  forAll(coupledRegion, i)
596  {
597  label celli = mesh.faceOwner()[i+mesh.nInternalFaces()];
598  coupledRegion[i] = cellRegion[celli];
599  }
600  syncTools::swapBoundaryFaceList(mesh, coupledRegion);
601 
602 
603  // Topology change container. Start off from existing mesh.
604  polyTopoChange meshMod(mesh);
605 
606  // Cell remover engine
607  removeCells cellRemover(mesh);
608 
609  // Select all but region cells
610  labelList cellsToRemove(getNonRegionCells(cellRegion, regionI));
611 
612  // Find out which faces will get exposed. Note that this
613  // gets faces in mesh face order. So both regions will get same
614  // face in same order (important!)
615  labelList exposedFaces = cellRemover.getExposedFaces(cellsToRemove);
616 
617  labelList exposedPatchIDs(exposedFaces.size());
618  forAll(exposedFaces, i)
619  {
620  label facei = exposedFaces[i];
621  label interfacei = faceToInterface[facei];
622 
623  label ownRegion = cellRegion[mesh.faceOwner()[facei]];
624  label neiRegion = -1;
625 
626  if (mesh.isInternalFace(facei))
627  {
628  neiRegion = cellRegion[mesh.faceNeighbour()[facei]];
629  }
630  else
631  {
632  neiRegion = coupledRegion[facei-mesh.nInternalFaces()];
633  }
634 
635 
636  // Check which side is being kept - determines which of the two
637  // patches will be used.
638 
639  label otherRegion = -1;
640 
641  if (ownRegion == regionI && neiRegion != regionI)
642  {
643  otherRegion = neiRegion;
644  }
645  else if (ownRegion != regionI && neiRegion == regionI)
646  {
647  otherRegion = ownRegion;
648  }
649  else
650  {
652  << "Exposed face:" << facei
653  << " fc:" << mesh.faceCentres()[facei]
654  << " has owner region " << ownRegion
655  << " and neighbour region " << neiRegion
656  << " when handling region:" << regionI
657  << exit(FatalError);
658  }
659 
660  // Find the patch.
661  if (regionI < otherRegion)
662  {
663  exposedPatchIDs[i] = interfacePatches[interfacei];
664  }
665  else
666  {
667  exposedPatchIDs[i] = interfacePatches[interfacei]+1;
668  }
669  }
670 
671  // Remove faces
672  cellRemover.setRefinement
673  (
674  cellsToRemove,
675  exposedFaces,
676  exposedPatchIDs,
677  meshMod
678  );
679 
680  autoPtr<mapPolyMesh> map = meshMod.makeMesh
681  (
682  newMesh,
683  IOobject
684  (
685  regionName,
686  mesh.time().timeName(),
687  mesh.time(),
690  ),
691  mesh
692  );
693 
694  return map;
695 }
696 
697 
698 void createAndWriteRegion
699 (
700  const fvMesh& mesh,
701  const labelList& cellRegion,
702  const wordList& regionNames,
703  const bool prefixRegion,
704  const labelList& faceToInterface,
705  const labelList& interfacePatches,
706  const label regionI,
707  const word& newMeshInstance
708 )
709 {
710  Info<< "Creating mesh for region " << regionI
711  << ' ' << regionNames[regionI] << endl;
712 
713  autoPtr<fvMesh> newMesh;
714  autoPtr<mapPolyMesh> map = createRegionMesh
715  (
716  mesh,
717  cellRegion,
718  regionI,
719  regionNames[regionI],
720  interfacePatches,
721  faceToInterface,
722  newMesh
723  );
724 
725 
726  // Make map of all added patches
727  labelHashSet addedPatches(2*interfacePatches.size());
728  forAll(interfacePatches, interfacei)
729  {
730  addedPatches.insert(interfacePatches[interfacei]);
731  addedPatches.insert(interfacePatches[interfacei]+1);
732  }
733 
734 
735  Info<< "Mapping fields" << endl;
736 
737  // Map existing fields
738  newMesh().updateMesh(map());
739 
740  // Add subsetted fields
741  subsetVolFields<volScalarField>
742  (
743  mesh,
744  newMesh(),
745  map().cellMap(),
746  map().faceMap(),
747  addedPatches
748  );
749  subsetVolFields<volVectorField>
750  (
751  mesh,
752  newMesh(),
753  map().cellMap(),
754  map().faceMap(),
755  addedPatches
756  );
757  subsetVolFields<volSphericalTensorField>
758  (
759  mesh,
760  newMesh(),
761  map().cellMap(),
762  map().faceMap(),
763  addedPatches
764  );
765  subsetVolFields<volSymmTensorField>
766  (
767  mesh,
768  newMesh(),
769  map().cellMap(),
770  map().faceMap(),
771  addedPatches
772  );
773  subsetVolFields<volTensorField>
774  (
775  mesh,
776  newMesh(),
777  map().cellMap(),
778  map().faceMap(),
779  addedPatches
780  );
781 
782  subsetSurfaceFields<surfaceScalarField>
783  (
784  mesh,
785  newMesh(),
786  map().cellMap(),
787  map().faceMap(),
788  addedPatches
789  );
790  subsetSurfaceFields<surfaceVectorField>
791  (
792  mesh,
793  newMesh(),
794  map().cellMap(),
795  map().faceMap(),
796  addedPatches
797  );
798  subsetSurfaceFields<surfaceSphericalTensorField>
799  (
800  mesh,
801  newMesh(),
802  map().cellMap(),
803  map().faceMap(),
804  addedPatches
805  );
806  subsetSurfaceFields<surfaceSymmTensorField>
807  (
808  mesh,
809  newMesh(),
810  map().cellMap(),
811  map().faceMap(),
812  addedPatches
813  );
814  subsetSurfaceFields<surfaceTensorField>
815  (
816  mesh,
817  newMesh(),
818  map().cellMap(),
819  map().faceMap(),
820  addedPatches
821  );
822 
823 
824  const polyBoundaryMesh& newPatches = newMesh().boundaryMesh();
825  newPatches.checkParallelSync(true);
826 
827  // Delete empty patches
828  // ~~~~~~~~~~~~~~~~~~~~
829 
830  // Create reordering list to move patches-to-be-deleted to end
831  labelList oldToNew(newPatches.size(), -1);
832  DynamicList<label> sharedPatches(newPatches.size());
833  label newI = 0;
834 
835  Info<< "Deleting empty patches" << endl;
836 
837  // Assumes all non-proc boundaries are on all processors!
838  forAll(newPatches, patchi)
839  {
840  const polyPatch& pp = newPatches[patchi];
841 
842  if (!isA<processorPolyPatch>(pp))
843  {
844  if (returnReduce(pp.size(), sumOp<label>()) > 0)
845  {
846  oldToNew[patchi] = newI;
847  if (!addedPatches.found(patchi))
848  {
849  sharedPatches.append(newI);
850  }
851  newI++;
852  }
853  }
854  }
855 
856  // Same for processor patches (but need no reduction)
857  forAll(newPatches, patchi)
858  {
859  const polyPatch& pp = newPatches[patchi];
860 
861  if (isA<processorPolyPatch>(pp) && pp.size())
862  {
863  oldToNew[patchi] = newI++;
864  }
865  }
866 
867  const label nNewPatches = newI;
868 
869  // Move all deleteable patches to the end
870  forAll(oldToNew, patchi)
871  {
872  if (oldToNew[patchi] == -1)
873  {
874  oldToNew[patchi] = newI++;
875  }
876  }
877 
878  //reorderPatches(newMesh(), oldToNew, nNewPatches);
879  fvMeshTools::reorderPatches(newMesh(), oldToNew, nNewPatches, true);
880 
881  // Rename shared patches with region name
882  if (prefixRegion)
883  {
884  Info<< "Prefixing patches with region name" << endl;
885 
886  renamePatches(newMesh(), regionNames[regionI], sharedPatches);
887  }
888 
889 
890  Info<< "Writing new mesh" << endl;
891 
892  newMesh().setInstance(newMeshInstance);
893  newMesh().write();
894  topoSet::removeFiles(newMesh());
895  processorMeshes::removeFiles(newMesh());
896 
897  // Write addressing files like decomposePar
898  Info<< "Writing addressing to base mesh" << endl;
899 
900  labelIOList pointProcAddressing
901  (
902  IOobject
903  (
904  "pointRegionAddressing",
905  newMesh().facesInstance(),
906  newMesh().meshSubDir,
907  newMesh(),
910  false
911  ),
912  map().pointMap()
913  );
914  Info<< "Writing map " << pointProcAddressing.name()
915  << " from region" << regionI
916  << " points back to base mesh." << endl;
917  pointProcAddressing.write();
918 
920  (
921  IOobject
922  (
923  "faceRegionAddressing",
924  newMesh().facesInstance(),
925  newMesh().meshSubDir,
926  newMesh(),
929  false
930  ),
931  newMesh().nFaces()
932  );
933  forAll(faceProcAddressing, facei)
934  {
935  // face + turning index. (see decomposePar)
936  // Is the face pointing in the same direction?
937  label oldFacei = map().faceMap()[facei];
938 
939  if
940  (
941  map().cellMap()[newMesh().faceOwner()[facei]]
942  == mesh.faceOwner()[oldFacei]
943  )
944  {
945  faceProcAddressing[facei] = oldFacei+1;
946  }
947  else
948  {
949  faceProcAddressing[facei] = -(oldFacei+1);
950  }
951  }
952  Info<< "Writing map " << faceProcAddressing.name()
953  << " from region" << regionI
954  << " faces back to base mesh." << endl;
955  faceProcAddressing.write();
956 
957  labelIOList cellProcAddressing
958  (
959  IOobject
960  (
961  "cellRegionAddressing",
962  newMesh().facesInstance(),
963  newMesh().meshSubDir,
964  newMesh(),
967  false
968  ),
969  map().cellMap()
970  );
971  Info<< "Writing map " <<cellProcAddressing.name()
972  << " from region" << regionI
973  << " cells back to base mesh." << endl;
974  cellProcAddressing.write();
975 
976  labelIOList boundaryProcAddressing
977  (
978  IOobject
979  (
980  "boundaryRegionAddressing",
981  newMesh().facesInstance(),
982  newMesh().meshSubDir,
983  newMesh(),
986  false
987  ),
988  labelList(nNewPatches, -1)
989  );
990  forAll(oldToNew, i)
991  {
992  if (!addedPatches.found(i))
993  {
994  label newI = oldToNew[i];
995  if (newI >= 0 && newI < nNewPatches)
996  {
997  boundaryProcAddressing[oldToNew[i]] = i;
998  }
999  }
1000  }
1001  Info<< "Writing map " << boundaryProcAddressing.name()
1002  << " from region" << regionI
1003  << " boundary back to base mesh." << endl;
1004  boundaryProcAddressing.write();
1005 }
1006 
1007 
1008 // Create for every region-region interface with non-zero size two patches.
1009 // First one is for minimumregion to maximumregion.
1010 // Note that patches get created in same order on all processors (if parallel)
1011 // since looping over synchronised 'interfaces'.
1012 labelList addRegionPatches
1013 (
1014  fvMesh& mesh,
1015  const wordList& regionNames,
1016  const edgeList& interfaces,
1017  const List<Pair<word>>& interfaceNames
1018 )
1019 {
1020  Info<< nl << "Adding patches" << nl << endl;
1021 
1022  labelList interfacePatches(interfaces.size());
1023 
1024  forAll(interfaces, interI)
1025  {
1026  const edge& e = interfaces[interI];
1027  const Pair<word>& names = interfaceNames[interI];
1028 
1029  //Info<< "For interface " << interI
1030  // << " between regions " << e
1031  // << " trying to add patches " << names << endl;
1032 
1033 
1034  mappedWallPolyPatch patch1
1035  (
1036  names[0],
1037  0, // overridden
1038  0, // overridden
1039  0, // overridden
1040  regionNames[e[1]], // sampleRegion
1042  names[1], // samplePatch
1043  point::zero, // offset
1044  mesh.boundaryMesh()
1045  );
1046 
1047  interfacePatches[interI] = fvMeshTools::addPatch
1048  (
1049  mesh,
1050  patch1,
1051  dictionary(), //optional per field value
1053  true //validBoundary
1054  );
1055 
1056  mappedWallPolyPatch patch2
1057  (
1058  names[1],
1059  0,
1060  0,
1061  0,
1062  regionNames[e[0]], // sampleRegion
1064  names[0],
1065  point::zero, // offset
1066  mesh.boundaryMesh()
1067  );
1069  (
1070  mesh,
1071  patch2,
1072  dictionary(), //optional per field value
1074  true //validBoundary
1075  );
1076 
1077  Info<< "For interface between region " << regionNames[e[0]]
1078  << " and " << regionNames[e[1]] << " added patches" << endl
1079  << " " << interfacePatches[interI]
1080  << "\t" << mesh.boundaryMesh()[interfacePatches[interI]].name()
1081  << endl
1082  << " " << interfacePatches[interI]+1
1083  << "\t" << mesh.boundaryMesh()[interfacePatches[interI]+1].name()
1084  << endl;
1085  }
1086  return interfacePatches;
1087 }
1088 
1089 
1090 // Find region that covers most of cell zone
1091 label findCorrespondingRegion
1092 (
1093  const labelList& existingZoneID, // per cell the (unique) zoneID
1094  const labelList& cellRegion,
1095  const label nCellRegions,
1096  const label zoneI,
1097  const label minOverlapSize
1098 )
1099 {
1100  // Per region the number of cells in zoneI
1101  labelList cellsInZone(nCellRegions, Zero);
1102 
1103  forAll(cellRegion, celli)
1104  {
1105  if (existingZoneID[celli] == zoneI)
1106  {
1107  cellsInZone[cellRegion[celli]]++;
1108  }
1109  }
1110 
1112  Pstream::listCombineScatter(cellsInZone);
1113 
1114  // Pick region with largest overlap of zoneI
1115  label regionI = findMax(cellsInZone);
1116 
1117 
1118  if (cellsInZone[regionI] < minOverlapSize)
1119  {
1120  // Region covers too little of zone. Not good enough.
1121  regionI = -1;
1122  }
1123  else
1124  {
1125  // Check that region contains no cells that aren't in cellZone.
1126  forAll(cellRegion, celli)
1127  {
1128  if (cellRegion[celli] == regionI && existingZoneID[celli] != zoneI)
1129  {
1130  // celli in regionI but not in zoneI
1131  regionI = -1;
1132  break;
1133  }
1134  }
1135  // If one in error, all should be in error. Note that branch gets taken
1136  // on all procs.
1137  reduce(regionI, minOp<label>());
1138  }
1139 
1140  return regionI;
1141 }
1142 
1143 
1144 // Get zone per cell
1145 // - non-unique zoning
1146 // - coupled zones
1147 void getZoneID
1148 (
1149  const polyMesh& mesh,
1150  const cellZoneMesh& cellZones,
1151  labelList& zoneID,
1152  labelList& neiZoneID
1153 )
1154 {
1155  // Existing zoneID
1157  zoneID = -1;
1158 
1159  forAll(cellZones, zoneI)
1160  {
1161  const cellZone& cz = cellZones[zoneI];
1162 
1163  forAll(cz, i)
1164  {
1165  label celli = cz[i];
1166  if (zoneID[celli] == -1)
1167  {
1168  zoneID[celli] = zoneI;
1169  }
1170  else
1171  {
1173  << "Cell " << celli << " with cell centre "
1174  << mesh.cellCentres()[celli]
1175  << " is multiple zones. This is not allowed." << endl
1176  << "It is in zone " << cellZones[zoneID[celli]].name()
1177  << " and in zone " << cellZones[zoneI].name()
1178  << exit(FatalError);
1179  }
1180  }
1181  }
1182 
1183  // Neighbour zoneID.
1184  neiZoneID.setSize(mesh.nBoundaryFaces());
1185 
1186  forAll(neiZoneID, i)
1187  {
1188  neiZoneID[i] = zoneID[mesh.faceOwner()[i+mesh.nInternalFaces()]];
1189  }
1191 }
1192 
1193 
1194 void matchRegions
1195 (
1196  const bool sloppyCellZones,
1197  const polyMesh& mesh,
1198 
1199  const label nCellRegions,
1200  const labelList& cellRegion,
1201 
1202  labelList& regionToZone,
1203  wordList& regionNames,
1204  labelList& zoneToRegion
1205 )
1206 {
1207  const cellZoneMesh& cellZones = mesh.cellZones();
1208 
1209  regionToZone.setSize(nCellRegions, -1);
1210  regionNames.setSize(nCellRegions);
1211  zoneToRegion.setSize(cellZones.size(), -1);
1212 
1213  // Get current per cell zoneID
1214  labelList zoneID(mesh.nCells(), -1);
1215  labelList neiZoneID(mesh.nBoundaryFaces());
1216  getZoneID(mesh, cellZones, zoneID, neiZoneID);
1217 
1218  // Sizes per cellzone
1219  labelList zoneSizes(cellZones.size(), Zero);
1220  {
1221  List<wordList> zoneNames(Pstream::nProcs());
1222  zoneNames[Pstream::myProcNo()] = cellZones.names();
1223  Pstream::gatherList(zoneNames);
1224  Pstream::scatterList(zoneNames);
1225 
1226  forAll(zoneNames, proci)
1227  {
1228  if (zoneNames[proci] != zoneNames[0])
1229  {
1231  << "cellZones not synchronised across processors." << endl
1232  << "Master has cellZones " << zoneNames[0] << endl
1233  << "Processor " << proci
1234  << " has cellZones " << zoneNames[proci]
1235  << exit(FatalError);
1236  }
1237  }
1238 
1239  forAll(cellZones, zoneI)
1240  {
1241  zoneSizes[zoneI] = returnReduce
1242  (
1243  cellZones[zoneI].size(),
1244  sumOp<label>()
1245  );
1246  }
1247  }
1248 
1249 
1250  if (sloppyCellZones)
1251  {
1252  Info<< "Trying to match regions to existing cell zones;"
1253  << " region can be subset of cell zone." << nl << endl;
1254 
1255  forAll(cellZones, zoneI)
1256  {
1257  label regionI = findCorrespondingRegion
1258  (
1259  zoneID,
1260  cellRegion,
1261  nCellRegions,
1262  zoneI,
1263  label(0.5*zoneSizes[zoneI]) // minimum overlap
1264  );
1265 
1266  if (regionI != -1)
1267  {
1268  Info<< "Sloppily matched region " << regionI
1269  //<< " size " << regionSizes[regionI]
1270  << " to zone " << zoneI << " size " << zoneSizes[zoneI]
1271  << endl;
1272  zoneToRegion[zoneI] = regionI;
1273  regionToZone[regionI] = zoneI;
1274  regionNames[regionI] = cellZones[zoneI].name();
1275  }
1276  }
1277  }
1278  else
1279  {
1280  Info<< "Trying to match regions to existing cell zones." << nl << endl;
1281 
1282  forAll(cellZones, zoneI)
1283  {
1284  label regionI = findCorrespondingRegion
1285  (
1286  zoneID,
1287  cellRegion,
1288  nCellRegions,
1289  zoneI,
1290  1 // minimum overlap
1291  );
1292 
1293  if (regionI != -1)
1294  {
1295  zoneToRegion[zoneI] = regionI;
1296  regionToZone[regionI] = zoneI;
1297  regionNames[regionI] = cellZones[zoneI].name();
1298  }
1299  }
1300  }
1301  // Allocate region names for unmatched regions.
1302  forAll(regionToZone, regionI)
1303  {
1304  if (regionToZone[regionI] == -1)
1305  {
1306  regionNames[regionI] = "domain" + Foam::name(regionI);
1307  }
1308  }
1309 }
1310 
1311 
1312 void writeCellToRegion(const fvMesh& mesh, const labelList& cellRegion)
1313 {
1314  // Write to manual decomposition option
1315  {
1316  labelIOList cellToRegion
1317  (
1318  IOobject
1319  (
1320  "cellToRegion",
1321  mesh.facesInstance(),
1322  mesh,
1325  false
1326  ),
1327  cellRegion
1328  );
1329  cellToRegion.write();
1330 
1331  Info<< "Writing region per cell file (for manual decomposition) to "
1332  << cellToRegion.objectPath() << nl << endl;
1333  }
1334  // Write for postprocessing
1335  {
1336  volScalarField cellToRegion
1337  (
1338  IOobject
1339  (
1340  "cellToRegion",
1341  mesh.time().timeName(),
1342  mesh,
1345  false
1346  ),
1347  mesh,
1349  zeroGradientFvPatchScalarField::typeName
1350  );
1351  forAll(cellRegion, celli)
1352  {
1353  cellToRegion[celli] = cellRegion[celli];
1354  }
1355  cellToRegion.write();
1356 
1357  Info<< "Writing region per cell as volScalarField to "
1358  << cellToRegion.objectPath() << nl << endl;
1359  }
1360 }
1361 
1362 
1363 
1364 
1365 int main(int argc, char *argv[])
1366 {
1368  (
1369  "Split mesh into multiple regions (detected by walking across faces)"
1370  );
1371  #include "addRegionOption.H"
1372  #include "addOverwriteOption.H"
1374  (
1375  "cellZones",
1376  "Additionally split cellZones off into separate regions"
1377  );
1379  (
1380  "cellZonesOnly",
1381  "Use cellZones only to split mesh into regions; do not use walking"
1382  );
1384  (
1385  "cellZonesFileOnly",
1386  "file",
1387  "Like -cellZonesOnly, but use specified file"
1388  );
1390  (
1391  "blockedFaces",
1392  "faceSet",
1393  "Specify additional region boundaries that walking does not cross"
1394  );
1396  (
1397  "makeCellZones",
1398  "Place cells into cellZones instead of splitting mesh"
1399  );
1401  (
1402  "largestOnly",
1403  "Only write largest region"
1404  );
1406  (
1407  "insidePoint",
1408  "point",
1409  "Only write region containing point"
1410  );
1412  (
1413  "detectOnly",
1414  "Do not write mesh"
1415  );
1417  (
1418  "sloppyCellZones",
1419  "Try to match heuristically regions to existing cell zones"
1420  );
1422  (
1423  "useFaceZones",
1424  "Use faceZones to patch inter-region faces instead of single patch"
1425  );
1427  (
1428  "prefixRegion",
1429  "Prefix region name to all patches, not just coupling patches"
1430  );
1431 
1432  argList::noFunctionObjects(); // Never use function objects
1433 
1434  #include "setRootCase.H"
1435  #include "createTime.H"
1436  #include "createNamedMesh.H"
1437 
1438  const word oldInstance = mesh.pointsInstance();
1439 
1440  word blockedFacesName;
1441  if (args.readIfPresent("blockedFaces", blockedFacesName))
1442  {
1443  Info<< "Reading blocked internal faces from faceSet "
1444  << blockedFacesName << nl << endl;
1445  }
1446 
1447  const bool makeCellZones = args.found("makeCellZones");
1448  const bool largestOnly = args.found("largestOnly");
1449  const bool insidePoint = args.found("insidePoint");
1450  const bool useCellZones = args.found("cellZones");
1451  const bool useCellZonesOnly = args.found("cellZonesOnly");
1452  const bool useCellZonesFile = args.found("cellZonesFileOnly");
1453  const bool overwrite = args.found("overwrite");
1454  const bool detectOnly = args.found("detectOnly");
1455  const bool sloppyCellZones = args.found("sloppyCellZones");
1456  const bool useFaceZones = args.found("useFaceZones");
1457  const bool prefixRegion = args.found("prefixRegion");
1458 
1459 
1460  if
1461  (
1462  (useCellZonesOnly || useCellZonesFile)
1463  && (useCellZones || blockedFacesName.size())
1464  )
1465  {
1467  << "You cannot specify both -cellZonesOnly or -cellZonesFileOnly"
1468  << " (which specify complete split)"
1469  << " in combination with -blockedFaces or -cellZones"
1470  << " (which imply a split based on topology)"
1471  << exit(FatalError);
1472  }
1473 
1474 
1475  if (useFaceZones)
1476  {
1477  Info<< "Using current faceZones to divide inter-region interfaces"
1478  << " into multiple patches."
1479  << nl << endl;
1480  }
1481  else
1482  {
1483  Info<< "Creating single patch per inter-region interface."
1484  << nl << endl;
1485  }
1486 
1487 
1488 
1489  if (insidePoint && largestOnly)
1490  {
1492  << "You cannot specify both -largestOnly"
1493  << " (keep region with most cells)"
1494  << " and -insidePoint (keep region containing point)"
1495  << exit(FatalError);
1496  }
1497 
1498 
1499  const cellZoneMesh& cellZones = mesh.cellZones();
1500 
1501  // Existing zoneID
1502  labelList zoneID(mesh.nCells(), -1);
1503  // Neighbour zoneID.
1504  labelList neiZoneID(mesh.nBoundaryFaces());
1505  getZoneID(mesh, cellZones, zoneID, neiZoneID);
1506 
1507 
1508 
1509  // Determine per cell the region it belongs to
1510  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1511 
1512  // cellRegion is the labelList with the region per cell.
1513  labelList cellRegion;
1514  // Region per zone
1515  labelList regionToZone;
1516  // Name of region
1517  wordList regionNames;
1518  // Zone to region
1519  labelList zoneToRegion;
1520 
1521  label nCellRegions = 0;
1522  if (useCellZonesOnly)
1523  {
1524  Info<< "Using current cellZones to split mesh into regions."
1525  << " This requires all"
1526  << " cells to be in one and only one cellZone." << nl << endl;
1527 
1528  label unzonedCelli = zoneID.find(-1);
1529  if (unzonedCelli != -1)
1530  {
1532  << "For the cellZonesOnly option all cells "
1533  << "have to be in a cellZone." << endl
1534  << "Cell " << unzonedCelli
1535  << " at" << mesh.cellCentres()[unzonedCelli]
1536  << " is not in a cellZone. There might be more unzoned cells."
1537  << exit(FatalError);
1538  }
1539  cellRegion = zoneID;
1540  nCellRegions = gMax(cellRegion)+1;
1541  regionToZone.setSize(nCellRegions);
1542  regionNames.setSize(nCellRegions);
1543  zoneToRegion.setSize(cellZones.size(), -1);
1544  for (label regionI = 0; regionI < nCellRegions; regionI++)
1545  {
1546  regionToZone[regionI] = regionI;
1547  zoneToRegion[regionI] = regionI;
1548  regionNames[regionI] = cellZones[regionI].name();
1549  }
1550  }
1551  else if (useCellZonesFile)
1552  {
1553  const word zoneFile(args["cellZonesFileOnly"]);
1554  Info<< "Reading split from cellZones file " << zoneFile << endl
1555  << "This requires all"
1556  << " cells to be in one and only one cellZone." << nl << endl;
1557 
1558  cellZoneMesh newCellZones
1559  (
1560  IOobject
1561  (
1562  zoneFile,
1563  mesh.facesInstance(),
1565  mesh,
1568  false
1569  ),
1570  mesh
1571  );
1572 
1573  labelList newZoneID(mesh.nCells(), -1);
1574  labelList newNeiZoneID(mesh.nBoundaryFaces());
1575  getZoneID(mesh, newCellZones, newZoneID, newNeiZoneID);
1576 
1577  label unzonedCelli = newZoneID.find(-1);
1578  if (unzonedCelli != -1)
1579  {
1581  << "For the cellZonesFileOnly option all cells "
1582  << "have to be in a cellZone." << endl
1583  << "Cell " << unzonedCelli
1584  << " at" << mesh.cellCentres()[unzonedCelli]
1585  << " is not in a cellZone. There might be more unzoned cells."
1586  << exit(FatalError);
1587  }
1588  cellRegion = newZoneID;
1589  nCellRegions = gMax(cellRegion)+1;
1590  zoneToRegion.setSize(newCellZones.size(), -1);
1591  regionToZone.setSize(nCellRegions);
1592  regionNames.setSize(nCellRegions);
1593  for (label regionI = 0; regionI < nCellRegions; regionI++)
1594  {
1595  regionToZone[regionI] = regionI;
1596  zoneToRegion[regionI] = regionI;
1597  regionNames[regionI] = newCellZones[regionI].name();
1598  }
1599  }
1600  else
1601  {
1602  // Determine connected regions
1603  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
1604 
1605  // Mark additional faces that are blocked
1606  boolList blockedFace;
1607 
1608  // Read from faceSet
1609  if (blockedFacesName.size())
1610  {
1611  faceSet blockedFaceSet(mesh, blockedFacesName);
1612  Info<< "Read "
1613  << returnReduce(blockedFaceSet.size(), sumOp<label>())
1614  << " blocked faces from set " << blockedFacesName << nl << endl;
1615 
1616  blockedFace.setSize(mesh.nFaces(), false);
1617 
1618  for (const label facei : blockedFaceSet)
1619  {
1620  blockedFace[facei] = true;
1621  }
1622  }
1623 
1624  // Imply from differing cellZones
1625  if (useCellZones)
1626  {
1627  blockedFace.setSize(mesh.nFaces(), false);
1628 
1629  for (label facei = 0; facei < mesh.nInternalFaces(); facei++)
1630  {
1631  label own = mesh.faceOwner()[facei];
1632  label nei = mesh.faceNeighbour()[facei];
1633 
1634  if (zoneID[own] != zoneID[nei])
1635  {
1636  blockedFace[facei] = true;
1637  }
1638  }
1639 
1640  // Different cellZones on either side of processor patch.
1641  forAll(neiZoneID, i)
1642  {
1643  label facei = i+mesh.nInternalFaces();
1644 
1645  if (zoneID[mesh.faceOwner()[facei]] != neiZoneID[i])
1646  {
1647  blockedFace[facei] = true;
1648  }
1649  }
1650  }
1651 
1652  // Do a topological walk to determine regions
1653  regionSplit regions(mesh, blockedFace);
1654  nCellRegions = regions.nRegions();
1655  cellRegion.transfer(regions);
1656 
1657  // Make up region names. If possible match them to existing zones.
1658  matchRegions
1659  (
1660  sloppyCellZones,
1661  mesh,
1662  nCellRegions,
1663  cellRegion,
1664 
1665  regionToZone,
1666  regionNames,
1667  zoneToRegion
1668  );
1669 
1670  // Override any default region names if single region selected
1671  if (largestOnly || insidePoint)
1672  {
1673  forAll(regionToZone, regionI)
1674  {
1675  if (regionToZone[regionI] == -1)
1676  {
1677  if (overwrite)
1678  {
1679  regionNames[regionI] = polyMesh::defaultRegion;
1680  }
1681  else if (insidePoint)
1682  {
1683  regionNames[regionI] = "insidePoint";
1684  }
1685  else if (largestOnly)
1686  {
1687  regionNames[regionI] = "largestOnly";
1688  }
1689  }
1690  }
1691  }
1692  }
1693 
1694  Info<< endl << "Number of regions:" << nCellRegions << nl << endl;
1695 
1696 
1697  // Write decomposition to file
1698  writeCellToRegion(mesh, cellRegion);
1699 
1700 
1701 
1702  // Sizes per region
1703  // ~~~~~~~~~~~~~~~~
1704 
1705  labelList regionSizes(nCellRegions, Zero);
1706 
1707  forAll(cellRegion, celli)
1708  {
1709  regionSizes[cellRegion[celli]]++;
1710  }
1711  forAll(regionSizes, regionI)
1712  {
1713  reduce(regionSizes[regionI], sumOp<label>());
1714  }
1715 
1716  Info<< "Region\tCells" << nl
1717  << "------\t-----" << endl;
1718 
1719  forAll(regionSizes, regionI)
1720  {
1721  Info<< regionI << '\t' << regionSizes[regionI] << nl;
1722  }
1723  Info<< endl;
1724 
1725 
1726 
1727  // Print region to zone
1728  Info<< "Region\tZone\tName" << nl
1729  << "------\t----\t----" << endl;
1730  forAll(regionToZone, regionI)
1731  {
1732  Info<< regionI << '\t' << regionToZone[regionI] << '\t'
1733  << regionNames[regionI] << nl;
1734  }
1735  Info<< endl;
1736 
1737 
1738 
1739  // Since we're going to mess with patches and zones make sure all
1740  // is synchronised
1743 
1744 
1745  // Interfaces
1746  // ----------
1747  // per interface:
1748  // - the two regions on either side
1749  // - the name
1750  // - the (global) size
1751  edgeList interfaces;
1752  List<Pair<word>> interfaceNames;
1753  labelList interfaceSizes;
1754  // per face the interface
1755  labelList faceToInterface;
1756 
1757  getInterfaceSizes
1758  (
1759  mesh,
1760  useFaceZones,
1761  cellRegion,
1762  regionNames,
1763 
1764  interfaces,
1765  interfaceNames,
1766  interfaceSizes,
1767  faceToInterface
1768  );
1769 
1770  Info<< "Sizes of interfaces between regions:" << nl << nl
1771  << "Interface\tRegion\tRegion\tFaces" << nl
1772  << "---------\t------\t------\t-----" << endl;
1773 
1774  forAll(interfaces, interI)
1775  {
1776  const edge& e = interfaces[interI];
1777 
1778  Info<< interI
1779  << "\t\t" << e[0] << '\t' << e[1]
1780  << '\t' << interfaceSizes[interI] << nl;
1781  }
1782  Info<< endl;
1783 
1784 
1785  if (detectOnly)
1786  {
1787  Info<< "End\n" << endl;
1788 
1789  return 0;
1790  }
1791 
1792 
1793  // Read objects in time directory
1794  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1795 
1796  IOobjectList objects(mesh, runTime.timeName());
1797 
1798  // Read vol fields.
1799 
1800  PtrList<volScalarField> vsFlds;
1801  ReadFields(mesh, objects, vsFlds);
1802 
1803  PtrList<volVectorField> vvFlds;
1804  ReadFields(mesh, objects, vvFlds);
1805 
1807  ReadFields(mesh, objects, vstFlds);
1808 
1809  PtrList<volSymmTensorField> vsymtFlds;
1810  ReadFields(mesh, objects, vsymtFlds);
1811 
1812  PtrList<volTensorField> vtFlds;
1813  ReadFields(mesh, objects, vtFlds);
1814 
1815  // Read surface fields.
1816 
1818  ReadFields(mesh, objects, ssFlds);
1819 
1821  ReadFields(mesh, objects, svFlds);
1822 
1824  ReadFields(mesh, objects, sstFlds);
1825 
1827  ReadFields(mesh, objects, ssymtFlds);
1828 
1830  ReadFields(mesh, objects, stFlds);
1831 
1832  Info<< endl;
1833 
1834 
1835  // Remove any demand-driven fields ('S', 'V' etc)
1836  mesh.clearOut();
1837 
1838 
1839  if (nCellRegions == 1)
1840  {
1841  Info<< "Only one region. Doing nothing." << endl;
1842  }
1843  else if (makeCellZones)
1844  {
1845  Info<< "Putting cells into cellZones instead of splitting mesh."
1846  << endl;
1847 
1848  // Check if region overlaps with existing zone. If so keep.
1849 
1850  for (label regionI = 0; regionI < nCellRegions; regionI++)
1851  {
1852  label zoneI = regionToZone[regionI];
1853 
1854  if (zoneI != -1)
1855  {
1856  Info<< " Region " << regionI << " : corresponds to existing"
1857  << " cellZone "
1858  << zoneI << ' ' << cellZones[zoneI].name() << endl;
1859  }
1860  else
1861  {
1862  // Create new cellZone.
1863  labelList regionCells = findIndices(cellRegion, regionI);
1864 
1865  word zoneName = "region" + Foam::name(regionI);
1866 
1867  zoneI = cellZones.findZoneID(zoneName);
1868 
1869  if (zoneI == -1)
1870  {
1871  zoneI = cellZones.size();
1872  mesh.cellZones().setSize(zoneI+1);
1873  mesh.cellZones().set
1874  (
1875  zoneI,
1876  new cellZone
1877  (
1878  zoneName, //name
1879  std::move(regionCells), //addressing
1880  zoneI, //index
1881  cellZones //cellZoneMesh
1882  )
1883  );
1884  }
1885  else
1886  {
1887  mesh.cellZones()[zoneI].clearAddressing();
1888  mesh.cellZones()[zoneI] = regionCells;
1889  }
1890  Info<< " Region " << regionI << " : created new cellZone "
1891  << zoneI << ' ' << cellZones[zoneI].name() << endl;
1892  }
1893  }
1894  mesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
1895 
1896  if (!overwrite)
1897  {
1898  ++runTime;
1900  }
1901  else
1902  {
1903  mesh.setInstance(oldInstance);
1904  }
1905 
1906  Info<< "Writing cellZones as new mesh to time " << runTime.timeName()
1907  << nl << endl;
1908 
1909  mesh.write();
1910 
1911 
1912  // Write cellSets for convenience
1913  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1914 
1915  Info<< "Writing cellSets corresponding to cellZones." << nl << endl;
1916 
1917  forAll(cellZones, zoneI)
1918  {
1919  const cellZone& cz = cellZones[zoneI];
1920 
1921  cellSet(mesh, cz.name(), cz).write();
1922  }
1923  }
1924  else
1925  {
1926  // Add patches for interfaces
1927  // ~~~~~~~~~~~~~~~~~~~~~~~~~~
1928 
1929  // Add all possible patches. Empty ones get filtered later on.
1930  Info<< nl << "Adding patches" << nl << endl;
1931 
1932  labelList interfacePatches
1933  (
1934  addRegionPatches
1935  (
1936  mesh,
1937  regionNames,
1938  interfaces,
1939  interfaceNames
1940  )
1941  );
1942 
1943 
1944  if (!overwrite)
1945  {
1946  ++runTime;
1947  }
1948 
1949 
1950  // Create regions
1951  // ~~~~~~~~~~~~~~
1952 
1953  if (insidePoint)
1954  {
1955  const point insidePoint = args.get<point>("insidePoint");
1956 
1957  label regionI = -1;
1958 
1959  (void)mesh.tetBasePtIs();
1960 
1961  label celli = mesh.findCell(insidePoint);
1962 
1963  Info<< nl << "Found point " << insidePoint << " in cell " << celli
1964  << endl;
1965 
1966  if (celli != -1)
1967  {
1968  regionI = cellRegion[celli];
1969  }
1970 
1971  reduce(regionI, maxOp<label>());
1972 
1973  Info<< nl
1974  << "Subsetting region " << regionI
1975  << " containing point " << insidePoint << endl;
1976 
1977  if (regionI == -1)
1978  {
1980  << "Point " << insidePoint
1981  << " is not inside the mesh." << nl
1982  << "Bounding box of the mesh:" << mesh.bounds()
1983  << exit(FatalError);
1984  }
1985 
1986  createAndWriteRegion
1987  (
1988  mesh,
1989  cellRegion,
1990  regionNames,
1991  prefixRegion,
1992  faceToInterface,
1993  interfacePatches,
1994  regionI,
1995  (overwrite ? oldInstance : runTime.timeName())
1996  );
1997  }
1998  else if (largestOnly)
1999  {
2000  label regionI = findMax(regionSizes);
2001 
2002  Info<< nl
2003  << "Subsetting region " << regionI
2004  << " of size " << regionSizes[regionI]
2005  << " as named region " << regionNames[regionI] << endl;
2006 
2007  createAndWriteRegion
2008  (
2009  mesh,
2010  cellRegion,
2011  regionNames,
2012  prefixRegion,
2013  faceToInterface,
2014  interfacePatches,
2015  regionI,
2016  (overwrite ? oldInstance : runTime.timeName())
2017  );
2018  }
2019  else
2020  {
2021  // Split all
2022  for (label regionI = 0; regionI < nCellRegions; regionI++)
2023  {
2024  Info<< nl
2025  << "Region " << regionI << nl
2026  << "-------- " << endl;
2027 
2028  createAndWriteRegion
2029  (
2030  mesh,
2031  cellRegion,
2032  regionNames,
2033  prefixRegion,
2034  faceToInterface,
2035  interfacePatches,
2036  regionI,
2037  (overwrite ? oldInstance : runTime.timeName())
2038  );
2039  }
2040  }
2041  }
2042 
2043  Info<< "End\n" << endl;
2044 
2045  return 0;
2046 }
2047 
2048 
2049 // ************************************************************************* //
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
volFields.H
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::UPstream::commsTypes::blocking
Foam::maxOp
Definition: ops.H:223
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
faceProcAddressing
PtrList< labelIOList > & faceProcAddressing
Definition: checkFaceAddressingComp.H:9
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:129
mappedWallPolyPatch.H
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
Definition: dimensionSets.H:50
Foam::UPstream::masterNo
static constexpr int masterNo() noexcept
Process index of the master.
Definition: UPstream.H:433
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:70
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fvMesh::write
virtual bool write(const bool valid=true) const
Write mesh using IO settings from time.
Definition: fvMesh.C:895
Foam::fvMeshTools::createDummyFvMeshFiles
static void createDummyFvMeshFiles(const objectRegistry &parent, const word &regionName, const bool verbose=false)
Create additional fv* files.
Definition: fvMeshTools.C:674
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
Foam::polyMesh::defaultRegion
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:312
Foam::ReadFields
wordList ReadFields(const typename GeoMesh::Mesh &mesh, const IOobjectList &objects, PtrList< GeometricField< Type, PatchField, GeoMesh >> &fields, const bool syncPar=true, const bool readOldTime=false)
Read Geometric fields of templated type.
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::removeCells
Given list of cells to remove, insert all the topology changes.
Definition: removeCells.H:63
Foam::DynamicList< label >
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:52
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::minOp
Definition: ops.H:224
fvMeshSubset.H
interface
interfaceProperties interface(alpha1, U, thermo->transportPropertiesDict())
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
addOverwriteOption.H
Foam::primitiveMesh::nFaces
label nFaces() const
Number of mesh faces.
Definition: primitiveMeshI.H:90
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:427
Foam::polyMesh::meshSubDir
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:315
polyTopoChange.H
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:415
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:785
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::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
Foam::polyMesh::facesInstance
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:821
Foam::HashTable< T, edge, Hash< edge > >::insert
bool insert(const edge &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:168
Foam::polyMesh::cellZones
const cellZoneMesh & cellZones() const
Return cell zone mesh.
Definition: polyMesh.H:483
Foam::Map< label >
Foam::syncTools::swapBoundaryFaceList
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues)
Swap coupled boundary face values. Uses eqOp.
Definition: syncTools.H:439
Foam::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
IOobjectList.H
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:435
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
removeCells.H
Foam::HashSet< label, Hash< label > >
processorMeshes.H
Foam::argList::get
T get(const label index) const
Get a value from the argument at index.
Definition: argListI.H:257
syncTools.H
Foam::argList::readIfPresent
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:302
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::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::cellZone
A subset of mesh cells.
Definition: cellZone.H:62
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const
Return face zone mesh.
Definition: polyMesh.H:477
Foam::polyMesh::pointsInstance
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:815
SortableList.H
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::polyBoundaryMesh::checkParallelSync
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order. Return.
Definition: polyBoundaryMesh.C:950
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::argList::noFunctionObjects
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition: argList.C:454
Foam::primitiveMesh::nCells
label nCells() const
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::UPstream::lastSlave
static int lastSlave(const label communicator=0)
Process index of last slave.
Definition: UPstream.H:468
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:67
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
argList.H
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1076
faceSet.H
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:459
regionSplit.H
addRegionOption.H
Foam::ZoneMesh< cellZone, polyMesh >
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:43
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::fvMeshTools::reorderPatches
static void reorderPatches(fvMesh &, const labelList &oldToNew, const label nPatches, const bool validBoundary)
Reorder and remove trailing patches. If validBoundary call is parallel.
Definition: fvMeshTools.C:329
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
Foam::PtrList::append
void append(T *ptr)
Append an element to the end of the list.
Definition: PtrListI.H:115
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::ZoneMesh::whichZone
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition: ZoneMesh.C:315
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
createNamedMesh.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
zoneID
const labelIOList & zoneID
Definition: interpolatedFaces.H:22
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
Foam::calculatedFvPatchField
This boundary condition is not designed to be evaluated; it is assmued that the value is assigned via...
Definition: calculatedFvPatchField.H:66
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::zone::name
const word & name() const
Return name.
Definition: zone.H:158
Foam::cellSet
A collection of cell labels.
Definition: cellSet.H:51
Foam::ZoneMesh::findZoneID
label findZoneID(const word &zoneName) const
Find zone index given a name, return -1 if not found.
Definition: ZoneMesh.C:484
Foam::IOobjectList
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:55
Foam::HashTable< T, edge, Hash< edge > >::find
iterator find(const edge &key)
Find and return an iterator set at the hashed entry.
Definition: HashTableI.H:114
Foam::mappedWallPolyPatch
Determines a mapping between patch face centres and mesh cell or face centres and processors they're ...
Definition: mappedWallPolyPatch.H:59
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::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:445
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:439
Foam::UPstream::firstSlave
static constexpr int firstSlave() noexcept
Process index of first slave.
Definition: UPstream.H:462
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
Foam::polyBoundaryMesh::updateMesh
void updateMesh()
Correct polyBoundaryMesh after topology update.
Definition: polyBoundaryMesh.C:1141
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::polyMesh::bounds
const boundBox & bounds() const
Return mesh bounding box.
Definition: polyMesh.H:441
Foam::argList::addBoolOption
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:325
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
setRootCase.H
Foam::EdgeMap
Map from edge (expressed as its endpoints) to value. For easier forward declaration it is currently i...
Definition: EdgeMap.H:51
Foam::polyMesh::findCell
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition: polyMesh.C:1446
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:175
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
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
edgeHashes.H
ReadFields.H
Field reading functions for post-processing utilities.
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::Pair< word >
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
fvMeshTools.H
Foam::mappedPatchBase::NEARESTPATCHFACE
nearest face on selected patch
Definition: mappedPatchBase.H:116
Foam::Vector< scalar >
Foam::findMax
label findMax(const ListType &input, label start=0)
Foam::List< label >
Foam::primitiveMesh::isInternalFace
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
Definition: primitiveMeshI.H:102
Foam::fvMeshTools::addPatch
static label addPatch(fvMesh &mesh, const polyPatch &patch, const dictionary &patchFieldDict, const word &defaultPatchFieldType, const bool validBoundary)
Add patch. Inserts patch before all processor patches.
Definition: fvMeshTools.C:37
Foam::primitiveMesh::faceCentres
const vectorField & faceCentres() const
Definition: primitiveMeshFaceCentresAndAreas.C:144
Foam::processorMeshes::removeFiles
static void removeFiles(const polyMesh &mesh)
Helper: remove all procAddressing files from mesh instance.
Definition: processorMeshes.C:274
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
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::IOList< label >
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:181
createTime.H
Foam::fvMeshSubset::interpolate
static tmp< GeometricField< Type, fvPatchField, volMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &, const fvMesh &sMesh, const labelUList &patchMap, const labelUList &cellMap, const labelUList &faceMap)
Map volume field.
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::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:248
Foam::VectorSpace< Vector< Cmpt >, Cmpt, 3 >::zero
static const Vector< Cmpt > zero
Definition: VectorSpace.H:115
Foam::findIndices
labelList findIndices(const ListType &input, typename ListType::const_reference val, label start=0)
Linear search to find all occurrences of given element.
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:52
Foam::plusEqOp
Definition: ops.H:72
cellSet.H
Foam::ZoneMesh::clearAddressing
void clearAddressing()
Clear addressing.
Definition: ZoneMesh.C:618
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::HashTable::found
bool found(const Key &key) const
Return true if hashed entry is found in table.
Definition: HashTableI.H:100
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::argList::addOption
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:336
Foam::IOobject::NO_READ
Definition: IOobject.H:123
args
Foam::argList args(argc, argv)
Foam::topoSet::removeFiles
static void removeFiles(const polyMesh &)
Helper: remove all sets files from mesh instance.
Definition: topoSet.C:638
zeroGradientFvPatchFields.H
Foam::ZoneMesh::checkParallelSync
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order.
Definition: ZoneMesh.C:660
Foam::patchIdentifier::name
const word & name() const
The patch name.
Definition: patchIdentifier.H:134
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:298
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:592
Foam::polyMesh::setInstance
void setInstance(const fileName &instance, const IOobject::writeOption wOpt=IOobject::AUTO_WRITE)
Set the instance for mesh files.
Definition: polyMeshIO.C:36
fields
multivariateSurfaceInterpolationScheme< scalar >::fieldTable fields
Definition: createFields.H:97
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1082
Foam::fvMesh::clearOut
void clearOut()
Clear all geometry and addressing.
Definition: fvMesh.C:227
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157
Foam::IOobject::MUST_READ
Definition: IOobject.H:120
Foam::polyMesh::tetBasePtIs
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:861