Loading...
Searching...
No Matches
foamRestoreFields.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) 2018-2022 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26Application
27 foamRestoreFields
28
29Group
30 grpMiscUtilities
31
32Description
33 Adjust (restore) field names by removing the ending.
34 The fields are selected automatically or can be specified as optional
35 command arguments.
36
37 The operation 'mean' renames files ending with 'Mean' and makes
38 a backup of existing names, using the '.orig' ending.
39
40 The operation 'orig' renames files ending with '.orig'.
41
42Usage
43 \b foamRestoreFields [OPTION]
44
45 Options:
46 - \par -method mean | orig
47 The renaming method.
48
49 - \par -processor
50 Use processor directories, taking information from processor0/
51
52 - \par -dry-run
53 Test without actually moving/renaming files.
54
55 - \par -verbose
56 Additional verbosity.
57
58\*---------------------------------------------------------------------------*/
59
60#include "argList.H"
61#include "autoPtr.H"
62#include "profiling.H"
63#include "timeSelector.H"
64#include "Enum.H"
65#include "TimePaths.H"
66#include "ListOps.H"
67#include "stringOps.H"
68#include "regionProperties.H"
69#include "polyMesh.H"
70#include "Time.H"
71
72using namespace Foam;
73
74// Many ways to name processor directories
75//
76// Uncollated | "processor0", "processor1" ...
77// Collated | "processors<N>"
78// Host collated | "processors<N>_<low>-<high>"
79
80const regExp matcher("processors?[0-9]+(_[0-9]+-[0-9]+)?");
81
82bool isProcessorDir(const string& dir)
83{
84 return (dir.starts_with("processor") && matcher.match(dir));
85}
86
87
88//- The known and support types of operations
89enum restoreMethod
90{
91 MEAN,
92 ORIG
93};
94
95
96static const Enum<restoreMethod> methodNames
97{
98 { restoreMethod::MEAN, "mean" },
99 { restoreMethod::ORIG, "orig" },
100};
101
102
103static const Enum<restoreMethod> methodEndings
104{
105 { restoreMethod::MEAN, "Mean" },
106 { restoreMethod::ORIG, ".orig" },
107};
108
109
110// Files in given directory at time instant
111inline wordList getFiles(const fileName& dir, const word& instance)
112{
114 (
115 Foam::readDir(dir/instance, fileName::FILE),
117 );
118}
119
120
121// Command-line options: -dry-run, -verbose
122bool dryrun = false, verbose = false;
123
124
125// Use predefined method to walk the directory and rename the files.
126//
127// If no target names are specified, the existing files are scanned for
128// candidates.
129label restoreFields
130(
131 const restoreMethod method,
132 const fileName& dirName,
133 const wordHashSet& existingFiles,
134 const wordList& targetNames
135)
136{
137 // The file ending to search for.
138 const word ending(methodEndings[method]);
139
140 // The backup ending for existing (if any)
141 word bak;
142
143 switch (method)
144 {
145 case restoreMethod::MEAN:
146 bak = methodEndings[restoreMethod::ORIG];
147 break;
148
149 default:
150 break;
151 }
152
153 wordHashSet targets(targetNames);
154
155 if (targets.empty())
156 {
157 // No target names specified - scan existing files for candidates.
158
159 for (word f : existingFiles) // Operate on a copy
160 {
161 // Eg, check for "UMean" and save as "U"
162 if (f.removeEnd(ending) && f.size())
163 {
164 targets.insert(f);
165 }
166 }
167 }
168
169 if (verbose)
170 {
171 Info<< "directory " << dirName.name() << nl;
172 }
173
174 // Count of files moved, including backups
175 label count = 0;
176
177 for (const word& dst : targets)
178 {
179 const word src(dst + ending);
180
181 if (!existingFiles.found(src))
182 {
183 continue;
184 }
185
186 if (bak.size() && existingFiles.found(dst))
187 {
188 if (dryrun || Foam::mv(dirName/dst, dirName/dst + bak))
189 {
190 Info<< " mv " << dst << " " << word(dst + bak) << nl;
191 ++count;
192 }
193 }
194
195 if (dryrun || Foam::mv(dirName/src, dirName/dst))
196 {
197 Info<< " mv " << src << " " << dst << nl;
198 ++count;
199 }
200 }
201
202 return count;
203}
204
205
206// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
207
208int main(int argc, char *argv[])
209{
211 (
212 "Restore field names by removing the ending. Fields are selected"
213 " automatically or can be specified as optional command arguments"
214 );
215
216 profiling::disable(); // Disable profiling (and its output)
218 argList::noFunctionObjects(); // Never use function objects
220 (
221 "method",
222 "name",
223 "The restore method (mean|orig) [MANDATORY]. "
224 "With <mean> renames files ending with 'Mean' "
225 "(with backup of existing as '.orig'). "
226 "With <orig> renames files ending with '.orig'"
227 );
229 (
230 "processor",
231 "In serial mode use times from processor0/ directory, but operate on "
232 "processor\\d+ directories"
233 );
235 (
236 "Report action without moving/renaming"
237 );
239
240 // Arguments are optional (non-mandatory)
242 argList::addArgument("fieldName ... fieldName");
243
244 timeSelector::addOptions(true, true); // constant(true), zero(true)
245
246 #include "addAllRegionOptions.H"
247 #include "setRootCase.H"
248
249 wordList regionNames0;
250 {
251 // Dummy time just for the database to read regionProperties
252
253 autoPtr<Time> dummyTimePtr(Time::New(args));
254
255 const auto& runTime = *dummyTimePtr;
256
257 // Handle -allRegions, -regions, -region
258 #include "getAllRegionOptions.H"
259
260 regionNames0 = std::move(regionNames);
261 }
262
263 dryrun = args.dryRun();
264 verbose = args.verbose();
265
266
267 // Construct time
268 // ~~~~~~~~~~~~~~
269
270 restoreMethod method = restoreMethod::ORIG;
271 {
272 word methodName;
273
274 if
275 (
276 args.readIfPresent("method", methodName)
277 && methodNames.found(methodName)
278 )
279 {
280 method = methodNames[methodName];
281 }
282 else
283 {
284 Info<< "Unspecified or unknown method name" << nl
285 << "Valid methods: "
286 << flatOutput(methodNames.sortedToc()) << nl
287 << "... stopping" << nl << nl;
288 return 1;
289 }
290 }
291
292 // Optional base or target field names (eg, 'U', 'T' etc)
293 wordList targetNames;
294 if (args.size() > 1)
295 {
296 targetNames.resize(args.size()-1);
297 wordHashSet uniq;
298
299 for (label argi=1; argi < args.size(); ++argi)
300 {
301 if (uniq.insert(args[argi]))
302 {
303 targetNames[uniq.size()-1] = args[argi];
304 }
305 }
306
307 targetNames.resize(uniq.size());
308
309 if (verbose)
310 {
311 Info<< nl
312 << "using method=" << methodNames[method] << nl
313 << "with fields " << flatOutput(targetNames) << nl;
314 }
315 }
316 else if (verbose)
317 {
318 Info<< nl
319 << "using method=" << methodNames[method] << nl
320 << "autodetect fields" << nl;
321 }
322
323
324 // Get times list from the master processor and subset based on
325 // command-line options
326
327 label nProcs = 0;
328 autoPtr<TimePaths> timePaths;
329
330 if (args.found("processor") && !Pstream::parRun())
331 {
332 // Determine the processor count
333 nProcs = fileHandler().nProcs(args.path());
334
335 if (!nProcs)
336 {
338 << "No processor* directories found"
339 << exit(FatalError);
340 }
341
342 // Obtain time directory names from "processor0/" only
343 timePaths = autoPtr<TimePaths>::New
344 (
345 args.rootPath(),
346 args.caseName()/"processor0"
347 );
348 }
349 else
350 {
351 timePaths = autoPtr<TimePaths>::New
352 (
353 args.rootPath(),
354 args.caseName()
355 );
356 }
357
358 const instantList timeDirs(timeSelector::select(timePaths->times(), args));
359
360 fileNameList procDirs;
361 label leadProcIdx = -1;
362
363 if (timeDirs.empty())
364 {
365 Info<< "No times selected" << nl;
366 }
367 else if (nProcs)
368 {
369 procDirs =
371 (
372 args.path(),
374 false, // No gzip anyhow
375 false // Do not follow linkts
376 );
377
378 inplaceSubsetList(procDirs, isProcessorDir);
379
380 // Perhaps not needed
382
383 // Decide who will be the "leading" processor for obtaining names
384 // - processor0
385 // - processors<N>
386 // - processors<N>_0-<high>
387
388 // Uncollated
389 leadProcIdx = procDirs.find("processor0");
390
391 if (!procDirs.empty())
392 {
393 if (leadProcIdx < 0)
394 {
395 // Collated
396 leadProcIdx = procDirs.find("processors" + Foam::name(nProcs));
397 }
398
399 if (leadProcIdx < 0)
400 {
401 // Host-collated
402 const std::string prefix
403 (
404 "processors" + Foam::name(nProcs) + "_0-"
405 );
406
407 forAll(procDirs, idx)
408 {
409 if (procDirs[idx].starts_with(prefix))
410 {
411 leadProcIdx = idx;
412 break;
413 }
414 }
415 }
416
417 // Just default to anything (safety)
418 if (leadProcIdx < 0)
419 {
420 leadProcIdx = 0;
421 }
422 }
423 }
424
425
426 for (const instant& t : timeDirs)
427 {
428 const word& timeName = t.name();
429
430 Info<< "\nTime = " << timeName << nl;
431
432 for (const word& regionName : regionNames0)
433 {
435
436 if (regionNames0.size() > 1)
437 {
438 Info<< "region = " << regionName << nl;
439 }
440
441 label count = 0;
442 wordList files;
443
444 if (nProcs)
445 {
446 if (leadProcIdx >= 0)
447 {
448 files =
449 getFiles
450 (
451 args.path()/procDirs[leadProcIdx],
453 );
454 }
455
456 for (const fileName& procDir : procDirs)
457 {
458 count += restoreFields
459 (
460 method,
461 args.path()/procDir/timeName/regionDir,
462 wordHashSet(files),
463 targetNames
464 );
465 }
466 }
467 else
468 {
469 if (Pstream::master())
470 {
471 files = getFiles(args.path(), timeName/regionDir);
472 }
473 Pstream::broadcast(files);
474
475 count += restoreFields
476 (
477 method,
478 args.path()/timeName/regionDir,
479 wordHashSet(files),
480 targetNames
481 );
482 }
483
484 if (dryrun)
485 {
486 Info<< "dry-run: ";
487 }
488 Info<< "moved " << count << " files" << nl;
489 }
490 }
491 Info<< "\nEnd\n" << endl;
492 return 0;
493}
494
495
496// ************************************************************************* //
Various functions to operate on Lists.
Required Classes.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition Enum.H:57
List< word > sortedToc() const
The sorted list of enum names.
Definition EnumI.H:63
bool found(const word &key) const
Same as contains().
Definition Enum.H:480
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition HashSet.H:229
label size() const noexcept
The number of elements in table.
Definition HashTable.H:358
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
static void broadcast(Type &value, const int communicator=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all communicator ranks. Does nothing in non-paral...
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition TimeNew.C:26
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
label find(const T &val) const
Find index of the first occurrence of the value.
Definition UList.C:160
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition argList.C:562
static void addVerboseOption(const string &usage="", bool advanced=false)
Enable a 'verbose' bool option, with usage information.
Definition argList.C:535
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition argList.C:366
static void noJobInfo()
Suppress JobInfo, overriding controlDict setting.
Definition argList.C:582
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a 'dry-run' bool option, with usage information.
Definition argList.C:519
static void noMandatoryArgs()
Flag command arguments as being optional (non-mandatory).
Definition argList.C:494
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition argList.C:389
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:400
static void addNote(const string &note)
Add extra notes for the usage information.
Definition argList.C:477
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition autoPtr.H:178
A class for handling file names.
Definition fileName.H:75
@ FILE
A regular file.
Definition fileName.H:84
@ DIRECTORY
A directory.
Definition fileName.H:85
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition fileNameI.H:192
An instant of time. Contains the time value and name. Uses Foam::Time when formatting the name.
Definition instant.H:56
static const word & regionName(const word &region)
The mesh region name or word::null if polyMesh::defaultRegion.
Definition polyMesh.C:796
static void disable() noexcept
Disallow profiling - turns the InfoSwitch off.
Definition profiling.C:113
bool starts_with(char c) const
True if string starts with given character (cf. C++20).
Definition string.H:436
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
instantList select(const instantList &times) const
Select a list of Time values that are within the ranges.
A class for handling words, derived from Foam::string.
Definition word.H:66
engineTime & runTime
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
const word & regionDir
wordList regionNames
word timeName
Definition getTimeIndex.H:3
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition BitOps.H:73
List< T > create(const UList< T2 > &input, const UnaryOperation &op)
Create a List from a List of a dissimilar type, using the entire list.
Namespace for OpenFOAM.
List< word > wordList
List of word.
Definition fileName.H:60
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
Definition HashSet.H:80
List< fileName > fileNameList
List of fileName.
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler().
messageStream Info
Information stream (stdout output on master, null elsewhere).
List< instant > instantList
List of instants.
Definition instantList.H:41
regExpCxx regExp
Selection of preferred regular expression implementation.
Definition regExpFwd.H:37
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
void inplaceSubsetList(ListType &input, const UnaryPredicate &pred, const bool invert=false)
Inplace subset of the list when predicate is true.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition FlatOutput.H:217
void sort(UList< T > &list)
Sort the list.
Definition UList.C:283
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition POSIX.C:1326
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
fileNameList readDir(const fileName &directory, const fileName::Type type=fileName::Type::FILE, const bool filtergz=true, const bool followLink=true)
Read a directory and return the entries as a fileName List.
Definition POSIX.C:965
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
labelList f(nPoints)
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Extract name (as a word) from an object, typically using its name() method.
Definition word.H:341
Encapsulation of natural order sorting for algorithms.