loadOrCreateMesh.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) 2012-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "loadOrCreateMesh.H"
30 #include "faMesh.H"
31 #include "Pstream.H"
32 #include "OSspecific.H"
33 #include "decomposedBlockData.H"
34 
35 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
36 
37 bool Foam::checkFileExistence(const fileName& fName)
38 {
39  // Trimmed-down version of lookupAndCacheProcessorsPath
40  // with Foam::exists() check. No caching.
41 
42  // Check for two conditions:
43  // - file has to exist
44  // - if collated the entry has to exist inside the file
45 
46  // Note: bypass fileOperation::filePath(IOobject&) since has problems
47  // with going to a different number of processors
48  // (in collated format). Use file-based searching instead
49 
50  const auto& handler = Foam::fileHandler();
51  typedef fileOperation::procRangeType procRangeType;
52 
53  fileName path, pDir, local;
54  procRangeType group;
55  label numProcs;
56  const label proci =
57  fileOperation::splitProcessorPath
58  (fName, path, pDir, local, group, numProcs);
59 
60  bool found = false;
61 
62  if (proci != -1)
63  {
64  // Read all directories to see any beginning with processor
65  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66 
67  const fileNameList dirEntries
68  (
69  handler.readDir(path, fileName::Type::DIRECTORY)
70  );
71 
72  // Extract info from processorN or processorsNN
73  // - highest processor number
74  // - directory+offset containing data for proci
75 
76  // label nProcs = 0;
77  for (const fileName& dirN : dirEntries)
78  {
79  // Analyse directory name
80  fileName rp, rd, rl;
81  label rNum;
82  const label readProci =
83  fileOperation::splitProcessorPath
84  (dirN, rp, rd, rl, group, rNum);
85 
86  if (proci == readProci)
87  {
88  // Found "processorN"
89  if (Foam::exists(path/dirN/local))
90  {
91  found = true;
92  break;
93  }
94  }
95  else if (rNum != -1)
96  {
97  // "processorsNN" or "processorsNN_start-end"
98  if (group.empty())
99  {
100  // "processorsNN"
101  if (proci < rNum && Foam::exists(path/dirN/local))
102  {
103  found = true;
104  break;
105  }
106  }
107  else if (group.contains(proci))
108  {
109  // "processorsNN_start-end"
110  // - save the local proc offset
111 
112  if (Foam::exists(path/dirN/local))
113  {
114  found = true;
115  break;
116  }
117  }
118  }
119  }
120  }
121 
122  if (!found)
123  {
124  found = Foam::exists(fName);
125  }
126 
127  return found;
128 }
129 
130 
132 (
133  const Time& runTime,
134  const fileName& meshPath,
135  const word& meshFile,
136  const bool verbose
137 )
138 {
139  #if 0
140 
141  // Simple directory scanning - too fragile
142  bool found = checkFileExistence(runTime.path()/meshPath/meshFile);
143 
144  #else
145 
146  // Trimmed-down version of lookupAndCacheProcessorsPath
147  // with Foam::exists() check. No caching.
148 
149  // Check for two conditions:
150  // - file has to exist
151  // - if collated the entry has to exist inside the file
152 
153  // Note: bypass fileOperation::filePath(IOobject&) since has problems
154  // with going to a different number of processors
155  // (in collated format). Use file-based searching instead
156 
157  const auto& handler = Foam::fileHandler();
158  typedef fileOperation::procRangeType procRangeType;
159 
160  const fileName fName
161  (
162  handler.filePath(runTime.path()/meshPath/meshFile)
163  );
164 
165  bool found = handler.isFile(fName);
166  if (returnReduceAnd(found)) // worldComm
167  {
168  autoPtr<ISstream> isPtr(fileHandler().NewIFstream(fName));
169  if (isPtr && isPtr->good())
170  {
171  auto& is = *isPtr;
172 
173  IOobject io(meshFile, meshPath, runTime);
174  io.readHeader(is);
175 
176  if (decomposedBlockData::isCollatedType(io))
177  {
178  fileName path, pDir, local;
179  procRangeType group;
180  label numProcs;
181  label proci = fileOperation::splitProcessorPath
182  (
183  fName,
184  path,
185  pDir,
186  local,
187  group,
188  numProcs
189  );
190 
191  label myBlockNumber = 0;
192  if (proci == -1 && group.empty())
193  {
194  // 'processorsXXX' format so contains all ranks
195  // according to worldComm
196  myBlockNumber = UPstream::myProcNo(UPstream::worldComm);
197  }
198  else
199  {
200  // 'processorsXXX_n-m' format so check for the
201  // relative rank
202  myBlockNumber = UPstream::myProcNo(fileHandler().comm());
203  }
204 
205  // Check if block for the local rank is inside file
206  found = decomposedBlockData::hasBlock(is, myBlockNumber);
207  }
208  }
209  }
210  #endif
211 
212  // Globally consistent information about who has a mesh
213  boolList haveFileOnProc
214  (
215  UPstream::allGatherValues<bool>(found, UPstream::worldComm)
216  );
217 
218  if (verbose)
219  {
220  Info<< "Per processor availability of \""
221  << meshFile << "\" file in " << meshPath << nl
222  << " " << flatOutput(haveFileOnProc) << nl << endl;
223  }
224 
225  return haveFileOnProc;
226 }
227 
228 
229 void Foam::removeProcAddressing(const faMesh& mesh)
230 {
231  IOobject io
232  (
233  "procAddressing",
234  mesh.facesInstance(),
235  faMesh::meshSubDir,
236  mesh.thisDb()
237  );
238 
239  for (const auto prefix : {"boundary", "edge", "face", "point"})
240  {
241  io.rename(prefix + word("ProcAddressing"));
242 
243  const fileName procFile(io.objectPath());
244  Foam::rm(procFile);
245  }
246 }
247 
248 
249 void Foam::removeProcAddressing(const polyMesh& mesh)
250 {
251  IOobject io
252  (
253  "procAddressing",
254  mesh.facesInstance(),
255  polyMesh::meshSubDir,
256  mesh.thisDb()
257  );
258 
259  for (const auto prefix : {"boundary", "cell", "face", "point"})
260  {
261  io.rename(prefix + word("ProcAddressing"));
262 
263  const fileName procFile(io.objectPath());
264  Foam::rm(procFile);
265  }
266 }
267 
268 
270 (
271  const IOobject& io,
272  fileName& facesInstance,
273  fileName& pointsInstance
274 )
275 {
276  const fileName meshSubDir
277  (
278  polyMesh::meshDir(io.name())
279  );
280 
281  if (UPstream::master())
282  {
283  const bool oldParRun = UPstream::parRun(false);
284  const label oldNumProcs = fileHandler().nProcs();
285  const int oldCache = fileOperation::cacheLevel(0);
286 
287  facesInstance = io.time().findInstance
288  (
289  meshSubDir,
290  "faces",
291  IOobjectOption::MUST_READ
292  );
293  pointsInstance = io.time().findInstance
294  (
295  meshSubDir,
296  "points",
297  IOobjectOption::MUST_READ
298  );
299 
300  fileOperation::cacheLevel(oldCache);
301  if (oldParRun)
302  {
303  const_cast<fileOperation&>(fileHandler()).nProcs(oldNumProcs);
304  }
305  UPstream::parRun(oldParRun);
306  }
307 
308  // Broadcast information to all
309  Pstream::broadcasts
310  (
311  UPstream::worldComm,
312  facesInstance,
313  pointsInstance
314  );
315 }
316 
317 
318 // ************************************************************************* //
boolList haveMeshFile(const Time &runTime, const fileName &meshPath, const word &meshFile="faces", const bool verbose=true)
Check for availability of specified mesh file (default: "faces")
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler()
constexpr const char *const group
Group name for atomic constants.
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
bool returnReduceAnd(const bool value, const label comm=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
dynamicFvMesh & mesh
void masterMeshInstance(const IOobject &io, fileName &facesInstance, fileName &pointsInstance)
Determine master faces instance.
regionProperties rp(runTime)
Miscellaneous file handling for meshes.
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:835
bool local
Definition: EEqn.H:20
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
bool checkFileExistence(const fileName &fName)
Check for availability of given file.
messageStream Info
Information stream (stdout output on master, null elsewhere)
void removeProcAddressing(const faMesh &mesh)
Remove procAddressing.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
List< fileName > fileNameList
List of fileName.
Definition: fileNameList.H:32
List< bool > boolList
A List of bools.
Definition: List.H:60
bool found
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1404