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-2025 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  meshTarget.postConstruct
202  (
203  false,
204  false,
206  );
207 
208  Info<< "Target mesh size: " << meshTarget.nCells() << endl;
209 
210  for (int proci=0; proci<nProcs; proci++)
211  {
212  Info<< nl << "Source processor " << proci << endl;
213 
215  (
217  rootDirSource,
218  caseDirSource/fileName(word("processor") + name(proci))
219  );
220 
221  #include "setTimeIndex.H"
222 
223  fvMesh meshSource
224  (
225  IOobject
226  (
227  sourceRegion,
230  ),
231  false
232  );
233 
234  meshSource.postConstruct
235  (
236  false,
237  false,
239  );
240 
241  Info<< "mesh size: " << meshSource.nCells() << endl;
242 
243  if (consistent)
244  {
246  (
247  meshSource,
248  meshTarget,
249  mapOrder
250  );
251  }
252  else
253  {
254  mapSubMesh
255  (
256  meshSource,
257  meshTarget,
258  patchMap,
259  cuttingPatches,
260  mapOrder
261  );
262  }
263  }
264  }
265  else if (!parallelSource && parallelTarget)
266  {
267  const int nProcs
268  (
270  (
271  "numberOfSubdomains"
272  )
273  );
274 
275  Info<< "Create source mesh\n" << endl;
276 
277  #include "setTimeIndex.H"
278 
279  fvMesh meshSource
280  (
281  IOobject
282  (
283  sourceRegion,
286  ),
287  false
288  );
289 
290  meshSource.postConstruct
291  (
292  false,
293  false,
295  );
296 
297  Info<< "Source mesh size: " << meshSource.nCells() << endl;
298 
299  for (int proci=0; proci<nProcs; proci++)
300  {
301  Info<< nl << "Target processor " << proci << endl;
302 
304  (
306  rootDirTarget,
307  caseDirTarget/fileName(word("processor") + name(proci))
308  );
309 
310  fvMesh meshTarget
311  (
312  IOobject
313  (
314  targetRegion,
317  ),
318  false
319  );
320 
321  meshTarget.postConstruct
322  (
323  false,
324  false,
326  );
327 
328  Info<< "mesh size: " << meshTarget.nCells() << endl;
329 
330  if (consistent)
331  {
333  (
334  meshSource,
335  meshTarget,
336  mapOrder
337  );
338  }
339  else
340  {
341  mapSubMesh
342  (
343  meshSource,
344  meshTarget,
345  patchMap,
346  addProcessorPatches(meshTarget, cuttingPatches),
347  mapOrder
348  );
349  }
350  }
351  }
352  else if (parallelSource && parallelTarget)
353  {
354  const int nProcsSource
355  (
357  (
358  "numberOfSubdomains"
359  )
360  );
361 
362  const int nProcsTarget
363  (
365  (
366  "numberOfSubdomains"
367  )
368  );
369 
370  List<boundBox> bbsTarget(nProcsTarget);
371  List<bool> bbsTargetSet(nProcsTarget, false);
372 
373  for (int procISource=0; procISource<nProcsSource; procISource++)
374  {
375  Info<< nl << "Source processor " << procISource << endl;
376 
378  (
380  rootDirSource,
381  caseDirSource/fileName(word("processor") + name(procISource))
382  );
383 
384  #include "setTimeIndex.H"
385 
386  fvMesh meshSource
387  (
388  IOobject
389  (
390  sourceRegion,
393  ),
394  false
395  );
396 
397  meshSource.postConstruct
398  (
399  false,
400  false,
402  );
403 
404  Info<< "mesh size: " << meshSource.nCells() << endl;
405 
406  boundBox bbSource(meshSource.bounds());
407 
408  for (int procITarget=0; procITarget<nProcsTarget; procITarget++)
409  {
410  if
411  (
412  !bbsTargetSet[procITarget]
413  || (
414  bbsTargetSet[procITarget]
415  && bbsTarget[procITarget].overlaps(bbSource)
416  )
417  )
418  {
419  Info<< nl << "Target processor " << procITarget << endl;
420 
422  (
424  rootDirTarget,
425  caseDirTarget/fileName(word("processor")
426  + name(procITarget))
427  );
428 
429  fvMesh meshTarget
430  (
431  IOobject
432  (
433  targetRegion,
436  ),
437  false
438  );
439 
440  meshTarget.postConstruct
441  (
442  false,
443  false,
445  );
446 
447  Info<< "mesh size: " << meshTarget.nCells() << endl;
448 
449  bbsTarget[procITarget] = meshTarget.bounds();
450  bbsTargetSet[procITarget] = true;
451 
452  if (bbsTarget[procITarget].overlaps(bbSource))
453  {
454  if (consistent)
455  {
457  (
458  meshSource,
459  meshTarget,
460  mapOrder
461  );
462  }
463  else
464  {
465  mapSubMesh
466  (
467  meshSource,
468  meshTarget,
469  patchMap,
470  addProcessorPatches(meshTarget, cuttingPatches),
471  mapOrder
472  );
473  }
474  }
475  }
476  }
477  }
478  }
479  else
480  {
481  #include "setTimeIndex.H"
482 
483  Info<< "Create meshes\n" << endl;
484 
485  fvMesh meshSource
486  (
487  IOobject
488  (
489  sourceRegion,
492  ),
493  false
494  );
495 
496  meshSource.postConstruct
497  (
498  false,
499  false,
501  );
502 
503  fvMesh meshTarget
504  (
505  IOobject
506  (
507  targetRegion,
510  ),
511  false
512  );
513 
514  meshTarget.postConstruct
515  (
516  false,
517  false,
519  );
520 
521  Info<< "Source mesh size: " << meshSource.nCells() << tab
522  << "Target mesh size: " << meshTarget.nCells() << nl << endl;
523 
524  if (consistent)
525  {
526  mapConsistentMesh(meshSource, meshTarget, mapOrder);
527  }
528  else
529  {
530  mapSubMesh
531  (
532  meshSource,
533  meshTarget,
534  patchMap,
535  cuttingPatches,
536  mapOrder
537  );
538  }
539  }
540 
541  Info<< "\nEnd\n" << endl;
542 
543  return 0;
544 }
545 
546 
547 // ************************************************************************* //
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:208
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 IOdictionary 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:284
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:96
order
Enumeration specifying required accuracy.
Definition: meshToMesh0.H:143
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:270
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
Time runTimeSource(Time::controlDictName, argsSrc)
Time runTimeTarget(Time::controlDictName, args)
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:258
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:266
messageStream Info
void mapConsistentMesh(const fvMesh &meshSource, const fvMesh &meshTarget, const meshToMesh0::order &mapOrder)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
error FatalError
wordList addProcessorPatches(const fvMesh &meshTarget, const wordList &cuttingPatches)
static const char nl
Definition: Ostream.H:267
void mapConsistentSubMesh(const fvMesh &meshSource, const fvMesh &meshTarget, const meshToMesh0::order &mapOrder)
Foam::argList args(argc, argv)