fvMeshAdder.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) 2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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\*---------------------------------------------------------------------------*/
28
29#include "fvMesh.H"
30#include "fvMeshAdder.H"
31#include "faceCoupleInfo.H"
32#include "polyTopoChange.H"
33
34/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
35
36namespace Foam
37{
39}
40
41
42// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43
44Foam::labelList Foam::fvMeshAdder::calcPatchMap
45(
46 const label oldStart,
47 const label oldSize,
48 const labelList& oldToNew,
49 const polyPatch& newPatch,
50 const label unmappedValue
51)
52{
53 labelList newToOld(newPatch.size(), unmappedValue);
54
55 const label newStart = newPatch.start();
56 const label newSize = newPatch.size();
57
58 for (label i = 0; i < oldSize; i++)
59 {
60 label newFacei = oldToNew[oldStart+i];
61
62 if (newFacei >= newStart && newFacei < newStart+newSize)
63 {
64 newToOld[newFacei-newStart] = i;
65 }
66 }
67 return newToOld;
68}
69
70
71// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
72
74(
75 fvMesh& mesh0,
76 const fvMesh& mesh1,
77 const faceCoupleInfo& coupleInfo,
78 const bool validBoundary,
79 const bool fullyMapped
80)
81{
82 mesh0.clearOut();
83
84 // Resulting merged mesh (polyMesh only!)
86 (
88 (
89 mesh0,
90 mesh1,
91 coupleInfo,
92 validBoundary
93 )
94 );
95 mapAddedPolyMesh& map = *mapPtr;
96
97 // Adjust the fvMesh part.
98 const polyBoundaryMesh& patches = mesh0.boundaryMesh();
99
100 fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh0.boundary());
101 fvPatches.setSize(patches.size());
102 forAll(patches, patchi)
103 {
104 fvPatches.set(patchi, fvPatch::New(patches[patchi], fvPatches));
105 }
106
107 // Do the mapping of the stored fields
108 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
109 fvMeshAdder::MapVolFields<scalar>(map, mesh0, mesh1, fullyMapped);
110 fvMeshAdder::MapVolFields<vector>(map, mesh0, mesh1, fullyMapped);
111 fvMeshAdder::MapVolFields<sphericalTensor>(map, mesh0, mesh1, fullyMapped);
112 fvMeshAdder::MapVolFields<symmTensor>(map, mesh0, mesh1, fullyMapped);
113 fvMeshAdder::MapVolFields<tensor>(map, mesh0, mesh1, fullyMapped);
114
115 fvMeshAdder::MapSurfaceFields<scalar>(map, mesh0, mesh1, fullyMapped);
116 fvMeshAdder::MapSurfaceFields<vector>(map, mesh0, mesh1, fullyMapped);
117 fvMeshAdder::MapSurfaceFields<sphericalTensor>
118 (
119 map, mesh0, mesh1, fullyMapped
120 );
121 fvMeshAdder::MapSurfaceFields<symmTensor>(map, mesh0, mesh1, fullyMapped);
122 fvMeshAdder::MapSurfaceFields<tensor>(map, mesh0, mesh1, fullyMapped);
123
124 fvMeshAdder::MapDimFields<scalar>(map, mesh0, mesh1);
125 fvMeshAdder::MapDimFields<vector>(map, mesh0, mesh1);
126 fvMeshAdder::MapDimFields<sphericalTensor>(map, mesh0, mesh1);
127 fvMeshAdder::MapDimFields<symmTensor>(map, mesh0, mesh1);
128 fvMeshAdder::MapDimFields<tensor>(map, mesh0, mesh1);
129
130 return mapPtr;
131}
132
133
135(
136 const label myProci, // index of mesh to modify
137 UPtrList<fvMesh>& fvMeshes,
138 const labelList& oldFaceOwner, // face owner for myProci mesh
139
140 // Coupling info
141 const labelListList& localBoundaryFace,
142 const labelListList& remoteFaceProc,
143 const labelListList& remoteBoundaryFace,
144
145 labelListList& constructPatchMap,
146 labelListList& constructCellMap,
147 labelListList& constructFaceMap,
148 labelListList& constructPointMap
149)
150{
151 // Do in-place addition. Modifies fvMeshes[myProci]
152
153 UPtrList<polyMesh> meshes(fvMeshes.size());
154 forAll(fvMeshes, proci)
155 {
156 if (fvMeshes.set(proci))
157 {
158 meshes.set(proci, &fvMeshes[proci]);
159 }
160 }
161
162
163 // All matched faces assumed to have vertex0 matched
164 labelListList remoteFaceStart(meshes.size());
165 forAll(localBoundaryFace, proci)
166 {
167 const labelList& procFaces = localBoundaryFace[proci];
168 remoteFaceStart[proci].setSize(procFaces.size(), 0);
169 }
170
171 // Assume all meshes have same global patches
172 labelListList patchMap(meshes.size());
173 labelListList pointZoneMap(meshes.size());
174 labelListList faceZoneMap(meshes.size());
175 labelListList cellZoneMap(meshes.size());
176 forAll(meshes, proci)
177 {
178 if (meshes.set(proci))
179 {
180 const polyMesh& mesh = meshes[proci];
181 patchMap[proci] = identity(mesh.boundaryMesh().nNonProcessor());
182 pointZoneMap[proci] = identity(mesh.pointZones().size());
183 faceZoneMap[proci] = identity(mesh.faceZones().size());
184 cellZoneMap[proci] = identity(mesh.cellZones().size());
185 }
186 }
187
188
189 // Swap myProci to 0th element
190 if (myProci != 0)
191 {
192 polyMesh* pm0 = meshes.get(0);
193 polyMesh* pmi = meshes.get(myProci);
194 meshes.set(0, pmi);
195 meshes.set(myProci, pm0);
196
197 fvMesh* fvm0 = fvMeshes.get(0);
198 fvMesh* fvmi = fvMeshes.get(myProci);
199 fvMeshes.set(0, fvmi);
200 fvMeshes.set(myProci, fvm0);
201
202 //Pout<< "swapped from 0 to " << myProci << endl;
203 //forAll(meshes, meshi)
204 //{
205 // Pout<< "meshi:" << meshi << endl;
206 // if (meshes.set(meshi))
207 // {
208 // Pout<< " nCells:" << meshes[meshi].nCells() << endl;
209 // }
210 //}
211
212
213 // Swap (and renumber) patch face information
214 labelListList& lbf = const_cast<labelListList&>(localBoundaryFace);
215 std::swap(lbf[0], lbf[myProci]);
216
217 labelListList& rfp = const_cast<labelListList&>(remoteFaceProc);
218 std::swap(rfp[0], rfp[myProci]);
219 forAll(rfp, proci)
220 {
221 for (label& proc : rfp[proci])
222 {
223 if (proc == 0) proc = myProci;
224 else if (proc == myProci) proc = 0;
225 }
226 }
227 labelListList& rbf = const_cast<labelListList&>(remoteBoundaryFace);
228 std::swap(rbf[0], rbf[myProci]);
229
230 labelListList& rfs = const_cast<labelListList&>(remoteFaceStart);
231 std::swap(rfs[0], rfs[myProci]);
232
233 // Swap optional renumbering maps
234 std::swap(patchMap[0], patchMap[myProci]);
235 std::swap(pointZoneMap[0], pointZoneMap[myProci]);
236 std::swap(faceZoneMap[0], faceZoneMap[myProci]);
237 std::swap(cellZoneMap[0], cellZoneMap[myProci]);
238 }
239
240 polyTopoChange meshMod(meshes[0].boundaryMesh().size(), true);
241 // Collect statistics for sizing
242 label nCells = 0;
243 label nFaces = 0;
244 label nPoints = 0;
245 forAll(meshes, proci)
246 {
247 if (meshes.set(proci))
248 {
249 const polyMesh& mesh = meshes[proci];
250 nCells += mesh.nCells();
251 nFaces += mesh.nFaces();
252 nPoints += mesh.nPoints();
253 }
254 }
255 meshMod.setCapacity(nPoints, nFaces, nCells);
256
257 // Add all cells in meshes' order
259 (
260 meshes,
261 patchMap,
262
263 // Information on (one-to-one) boundary faces to stitch
264 localBoundaryFace,
265 remoteFaceProc,
266 remoteBoundaryFace,
267 remoteFaceStart,
268
269 pointZoneMap,
270 faceZoneMap,
271 cellZoneMap,
272
273 meshMod,
274
275 constructCellMap,
276 constructFaceMap,
277 constructPointMap
278 );
279
280 // Replace mesh
282 (
283 meshMod.changeMesh
284 (
285 fvMeshes[0], // note: still swapped to position 0
286 false // no inflation
287 )
288 );
289
290 // Update fields. Note that this tries to interpolate from the mesh
291 // before adding all the remote meshes so is quite wrong.
292 //fvMeshes[0.updateMesh(mapPtr());
293 // Update polyMesh but not fvMesh to avoid mapping all the fields
294 fvMeshes[0].polyMesh::updateMesh(mapPtr());
295
296 // Now reverseFaceMap contains from order in which face was added
297 // to mesh face (after e.g. upper-triangular ordering)
298
299 // Renumber output of any mesh ordering done by changeMesh
300 for (labelList& cellMap : constructCellMap)
301 {
302 inplaceRenumber(mapPtr().reverseCellMap(), cellMap);
303 }
304 for (labelList& faceMap : constructFaceMap)
305 {
306 inplaceRenumber(mapPtr().reverseFaceMap(), faceMap);
307 }
308 for (labelList& pointMap : constructPointMap)
309 {
310 inplaceRenumber(mapPtr().reversePointMap(), pointMap);
311 }
312
313 // constructPatchMap is patchMap with -1 for the removed
314 // patches
315 forAll(meshes, meshi)
316 {
317 if (meshes.set(meshi))
318 {
319 constructPatchMap[meshi] = patchMap[meshi];
320 constructPatchMap[meshi].setSize
321 (
322 meshes[meshi].boundaryMesh().size(),
323 -1
324 );
325 }
326 }
327
328
329 // Map all fields
330 fvMeshAdder::MapVolFields<scalar>
331 (
332 fvMeshes,
333 mapPtr().oldPatchStarts(),
334 mapPtr().oldPatchSizes(),
335 patchMap,
336 constructCellMap,
337 constructFaceMap,
338 constructPointMap
339 );
340 fvMeshAdder::MapVolFields<vector>
341 (
342 fvMeshes,
343 mapPtr().oldPatchStarts(),
344 mapPtr().oldPatchSizes(),
345 patchMap,
346 constructCellMap,
347 constructFaceMap,
348 constructPointMap
349 );
350 fvMeshAdder::MapVolFields<sphericalTensor>
351 (
352 fvMeshes,
353 mapPtr().oldPatchStarts(),
354 mapPtr().oldPatchSizes(),
355 patchMap,
356 constructCellMap,
357 constructFaceMap,
358 constructPointMap
359 );
360 fvMeshAdder::MapVolFields<symmTensor>
361 (
362 fvMeshes,
363 mapPtr().oldPatchStarts(),
364 mapPtr().oldPatchSizes(),
365 patchMap,
366 constructCellMap,
367 constructFaceMap,
368 constructPointMap
369 );
370 fvMeshAdder::MapVolFields<tensor>
371 (
372 fvMeshes,
373 mapPtr().oldPatchStarts(),
374 mapPtr().oldPatchSizes(),
375 patchMap,
376 constructCellMap,
377 constructFaceMap,
378 constructPointMap
379 );
380 fvMeshAdder::MapSurfaceFields<scalar>
381 (
382 fvMeshes,
383 oldFaceOwner,
384 mapPtr().oldPatchStarts(),
385 mapPtr().oldPatchSizes(),
386 patchMap,
387 constructCellMap,
388 constructFaceMap,
389 constructPointMap
390 );
391 fvMeshAdder::MapSurfaceFields<vector>
392 (
393 fvMeshes,
394 oldFaceOwner,
395 mapPtr().oldPatchStarts(),
396 mapPtr().oldPatchSizes(),
397 patchMap,
398 constructCellMap,
399 constructFaceMap,
400 constructPointMap
401 );
402 fvMeshAdder::MapSurfaceFields<sphericalTensor>
403 (
404 fvMeshes,
405 oldFaceOwner,
406 mapPtr().oldPatchStarts(),
407 mapPtr().oldPatchSizes(),
408 patchMap,
409 constructCellMap,
410 constructFaceMap,
411 constructPointMap
412 );
413 fvMeshAdder::MapSurfaceFields<symmTensor>
414 (
415 fvMeshes,
416 oldFaceOwner,
417 mapPtr().oldPatchStarts(),
418 mapPtr().oldPatchSizes(),
419 patchMap,
420 constructCellMap,
421 constructFaceMap,
422 constructPointMap
423 );
424 fvMeshAdder::MapSurfaceFields<tensor>
425 (
426 fvMeshes,
427 oldFaceOwner,
428 mapPtr().oldPatchStarts(),
429 mapPtr().oldPatchSizes(),
430 patchMap,
431 constructCellMap,
432 constructFaceMap,
433 constructPointMap
434 );
435 fvMeshAdder::MapDimFields<scalar>(fvMeshes, constructCellMap);
436 fvMeshAdder::MapDimFields<vector>(fvMeshes, constructCellMap);
437 fvMeshAdder::MapDimFields<sphericalTensor>(fvMeshes, constructCellMap);
438 fvMeshAdder::MapDimFields<symmTensor>(fvMeshes, constructCellMap);
439 fvMeshAdder::MapDimFields<tensor>(fvMeshes, constructCellMap);
440
441 // Swap returned data back to processor order
442 if (myProci != 0)
443 {
444 fvMesh* fvm0 = fvMeshes.get(0);
445 fvMesh* fvmi = fvMeshes.get(myProci);
446 fvMeshes.set(0, fvmi);
447 fvMeshes.set(myProci, fvm0);
448
449 // Swap (and renumber) patch face information
450 labelListList& lbf = const_cast<labelListList&>(localBoundaryFace);
451 std::swap(lbf[0], lbf[myProci]);
452 labelListList& rfp = const_cast<labelListList&>(remoteFaceProc);
453 std::swap(rfp[0], rfp[myProci]);
454 forAll(rfp, proci)
455 {
456 for (label& proc : rfp[proci])
457 {
458 if (proc == 0) proc = myProci;
459 else if (proc == myProci) proc = 0;
460 }
461 }
462 labelListList& rbf = const_cast<labelListList&>(remoteBoundaryFace);
463 std::swap(rbf[0], rbf[myProci]);
464
465 std::swap(constructPatchMap[0], constructPatchMap[myProci]);
466 std::swap(constructCellMap[0], constructCellMap[myProci]);
467 std::swap(constructFaceMap[0], constructFaceMap[myProci]);
468 std::swap(constructPointMap[0], constructPointMap[myProci]);
469 }
470
471 return mapPtr;
472}
473
474
475// ************************************************************************* //
void setSize(const label n)
Alias for resize()
Definition: List.H:218
const T * set(const label i) const
Definition: PtrList.H:138
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:151
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: UPtrList.H:71
const T * set(const label i) const
Definition: UPtrList.H:248
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
T * get(const label i)
Definition: UPtrListI.H:127
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:63
Container for information needed to couple to meshes. When constructed from two meshes and a geometri...
Sums a given list of (at least two or more) fields and outputs the result into a new field,...
Definition: add.H:161
Foam::fvBoundaryMesh.
Adds two fvMeshes without using any polyMesh morphing. Uses polyMeshAdder.
Definition: fvMeshAdder.H:70
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:712
void clearOut()
Clear all geometry and addressing.
Definition: fvMesh.C:239
Class containing mesh-to-mesh mapping information after a mesh addition where we add a mesh ('added m...
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
label nNonProcessor() const
The number of patches before the first processor patch.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:498
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:456
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
Definition: polyMesh.H:504
const pointZoneMesh & pointZones() const noexcept
Return point zone mesh.
Definition: polyMesh.H:492
Direct mesh changes based on v1.3 polyTopoChange syntax.
void setCapacity(const label nPoints, const label nFaces, const label nCells)
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, const labelUList &patchMap, const bool inflate, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
label nPoints() const noexcept
Number of mesh points.
label nCells() const noexcept
Number of mesh cells.
label nFaces() const noexcept
Number of mesh faces.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
const polyBoundaryMesh & patches
dynamicFvMesh & mesh
Foam::PtrList< Foam::fvMesh > meshes(regionNames.size())
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
label nPoints
Namespace for OpenFOAM.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:38
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
List< label > labelList
A List of labels.
Definition: List.H:66
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333