slidingInterfaceAttachedAddressing.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) 2017-2020 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 "slidingInterface.H"
30 #include "polyMesh.H"
31 #include "mapPolyMesh.H"
32 #include "polyTopoChanger.H"
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 void Foam::slidingInterface::calcAttachedAddressing() const
37 {
38  if (debug)
39  {
41  << " for object " << name() << " : "
42  << "Calculating zone face-cell addressing."
43  << endl;
44  }
45 
46  if (!attached_)
47  {
48  // Clear existing addressing
49  clearAttachedAddressing();
50 
51  const polyMesh& mesh = topoChanger().mesh();
52  const labelList& own = mesh.faceOwner();
53  const labelList& nei = mesh.faceNeighbour();
54  const faceZoneMesh& faceZones = mesh.faceZones();
55 
56  // Master side
57 
58  const primitiveFacePatch& masterPatch =
59  faceZones[masterFaceZoneID_.index()]();
60 
61  const labelList& masterPatchFaces =
62  faceZones[masterFaceZoneID_.index()];
63 
64  const boolList& masterFlip =
65  faceZones[masterFaceZoneID_.index()].flipMap();
66 
67  masterFaceCellsPtr_.reset(new labelList(masterPatchFaces.size()));
68  auto& mfc = *masterFaceCellsPtr_;
69 
70  forAll(masterPatchFaces, facei)
71  {
72  if (masterFlip[facei])
73  {
74  mfc[facei] = nei[masterPatchFaces[facei]];
75  }
76  else
77  {
78  mfc[facei] = own[masterPatchFaces[facei]];
79  }
80  }
81 
82  // Slave side
83 
84  const primitiveFacePatch& slavePatch =
85  faceZones[slaveFaceZoneID_.index()]();
86 
87  const labelList& slavePatchFaces =
88  faceZones[slaveFaceZoneID_.index()];
89 
90  const boolList& slaveFlip =
91  faceZones[slaveFaceZoneID_.index()].flipMap();
92 
93  slaveFaceCellsPtr_.reset(new labelList(slavePatchFaces.size()));
94  auto& sfc = *slaveFaceCellsPtr_;
95 
96  forAll(slavePatchFaces, facei)
97  {
98  if (slaveFlip[facei])
99  {
100  sfc[facei] = nei[slavePatchFaces[facei]];
101  }
102  else
103  {
104  sfc[facei] = own[slavePatchFaces[facei]];
105  }
106  }
107 
108  // Check that the addressing is valid
109  if (min(mfc) < 0 || min(sfc) < 0)
110  {
111  if (debug)
112  {
113  forAll(mfc, facei)
114  {
115  if (mfc[facei] < 0)
116  {
117  Pout<< "No cell next to master patch face " << facei
118  << ". Global face no: " << mfc[facei]
119  << " own: " << own[masterPatchFaces[facei]]
120  << " nei: " << nei[masterPatchFaces[facei]]
121  << " flip: " << masterFlip[facei] << endl;
122  }
123  }
124 
125  forAll(sfc, facei)
126  {
127  if (sfc[facei] < 0)
128  {
129  Pout<< "No cell next to slave patch face " << facei
130  << ". Global face no: " << sfc[facei]
131  << " own: " << own[slavePatchFaces[facei]]
132  << " nei: " << nei[slavePatchFaces[facei]]
133  << " flip: " << slaveFlip[facei] << endl;
134  }
135  }
136  }
137 
139  << "decoupled mesh or sliding interface definition."
140  << abort(FatalError);
141  }
142 
143  // Calculate stick-out faces
144  const labelListList& pointFaces = mesh.pointFaces();
145 
146  labelHashSet stickOutFaceMap
147  (
149  * max(masterPatch.size(), slavePatch.size())
150  );
151 
152  // Master side
153  const labelList& masterMeshPoints = masterPatch.meshPoints();
154 
155  stickOutFaceMap.clear();
156 
157  for (const label pointi : masterMeshPoints)
158  {
159  for (const label facei : pointFaces[pointi])
160  {
161  const label zoneIdx = faceZones.whichZone(facei);
162 
163  // Add if face not already part of master or slave face zone
164  // This handles partially attached faces.
165  if
166  (
167  zoneIdx != masterFaceZoneID_.index()
168  && zoneIdx != slaveFaceZoneID_.index()
169  )
170  {
171  stickOutFaceMap.insert(facei);
172  }
173  }
174  }
175 
176  masterStickOutFacesPtr_.reset(new labelList(stickOutFaceMap.toc()));
177 
178  // Sort in debug mode for easier diagnostics
179  if (debug)
180  {
181  Foam::sort(*masterStickOutFacesPtr_);
182  }
183 
184  // Slave side
185  const labelList& slaveMeshPoints = slavePatch.meshPoints();
186 
187  stickOutFaceMap.clear();
188 
189  for (const label pointi : slaveMeshPoints)
190  {
191  for (const label facei : pointFaces[pointi])
192  {
193  const label zoneIdx = faceZones.whichZone(facei);
194 
195  // Add if face not already part of master or slave face zone
196  // This handles partially attached faces.
197  if
198  (
199  zoneIdx != masterFaceZoneID_.index()
200  && zoneIdx != slaveFaceZoneID_.index()
201  )
202  {
203  stickOutFaceMap.insert(facei);
204  }
205  }
206  }
207 
208  slaveStickOutFacesPtr_.reset(new labelList(stickOutFaceMap.toc()));
209 
210  // Sort in debug mode for easier diagnostics
211  if (debug)
212  {
213  Foam::sort(*slaveStickOutFacesPtr_);
214  }
215 
216  stickOutFaceMap.clear();
217 
218  // Retired point addressing does not exist at this stage.
219  // It will be filled when the interface is coupled.
220  retiredPointMapPtr_.reset
221  (
222  new Map<label>
223  (
224  2*faceZones[slaveFaceZoneID_.index()]().nPoints()
225  )
226  );
227 
228  // Ditto for cut point edge map. This is a rough guess of its size
229  cutPointEdgePairMapPtr_.reset
230  (
231  new Map<Pair<edge>>
232  (
233  faceZones[slaveFaceZoneID_.index()]().nEdges()
234  )
235  );
236  }
237  else
238  {
240  << "cannot be assembled for object " << name()
241  << abort(FatalError);
242  }
243 
244  if (debug)
245  {
247  << " for object " << name() << " : "
248  << "Finished calculating zone face-cell addressing."
249  << endl;
250  }
251 }
252 
253 
254 void Foam::slidingInterface::clearAttachedAddressing() const
255 {
256  masterFaceCellsPtr_.reset(nullptr);
257  slaveFaceCellsPtr_.reset(nullptr);
258 
259  masterStickOutFacesPtr_.reset(nullptr);
260  slaveStickOutFacesPtr_.reset(nullptr);
261 
262  retiredPointMapPtr_.reset(nullptr);
263  cutPointEdgePairMapPtr_.reset(nullptr);
264 }
265 
266 
267 void Foam::slidingInterface::renumberAttachedAddressing
268 (
269  const mapPolyMesh& m
270 ) const
271 {
272  // Get reference to reverse cell renumbering
273  // The renumbering map is needed the other way around, i.e. giving
274  // the new cell number for every old cell next to the interface.
275  const labelList& reverseCellMap = m.reverseCellMap();
276 
277  const labelList& mfc = masterFaceCells();
278  const labelList& sfc = slaveFaceCells();
279 
280  // Master side
281  std::unique_ptr<labelList> newMfcPtr(new labelList(mfc.size(), -1));
282  auto& newMfc = *newMfcPtr;
283 
284  const labelList& mfzRenumber =
285  m.faceZoneFaceMap()[masterFaceZoneID_.index()];
286 
287  forAll(mfc, facei)
288  {
289  label newCelli = reverseCellMap[mfc[mfzRenumber[facei]]];
290 
291  if (newCelli >= 0)
292  {
293  newMfc[facei] = newCelli;
294  }
295  }
296 
297  // Slave side
298  std::unique_ptr<labelList> newSfcPtr(new labelList(sfc.size(), -1));
299  auto& newSfc = *newSfcPtr;
300 
301  const labelList& sfzRenumber =
302  m.faceZoneFaceMap()[slaveFaceZoneID_.index()];
303 
304  forAll(sfc, facei)
305  {
306  label newCelli = reverseCellMap[sfc[sfzRenumber[facei]]];
307 
308  if (newCelli >= 0)
309  {
310  newSfc[facei] = newCelli;
311  }
312  }
313 
314  if (debug)
315  {
316  // Check if all the mapped cells are live
317  if (min(newMfc) < 0 || min(newSfc) < 0)
318  {
320  << "Error in cell renumbering for object " << name()
321  << ". Some of master cells next "
322  << "to the interface have been removed."
323  << abort(FatalError);
324  }
325  }
326 
327  // Renumber stick-out faces
328 
329  const labelList& reverseFaceMap = m.reverseFaceMap();
330 
331  // Master side
332  const labelList& msof = masterStickOutFaces();
333 
334  std::unique_ptr<labelList> newMsofPtr(new labelList(msof.size(), -1));
335  auto& newMsof = *newMsofPtr;
336 
337  forAll(msof, facei)
338  {
339  label newFacei = reverseFaceMap[msof[facei]];
340 
341  if (newFacei >= 0)
342  {
343  newMsof[facei] = newFacei;
344  }
345  }
346 // Pout<< "newMsof: " << newMsof << endl;
347  // Slave side
348  const labelList& ssof = slaveStickOutFaces();
349 
350  std::unique_ptr<labelList> newSsofPtr(new labelList(ssof.size(), -1));
351  auto& newSsof = *newSsofPtr;
352 
353  forAll(ssof, facei)
354  {
355  label newFacei = reverseFaceMap[ssof[facei]];
356 
357  if (newFacei >= 0)
358  {
359  newSsof[facei] = newFacei;
360  }
361  }
362 // Pout<< "newSsof: " << newSsof << endl;
363  if (debug)
364  {
365  // Check if all the mapped cells are live
366  if (min(newMsof) < 0 || min(newSsof) < 0)
367  {
369  << "Error in face renumbering for object " << name()
370  << ". Some of stick-out next "
371  << "to the interface have been removed."
372  << abort(FatalError);
373  }
374  }
375 
376  // Renumber the retired point map. Need to take a copy!
377  const Map<label> rpm = retiredPointMap();
378 
379  std::unique_ptr<Map<label>> newRpmPtr(new Map<label>(rpm.size()));
380  auto& newRpm = *newRpmPtr;
381 
382  // Get reference to point renumbering
383  const labelList& reversePointMap = m.reversePointMap();
384 
385  forAllConstIters(rpm, iter)
386  {
387  const label key = reversePointMap[iter.key()];
388  const label val = reversePointMap[iter.val()];
389 
390  if (debug)
391  {
392  // Check if all the mapped cells are live
393  if (key < 0 || val < 0)
394  {
396  << "Error in retired point numbering for object "
397  << name() << ". Some of master "
398  << "points have been removed."
399  << abort(FatalError);
400  }
401  }
402 
403  newRpm.insert(key, val);
404  }
405 
406  // Renumber the cut point edge pair map. Need to take a copy!
407  const Map<Pair<edge>> cpepm = cutPointEdgePairMap();
408 
409  std::unique_ptr<Map<Pair<edge>>> newCpepmPtr
410  (
411  new Map<Pair<edge>>(cpepm.size())
412  );
413  auto& newCpepm = *newCpepmPtr;
414 
415  forAllConstIters(cpepm, iter)
416  {
417  const label key = reversePointMap[iter.key()];
418 
419  const Pair<edge>& oldPe = iter.val();
420 
421  // Re-do the edges in global addressing
422  const label ms = reversePointMap[oldPe.first().start()];
423  const label me = reversePointMap[oldPe.first().end()];
424 
425  const label ss = reversePointMap[oldPe.second().start()];
426  const label se = reversePointMap[oldPe.second().end()];
427 
428  if (debug)
429  {
430  // Check if all the mapped cells are live
431  if (key < 0 || ms < 0 || me < 0 || ss < 0 || se < 0)
432  {
434  << "Error in cut point edge pair map numbering for object "
435  << name() << ". Some of master points have been removed."
436  << abort(FatalError);
437  }
438  }
439 
440  newCpepm.insert(key, Pair<edge>(edge(ms, me), edge(ss, se)));
441  }
442 
443  if (!projectedSlavePointsPtr_)
444  {
446  << "Error in projected point numbering for object " << name()
447  << abort(FatalError);
448  }
449 
450  // Renumber the projected slave zone points
451  const pointField& projectedSlavePoints = *projectedSlavePointsPtr_;
452 
453  std::unique_ptr<pointField> newProjectedSlavePointsPtr
454  (
455  new pointField(projectedSlavePoints.size())
456  );
457  auto& newProjectedSlavePoints = *newProjectedSlavePointsPtr;
458 
459  const labelList& sfzPointRenumber =
460  m.faceZonePointMap()[slaveFaceZoneID_.index()];
461 
462  forAll(newProjectedSlavePoints, pointi)
463  {
464  if (sfzPointRenumber[pointi] > -1)
465  {
466  newProjectedSlavePoints[pointi] =
467  projectedSlavePoints[sfzPointRenumber[pointi]];
468  }
469  }
470 
471  // Re-set the lists
472  clearAttachedAddressing();
473 
474  projectedSlavePointsPtr_.reset(nullptr);
475 
476  masterFaceCellsPtr_ = std::move(newMfcPtr);
477  slaveFaceCellsPtr_ = std::move(newSfcPtr);
478 
479  masterStickOutFacesPtr_ = std::move(newMsofPtr);
480  slaveStickOutFacesPtr_ = std::move(newSsofPtr);
481 
482  retiredPointMapPtr_ = std::move(newRpmPtr);
483  cutPointEdgePairMapPtr_ = std::move(newCpepmPtr);
484  projectedSlavePointsPtr_ = std::move(newProjectedSlavePointsPtr);
485 }
486 
487 
488 const Foam::labelList& Foam::slidingInterface::masterFaceCells() const
489 {
490  if (!masterFaceCellsPtr_)
491  {
493  << "Master zone face-cell addressing not available for object "
494  << name()
495  << abort(FatalError);
496  }
497 
498  return *masterFaceCellsPtr_;
499 }
500 
501 
502 const Foam::labelList& Foam::slidingInterface::slaveFaceCells() const
503 {
504  if (!slaveFaceCellsPtr_)
505  {
507  << "Slave zone face-cell addressing not available for object "
508  << name()
509  << abort(FatalError);
510  }
511 
512  return *slaveFaceCellsPtr_;
513 }
514 
515 
516 const Foam::labelList& Foam::slidingInterface::masterStickOutFaces() const
517 {
518  if (!masterStickOutFacesPtr_)
519  {
521  << "Master zone stick-out face addressing not available for object "
522  << name()
523  << abort(FatalError);
524  }
525 
526  return *masterStickOutFacesPtr_;
527 }
528 
529 
530 const Foam::labelList& Foam::slidingInterface::slaveStickOutFaces() const
531 {
532  if (!slaveStickOutFacesPtr_)
533  {
535  << "Slave zone stick-out face addressing not available for object "
536  << name()
537  << abort(FatalError);
538  }
539 
540  return *slaveStickOutFacesPtr_;
541 }
542 
543 
544 const Foam::Map<Foam::label>& Foam::slidingInterface::retiredPointMap() const
545 {
546  if (!retiredPointMapPtr_)
547  {
549  << "Retired point map not available for object " << name()
550  << abort(FatalError);
551  }
552 
553  return *retiredPointMapPtr_;
554 }
555 
556 
558 Foam::slidingInterface::cutPointEdgePairMap() const
559 {
560  if (!cutPointEdgePairMapPtr_)
561  {
563  << "Retired point map not available for object " << name()
564  << abort(FatalError);
565  }
566 
567  return *cutPointEdgePairMapPtr_;
568 }
569 
570 
571 // ************************************************************************* //
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
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:598
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
const dimensionedScalar me
Electron mass.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
static const unsigned facesPerCell_
Estimated number of faces per cell.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:137
label nPoints
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:296
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
errorManip< error > abort(error &err)
Definition: errorManip.H:139
label index() const
The index of the first matching items, -1 if no matches.
Definition: DynamicID.H:139
int debug
Static debugging option.
#define FUNCTION_NAME
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
A PrimitivePatch with List storage for the faces, const reference for the point field.
const polyTopoChanger & topoChanger() const
Return reference to morph engine.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
const word & name() const
Return name of this modifier.
List< label > labelList
A List of labels.
Definition: List.H:62
const polyMesh & mesh() const
Return the mesh reference.
List< bool > boolList
A List of bools.
Definition: List.H:60
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
A HashTable to objects of type <T> with a label key.