reorderPatches.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2024 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 Application
25  reorderPatches
26 
27 Description
28  Utility to reorder the patches of a case
29 
30  The new patch order may be specified directly as a list of patch names
31  following the -patchOrder option or from the boundary file of a reference
32  case specified using the -referenceCase option with or without the
33  -referenceRegion option.
34 
35  This utility run either serial or parallel but either way the reference
36  case boundary file is read from the constant directory.
37 
38 Usage
39  \b reorderPatches
40 
41  Options:
42  - \par -patchOrder <patch names>
43  Specify the list of patch names in the new order.
44 
45  - \par -referenceCase <case path>
46  Specify the reference case path
47 
48  - \par -referenceRegion <name>
49  Specify an alternative mesh region for the reference case.
50  If -referenceCase is not specified the current case is used.
51 
52  - \par -overwrite \n
53  Replace the old mesh with the new one, rather than writing the new one
54  into a separate time directory
55 
56  - \par -region <name>
57  Specify an alternative mesh region.
58 
59 \*---------------------------------------------------------------------------*/
60 
61 #include "argList.H"
62 #include "fvMesh.H"
64 #include "timeSelector.H"
65 
66 using namespace Foam;
67 
68 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
69 
70 int main(int argc, char *argv[])
71 {
72  timeSelector::addOptions(true, false);
73 
75  (
76  "Utility to reorder the patches of a case.\n"
77  );
78 
79  #include "addOverwriteOption.H"
80  #include "addRegionOption.H"
81 
83  (
84  "patchOrder",
85  "wordList",
86  "specify the list of patch names in the new order"
87  );
88 
90  (
91  "referenceCase",
92  "fileName",
93  "specify the reference case path"
94  );
95 
97  (
98  "referenceRegion",
99  "word",
100  "specify the reference region"
101  );
102 
103  #include "setRootCase.H"
104 
105  wordList referencePatchNames;
106 
107  if (args.optionFound("patchOrder"))
108  {
109  args.optionLookup("patchOrder")() >> referencePatchNames;
110  }
111  else if
112  (
113  args.optionFound("referenceCase")
114  || args.optionFound("referenceRegion")
115  )
116  {
117  const fileName referenceCasePath
118  (
119  args.optionLookupOrDefault<fileName>("referenceCase", args.path())
120  );
121  const fileName rootDirReference = referenceCasePath.path().toAbsolute();
122  const fileName caseDirReference = referenceCasePath.name();
123 
124  const string caseDirOrig = getEnv("FOAM_CASE");
125  const string caseNameOrig = getEnv("FOAM_CASENAME");
126  setEnv("FOAM_CASE", rootDirReference/caseDirReference, true);
127  setEnv("FOAM_CASENAME", caseDirReference, true);
128  Time referenceRunTime
129  (
131  rootDirReference,
132  caseDirReference,
133  false
134  );
135  setEnv("FOAM_CASE", caseDirOrig, true);
136  setEnv("FOAM_CASENAME", caseNameOrig, true);
137 
138  word referenceRegion;
139  if (args.optionFound("referenceRegion"))
140  {
141  referenceRegion = args["referenceRegion"];
142  Info<< "Reference region: " << referenceRegion << endl;
143  }
144 
145  const fileName referenceMeshDir(referenceRegion/polyMesh::meshSubDir);
146 
148  (
149  "boundary",
150  referenceRunTime.findInstance
151  (
152  referenceMeshDir,
153  "boundary",
155  ),
156  referenceMeshDir,
157  referenceRunTime,
160  false
161  );
162 
163  if (ioObj.headerOk())
164  {
165  polyBoundaryMeshEntries patchEntries(ioObj);
166 
167  referencePatchNames.setSize(patchEntries.size());
168 
169  forAll(patchEntries, patchi)
170  {
171  referencePatchNames[patchi] = patchEntries[patchi].keyword();
172  }
173  }
174  else
175  {
177  << "Cannot find or read the boundary file for reference case "
178  << nl
179  << " " << referenceCasePath
180  << exit(FatalError);
181  }
182  }
183  else
184  {
186  << "Reference patch order not specified"
187  << exit(FatalError);
188  }
189 
192 
193  // Select time if specified
195 
196  const bool overwrite = args.optionFound("overwrite");
197 
198  const word oldInstance = mesh.pointsInstance();
199 
200  if (!overwrite)
201  {
202  runTime++;
203  }
204 
205  if
206  (
207  !Pstream::parRun()
208  && mesh.boundaryMesh().size() != referencePatchNames.size()
209  )
210  {
212  << "Number of reference patches " << referencePatchNames.size()
213  << " is not equal to the number of patches in the mesh "
214  << mesh.boundaryMesh().size()
215  << exit(FatalError);
216  }
217 
218  // Reorder the patches
219  labelList newToOldPatches(identityMap(mesh.boundaryMesh().size()));
220 
221  forAll(referencePatchNames, patchi)
222  {
223  const label oldPatchi =
224  mesh.boundaryMesh().findIndex(referencePatchNames[patchi]);
225 
226  if (oldPatchi != -1)
227  {
228  newToOldPatches[patchi] = oldPatchi;
229  }
230  else
231  {
233  << "Cannot find reference patch " << referencePatchNames[patchi]
234  << " in the mesh which has patches "
235  << mesh.boundaryMesh().names()
236  << exit(FatalError);
237  }
238  }
239  mesh.reorderPatches(newToOldPatches, false);
240 
241  if (overwrite)
242  {
243  mesh.setInstance(oldInstance);
244  }
245 
246  Info<< "Writing mesh to " << mesh.facesInstance() << endl;
247  mesh.write();
248 
249  Info<< "End\n" << endl;
250 
251  return 0;
252 }
253 
254 
255 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
virtual Ostream & write(const char)=0
Write character.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
static word controlDictName
The default control dictionary name (normally "controlDict")
Definition: Time.H:208
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
static void addOption(const word &opt, const string &param="", const string &usage="")
Add to an option to validOptions with usage information.
Definition: argList.C:128
static void addNote(const string &)
Add extra notes for the usage information.
Definition: argList.C:159
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:114
fileName path() const
Return the path to the caseName.
Definition: argListI.H:66
IStringStream optionLookup(const word &opt) const
Return an IStringStream from the named option.
Definition: argListI.H:120
T optionLookupOrDefault(const word &opt, const T &deflt) const
Read a value from the named option if present.
Definition: argListI.H:243
A class for handling file names.
Definition: fileName.H:82
word name() const
Return file name (part beyond last /)
Definition: fileName.C:195
fileName & toAbsolute()
Convert from relative to absolute.
Definition: fileName.C:79
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:265
Foam::polyBoundaryMeshEntries.
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:270
static void addOptions(const bool constant=true, const bool withZero=false)
Add the options handled by timeSelector to argList::validOptions.
Definition: timeSelector.C:114
static instantList selectIfPresent(Time &runTime, const argList &args)
If any time option provided return the set of times (as select0)
Definition: timeSelector.C:283
Templated form of IOobject providing type information for file reading and header type checking.
Definition: IOobject.H:531
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
int main(int argc, char *argv[])
Definition: financialFoam.C:44
label patchi
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
Definition: POSIX.C:115
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
messageStream Info
string getEnv(const word &)
Return environment variable of given name.
Definition: POSIX.C:97
error FatalError
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
static const char nl
Definition: Ostream.H:266
Foam::argList args(argc, argv)