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-2019 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_ = new labelList(masterPatchFaces.size());
68  labelList& 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_ = new labelList(slavePatchFaces.size());
94  labelList& 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  // Sort in debug mode for easier diagnostics
177  if (debug)
178  {
179  masterStickOutFacesPtr_ =
180  new labelList(stickOutFaceMap.sortedToc());
181  }
182  else
183  {
184  masterStickOutFacesPtr_ = new labelList(stickOutFaceMap.toc());
185  }
186 
187  // Slave side
188  const labelList& slaveMeshPoints = slavePatch.meshPoints();
189 
190  stickOutFaceMap.clear();
191 
192  for (const label pointi : slaveMeshPoints)
193  {
194  for (const label facei : pointFaces[pointi])
195  {
196  const label zoneIdx = faceZones.whichZone(facei);
197 
198  // Add if face not already part of master or slave face zone
199  // This handles partially attached faces.
200  if
201  (
202  zoneIdx != masterFaceZoneID_.index()
203  && zoneIdx != slaveFaceZoneID_.index()
204  )
205  {
206  stickOutFaceMap.insert(facei);
207  }
208  }
209  }
210 
211  // Sort in debug mode for easier diagnostics
212  if (debug)
213  {
214  slaveStickOutFacesPtr_ =
215  new labelList(stickOutFaceMap.sortedToc());
216  }
217  else
218  {
219  slaveStickOutFacesPtr_ = new labelList(stickOutFaceMap.toc());
220  }
221 
222  stickOutFaceMap.clear();
223 
224  // Retired point addressing does not exist at this stage.
225  // It will be filled when the interface is coupled.
226  retiredPointMapPtr_ =
227  new Map<label>
228  (
229  2*faceZones[slaveFaceZoneID_.index()]().nPoints()
230  );
231 
232  // Ditto for cut point edge map. This is a rough guess of its size
233  cutPointEdgePairMapPtr_ =
234  new Map<Pair<edge>>
235  (
236  faceZones[slaveFaceZoneID_.index()]().nEdges()
237  );
238  }
239  else
240  {
242  << "cannot be assembled for object " << name()
243  << abort(FatalError);
244  }
245 
246  if (debug)
247  {
249  << " for object " << name() << " : "
250  << "Finished calculating zone face-cell addressing."
251  << endl;
252  }
253 }
254 
255 
256 void Foam::slidingInterface::clearAttachedAddressing() const
257 {
258  deleteDemandDrivenData(masterFaceCellsPtr_);
259  deleteDemandDrivenData(slaveFaceCellsPtr_);
260 
261  deleteDemandDrivenData(masterStickOutFacesPtr_);
262  deleteDemandDrivenData(slaveStickOutFacesPtr_);
263 
264  deleteDemandDrivenData(retiredPointMapPtr_);
265  deleteDemandDrivenData(cutPointEdgePairMapPtr_);
266 }
267 
268 
269 void Foam::slidingInterface::renumberAttachedAddressing
270 (
271  const mapPolyMesh& m
272 ) const
273 {
274  // Get reference to reverse cell renumbering
275  // The renumbering map is needed the other way around, i.e. giving
276  // the new cell number for every old cell next to the interface.
277  const labelList& reverseCellMap = m.reverseCellMap();
278 
279  const labelList& mfc = masterFaceCells();
280  const labelList& sfc = slaveFaceCells();
281 
282  // Master side
283  labelList* newMfcPtr = new labelList(mfc.size(), -1);
284  labelList& newMfc = *newMfcPtr;
285 
286  const labelList& mfzRenumber =
287  m.faceZoneFaceMap()[masterFaceZoneID_.index()];
288 
289  forAll(mfc, facei)
290  {
291  label newCelli = reverseCellMap[mfc[mfzRenumber[facei]]];
292 
293  if (newCelli >= 0)
294  {
295  newMfc[facei] = newCelli;
296  }
297  }
298 
299  // Slave side
300  labelList* newSfcPtr = new labelList(sfc.size(), -1);
301  labelList& newSfc = *newSfcPtr;
302 
303  const labelList& sfzRenumber =
304  m.faceZoneFaceMap()[slaveFaceZoneID_.index()];
305 
306  forAll(sfc, facei)
307  {
308  label newCelli = reverseCellMap[sfc[sfzRenumber[facei]]];
309 
310  if (newCelli >= 0)
311  {
312  newSfc[facei] = newCelli;
313  }
314  }
315 
316  if (debug)
317  {
318  // Check if all the mapped cells are live
319  if (min(newMfc) < 0 || min(newSfc) < 0)
320  {
322  << "Error in cell renumbering for object " << name()
323  << ". Some of master cells next "
324  << "to the interface have been removed."
325  << abort(FatalError);
326  }
327  }
328 
329  // Renumber stick-out faces
330 
331  const labelList& reverseFaceMap = m.reverseFaceMap();
332 
333  // Master side
334  const labelList& msof = masterStickOutFaces();
335 
336  labelList* newMsofPtr = new labelList(msof.size(), -1);
337  labelList& newMsof = *newMsofPtr;
338 
339  forAll(msof, facei)
340  {
341  label newFacei = reverseFaceMap[msof[facei]];
342 
343  if (newFacei >= 0)
344  {
345  newMsof[facei] = newFacei;
346  }
347  }
348 // Pout<< "newMsof: " << newMsof << endl;
349  // Slave side
350  const labelList& ssof = slaveStickOutFaces();
351 
352  labelList* newSsofPtr = new labelList(ssof.size(), -1);
353  labelList& newSsof = *newSsofPtr;
354 
355  forAll(ssof, facei)
356  {
357  label newFacei = reverseFaceMap[ssof[facei]];
358 
359  if (newFacei >= 0)
360  {
361  newSsof[facei] = newFacei;
362  }
363  }
364 // Pout<< "newSsof: " << newSsof << endl;
365  if (debug)
366  {
367  // Check if all the mapped cells are live
368  if (min(newMsof) < 0 || min(newSsof) < 0)
369  {
371  << "Error in face renumbering for object " << name()
372  << ". Some of stick-out next "
373  << "to the interface have been removed."
374  << abort(FatalError);
375  }
376  }
377 
378  // Renumber the retired point map. Need to take a copy!
379  const Map<label> rpm = retiredPointMap();
380 
381  Map<label>* newRpmPtr = new Map<label>(rpm.size());
382  Map<label>& newRpm = *newRpmPtr;
383 
384  // Get reference to point renumbering
385  const labelList& reversePointMap = m.reversePointMap();
386 
387  forAllConstIters(rpm, iter)
388  {
389  const label key = reversePointMap[iter.key()];
390  const label val = reversePointMap[iter.val()];
391 
392  if (debug)
393  {
394  // Check if all the mapped cells are live
395  if (key < 0 || val < 0)
396  {
398  << "Error in retired point numbering for object "
399  << name() << ". Some of master "
400  << "points have been removed."
401  << abort(FatalError);
402  }
403  }
404 
405  newRpm.insert(key, val);
406  }
407 
408  // Renumber the cut point edge pair map. Need to take a copy!
409  const Map<Pair<edge>> cpepm = cutPointEdgePairMap();
410 
411  Map<Pair<edge>>* newCpepmPtr = new Map<Pair<edge>>(cpepm.size());
412  Map<Pair<edge>>& newCpepm = *newCpepmPtr;
413 
414  forAllConstIters(cpepm, iter)
415  {
416  const label key = reversePointMap[iter.key()];
417 
418  const Pair<edge>& oldPe = iter.val();
419 
420  // Re-do the edges in global addressing
421  const label ms = reversePointMap[oldPe.first().start()];
422  const label me = reversePointMap[oldPe.first().end()];
423 
424  const label ss = reversePointMap[oldPe.second().start()];
425  const label se = reversePointMap[oldPe.second().end()];
426 
427  if (debug)
428  {
429  // Check if all the mapped cells are live
430  if (key < 0 || ms < 0 || me < 0 || ss < 0 || se < 0)
431  {
433  << "Error in cut point edge pair map numbering for object "
434  << name() << ". Some of master points have been removed."
435  << abort(FatalError);
436  }
437  }
438 
439  newCpepm.insert(key, Pair<edge>(edge(ms, me), edge(ss, se)));
440  }
441 
442  if (!projectedSlavePointsPtr_)
443  {
445  << "Error in projected point numbering for object " << name()
446  << abort(FatalError);
447  }
448 
449  // Renumber the projected slave zone points
450  const pointField& projectedSlavePoints = *projectedSlavePointsPtr_;
451 
452  pointField* newProjectedSlavePointsPtr
453  (
454  new pointField(projectedSlavePoints.size())
455  );
456  pointField& newProjectedSlavePoints = *newProjectedSlavePointsPtr;
457 
458  const labelList& sfzPointRenumber =
459  m.faceZonePointMap()[slaveFaceZoneID_.index()];
460 
461  forAll(newProjectedSlavePoints, pointi)
462  {
463  if (sfzPointRenumber[pointi] > -1)
464  {
465  newProjectedSlavePoints[pointi] =
466  projectedSlavePoints[sfzPointRenumber[pointi]];
467  }
468  }
469 
470  // Re-set the lists
471  clearAttachedAddressing();
472 
473  deleteDemandDrivenData(projectedSlavePointsPtr_);
474 
475  masterFaceCellsPtr_ = newMfcPtr;
476  slaveFaceCellsPtr_ = newSfcPtr;
477 
478  masterStickOutFacesPtr_ = newMsofPtr;
479  slaveStickOutFacesPtr_ = newSsofPtr;
480 
481  retiredPointMapPtr_ = newRpmPtr;
482  cutPointEdgePairMapPtr_ = newCpepmPtr;
483  projectedSlavePointsPtr_ = newProjectedSlavePointsPtr;
484 }
485 
486 
487 const Foam::labelList& Foam::slidingInterface::masterFaceCells() const
488 {
489  if (!masterFaceCellsPtr_)
490  {
492  << "Master zone face-cell addressing not available for object "
493  << name()
494  << abort(FatalError);
495  }
496 
497  return *masterFaceCellsPtr_;
498 }
499 
500 
501 const Foam::labelList& Foam::slidingInterface::slaveFaceCells() const
502 {
503  if (!slaveFaceCellsPtr_)
504  {
506  << "Slave zone face-cell addressing not available for object "
507  << name()
508  << abort(FatalError);
509  }
510 
511  return *slaveFaceCellsPtr_;
512 }
513 
514 
515 const Foam::labelList& Foam::slidingInterface::masterStickOutFaces() const
516 {
517  if (!masterStickOutFacesPtr_)
518  {
520  << "Master zone stick-out face addressing not available for object "
521  << name()
522  << abort(FatalError);
523  }
524 
525  return *masterStickOutFacesPtr_;
526 }
527 
528 
529 const Foam::labelList& Foam::slidingInterface::slaveStickOutFaces() const
530 {
531  if (!slaveStickOutFacesPtr_)
532  {
534  << "Slave zone stick-out face addressing not available for object "
535  << name()
536  << abort(FatalError);
537  }
538 
539  return *slaveStickOutFacesPtr_;
540 }
541 
542 
543 const Foam::Map<Foam::label>& Foam::slidingInterface::retiredPointMap() const
544 {
545  if (!retiredPointMapPtr_)
546  {
548  << "Retired point map not available for object " << name()
549  << abort(FatalError);
550  }
551 
552  return *retiredPointMapPtr_;
553 }
554 
555 
557 Foam::slidingInterface::cutPointEdgePairMap() const
558 {
559  if (!cutPointEdgePairMapPtr_)
560  {
562  << "Retired point map not available for object " << name()
563  << abort(FatalError);
564  }
565 
566  return *cutPointEdgePairMapPtr_;
567 }
568 
569 
570 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::val
label ListType::const_reference val
Definition: ListOps.H:407
Foam::primitiveFacePatch
PrimitivePatch< face, List, const pointField & > primitiveFacePatch
Foam::primitiveFacePatch.
Definition: primitiveFacePatch.H:47
Foam::polyMeshModifier::topoChanger
const polyTopoChanger & topoChanger() const
Return reference to morph engine.
Definition: polyMeshModifier.C:71
mapPolyMesh.H
polyTopoChanger.H
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: HashTableFwd.H:46
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:72
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
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:290
Foam::primitiveMesh::facesPerCell_
static const unsigned facesPerCell_
Estimated number of faces per cell.
Definition: primitiveMesh.H:417
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:42
Foam::faceZoneMesh
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
Definition: faceZoneMeshFwd.H:44
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
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:137
Foam::polyMeshModifier::name
const word & name() const
Return name of this modifier.
Definition: polyMeshModifier.H:153
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:355
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:116
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:261
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys and label hasher.
Definition: HashSet.H:415
Foam::DynamicID::index
label index() const
Return index of first matching zone.
Definition: DynamicID.H:110