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