mapFields.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) 2011-2022 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  mapFields
26 
27 Description
28  Maps volume fields from one mesh to another, reading and
29  interpolating all fields present in the time directory of both cases.
30  Parallel and non-parallel cases are handled without the need to reconstruct
31  them first.
32 
33 \*---------------------------------------------------------------------------*/
34 
35 #include "argList.H"
36 #include "mapMeshes.H"
37 #include "decompositionMethod.H"
38 
39 using namespace Foam;
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 int main(int argc, char *argv[])
44 {
46  (
47  "map volume fields from one mesh to another"
48  );
50  argList::validArgs.append("sourceCase");
51 
53  (
54  "sourceTime",
55  "scalar|'latestTime'",
56  "specify the source time"
57  );
59  (
60  "sourceRegion",
61  "word",
62  "specify the source region"
63  );
65  (
66  "targetRegion",
67  "word",
68  "specify the target region"
69  );
71  (
72  "parallelSource",
73  "the source is decomposed"
74  );
76  (
77  "parallelTarget",
78  "the target is decomposed"
79  );
81  (
82  "consistent",
83  "source and target geometry and boundary conditions identical"
84  );
86  (
87  "mapMethod",
88  "word",
89  "specify the mapping method"
90  );
91 
92  argList args(argc, argv);
93 
94  if (!args.check())
95  {
96  FatalError.exit();
97  }
98 
99  fileName rootDirTarget(args.rootPath());
100  fileName caseDirTarget(args.globalCaseName());
101 
102  fileName casePath = args[1];
103  const fileName rootDirSource = casePath.path().toAbsolute();
104  const fileName caseDirSource = casePath.name();
105 
106  Info<< "Source: " << rootDirSource << " " << caseDirSource << endl;
107  word sourceRegion = fvMesh::defaultRegion;
108  if (args.optionFound("sourceRegion"))
109  {
110  sourceRegion = args["sourceRegion"];
111  Info<< "Source region: " << sourceRegion << endl;
112  }
113 
114  Info<< "Target: " << rootDirTarget << " " << caseDirTarget << endl;
115  word targetRegion = fvMesh::defaultRegion;
116  if (args.optionFound("targetRegion"))
117  {
118  targetRegion = args["targetRegion"];
119  Info<< "Target region: " << targetRegion << endl;
120  }
121 
122  const bool parallelSource = args.optionFound("parallelSource");
123  const bool parallelTarget = args.optionFound("parallelTarget");
124  const bool consistent = args.optionFound("consistent");
125 
127  if (args.optionFound("mapMethod"))
128  {
129  const word mapMethod(args["mapMethod"]);
130  if (mapMethod == "mapNearest")
131  {
132  mapOrder = meshToMesh0::MAP;
133  }
134  else if (mapMethod == "interpolate")
135  {
136  mapOrder = meshToMesh0::INTERPOLATE;
137  }
138  else if (mapMethod == "cellPointInterpolate")
139  {
141  }
142  else
143  {
145  << "Unknown mapMethod " << mapMethod << ". Valid options are: "
146  << "mapNearest, interpolate and cellPointInterpolate"
147  << exit(FatalError);
148  }
149 
150  Info<< "Mapping method: " << mapMethod << endl;
151  }
152 
153 
154  #include "createTimes.H"
155 
156  HashTable<word> patchMap;
157  wordList cuttingPatches;
158 
159  if (!consistent)
160  {
161  IOdictionary mapFieldsDict
162  (
163  IOobject
164  (
165  "mapFieldsDict",
170  false
171  )
172  );
173 
174  mapFieldsDict.lookup("patchMap") >> patchMap;
175  mapFieldsDict.lookup("cuttingPatches") >> cuttingPatches;
176  }
177 
178  if (parallelSource && !parallelTarget)
179  {
180  const int nProcs
181  (
183  (
184  "numberOfSubdomains"
185  )
186  );
187 
188  Info<< "Create target mesh\n" << endl;
189 
190  fvMesh meshTarget
191  (
192  IOobject
193  (
194  targetRegion,
197  ),
198  false
199  );
200 
201  Info<< "Target mesh size: " << meshTarget.nCells() << endl;
202 
203  for (int proci=0; proci<nProcs; proci++)
204  {
205  Info<< nl << "Source processor " << proci << endl;
206 
208  (
210  rootDirSource,
211  caseDirSource/fileName(word("processor") + name(proci))
212  );
213 
214  #include "setTimeIndex.H"
215 
216  fvMesh meshSource
217  (
218  IOobject
219  (
220  sourceRegion,
223  ),
224  false
225  );
226 
227  Info<< "mesh size: " << meshSource.nCells() << endl;
228 
229  if (consistent)
230  {
232  (
233  meshSource,
234  meshTarget,
235  mapOrder
236  );
237  }
238  else
239  {
240  mapSubMesh
241  (
242  meshSource,
243  meshTarget,
244  patchMap,
245  cuttingPatches,
246  mapOrder
247  );
248  }
249  }
250  }
251  else if (!parallelSource && parallelTarget)
252  {
253  const int nProcs
254  (
256  (
257  "numberOfSubdomains"
258  )
259  );
260 
261  Info<< "Create source mesh\n" << endl;
262 
263  #include "setTimeIndex.H"
264 
265  fvMesh meshSource
266  (
267  IOobject
268  (
269  sourceRegion,
272  ),
273  false
274  );
275 
276  Info<< "Source mesh size: " << meshSource.nCells() << endl;
277 
278  for (int proci=0; proci<nProcs; proci++)
279  {
280  Info<< nl << "Target processor " << proci << endl;
281 
283  (
285  rootDirTarget,
286  caseDirTarget/fileName(word("processor") + name(proci))
287  );
288 
289  fvMesh meshTarget
290  (
291  IOobject
292  (
293  targetRegion,
296  ),
297  false
298  );
299 
300  Info<< "mesh size: " << meshTarget.nCells() << endl;
301 
302  if (consistent)
303  {
305  (
306  meshSource,
307  meshTarget,
308  mapOrder
309  );
310  }
311  else
312  {
313  mapSubMesh
314  (
315  meshSource,
316  meshTarget,
317  patchMap,
318  addProcessorPatches(meshTarget, cuttingPatches),
319  mapOrder
320  );
321  }
322  }
323  }
324  else if (parallelSource && parallelTarget)
325  {
326  const int nProcsSource
327  (
329  (
330  "numberOfSubdomains"
331  )
332  );
333 
334  const int nProcsTarget
335  (
337  (
338  "numberOfSubdomains"
339  )
340  );
341 
342  List<boundBox> bbsTarget(nProcsTarget);
343  List<bool> bbsTargetSet(nProcsTarget, false);
344 
345  for (int procISource=0; procISource<nProcsSource; procISource++)
346  {
347  Info<< nl << "Source processor " << procISource << endl;
348 
350  (
352  rootDirSource,
353  caseDirSource/fileName(word("processor") + name(procISource))
354  );
355 
356  #include "setTimeIndex.H"
357 
358  fvMesh meshSource
359  (
360  IOobject
361  (
362  sourceRegion,
365  ),
366  false
367  );
368 
369  Info<< "mesh size: " << meshSource.nCells() << endl;
370 
371  boundBox bbSource(meshSource.bounds());
372 
373  for (int procITarget=0; procITarget<nProcsTarget; procITarget++)
374  {
375  if
376  (
377  !bbsTargetSet[procITarget]
378  || (
379  bbsTargetSet[procITarget]
380  && bbsTarget[procITarget].overlaps(bbSource)
381  )
382  )
383  {
384  Info<< nl << "Target processor " << procITarget << endl;
385 
387  (
389  rootDirTarget,
390  caseDirTarget/fileName(word("processor")
391  + name(procITarget))
392  );
393 
394  fvMesh meshTarget
395  (
396  IOobject
397  (
398  targetRegion,
401  ),
402  false
403  );
404 
405  Info<< "mesh size: " << meshTarget.nCells() << endl;
406 
407  bbsTarget[procITarget] = meshTarget.bounds();
408  bbsTargetSet[procITarget] = true;
409 
410  if (bbsTarget[procITarget].overlaps(bbSource))
411  {
412  if (consistent)
413  {
415  (
416  meshSource,
417  meshTarget,
418  mapOrder
419  );
420  }
421  else
422  {
423  mapSubMesh
424  (
425  meshSource,
426  meshTarget,
427  patchMap,
428  addProcessorPatches(meshTarget, cuttingPatches),
429  mapOrder
430  );
431  }
432  }
433  }
434  }
435  }
436  }
437  else
438  {
439  #include "setTimeIndex.H"
440 
441  Info<< "Create meshes\n" << endl;
442 
443  fvMesh meshSource
444  (
445  IOobject
446  (
447  sourceRegion,
450  ),
451  false
452  );
453 
454  fvMesh meshTarget
455  (
456  IOobject
457  (
458  targetRegion,
461  ),
462  false
463  );
464 
465  Info<< "Source mesh size: " << meshSource.nCells() << tab
466  << "Target mesh size: " << meshTarget.nCells() << nl << endl;
467 
468  if (consistent)
469  {
470  mapConsistentMesh(meshSource, meshTarget, mapOrder);
471  }
472  else
473  {
474  mapSubMesh
475  (
476  meshSource,
477  meshTarget,
478  patchMap,
479  cuttingPatches,
480  mapOrder
481  );
482  }
483  }
484 
485  Info<< "\nEnd\n" << endl;
486 
487  return 0;
488 }
489 
490 
491 // ************************************************************************* //
An STL-conforming hash table.
Definition: HashTable.H:127
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:119
static const word & system()
Return system name.
Definition: TimePaths.H:112
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:204
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:103
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
const fileName & globalCaseName() const
Return case name.
Definition: argListI.H:54
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
Definition: argList.C:118
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:114
static void noParallel()
Remove the parallel options.
Definition: argList.C:175
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:153
const fileName & rootPath() const
Return root path.
Definition: argListI.H:42
bool check(bool checkArgs=true, bool checkOpts=true) const
Check argument list.
Definition: argList.C:1400
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:59
static dictionary decomposeParDict(const Time &time)
Read and return the decomposeParDict.
const word & name() const
Return const reference to name.
void exit(const int errNo=1)
Exit : can be called for any error to exit program.
Definition: error.C:125
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
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:101
order
Enumeration specifying required accuracy.
Definition: meshToMesh0.H:144
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:268
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
int main(int argc, char *argv[])
Definition: financialFoam.C:44
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
void mapSubMesh(const fvMesh &meshSource, const fvMesh &meshTarget, const HashTable< word > &patchMap, const wordList &cuttingPatches, const meshToMesh0::order &mapOrder)
static const char tab
Definition: Ostream.H:259
messageStream Info
void mapConsistentMesh(const fvMesh &meshSource, const fvMesh &meshTarget, const meshToMesh0::order &mapOrder)
error FatalError
wordList addProcessorPatches(const fvMesh &meshTarget, const wordList &cuttingPatches)
static const char nl
Definition: Ostream.H:260
void mapConsistentSubMesh(const fvMesh &meshSource, const fvMesh &meshTarget, const meshToMesh0::order &mapOrder)
Time runTimeSource(Time::controlDictName, argsSrc)
Time runTimeTarget(Time::controlDictName, args)
Foam::argList args(argc, argv)