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 -------------------------------------------------------------------------------
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 \*---------------------------------------------------------------------------*/
28 
29 #include "fvMesh.H"
30 #include "fvMeshAdder.H"
31 #include "faceCoupleInfo.H"
32 #include "polyTopoChange.H"
33 
34 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
35 
36 namespace Foam
37 {
38 defineTypeNameAndDebug(fvMeshAdder, 0);
39 }
40 
41 
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 
44 Foam::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
281  autoPtr<mapPolyMesh> mapPtr
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 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::UPtrList::size
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
polyTopoChange.H
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:99
Foam::UPtrList::get
T * get(const label i)
Definition: UPtrListI.H:120
Foam::fvPatch::New
static autoPtr< fvPatch > New(const polyPatch &, const fvBoundaryMesh &)
Return a pointer to a new patch created on freestore from polyPatch.
Definition: fvPatchNew.C:35
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::PtrList::set
const T * set(const label i) const
Return const pointer to element (can be nullptr),.
Definition: PtrList.H:138
Foam::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:61
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
fvMeshAdder.H
Foam::primitiveMesh::nPoints
label nPoints() const noexcept
Number of mesh points.
Definition: primitiveMeshI.H:37
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fvMeshAdder::add
static autoPtr< mapAddedPolyMesh > add(fvMesh &mesh0, const fvMesh &mesh1, const faceCoupleInfo &coupleInfo, const bool validBoundary=true, const bool fullyMapped=false)
Inplace add mesh to fvMesh. Maps all stored fields. Returns map.
Definition: fvMeshAdder.C:74
Foam::polyTopoChange::setCapacity
void setCapacity(const label nPoints, const label nFaces, const label nCells)
Definition: polyTopoChange.C:2449
Foam::fvBoundaryMesh
Foam::fvBoundaryMesh.
Definition: fvBoundaryMesh.H:57
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::polyMesh::cellZones
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
Definition: polyMesh.H:492
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
meshes
Foam::PtrList< Foam::fvMesh > meshes(regionNames.size())
Foam::PtrList::setSize
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:151
Foam::UPtrList
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: UPtrList.H:62
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:486
Foam::polyTopoChange::changeMesh
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.
Definition: polyTopoChange.C:2980
faceCoupleInfo.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::polyBoundaryMesh::nNonProcessor
label nNonProcessor() const
The number of patches before the first processor patch.
Definition: polyBoundaryMesh.C:535
Foam::fvMesh::boundary
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:685
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::UPtrList::set
const T * set(const label i) const
Definition: UPtrList.H:176
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::polyMesh::pointZones
const pointZoneMesh & pointZones() const noexcept
Return point zone mesh.
Definition: polyMesh.H:480
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::polyMeshAdder::add
static autoPtr< polyMesh > add(const IOobject &io, const polyMesh &mesh0, const polyMesh &mesh1, const faceCoupleInfo &coupleInfo, autoPtr< mapAddedPolyMesh > &mapPtr)
Add two polyMeshes. Returns new polyMesh and map construct.
Definition: polyMeshAdder.C:1452
Foam::faceCoupleInfo
Container for information needed to couple to meshes. When constructed from two meshes and a geometri...
Definition: faceCoupleInfo.H:160
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:62
Foam::primitiveMesh::nFaces
label nFaces() const noexcept
Number of mesh faces.
Definition: primitiveMeshI.H:90
Foam::mapAddedPolyMesh
Class containing mesh-to-mesh mapping information after a mesh addition where we add a mesh ('added m...
Definition: mapAddedPolyMesh.H:58
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::fvMesh::clearOut
void clearOut()
Clear all geometry and addressing.
Definition: fvMesh.C:239