mapFieldsPar.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2021 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 Application
28  mapFieldsPar
29 
30 Group
31  grpPreProcessingUtilities
32 
33 Description
34  Maps volume fields from one mesh to another, reading and
35  interpolating all fields present in the time directory of both cases.
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #include "fvCFD.H"
40 #include "meshToMesh.H"
41 #include "processorPolyPatch.H"
42 #include "MapMeshes.H"
43 
44 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 
46 void mapConsistentMesh
47 (
48  const fvMesh& meshSource,
49  const fvMesh& meshTarget,
50  const word& mapMethod,
51  const word& AMIMapMethod,
52  const word& procMapMethod,
53  const bool subtract,
54  const wordRes& selectedFields,
55  const bool noLagrangian
56 )
57 {
58  Info<< nl << "Consistently creating and mapping fields for time "
59  << meshSource.time().timeName() << nl << endl;
60 
61  meshToMesh interp
62  (
63  meshSource,
64  meshTarget,
65  mapMethod,
66  AMIMapMethod,
67  meshToMesh::procMapMethodNames_[procMapMethod]
68  );
69 
70  if (subtract)
71  {
72  MapMesh<minusEqOp>
73  (
74  interp,
75  selectedFields,
76  noLagrangian
77  );
78  }
79  else
80  {
81  MapMesh<plusEqOp>
82  (
83  interp,
84  selectedFields,
85  noLagrangian
86  );
87  }
88 }
89 
90 
91 void mapSubMesh
92 (
93  const fvMesh& meshSource,
94  const fvMesh& meshTarget,
95  const HashTable<word>& patchMap,
96  const wordList& cuttingPatches,
97  const word& mapMethod,
98  const word& AMIMapMethod,
99  const word& procMapMethod,
100  const bool subtract,
101  const wordRes& selectedFields,
102  const bool noLagrangian
103 )
104 {
105  Info<< nl << "Creating and mapping fields for time "
106  << meshSource.time().timeName() << nl << endl;
107 
108  meshToMesh interp
109  (
110  meshSource,
111  meshTarget,
112  mapMethod,
113  AMIMapMethod,
114  patchMap,
115  cuttingPatches,
116  meshToMesh::procMapMethodNames_[procMapMethod]
117  );
118 
119  if (subtract)
120  {
121  MapMesh<minusEqOp>
122  (
123  interp,
124  selectedFields,
125  noLagrangian
126  );
127  }
128  else
129  {
130  MapMesh<plusEqOp>
131  (
132  interp,
133  selectedFields,
134  noLagrangian
135  );
136  }
137 }
138 
139 
140 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
141 
142 int main(int argc, char *argv[])
143 {
144  argList::addNote
145  (
146  "Map volume fields from one mesh to another"
147  );
148 
149  argList::addArgument("sourceCase");
150 
151  argList::addOption
152  (
153  "sourceTime",
154  "scalar|'latestTime'",
155  "Specify the source time"
156  );
157  argList::addOption
158  (
159  "sourceRegion",
160  "word",
161  "Specify the source region"
162  );
163  argList::addOption
164  (
165  "targetRegion",
166  "word",
167  "Specify the target region"
168  );
169  argList::addBoolOption
170  (
171  "consistent",
172  "Source and target geometry and boundary conditions identical"
173  );
174  argList::addOption
175  (
176  "mapMethod",
177  "word",
178  "Specify the mapping method "
179  "(direct|mapNearest|cellVolumeWeight|correctedCellVolumeWeight)"
180  );
181  argList::addOption
182  (
183  "patchMapMethod",
184  "word",
185  "Specify the patch mapping method (direct|mapNearest|faceAreaWeight)"
186  );
187  argList::addOption
188  (
189  "procMapMethod",
190  "word",
191  "Specify the processor distribution map method (AABB|LOD)"
192  );
193  argList::addBoolOption
194  (
195  "subtract",
196  "Subtract mapped source from target"
197  );
198  argList::addOption
199  (
200  "fields",
201  "wordRes",
202  "Specify single or multiple fields to reconstruct (all by default)."
203  " Eg, 'T' or '(p T U \"alpha.*\")'"
204  );
205 
206  argList::addBoolOption
207  (
208  "no-lagrangian", // noLagrangian
209  "Skip mapping lagrangian positions and fields"
210  );
211  argList::addOptionCompat("no-lagrangian", {"noLagrangian", 2106});
212 
213  argList args(argc, argv);
214  #include "foamDlOpenLibs.H"
215 
216  fileName rootDirTarget(args.rootPath());
217  fileName caseDirTarget(args.globalCaseName());
218 
219  const auto casePath = args.get<fileName>(1);
220  const fileName rootDirSource = casePath.path();
221  const fileName caseDirSource = casePath.name();
222 
223  Info<< "Source: " << rootDirSource << ' ' << caseDirSource;
224  word sourceRegion(polyMesh::defaultRegion);
225  if (args.readIfPresent("sourceRegion", sourceRegion))
226  {
227  Info<< " (region " << sourceRegion << ')';
228  }
229  Info<< endl;
230 
231  Info<< "Target: " << rootDirTarget << ' ' << caseDirTarget;
232  word targetRegion(polyMesh::defaultRegion);
233  if (args.readIfPresent("targetRegion", targetRegion))
234  {
235  Info<< " (region " << targetRegion << ')';
236  }
237  Info<< endl;
238 
239  const bool consistent = args.found("consistent");
240 
241 
242  word mapMethod = meshToMesh::interpolationMethodNames_
243  [
244  meshToMesh::interpolationMethod::imCellVolumeWeight
245  ];
246 
247  if (args.readIfPresent("mapMethod", mapMethod))
248  {
249  Info<< "Mapping method: " << mapMethod << endl;
250  }
251 
252  word patchMapMethod;
253  if (meshToMesh::interpolationMethodNames_.found(mapMethod))
254  {
255  // Lookup corresponding AMI method
256  meshToMesh::interpolationMethod method =
257  meshToMesh::interpolationMethodNames_[mapMethod];
258 
259  patchMapMethod = meshToMesh::interpolationMethodAMI(method);
260  }
261 
262  word procMapMethod =
263  meshToMesh::procMapMethodNames_
264  [
265  meshToMesh::procMapMethod::pmAABB
266  ];
267 
268  if (args.readIfPresent("procMapMethod", procMapMethod))
269  {
270  Info<< "Processor map method: " << procMapMethod << endl;
271  }
272 
273 
274  // Optionally override
275  if (args.readIfPresent("patchMapMethod", patchMapMethod))
276  {
277  Info<< "Patch mapping method: " << patchMapMethod << endl;
278  }
279 
280 
281  if (patchMapMethod.empty())
282  {
284  << "No valid patchMapMethod for method " << mapMethod
285  << ". Please supply one through the 'patchMapMethod' option"
286  << exit(FatalError);
287  }
288 
289  const bool subtract = args.found("subtract");
290  if (subtract)
291  {
292  Info<< "Subtracting mapped source field from target" << endl;
293  }
294 
295  // Non-mandatory
296  const wordRes selectedFields(args.getList<wordRe>("fields", false));
297 
298  const bool noLagrangian = args.found("no-lagrangian");
299 
300  #include "createTimes.H"
301 
302  HashTable<word> patchMap;
303  wordList cuttingPatches;
304 
305  if (!consistent)
306  {
307  IOdictionary mapFieldsDict
308  (
309  IOobject
310  (
311  "mapFieldsDict",
312  runTimeTarget.system(),
314  IOobject::MUST_READ_IF_MODIFIED,
315  IOobject::NO_WRITE,
316  false
317  )
318  );
319 
320  mapFieldsDict.readEntry("patchMap", patchMap);
321  mapFieldsDict.readEntry("cuttingPatches", cuttingPatches);
322  }
323 
324  #include "setTimeIndex.H"
325 
326  Info<< "\nCreate meshes\n" << endl;
327 
328  fvMesh meshSource
329  (
330  IOobject
331  (
332  sourceRegion,
333  runTimeSource.timeName(),
335  )
336  );
337 
338  fvMesh meshTarget
339  (
340  IOobject
341  (
342  targetRegion,
343  runTimeTarget.timeName(),
345  )
346  );
347 
348  Info<< "Source mesh size: " << meshSource.globalData().nTotalCells() << tab
349  << "Target mesh size: " << meshTarget.globalData().nTotalCells()
350  << nl << endl;
351 
352  if (consistent)
353  {
354  mapConsistentMesh
355  (
356  meshSource,
357  meshTarget,
358  mapMethod,
359  patchMapMethod,
360  procMapMethod,
361  subtract,
362  selectedFields,
363  noLagrangian
364  );
365  }
366  else
367  {
368  mapSubMesh
369  (
370  meshSource,
371  meshTarget,
372  patchMap,
373  cuttingPatches,
374  mapMethod,
375  patchMapMethod,
376  procMapMethod,
377  subtract,
378  selectedFields,
379  noLagrangian
380  );
381  }
382 
383  runTimeSource.printExecutionTime(Info);
384 
385  Info<< "\nEnd\n" << endl;
386 
387  return 0;
388 }
389 
390 
391 // ************************************************************************* //
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
List< T > getList(const label index) const
Get a List of values from the argument at index.
const fileName & globalCaseName() const noexcept
Return global case name.
Definition: argListI.H:68
constexpr char tab
The tab &#39;\t&#39; character(0x09)
Definition: Ostream.H:48
void subtract(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Time runTimeTarget(Time::controlDictName, args)
Time runTimeSource(Time::controlDictName, argsSrc)
const fileName & rootPath() const noexcept
Return root path.
Definition: argListI.H:56
List< word > wordList
A List of words.
Definition: fileName.H:58
T get(const label index) const
Get a value from the argument at index.
Definition: argListI.H:271
messageStream Info
Information stream (stdout output on master, null elsewhere)
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:316
Foam::argList args(argc, argv)
bool found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171