domainDecomposition.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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "domainDecomposition.H"
27 #include "dictionary.H"
28 #include "labelIOList.H"
29 #include "processorPolyPatch.H"
31 #include "fvMesh.H"
32 #include "OSspecific.H"
33 #include "Map.H"
34 #include "DynamicList.H"
35 #include "fvFieldDecomposer.H"
36 #include "IOobjectList.H"
37 #include "cellSet.H"
38 #include "faceSet.H"
39 #include "pointSet.H"
40 #include "decompositionModel.H"
41 #include "hexRef8Data.H"
42 
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 
46 (
47  const labelList& zoneElems,
48  const label zoneI,
49  labelList& elementToZone
50 )
51 {
52  forAll(zoneElems, i)
53  {
54  label pointi = zoneElems[i];
55 
56  if (elementToZone[pointi] == -1)
57  {
58  // First occurrence
59  elementToZone[pointi] = zoneI;
60  }
61  else if (elementToZone[pointi] >= 0)
62  {
63  // Multiple zones
64  elementToZone[pointi] = -2;
65  }
66  }
67 }
68 
69 
70 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
71 
72 // from components
74 (
75  const IOobject& io,
76  const fileName& decompDictFile
77 )
78 :
79  fvMesh(io),
80  facesInstancePointsPtr_
81  (
82  pointsInstance() != facesInstance()
83  ? new pointIOField
84  (
85  IOobject
86  (
87  "points",
88  facesInstance(),
89  polyMesh::meshSubDir,
90  *this,
91  IOobject::MUST_READ,
92  IOobject::NO_WRITE,
93  false
94  )
95  )
96  : NULL
97  ),
98  decompDictFile_(decompDictFile),
99  nProcs_
100  (
101  readInt
102  (
104  (
105  *this,
106  decompDictFile
107  ).lookup("numberOfSubdomains")
108  )
109  ),
110  distributed_(false),
111  cellToProc_(nCells()),
112  procPointAddressing_(nProcs_),
113  procFaceAddressing_(nProcs_),
114  procCellAddressing_(nProcs_),
115  procPatchSize_(nProcs_),
116  procPatchStartIndex_(nProcs_),
117  procNeighbourProcessors_(nProcs_),
118  procProcessorPatchSize_(nProcs_),
119  procProcessorPatchStartIndex_(nProcs_),
120  procProcessorPatchSubPatchIDs_(nProcs_),
121  procProcessorPatchSubPatchStarts_(nProcs_)
122 {
124  (
125  *this,
126  decompDictFile
127  ).readIfPresent("distributed", distributed_);
128 }
129 
130 
131 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
132 
134 {}
135 
136 
137 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
138 
139 bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
140 {
141  Info<< "\nConstructing processor meshes" << endl;
142 
143  // Mark point/faces/cells that are in zones.
144  // -1 : not in zone
145  // -2 : in multiple zones
146  // >= 0 : in single given zone
147  // This will give direct lookup of elements that are in a single zone
148  // and we'll only have to revert back to searching through all zones
149  // for the duplicate elements
150 
151  // Point zones
152  labelList pointToZone(points().size(), -1);
153 
154  forAll(pointZones(), zoneI)
155  {
156  mark(pointZones()[zoneI], zoneI, pointToZone);
157  }
158 
159  // Face zones
160  labelList faceToZone(faces().size(), -1);
161 
162  forAll(faceZones(), zoneI)
163  {
164  mark(faceZones()[zoneI], zoneI, faceToZone);
165  }
166 
167  // Cell zones
168  labelList cellToZone(nCells(), -1);
169 
170  forAll(cellZones(), zoneI)
171  {
172  mark(cellZones()[zoneI], zoneI, cellToZone);
173  }
174 
175 
178  PtrList<const pointSet> pointSets;
179  if (decomposeSets)
180  {
181  // Read sets
182  IOobjectList objects(*this, facesInstance(), "polyMesh/sets");
183  {
184  IOobjectList cSets(objects.lookupClass(cellSet::typeName));
185  forAllConstIter(IOobjectList, cSets, iter)
186  {
187  cellSets.append(new cellSet(*iter()));
188  }
189  }
190  {
191  IOobjectList fSets(objects.lookupClass(faceSet::typeName));
192  forAllConstIter(IOobjectList, fSets, iter)
193  {
194  faceSets.append(new faceSet(*iter()));
195  }
196  }
197  {
198  IOobjectList pSets(objects.lookupClass(pointSet::typeName));
199  forAllConstIter(IOobjectList, pSets, iter)
200  {
201  pointSets.append(new pointSet(*iter()));
202  }
203  }
204  }
205 
206 
207  // Load refinement data (if any)
208  hexRef8Data baseMeshData
209  (
210  IOobject
211  (
212  "dummy",
213  facesInstance(),
215  *this,
218  false
219  )
220  );
221 
222 
223 
224  label maxProcCells = 0;
225  label totProcFaces = 0;
226  label maxProcPatches = 0;
227  label totProcPatches = 0;
228  label maxProcFaces = 0;
229 
230 
231  // Write out the meshes
232  for (label procI = 0; procI < nProcs_; procI++)
233  {
234  // Create processor points
235  const labelList& curPointLabels = procPointAddressing_[procI];
236 
237  const pointField& meshPoints = points();
238 
239  labelList pointLookup(nPoints(), -1);
240 
241  pointField procPoints(curPointLabels.size());
242 
243  forAll(curPointLabels, pointi)
244  {
245  procPoints[pointi] = meshPoints[curPointLabels[pointi]];
246 
247  pointLookup[curPointLabels[pointi]] = pointi;
248  }
249 
250  // Create processor faces
251  const labelList& curFaceLabels = procFaceAddressing_[procI];
252 
253  const faceList& meshFaces = faces();
254 
255  labelList faceLookup(nFaces(), -1);
256 
257  faceList procFaces(curFaceLabels.size());
258 
259  forAll(curFaceLabels, facei)
260  {
261  // Mark the original face as used
262  // Remember to decrement the index by one (turning index)
263  //
264  label curF = mag(curFaceLabels[facei]) - 1;
265 
266  faceLookup[curF] = facei;
267 
268  // get the original face
269  labelList origFaceLabels;
270 
271  if (curFaceLabels[facei] >= 0)
272  {
273  // face not turned
274  origFaceLabels = meshFaces[curF];
275  }
276  else
277  {
278  origFaceLabels = meshFaces[curF].reverseFace();
279  }
280 
281  // translate face labels into local point list
282  face& procFaceLabels = procFaces[facei];
283 
284  procFaceLabels.setSize(origFaceLabels.size());
285 
286  forAll(origFaceLabels, pointi)
287  {
288  procFaceLabels[pointi] = pointLookup[origFaceLabels[pointi]];
289  }
290  }
291 
292  // Create processor cells
293  const labelList& curCellLabels = procCellAddressing_[procI];
294 
295  const cellList& meshCells = cells();
296 
297  cellList procCells(curCellLabels.size());
298 
299  forAll(curCellLabels, celli)
300  {
301  const labelList& origCellLabels = meshCells[curCellLabels[celli]];
302 
303  cell& curCell = procCells[celli];
304 
305  curCell.setSize(origCellLabels.size());
306 
307  forAll(origCellLabels, cellFaceI)
308  {
309  curCell[cellFaceI] = faceLookup[origCellLabels[cellFaceI]];
310  }
311  }
312 
313  // Create processor mesh without a boundary
314 
315  fileName processorCasePath
316  (
317  time().caseName()/fileName(word("processor") + Foam::name(procI))
318  );
319 
320  // make the processor directory
321  mkDir(time().rootPath()/processorCasePath);
322 
323  // create a database
324  Time processorDb
325  (
327  time().rootPath(),
328  processorCasePath,
329  word("system"),
330  word("constant")
331  );
332  processorDb.setTime(time());
333 
334  // create the mesh. Two situations:
335  // - points and faces come from the same time ('instance'). The mesh
336  // will get constructed in the same instance.
337  // - points come from a different time (moving mesh cases).
338  // It will read the points belonging to the faces instance and
339  // construct the procMesh with it which then gets handled as above.
340  // (so with 'old' geometry).
341  // Only at writing time will it additionally write the current
342  // points.
343 
344  autoPtr<polyMesh> procMeshPtr;
345 
346  if (facesInstancePointsPtr_.valid())
347  {
348  // Construct mesh from facesInstance.
349  pointField facesInstancePoints
350  (
351  facesInstancePointsPtr_(),
352  curPointLabels
353  );
354 
355  procMeshPtr.reset
356  (
357  new polyMesh
358  (
359  IOobject
360  (
361  this->polyMesh::name(), // region of undecomposed mesh
362  facesInstance(),
363  processorDb
364  ),
365  xferMove(facesInstancePoints),
366  xferMove(procFaces),
367  xferMove(procCells)
368  )
369  );
370  }
371  else
372  {
373  procMeshPtr.reset
374  (
375  new polyMesh
376  (
377  IOobject
378  (
379  this->polyMesh::name(), // region of undecomposed mesh
380  facesInstance(),
381  processorDb
382  ),
383  xferMove(procPoints),
384  xferMove(procFaces),
385  xferMove(procCells)
386  )
387  );
388  }
389  polyMesh& procMesh = procMeshPtr();
390 
391 
392  // Create processor boundary patches
393  const labelList& curPatchSizes = procPatchSize_[procI];
394 
395  const labelList& curPatchStarts = procPatchStartIndex_[procI];
396 
397  const labelList& curNeighbourProcessors =
398  procNeighbourProcessors_[procI];
399 
400  const labelList& curProcessorPatchSizes =
401  procProcessorPatchSize_[procI];
402 
403  const labelList& curProcessorPatchStarts =
404  procProcessorPatchStartIndex_[procI];
405 
406  const labelListList& curSubPatchIDs =
407  procProcessorPatchSubPatchIDs_[procI];
408 
409  const labelListList& curSubStarts =
410  procProcessorPatchSubPatchStarts_[procI];
411 
412  const polyPatchList& meshPatches = boundaryMesh();
413 
414 
415  // Count the number of inter-proc patches
416  label nInterProcPatches = 0;
417  forAll(curSubPatchIDs, procPatchI)
418  {
419  //Info<< "For processor " << procI
420  // << " have to destination processor "
421  // << curNeighbourProcessors[procPatchI] << endl;
422  //
423  //forAll(curSubPatchIDs[procPatchI], i)
424  //{
425  // Info<< " from patch:" << curSubPatchIDs[procPatchI][i]
426  // << " starting at:" << curSubStarts[procPatchI][i]
427  // << endl;
428  //}
429 
430  nInterProcPatches += curSubPatchIDs[procPatchI].size();
431  }
432 
433  //Info<< "For processor " << procI
434  // << " have " << nInterProcPatches
435  // << " patches to neighbouring processors" << endl;
436 
437 
438  List<polyPatch*> procPatches
439  (
440  curPatchSizes.size()
441  + nInterProcPatches, //curProcessorPatchSizes.size(),
442  reinterpret_cast<polyPatch*>(0)
443  );
444 
445  label nPatches = 0;
446 
447  forAll(curPatchSizes, patchi)
448  {
449  // Get the face labels consistent with the field mapping
450  // (reuse the patch field mappers)
451  const polyPatch& meshPatch = meshPatches[patchi];
452 
454  (
456  (
457  curFaceLabels,
458  curPatchSizes[patchi],
459  curPatchStarts[patchi]
460  ),
461  meshPatch.start()
462  );
463 
464  // Map existing patches
465  procPatches[nPatches] = meshPatch.clone
466  (
467  procMesh.boundaryMesh(),
468  nPatches,
469  patchMapper.directAddressing(),
470  curPatchStarts[patchi]
471  ).ptr();
472 
473  nPatches++;
474  }
475 
476  forAll(curProcessorPatchSizes, procPatchI)
477  {
478  const labelList& subPatchID = curSubPatchIDs[procPatchI];
479  const labelList& subStarts = curSubStarts[procPatchI];
480 
481  label curStart = curProcessorPatchStarts[procPatchI];
482 
483  forAll(subPatchID, i)
484  {
485  label size =
486  (
487  i < subPatchID.size()-1
488  ? subStarts[i+1] - subStarts[i]
489  : curProcessorPatchSizes[procPatchI] - subStarts[i]
490  );
491 
492 // Info<< "From processor:" << procI << endl
493 // << " to processor:" << curNeighbourProcessors[procPatchI]
494 // << endl
495 // << " via patch:" << subPatchID[i] << endl
496 // << " start :" << curStart << endl
497 // << " size :" << size << endl;
498 
499  if (subPatchID[i] == -1)
500  {
501  // From internal faces
502  procPatches[nPatches] =
504  (
505  word("procBoundary") + Foam::name(procI)
506  + "to"
507  + Foam::name(curNeighbourProcessors[procPatchI]),
508  size,
509  curStart,
510  nPatches,
511  procMesh.boundaryMesh(),
512  procI,
513  curNeighbourProcessors[procPatchI]
514  );
515  }
516  else
517  {
518  const coupledPolyPatch& pcPatch
519  = refCast<const coupledPolyPatch>
520  (
521  boundaryMesh()[subPatchID[i]]
522  );
523 
524  // From cyclic
525  const word& referPatch = pcPatch.name();
526 
527  procPatches[nPatches] =
529  (
530  word("procBoundary") + Foam::name(procI)
531  + "to"
532  + Foam::name(curNeighbourProcessors[procPatchI])
533  + "through"
534  + referPatch,
535  size,
536  curStart,
537  nPatches,
538  procMesh.boundaryMesh(),
539  procI,
540  curNeighbourProcessors[procPatchI],
541  referPatch,
542  pcPatch.transform()
543  );
544  }
545 
546  curStart += size;
547 
548  nPatches++;
549  }
550  }
551 
552 
553  //forAll(procPatches, patchI)
554  //{
555  // Pout<< " " << patchI
556  // << '\t' << "name:" << procPatches[patchI]->name()
557  // << '\t' << "type:" << procPatches[patchI]->type()
558  // << '\t' << "size:" << procPatches[patchI]->size()
559  // << endl;
560  //}
561 
562  // Add boundary patches
563  procMesh.addPatches(procPatches);
564 
565  // Create and add zones
566 
567  // Point zones
568  {
569  const pointZoneMesh& pz = pointZones();
570 
571  // Go through all the zoned points and find out if they
572  // belong to a zone. If so, add it to the zone as
573  // necessary
574  List<DynamicList<label> > zonePoints(pz.size());
575 
576  // Estimate size
577  forAll(zonePoints, zoneI)
578  {
579  zonePoints[zoneI].setCapacity(pz[zoneI].size() / nProcs_);
580  }
581 
582  // Use the pointToZone map to find out the single zone (if any),
583  // use slow search only for shared points.
584  forAll(curPointLabels, pointi)
585  {
586  label curPoint = curPointLabels[pointi];
587 
588  label zoneI = pointToZone[curPoint];
589 
590  if (zoneI >= 0)
591  {
592  // Single zone.
593  zonePoints[zoneI].append(pointi);
594  }
595  else if (zoneI == -2)
596  {
597  // Multiple zones. Lookup.
598  forAll(pz, zoneI)
599  {
600  label index = pz[zoneI].whichPoint(curPoint);
601 
602  if (index != -1)
603  {
604  zonePoints[zoneI].append(pointi);
605  }
606  }
607  }
608  }
609 
610  procMesh.pointZones().clearAddressing();
611  procMesh.pointZones().setSize(zonePoints.size());
612  forAll(zonePoints, zoneI)
613  {
614  procMesh.pointZones().set
615  (
616  zoneI,
617  pz[zoneI].clone
618  (
619  procMesh.pointZones(),
620  zoneI,
621  zonePoints[zoneI].shrink()
622  )
623  );
624  }
625 
626  if (pz.size())
627  {
628  // Force writing on all processors
629  procMesh.pointZones().writeOpt() = IOobject::AUTO_WRITE;
630  }
631  }
632 
633  // Face zones
634  {
635  const faceZoneMesh& fz = faceZones();
636 
637  // Go through all the zoned face and find out if they
638  // belong to a zone. If so, add it to the zone as
639  // necessary
640  List<DynamicList<label> > zoneFaces(fz.size());
641  List<DynamicList<bool> > zoneFaceFlips(fz.size());
642 
643  // Estimate size
644  forAll(zoneFaces, zoneI)
645  {
646  label procSize = fz[zoneI].size() / nProcs_;
647 
648  zoneFaces[zoneI].setCapacity(procSize);
649  zoneFaceFlips[zoneI].setCapacity(procSize);
650  }
651 
652  // Go through all the zoned faces and find out if they
653  // belong to a zone. If so, add it to the zone as
654  // necessary
655  forAll(curFaceLabels, facei)
656  {
657  // Remember to decrement the index by one (turning index)
658  //
659  label curF = mag(curFaceLabels[facei]) - 1;
660 
661  label zoneI = faceToZone[curF];
662 
663  if (zoneI >= 0)
664  {
665  // Single zone. Add the face
666  zoneFaces[zoneI].append(facei);
667 
668  label index = fz[zoneI].whichFace(curF);
669 
670  bool flip = fz[zoneI].flipMap()[index];
671 
672  if (curFaceLabels[facei] < 0)
673  {
674  flip = !flip;
675  }
676 
677  zoneFaceFlips[zoneI].append(flip);
678  }
679  else if (zoneI == -2)
680  {
681  // Multiple zones. Lookup.
682  forAll(fz, zoneI)
683  {
684  label index = fz[zoneI].whichFace(curF);
685 
686  if (index != -1)
687  {
688  zoneFaces[zoneI].append(facei);
689 
690  bool flip = fz[zoneI].flipMap()[index];
691 
692  if (curFaceLabels[facei] < 0)
693  {
694  flip = !flip;
695  }
696 
697  zoneFaceFlips[zoneI].append(flip);
698  }
699  }
700  }
701  }
702 
703  procMesh.faceZones().clearAddressing();
704  procMesh.faceZones().setSize(zoneFaces.size());
705  forAll(zoneFaces, zoneI)
706  {
707  procMesh.faceZones().set
708  (
709  zoneI,
710  fz[zoneI].clone
711  (
712  zoneFaces[zoneI].shrink(), // addressing
713  zoneFaceFlips[zoneI].shrink(), // flipmap
714  zoneI,
715  procMesh.faceZones()
716  )
717  );
718  }
719 
720  if (fz.size())
721  {
722  // Force writing on all processors
723  procMesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
724  }
725  }
726 
727  // Cell zones
728  {
729  const cellZoneMesh& cz = cellZones();
730 
731  // Go through all the zoned cells and find out if they
732  // belong to a zone. If so, add it to the zone as
733  // necessary
734  List<DynamicList<label> > zoneCells(cz.size());
735 
736  // Estimate size
737  forAll(zoneCells, zoneI)
738  {
739  zoneCells[zoneI].setCapacity(cz[zoneI].size() / nProcs_);
740  }
741 
742  forAll(curCellLabels, celli)
743  {
744  label curCellI = curCellLabels[celli];
745 
746  label zoneI = cellToZone[curCellI];
747 
748  if (zoneI >= 0)
749  {
750  // Single zone.
751  zoneCells[zoneI].append(celli);
752  }
753  else if (zoneI == -2)
754  {
755  // Multiple zones. Lookup.
756  forAll(cz, zoneI)
757  {
758  label index = cz[zoneI].whichCell(curCellI);
759 
760  if (index != -1)
761  {
762  zoneCells[zoneI].append(celli);
763  }
764  }
765  }
766  }
767 
768  procMesh.cellZones().clearAddressing();
769  procMesh.cellZones().setSize(zoneCells.size());
770  forAll(zoneCells, zoneI)
771  {
772  procMesh.cellZones().set
773  (
774  zoneI,
775  cz[zoneI].clone
776  (
777  zoneCells[zoneI].shrink(),
778  zoneI,
779  procMesh.cellZones()
780  )
781  );
782  }
783 
784  if (cz.size())
785  {
786  // Force writing on all processors
787  procMesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
788  }
789  }
790 
791  // Set the precision of the points data to be min 10
793 
794  procMesh.write();
795 
796  // Write points if pointsInstance differing from facesInstance
797  if (facesInstancePointsPtr_.valid())
798  {
799  pointIOField pointsInstancePoints
800  (
801  IOobject
802  (
803  "points",
804  pointsInstance(),
806  procMesh,
809  false
810  ),
811  xferMove(procPoints)
812  );
813  pointsInstancePoints.write();
814  }
815 
816 
817  // Decompose any sets
818  if (decomposeSets)
819  {
820  forAll(cellSets, i)
821  {
822  const cellSet& cs = cellSets[i];
823  cellSet set(procMesh, cs.name(), cs.size()/nProcs_);
824  forAll(curCellLabels, i)
825  {
826  if (cs.found(curCellLabels[i]))
827  {
828  set.insert(i);
829  }
830  }
831  set.write();
832  }
833  forAll(faceSets, i)
834  {
835  const faceSet& cs = faceSets[i];
836  faceSet set(procMesh, cs.name(), cs.size()/nProcs_);
837  forAll(curFaceLabels, i)
838  {
839  if (cs.found(mag(curFaceLabels[i])-1))
840  {
841  set.insert(i);
842  }
843  }
844  set.write();
845  }
846  forAll(pointSets, i)
847  {
848  const pointSet& cs = pointSets[i];
849  pointSet set(procMesh, cs.name(), cs.size()/nProcs_);
850  forAll(curPointLabels, i)
851  {
852  if (cs.found(curPointLabels[i]))
853  {
854  set.insert(i);
855  }
856  }
857  set.write();
858  }
859  }
860 
861 
862  // Optional hexRef8 data
864  (
865  IOobject
866  (
867  "dummy",
868  facesInstance(),
870  procMesh,
873  false
874  ),
875  baseMeshData,
876  procCellAddressing_[procI],
877  procPointAddressing_[procI]
878  ).write();
879 
880 
881  // Statistics
882 
883  Info<< endl
884  << "Processor " << procI << nl
885  << " Number of cells = " << procMesh.nCells()
886  << endl;
887 
888  maxProcCells = max(maxProcCells, procMesh.nCells());
889 
890  label nBoundaryFaces = 0;
891  label nProcPatches = 0;
892  label nProcFaces = 0;
893 
894  forAll(procMesh.boundaryMesh(), patchi)
895  {
896  if (isA<processorPolyPatch>(procMesh.boundaryMesh()[patchi]))
897  {
898  const processorPolyPatch& ppp =
899  refCast<const processorPolyPatch>
900  (
901  procMesh.boundaryMesh()[patchi]
902  );
903 
904  Info<< " Number of faces shared with processor "
905  << ppp.neighbProcNo() << " = " << ppp.size() << endl;
906 
907  nProcPatches++;
908  nProcFaces += ppp.size();
909  }
910  else
911  {
912  nBoundaryFaces += procMesh.boundaryMesh()[patchi].size();
913  }
914  }
915 
916  Info<< " Number of processor patches = " << nProcPatches << nl
917  << " Number of processor faces = " << nProcFaces << nl
918  << " Number of boundary faces = " << nBoundaryFaces << endl;
919 
920  totProcFaces += nProcFaces;
921  totProcPatches += nProcPatches;
922  maxProcPatches = max(maxProcPatches, nProcPatches);
923  maxProcFaces = max(maxProcFaces, nProcFaces);
924 
925  // create and write the addressing information
926  labelIOList pointProcAddressing
927  (
928  IOobject
929  (
930  "pointProcAddressing",
931  procMesh.facesInstance(),
932  procMesh.meshSubDir,
933  procMesh,
936  ),
937  procPointAddressing_[procI]
938  );
939  pointProcAddressing.write();
940 
942  (
943  IOobject
944  (
945  "faceProcAddressing",
946  procMesh.facesInstance(),
947  procMesh.meshSubDir,
948  procMesh,
951  ),
952  procFaceAddressing_[procI]
953  );
954  faceProcAddressing.write();
955 
956  labelIOList cellProcAddressing
957  (
958  IOobject
959  (
960  "cellProcAddressing",
961  procMesh.facesInstance(),
962  procMesh.meshSubDir,
963  procMesh,
966  ),
967  procCellAddressing_[procI]
968  );
969  cellProcAddressing.write();
970 
971  // Write patch map for backwards compatibility.
972  // (= identity map for original patches, -1 for processor patches)
973  label nMeshPatches = curPatchSizes.size();
974  labelList procBoundaryAddressing(identity(nMeshPatches));
975  procBoundaryAddressing.setSize(nMeshPatches+nProcPatches, -1);
976 
977  labelIOList boundaryProcAddressing
978  (
979  IOobject
980  (
981  "boundaryProcAddressing",
982  procMesh.facesInstance(),
983  procMesh.meshSubDir,
984  procMesh,
987  ),
988  procBoundaryAddressing
989  );
990  boundaryProcAddressing.write();
991  }
992 
993  scalar avgProcCells = scalar(nCells())/nProcs_;
994  scalar avgProcPatches = scalar(totProcPatches)/nProcs_;
995  scalar avgProcFaces = scalar(totProcFaces)/nProcs_;
996 
997  // In case of all faces on one processor. Just to avoid division by 0.
998  if (totProcPatches == 0)
999  {
1000  avgProcPatches = 1;
1001  }
1002  if (totProcFaces == 0)
1003  {
1004  avgProcFaces = 1;
1005  }
1006 
1007  Info<< nl
1008  << "Number of processor faces = " << totProcFaces/2 << nl
1009  << "Max number of cells = " << maxProcCells
1010  << " (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
1011  << "% above average " << avgProcCells << ")" << nl
1012  << "Max number of processor patches = " << maxProcPatches
1013  << " (" << 100.0*(maxProcPatches-avgProcPatches)/avgProcPatches
1014  << "% above average " << avgProcPatches << ")" << nl
1015  << "Max number of faces between processors = " << maxProcFaces
1016  << " (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces
1017  << "% above average " << avgProcFaces << ")" << nl
1018  << endl;
1019 
1020  return true;
1021 }
1022 
1023 
1024 // ************************************************************************* //
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::domainDecomposition::domainDecomposition
domainDecomposition(const IOobject &io, const fileName &decompDictFile="")
Construct from IOobjects (for mesh and optional non-standard.
Definition: domainDecomposition.C:74
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::compressible::New
autoPtr< BasicCompressibleTurbulenceModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const typename BasicCompressibleTurbulenceModel::transportModel &transport, const word &propertiesName)
Definition: turbulentFluidThermoModel.C:36
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::IOField< vector >
Foam::PtrList::append
void append(T *)
Append an element at the end of the list.
Foam::processorCyclicPolyPatch
Neighbour processor patch.
Definition: processorCyclicPolyPatch.H:50
Foam::IOobject::AUTO_WRITE
@ AUTO_WRITE
Definition: IOobject.H:117
nPatches
label nPatches
Definition: readKivaGrid.H:402
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::polyMesh::meshSubDir
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:309
Foam::polyMesh::facesInstance
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:778
Foam::polyMesh::cellZones
const cellZoneMesh & cellZones() const
Return cell zone mesh.
Definition: polyMesh.H:469
Foam::regIOobject::write
virtual bool write() const
Write using setting from DB.
Definition: regIOobjectWrite.C:126
Foam::processorPolyPatch::neighbProcNo
int neighbProcNo() const
Return neigbour processor number.
Definition: processorPolyPatch.H:255
Foam::faceSet
A list of face labels.
Definition: faceSet.H:48
IOobjectList.H
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::coupledPolyPatch
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
Definition: coupledPolyPatch.H:51
Foam::domainDecomposition::mark
static void mark(const labelList &zoneElems, const label zoneI, labelList &elementToZone)
Mark all elements with value or -2 if occur twice.
Definition: domainDecomposition.C:46
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::domainDecomposition::~domainDecomposition
~domainDecomposition()
Destructor.
Definition: domainDecomposition.C:133
processorCyclicPolyPatch.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Foam::IOobject::NO_WRITE
@ NO_WRITE
Definition: IOobject.H:118
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const
Return face zone mesh.
Definition: polyMesh.H:463
Foam::faceSets
Definition: faceSets.H:44
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::primitiveMesh::nCells
label nCells() const
Definition: primitiveMeshI.H:64
Map.H
Foam::readInt
int readInt(Istream &)
Definition: intIO.C:31
Foam::fvFieldDecomposer::patchFieldDecomposer
Patch field decomposer class.
Definition: fvFieldDecomposer.H:58
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::List::append
void append(const T &)
Append an element at the end of the list.
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
Foam::domainDecomposition::writeDecomposition
bool writeDecomposition(const bool decomposeSets)
Write decomposition.
Definition: domainDecomposition.C:139
Foam::polyMesh::pointZones
const pointZoneMesh & pointZones() const
Return point zone mesh.
Definition: polyMesh.H:457
domainDecomposition.H
faceSet.H
Foam::ZoneMesh
A list of mesh zones.
Definition: cellZoneMeshFwd.H:39
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobject.H:273
Foam::processorPolyPatch
Neighbour processor patch.
Definition: processorPolyPatch.H:55
Foam::PtrList
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:61
Foam::hexRef8Data
Various for reading/decomposing/reconstructing/distributing refinement data.
Definition: hexRef4Data.H:57
Foam::cellSets
Definition: cellSets.H:44
Foam::identity
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
processorPolyPatch.H
Foam::HashTable::size
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
Foam::Time::setTime
virtual void setTime(const Time &)
Reset the time and time-index to those of the given time.
Definition: Time.C:964
Foam::HashTable::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
hexRef8Data.H
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
fvMesh.H
Foam::cellSet
A collection of cell labels.
Definition: cellSet.H:48
Foam::IOobjectList::lookupClass
IOobjectList lookupClass(const word &className) const
Return the list for all IOobjects of a given class.
Definition: IOobjectList.C:199
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:312
Foam::coupledPolyPatch::transform
virtual transformType transform() const
Type of transform.
Definition: coupledPolyPatch.H:256
Foam::IOobjectList
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:50
fvFieldDecomposer.H
Foam::polyPatch::clone
virtual autoPtr< polyPatch > clone(const polyBoundaryMesh &bm) const
Construct and return a clone, resetting the boundary mesh.
Definition: polyPatch.H:231
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
Foam::hexRef8Data::write
bool write() const
Write.
Definition: hexRef4Data.C:324
Foam::fvFieldDecomposer::patchFieldDecomposer::directAddressing
const labelUList & directAddressing() const
Definition: fvFieldDecomposer.H:96
Foam::xferMove
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
Foam::pointSet
A set of point labels.
Definition: pointSet.H:48
Foam::IOstream::defaultPrecision
static unsigned int defaultPrecision()
Return the default precision.
Definition: IOstream.H:461
Foam::polyMesh::addPatches
void addPatches(const List< polyPatch * > &, const bool validBoundary=true)
Add boundary patches.
Definition: polyMesh.C:878
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
labelIOList.H
patchi
label patchi
Definition: getPatchFieldScalar.H:1
points
const pointField & points
Definition: gmvOutputHeader.H:1
dictionary.H
Foam::IOList< label >
Foam::PtrList::size
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
faceProcAddressing
PtrList< labelIOList > & faceProcAddressing
Definition: checkFaceAddressingComp.H:9
Foam::autoPtr::reset
void reset(T *=0)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:59
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
decompositionModel.H
DynamicList.H
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
cellSet.H
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::ZoneMesh::clearAddressing
void clearAddressing()
Clear addressing.
Definition: ZoneMesh.C:394
Foam::Time::controlDictName
static word controlDictName
The default control dictionary name (normally "controlDict")
Definition: Time.H:213
Foam::mkDir
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:419
Foam::IOobject::READ_IF_PRESENT
@ READ_IF_PRESENT
Definition: IOobject.H:110
Foam::patchIdentifier::name
const word & name() const
Return name.
Definition: patchIdentifier.H:109
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
lookup
stressControl lookup("compactNormalStress") >> compactNormalStress
pointSet.H