reconstructParMesh.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-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  reconstructParMesh
29 
30 Group
31  grpParallelUtilities
32 
33 Description
34  Reconstructs a mesh using geometric information only.
35 
36  Writes point/face/cell procAddressing so afterwards reconstructPar can be
37  used to reconstruct fields.
38 
39  Note:
40  - uses geometric matching tolerance (set with -mergeTol (at your option)
41 
42  If the parallel case does not have correct procBoundaries use the
43  -fullMatch option which will check all boundary faces (bit slower).
44 
45 \*---------------------------------------------------------------------------*/
46 
47 #include "argList.H"
48 #include "timeSelector.H"
49 
50 #include "IOobjectList.H"
51 #include "labelIOList.H"
52 #include "processorPolyPatch.H"
53 #include "mapAddedPolyMesh.H"
54 #include "polyMeshAdder.H"
55 #include "faceCoupleInfo.H"
56 #include "fvMeshAdder.H"
57 #include "polyTopoChange.H"
59 #include "topoSet.H"
60 
61 using namespace Foam;
62 
63 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
64 
65 // Tolerance (as fraction of the bounding box). Needs to be fairly lax since
66 // usually meshes get written with limited precision (6 digits)
67 static const scalar defaultMergeTol = 1e-7;
68 
69 
70 static void renumber
71 (
72  const labelList& map,
73  labelList& elems
74 )
75 {
76  forAll(elems, i)
77  {
78  if (elems[i] >= 0)
79  {
80  elems[i] = map[elems[i]];
81  }
82  }
83 }
84 
85 
86 // Determine which faces are coupled. Uses geometric merge distance.
87 // Looks either at all boundaryFaces (fullMatch) or only at the
88 // procBoundaries for proci. Assumes that masterMesh contains already merged
89 // all the processors < proci.
90 autoPtr<faceCoupleInfo> determineCoupledFaces
91 (
92  const bool fullMatch,
93  const label masterMeshProcStart,
94  const label masterMeshProcEnd,
95  const polyMesh& masterMesh,
96  const label meshToAddProcStart,
97  const label meshToAddProcEnd,
98  const polyMesh& meshToAdd,
99  const scalar mergeDist
100 )
101 {
102  if (fullMatch || masterMesh.nCells() == 0)
103  {
105  (
106  masterMesh,
107  meshToAdd,
108  mergeDist, // Absolute merging distance
109  true // Matching faces identical
110  );
111  }
112  else
113  {
114  // Pick up all patches on masterMesh ending in "toDDD" where DDD is
115  // the processor number proci.
116 
117  const polyBoundaryMesh& masterPatches = masterMesh.boundaryMesh();
118 
119 
120  DynamicList<label> masterFaces
121  (
122  masterMesh.nFaces()
123  - masterMesh.nInternalFaces()
124  );
125 
126 
127  forAll(masterPatches, patchi)
128  {
129  const polyPatch& pp = masterPatches[patchi];
130 
131  if (isA<processorPolyPatch>(pp))
132  {
133  for
134  (
135  label proci=meshToAddProcStart;
136  proci<meshToAddProcEnd;
137  proci++
138  )
139  {
140  const string toProcString("to" + name(proci));
141  if (
142  pp.name().rfind(toProcString)
143  == (pp.name().size()-toProcString.size())
144  )
145  {
146  label meshFacei = pp.start();
147  forAll(pp, i)
148  {
149  masterFaces.append(meshFacei++);
150  }
151  break;
152  }
153  }
154 
155  }
156  }
157  masterFaces.shrink();
158 
159 
160  // Pick up all patches on meshToAdd ending in "procBoundaryDDDtoYYY"
161  // where DDD is the processor number proci and YYY is < proci.
162 
163  const polyBoundaryMesh& addPatches = meshToAdd.boundaryMesh();
164 
165  DynamicList<label> addFaces
166  (
167  meshToAdd.nFaces()
168  - meshToAdd.nInternalFaces()
169  );
170 
171  forAll(addPatches, patchi)
172  {
173  const polyPatch& pp = addPatches[patchi];
174 
175  if (isA<processorPolyPatch>(pp))
176  {
177  bool isConnected = false;
178 
179  for
180  (
181  label mergedProci=masterMeshProcStart;
182  !isConnected && (mergedProci < masterMeshProcEnd);
183  mergedProci++
184  )
185  {
186  for
187  (
188  label proci = meshToAddProcStart;
189  proci < meshToAddProcEnd;
190  proci++
191  )
192  {
193  const word fromProcString
194  (
195  processorPolyPatch::newName(proci, mergedProci)
196  );
197 
198  if (pp.name() == fromProcString)
199  {
200  isConnected = true;
201  break;
202  }
203  }
204  }
205 
206  if (isConnected)
207  {
208  label meshFacei = pp.start();
209  forAll(pp, i)
210  {
211  addFaces.append(meshFacei++);
212  }
213  }
214  }
215  }
216  addFaces.shrink();
217 
219  (
220  masterMesh,
221  masterFaces,
222  meshToAdd,
223  addFaces,
224  mergeDist, // Absolute merging distance
225  true, // Matching faces identical?
226  false, // If perfect match are faces already ordered
227  // (e.g. processor patches)
228  false // are faces each on separate patch?
229  );
230  }
231 }
232 
233 
234 autoPtr<mapPolyMesh> mergeSharedPoints
235 (
236  const scalar mergeDist,
237  polyMesh& mesh,
238  labelListList& pointProcAddressing
239 )
240 {
241  // Find out which sets of points get merged and create a map from
242  // mesh point to unique point.
243  Map<label> pointToMaster
244  (
246  (
247  mesh,
248  mergeDist
249  )
250  );
251 
252  Info<< "mergeSharedPoints : detected " << pointToMaster.size()
253  << " points that are to be merged." << endl;
254 
255  if (returnReduce(pointToMaster.size(), sumOp<label>()) == 0)
256  {
257  return nullptr;
258  }
259 
260  polyTopoChange meshMod(mesh);
261 
262  fvMeshAdder::mergePoints(mesh, pointToMaster, meshMod);
263 
264  // Change the mesh (no inflation). Note: parallel comms allowed.
265  autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false, true);
266 
267  // Update fields. No inflation, parallel sync.
268  mesh.updateMesh(map());
269 
270  // pointProcAddressing give indices into the master mesh so adapt them
271  // for changed point numbering.
272 
273  // Adapt constructMaps for merged points.
274  forAll(pointProcAddressing, proci)
275  {
276  labelList& constructMap = pointProcAddressing[proci];
277 
278  forAll(constructMap, i)
279  {
280  label oldPointi = constructMap[i];
281 
282  // New label of point after changeMesh.
283  label newPointi = map().reversePointMap()[oldPointi];
284 
285  if (newPointi < -1)
286  {
287  constructMap[i] = -newPointi-2;
288  }
289  else if (newPointi >= 0)
290  {
291  constructMap[i] = newPointi;
292  }
293  else
294  {
296  << "Problem. oldPointi:" << oldPointi
297  << " newPointi:" << newPointi << abort(FatalError);
298  }
299  }
300  }
301 
302  return map;
303 }
304 
305 
306 boundBox procBounds
307 (
308  const argList& args,
309  const PtrList<Time>& databases,
310  const word& regionDir
311 )
312 {
314 
315  forAll(databases, proci)
316  {
317  fileName pointsInstance
318  (
319  databases[proci].findInstance
320  (
321  regionDir/polyMesh::meshSubDir,
322  "points"
323  )
324  );
325 
326  if (pointsInstance != databases[proci].timeName())
327  {
329  << "Your time was specified as " << databases[proci].timeName()
330  << " but there is no polyMesh/points in that time." << endl
331  << "(there is a points file in " << pointsInstance
332  << ")" << endl
333  << "Please rerun with the correct time specified"
334  << " (through the -constant, -time or -latestTime "
335  << "(at your option)."
336  << endl << exit(FatalError);
337  }
338 
339  Info<< "Reading points from "
340  << databases[proci].caseName()
341  << " for time = " << databases[proci].timeName()
342  << nl << endl;
343 
345  (
346  IOobject
347  (
348  "points",
349  databases[proci].findInstance
350  (
351  regionDir/polyMesh::meshSubDir,
352  "points"
353  ),
354  regionDir/polyMesh::meshSubDir,
355  databases[proci],
358  false
359  )
360  );
361 
362  bb.add(points);
363  }
364 
365  return bb;
366 }
367 
368 
369 void writeCellDistance
370 (
371  Time& runTime,
372  const fvMesh& masterMesh,
373  const labelListList& cellProcAddressing
374 
375 )
376 {
377  // Write the decomposition as labelList for use with 'manual'
378  // decomposition method.
379  labelIOList cellDecomposition
380  (
381  IOobject
382  (
383  "cellDecomposition",
384  masterMesh.facesInstance(),
385  masterMesh,
388  false
389  ),
390  masterMesh.nCells()
391  );
392 
393  forAll(cellProcAddressing, proci)
394  {
395  const labelList& pCells = cellProcAddressing[proci];
396  labelUIndList(cellDecomposition, pCells) = proci;
397  }
398 
399  cellDecomposition.write();
400 
401  Info<< nl << "Wrote decomposition to "
402  << cellDecomposition.objectPath()
403  << " for use in manual decomposition." << endl;
404 
405 
406  // Write as volScalarField for postprocessing. Change time to 0
407  // if was 'constant'
408  {
409  const scalar oldTime = runTime.value();
410  const label oldIndex = runTime.timeIndex();
411  if (runTime.timeName() == runTime.constant() && oldIndex == 0)
412  {
413  runTime.setTime(0, oldIndex+1);
414  }
415 
416  volScalarField cellDist
417  (
418  IOobject
419  (
420  "cellDist",
421  runTime.timeName(),
422  masterMesh,
425  ),
426  masterMesh,
428  extrapolatedCalculatedFvPatchScalarField::typeName
429  );
430 
431  forAll(cellDecomposition, celli)
432  {
433  cellDist[celli] = cellDecomposition[celli];
434  }
435  cellDist.correctBoundaryConditions();
436 
437  cellDist.write();
438 
439  Info<< nl << "Wrote decomposition as volScalarField to "
440  << cellDist.name() << " for use in postprocessing."
441  << endl;
442 
443  // Restore time
444  runTime.setTime(oldTime, oldIndex);
445  }
446 }
447 
448 
449 int main(int argc, char *argv[])
450 {
452  (
453  "Reconstruct a mesh using geometric information only"
454  );
455 
456  // Enable -constant ... if someone really wants it
457  // Enable -withZero to prevent accidentally trashing the initial fields
458  timeSelector::addOptions(true, true); // constant(true), zero(true)
459 
462  (
463  "mergeTol",
464  "scalar",
465  "The merge distance relative to the bounding box size (default 1e-7)"
466  );
468  (
469  "fullMatch",
470  "Do (slower) geometric matching on all boundary faces"
471  );
473  (
474  "cellDist",
475  "Write cell distribution as a labelList - for use with 'manual' "
476  "decomposition method or as a volScalarField for post-processing."
477  );
478 
479  #include "addRegionOption.H"
480  #include "setRootCase.H"
481  #include "createTime.H"
482 
483  Info<< "This is an experimental tool which tries to merge"
484  << " individual processor" << nl
485  << "meshes back into one master mesh. Use it if the original"
486  << " master mesh has" << nl
487  << "been deleted or if the processor meshes have been modified"
488  << " (topology change)." << nl
489  << "This tool will write the resulting mesh to a new time step"
490  << " and construct" << nl
491  << "xxxxProcAddressing files in the processor meshes so"
492  << " reconstructPar can be" << nl
493  << "used to regenerate the fields on the master mesh." << nl
494  << nl
495  << "Not well tested & use at your own risk!" << nl
496  << endl;
497 
498 
500  word regionDir = word::null;
501 
502  if
503  (
504  args.readIfPresent("region", regionName)
506  )
507  {
508  regionDir = regionName;
509  Info<< "Operating on region " << regionName << nl << endl;
510  }
511 
512  const scalar mergeTol =
513  args.getOrDefault<scalar>("mergeTol", defaultMergeTol);
514 
515  scalar writeTol = Foam::pow(10.0, -scalar(IOstream::defaultPrecision()));
516 
517  Info<< "Merge tolerance : " << mergeTol << nl
518  << "Write tolerance : " << writeTol << endl;
519 
520  if (runTime.writeFormat() == IOstream::ASCII && mergeTol < writeTol)
521  {
523  << "Your current settings specify ASCII writing with "
524  << IOstream::defaultPrecision() << " digits precision." << endl
525  << "Your merging tolerance (" << mergeTol << ") is finer than this."
526  << endl
527  << "Please change your writeFormat to binary"
528  << " or increase the writePrecision" << endl
529  << "or adjust the merge tolerance (-mergeTol)."
530  << exit(FatalError);
531  }
532 
533 
534  const bool fullMatch = args.found("fullMatch");
535  const bool writeCellDist = args.found("cellDist");
536 
537  if (fullMatch)
538  {
539  Info<< "Doing geometric matching on all boundary faces." << nl << endl;
540  }
541  else
542  {
543  Info<< "Doing geometric matching on correct procBoundaries only."
544  << nl << "This assumes a correct decomposition." << endl;
545  }
546 
547  label nProcs = fileHandler().nProcs(args.path());
548 
549  Info<< "Found " << nProcs << " processor directories" << nl << endl;
550 
551  // Read all time databases
552  PtrList<Time> databases(nProcs);
553 
554  forAll(databases, proci)
555  {
556  Info<< "Reading database "
557  << args.caseName()/("processor" + Foam::name(proci))
558  << endl;
559 
560  databases.set
561  (
562  proci,
563  new Time
564  (
566  args.rootPath(),
567  args.caseName()/("processor" + Foam::name(proci))
568  )
569  );
570  }
571 
572  // Use the times list from the master processor
573  // and select a subset based on the command-line options
575  (
576  databases[0].times(),
577  args
578  );
579 
580  // Loop over all times
581  forAll(timeDirs, timeI)
582  {
583  // Set time for global database
584  runTime.setTime(timeDirs[timeI], timeI);
585 
586  Info<< "Time = " << runTime.timeName() << nl << endl;
587 
588  // Set time for all databases
589  forAll(databases, proci)
590  {
591  databases[proci].setTime(timeDirs[timeI], timeI);
592  }
593 
594  IOobject facesIO
595  (
596  "faces",
597  databases[0].timeName(),
598  regionDir/polyMesh::meshSubDir,
599  databases[0],
602  );
603 
604 
605  // Problem: faceCompactIOList recognises both 'faceList' and
606  // 'faceCompactList' so we should be lenient when doing
607  // typeHeaderOk
608  if (!facesIO.typeHeaderOk<faceCompactIOList>(false))
609  {
610  Info<< "No mesh." << nl << endl;
611  continue;
612  }
613 
614 
615  // Read point on individual processors to determine merge tolerance
616  // (otherwise single cell domains might give problems)
617 
618  const boundBox bb = procBounds(args, databases, regionDir);
619  const scalar mergeDist = mergeTol*bb.mag();
620 
621  Info<< "Overall mesh bounding box : " << bb << nl
622  << "Relative tolerance : " << mergeTol << nl
623  << "Absolute matching distance : " << mergeDist << nl
624  << endl;
625 
626 
627  // Addressing from processor to reconstructed case
628  labelListList cellProcAddressing(nProcs);
630  labelListList pointProcAddressing(nProcs);
631  labelListList boundaryProcAddressing(nProcs);
632 
633  // Internal faces on the final reconstructed mesh
634  label masterInternalFaces;
635 
636  // Owner addressing on the final reconstructed mesh
637  labelList masterOwner;
638 
639  {
640  // Construct empty mesh.
641  // fvMesh** masterMesh = new fvMesh*[nProcs];
642  PtrList<fvMesh> masterMesh(nProcs);
643 
644  for (label proci=0; proci<nProcs; proci++)
645  {
646  masterMesh.set
647  (
648  proci,
649  new fvMesh
650  (
651  IOobject
652  (
653  regionName,
654  runTime.timeName(),
655  runTime,
657  ),
658  Zero
659  )
660  );
661 
662  fvMesh meshToAdd
663  (
664  IOobject
665  (
666  regionName,
667  databases[proci].timeName(),
668  databases[proci]
669  )
670  );
671 
672  // Initialize its addressing
673  cellProcAddressing[proci] = identity(meshToAdd.nCells());
674  faceProcAddressing[proci] = identity(meshToAdd.nFaces());
675  pointProcAddressing[proci] = identity(meshToAdd.nPoints());
676  boundaryProcAddressing[proci] =
677  identity(meshToAdd.boundaryMesh().size());
678 
679  // Find geometrically shared points/faces.
680  autoPtr<faceCoupleInfo> couples = determineCoupledFaces
681  (
682  fullMatch,
683  proci,
684  proci,
685  masterMesh[proci],
686  proci,
687  proci,
688  meshToAdd,
689  mergeDist
690  );
691 
692  // Add elements to mesh
694  (
695  masterMesh[proci],
696  meshToAdd,
697  couples()
698  );
699 
700  // Added processor
701  renumber(map().addedCellMap(), cellProcAddressing[proci]);
702  renumber(map().addedFaceMap(), faceProcAddressing[proci]);
703  renumber(map().addedPointMap(), pointProcAddressing[proci]);
704  renumber(map().addedPatchMap(), boundaryProcAddressing[proci]);
705  }
706  for (label step=2; step<nProcs*2; step*=2)
707  {
708  for (label proci=0; proci<nProcs; proci+=step)
709  {
710  label next = proci + step/2;
711  if(next >= nProcs)
712  {
713  continue;
714  }
715 
716  Info<< "Merging mesh " << proci << " with " << next << endl;
717 
718  // Find geometrically shared points/faces.
719  autoPtr<faceCoupleInfo> couples = determineCoupledFaces
720  (
721  fullMatch,
722  proci,
723  next,
724  masterMesh[proci],
725  next,
726  proci+step,
727  masterMesh[next],
728  mergeDist
729  );
730 
731  // Add elements to mesh
733  (
734  masterMesh[proci],
735  masterMesh[next],
736  couples()
737  );
738 
739  // Processors that were already in masterMesh
740  for (label mergedI=proci; mergedI<next; mergedI++)
741  {
742  renumber
743  (
744  map().oldCellMap(),
745  cellProcAddressing[mergedI]
746  );
747 
748  renumber
749  (
750  map().oldFaceMap(),
751  faceProcAddressing[mergedI]
752  );
753 
754  renumber
755  (
756  map().oldPointMap(),
757  pointProcAddressing[mergedI]
758  );
759 
760  // Note: boundary is special since can contain -1.
761  renumber
762  (
763  map().oldPatchMap(),
764  boundaryProcAddressing[mergedI]
765  );
766  }
767 
768  // Added processor
769  for
770  (
771  label addedI=next;
772  addedI<min(proci+step, nProcs);
773  addedI++
774  )
775  {
776  renumber
777  (
778  map().addedCellMap(),
779  cellProcAddressing[addedI]
780  );
781 
782  renumber
783  (
784  map().addedFaceMap(),
785  faceProcAddressing[addedI]
786  );
787 
788  renumber
789  (
790  map().addedPointMap(),
791  pointProcAddressing[addedI]
792  );
793 
794  renumber
795  (
796  map().addedPatchMap(),
797  boundaryProcAddressing[addedI]
798  );
799  }
800 
801  masterMesh.set(next, nullptr);
802  }
803  }
804 
805  for (label proci=0; proci<nProcs; proci++)
806  {
807  Info<< "Reading mesh to add from "
808  << databases[proci].caseName()
809  << " for time = " << databases[proci].timeName()
810  << nl << nl << endl;
811  }
812 
813  // See if any points on the mastermesh have become connected
814  // because of connections through processor meshes.
815  mergeSharedPoints(mergeDist, masterMesh[0], pointProcAddressing);
816 
817  // Save some properties on the reconstructed mesh
818  masterInternalFaces = masterMesh[0].nInternalFaces();
819  masterOwner = masterMesh[0].faceOwner();
820 
821 
822  Info<< "\nWriting merged mesh to "
824  << nl << endl;
825 
826  if (!masterMesh[0].write())
827  {
829  << "Failed writing polyMesh."
830  << exit(FatalError);
831  }
832  topoSet::removeFiles(masterMesh[0]);
833 
834  if (writeCellDist)
835  {
836  writeCellDistance
837  (
838  runTime,
839  masterMesh[0],
840  cellProcAddressing
841  );
842  }
843  }
844 
845 
846  // Write the addressing
847 
848  Info<< "Reconstructing the addressing from the processor meshes"
849  << " to the newly reconstructed mesh" << nl << endl;
850 
851  forAll(databases, proci)
852  {
853  Info<< "Reading processor " << proci << " mesh from "
854  << databases[proci].caseName() << endl;
855 
856  polyMesh procMesh
857  (
858  IOobject
859  (
860  regionName,
861  databases[proci].timeName(),
862  databases[proci]
863  )
864  );
865 
866 
867  // From processor point to reconstructed mesh point
868 
869  Info<< "Writing pointProcAddressing to "
870  << databases[proci].caseName()
871  /procMesh.facesInstance()
873  << endl;
874 
876  (
877  IOobject
878  (
879  "pointProcAddressing",
880  procMesh.facesInstance(),
882  procMesh,
885  false // Do not register
886  ),
887  pointProcAddressing[proci]
888  ).write();
889 
890 
891  // From processor face to reconstructed mesh face
892 
893  Info<< "Writing faceProcAddressing to "
894  << databases[proci].caseName()
895  /procMesh.facesInstance()
897  << endl;
898 
899  labelIOList faceProcAddr
900  (
901  IOobject
902  (
903  "faceProcAddressing",
904  procMesh.facesInstance(),
906  procMesh,
909  false // Do not register
910  ),
911  faceProcAddressing[proci]
912  );
913 
914  // Now add turning index to faceProcAddressing.
915  // See reconstructPar for meaning of turning index.
916  forAll(faceProcAddr, procFacei)
917  {
918  const label masterFacei = faceProcAddr[procFacei];
919 
920  if
921  (
922  !procMesh.isInternalFace(procFacei)
923  && masterFacei < masterInternalFaces
924  )
925  {
926  // proc face is now external but used to be internal face.
927  // Check if we have owner or neighbour.
928 
929  label procOwn = procMesh.faceOwner()[procFacei];
930  label masterOwn = masterOwner[masterFacei];
931 
932  if (cellProcAddressing[proci][procOwn] == masterOwn)
933  {
934  // No turning. Offset by 1.
935  faceProcAddr[procFacei]++;
936  }
937  else
938  {
939  // Turned face.
940  faceProcAddr[procFacei] =
941  -1 - faceProcAddr[procFacei];
942  }
943  }
944  else
945  {
946  // No turning. Offset by 1.
947  faceProcAddr[procFacei]++;
948  }
949  }
950 
951  faceProcAddr.write();
952 
953 
954  // From processor cell to reconstructed mesh cell
955 
956  Info<< "Writing cellProcAddressing to "
957  << databases[proci].caseName()
958  /procMesh.facesInstance()
960  << endl;
961 
963  (
964  IOobject
965  (
966  "cellProcAddressing",
967  procMesh.facesInstance(),
969  procMesh,
972  false // Do not register
973  ),
974  cellProcAddressing[proci]
975  ).write();
976 
977 
978 
979  // From processor patch to reconstructed mesh patch
980 
981  Info<< "Writing boundaryProcAddressing to "
982  << databases[proci].caseName()
983  /procMesh.facesInstance()
985  << endl;
986 
988  (
989  IOobject
990  (
991  "boundaryProcAddressing",
992  procMesh.facesInstance(),
994  procMesh,
997  false // Do not register
998  ),
999  boundaryProcAddressing[proci]
1000  ).write();
1001 
1002  Info<< endl;
1003  }
1004  }
1005 
1006 
1007  Info<< "\nEnd\n" << endl;
1008 
1009  return 0;
1010 }
1011 
1012 
1013 // ************************************************************************* //
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
runTime
engineTime & runTime
Definition: createEngineTime.H:13
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
Foam::boundBox::mag
scalar mag() const
The magnitude of the bounding box span.
Definition: boundBoxI.H:133
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
Definition: dimensionSets.H:50
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::IOField
A primitive field of type <T> with automated input and output.
Definition: foamVtkLagrangianWriter.H:61
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::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:286
topoSet.H
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList< label >
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::Time::writeFormat
IOstream::streamFormat writeFormat() const
The write stream format.
Definition: Time.H:387
Foam::primitiveMesh::nFaces
label nFaces() const
Number of mesh faces.
Definition: primitiveMeshI.H:90
Foam::boundBox::invertedBox
static const boundBox invertedBox
A large inverted boundBox: min/max == +/- ROOTVGREAT.
Definition: boundBox.H:86
Foam::polyMesh::meshSubDir
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:315
polyTopoChange.H
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
oldTime
Info<< "Creating field kinetic energy K\n"<< endl;volScalarField K("K", 0.5 *magSqr(U));if(U.nOldTimes()){ volVectorField *Uold=&U.oldTime();volScalarField *Kold=&K.oldTime();*Kold==0.5 *magSqr(*Uold);while(Uold->nOldTimes()) { Uold=&Uold-> oldTime()
Definition: createK.H:12
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
Foam::timeSelector::select
instantList select(const instantList &times) const
Select a list of Time values that are within the ranges.
Definition: timeSelector.C:95
Foam::polyMesh::facesInstance
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:821
Foam::Map< label >
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:123
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1170
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
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:434
Foam::labelIOList
IOList< label > labelIOList
Label container classes.
Definition: labelIOList.H:44
Foam::Time::controlDictName
static word controlDictName
The default control dictionary name (normally "controlDict")
Definition: Time.H:226
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::argList::rootPath
const fileName & rootPath() const
Return root path.
Definition: argListI.H:63
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
fvMeshAdder.H
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fvMeshAdder::add
static autoPtr< mapAddedPolyMesh > add(fvMesh &mesh0, const fvMesh &mesh1, const faceCoupleInfo &coupleInfo, const bool validBoundary=true, const bool fullyMapped=false)
Inplace add mesh to fvMesh. Maps all stored fields. Returns map.
Definition: fvMeshAdder.C:72
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::primitiveMesh::nCells
label nCells() const
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::regIOobject::write
virtual bool write(const bool valid=true) const
Write using setting from DB.
Definition: regIOobjectWrite.C:165
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
Foam::fileOperation::nProcs
virtual label nProcs(const fileName &dir, const fileName &local="") const
Get number of processor directories/results. Used for e.g.
Definition: fileOperation.C:915
argList.H
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1076
addRegionOption.H
Foam::fvMesh::updateMesh
virtual void updateMesh(const mapPolyMesh &mpm)
Update mesh corresponding to the given map.
Definition: fvMesh.C:807
Foam::CompactIOList< face, label >
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:43
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:62
mapAddedPolyMesh.H
Foam::pow
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Definition: dimensionedScalar.C:75
faceCoupleInfo.H
timeName
word timeName
Definition: getTimeIndex.H:3
newPointi
label newPointi
Definition: readKivaGrid.H:496
Foam::argList::path
fileName path() const
Return the full path to the (processor local) case.
Definition: argListI.H:81
Foam::FatalError
error FatalError
processorPolyPatch.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
Foam::PtrList::set
const T * set(const label i) const
Return const pointer to element (if set) or nullptr.
Definition: PtrListI.H:143
polyMeshAdder.H
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:312
Foam::polyMeshAdder::findSharedPoints
static Map< label > findSharedPoints(const polyMesh &, const scalar mergeTol)
Find topologically and geometrically shared points.
Definition: polyMeshAdder.C:2000
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
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::renumber
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:37
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::Time::path
fileName path() const
Return path.
Definition: Time.H:358
Foam::IOstream::defaultPrecision
static unsigned int defaultPrecision()
Return the default precision.
Definition: IOstream.H:333
Foam::timeSelector::addOptions
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
Definition: timeSelector.C:108
Foam::List< label >
Foam::processorPolyPatch::newName
static word newName(const label myProcNo, const label neighbProcNo)
Return the name of a processorPolyPatch.
Definition: processorPolyPatch.C:186
Foam::Time::setTime
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:1006
labelIOList.H
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::primitiveMesh::nPoints
label nPoints() const
Number of mesh points.
Definition: primitiveMeshI.H:37
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::IOList< label >
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
timeSelector.H
createTime.H
Foam::HashTable::set
bool set(const Key &key, const T &obj)
Copy assign a new entry, overwriting existing entries.
Definition: HashTableI.H:190
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::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
Foam::argList::caseName
const fileName & caseName() const
Return case name (parallel run) or global case (serial run)
Definition: argListI.H:69
Foam::TimeState::timeIndex
label timeIndex() const
Return current time index.
Definition: TimeStateI.H:36
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:491
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:88
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
Foam::patchIdentifier::name
const word & name() const
The patch name.
Definition: patchIdentifier.H:134
Foam::polyMeshAdder::mergePoints
static void mergePoints(const polyMesh &, const Map< label > &pointToMaster, polyTopoChange &meshMod)
Helper: Merge points.
Definition: polyMeshAdder.C:2212
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157
Foam::boundBox::add
void add(const boundBox &bb)
Extend to include the second box.
Definition: boundBoxI.H:191
extrapolatedCalculatedFvPatchFields.H
Foam::IOobject::MUST_READ
Definition: IOobject.H:120
Foam::labelUIndList
UIndirectList< label > labelUIndList
UIndirectList of labels.
Definition: UIndirectList.H:58