decoupleSlidingInterface.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 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 "primitiveMesh.H"
32 #include "polyTopoChange.H"
33 #include "polyTopoChanger.H"
34 #include "polyModifyFace.H"
35 #include "polyModifyPoint.H"
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 void Foam::slidingInterface::decoupleInterface
40 (
41  polyTopoChange& ref
42 ) const
43 {
44  if (debug)
45  {
46  Pout<< FUNCTION_NAME << nl
47  << ": Decoupling sliding interface " << name() << endl;
48  }
49 
50  if (!attached_)
51  {
52  if (debug)
53  {
54  Pout<< FUNCTION_NAME << nl
55  << ": Interface already decoupled." << endl;
56  }
57 
58  return;
59  }
60 
61  // Clear previous couple
62  clearCouple(ref);
63 
64  const polyMesh& mesh = topoChanger().mesh();
65  const pointField& points = mesh.points();
66  const faceList& faces = mesh.faces();
67  const cellList& cells = mesh.cells();
68  const labelList& own = mesh.faceOwner();
69  const labelList& nei = mesh.faceNeighbour();
70  const faceZoneMesh& faceZones = mesh.faceZones();
71 
72  // Master side
73 
74  const primitiveFacePatch& masterPatch =
75  faceZones[masterFaceZoneID_.index()]();
76 
77  const labelList& masterPatchAddr =
78  faceZones[masterFaceZoneID_.index()];
79 
80  const boolList& masterPatchFlip =
81  faceZones[masterFaceZoneID_.index()].flipMap();
82 
83  const labelList& masterFc = masterFaceCells();
84 
85  // Recover faces in master patch
86 
87  forAll(masterPatchAddr, facei)
88  {
89  // Make a copy of the face and turn it if necessary
90  face newFace = faces[masterPatchAddr[facei]];
91 
92  if (masterPatchFlip[facei])
93  {
94  newFace.flip();
95  }
96 
97  ref.setAction
98  (
99  polyModifyFace
100  (
101  newFace, // new face
102  masterPatchAddr[facei], // master face index
103  masterFc[facei], // owner
104  -1, // neighbour
105  false, // flux flip
106  masterPatchID_.index(), // patch ID
107  false, // remove from zone
108  masterFaceZoneID_.index(), // zone ID
109  false // zone flip. Face corrected
110  )
111  );
112 
113  // Pout<< "Modifying master patch face no "
114  // << masterPatchAddr[facei]
115  // << " face: " << faces[masterPatchAddr[facei]]
116  // << " old owner: " << own[masterPatchAddr[facei]]
117  // << " new owner: " << masterFc[facei]
118  // << endl;
119  }
120 
121  // Slave side
122 
123  const primitiveFacePatch& slavePatch =
124  faceZones[slaveFaceZoneID_.index()]();
125 
126  const labelList& slavePatchAddr =
127  faceZones[slaveFaceZoneID_.index()];
128 
129  const boolList& slavePatchFlip =
130  faceZones[slaveFaceZoneID_.index()].flipMap();
131 
132  const labelList& slaveFc = slaveFaceCells();
133 
134  // Grab retired point mapping
135  const Map<label>& rpm = retiredPointMap();
136 
137  // Recover faces in slave patch
138 
139  forAll(slavePatchAddr, facei)
140  {
141  // Make a copy of face and turn it if necessary
142  face newFace = faces[slavePatchAddr[facei]];
143 
144  if (slavePatchFlip[facei])
145  {
146  newFace.flip();
147  }
148 
149  // Recover retired points on the slave side
150  forAll(newFace, pointi)
151  {
152  newFace[pointi] = rpm.lookup(newFace[pointi], newFace[pointi]);
153  }
154 
155  ref.setAction
156  (
157  polyModifyFace
158  (
159  newFace, // new face
160  slavePatchAddr[facei], // master face index
161  slaveFc[facei], // owner
162  -1, // neighbour
163  false, // flux flip
164  slavePatchID_.index(), // patch ID
165  false, // remove from zone
166  slaveFaceZoneID_.index(), // zone ID
167  false // zone flip. Face corrected
168  )
169  );
170  }
171 
172  // Re-create the master stick-out faces
173 
174  // Grab the list of faces in the layer
175  const labelList& masterStickOuts = masterStickOutFaces();
176 
177  for (const label curFaceID : masterStickOuts)
178  {
179  // Renumber the face and remove additional points
180 
181  const face& oldFace = faces[curFaceID];
182 
183  DynamicList<label> newFaceLabels(oldFace.size());
184 
185  bool changed = false;
186 
187  forAll(oldFace, pointi)
188  {
189  // Check if the point is removed
190  if (ref.pointRemoved(oldFace[pointi]))
191  {
192  // Point removed; skip it
193  changed = true;
194  }
195  else
196  {
197  newFaceLabels.append(oldFace[pointi]);
198  }
199  }
200 
201  if (changed)
202  {
203  if (newFaceLabels.size() < 3)
204  {
206  << "Face " << curFaceID << " reduced to less than "
207  << "3 points. Topological/cutting error." << nl
208  << "Old face: " << oldFace << " new face: " << newFaceLabels
209  << abort(FatalError);
210  }
211 
212  // Get face zone and its flip
213  const label modifiedFaceZone = faceZones.whichZone(curFaceID);
214 
215  const bool modifiedFaceZoneFlip =
216  (
217  modifiedFaceZone >= 0
218  ?
219  faceZones[modifiedFaceZone].flipMap()
220  [
221  faceZones[modifiedFaceZone].whichFace(curFaceID)
222  ]
223  : false
224  );
225 
226  face newFace;
227  newFace.transfer(newFaceLabels);
228 
229  // Pout<< "Modifying master stick-out face " << curFaceID
230  // << " old face: " << oldFace
231  // << " new face: " << newFace
232  // << endl;
233 
234  // Modify the face
235  ref.setAction
236  (
237  polyModifyFace
238  (
239  newFace, // modified face
240  curFaceID, // label of face being modified
241  own[curFaceID], // owner
242  nei[curFaceID], // neighbour
243  false, // face flip
244  mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
245  false, // remove from zone
246  modifiedFaceZone, // zone for face
247  modifiedFaceZoneFlip // face flip in zone
248  )
249  );
250  }
251  }
252 
253  // Re-create the slave stick-out faces
254 
255  labelHashSet slaveLayerCellFaceMap
256  (
257  primitiveMesh::facesPerCell_*(masterPatch.size() + slavePatch.size())
258  );
259 
260  for (const label slaveFci : slaveFc)
261  {
262  const labelList& curFaces = cells[slaveFci];
263 
264  for (const label facei : curFaces)
265  {
266  // Check if the face belongs to the slave face zone; and
267  // if it has been removed; if not add it
268  if
269  (
270  faceZones.whichZone(facei)
271  != slaveFaceZoneID_.index()
272  && !ref.faceRemoved(facei)
273  )
274  {
275  slaveLayerCellFaceMap.insert(facei);
276  }
277  }
278  }
279 
280  // Grab the list of faces in the layer
281  const labelList& slaveStickOuts = slaveStickOutFaces();
282 
283  // Grab master point mapping
284  const Map<label>& masterPm = masterPatch.meshPointMap();
285 
286  for (const label curFaceID : slaveStickOuts)
287  {
288  // Renumber the face and remove additional points
289 
290  const face& oldFace = faces[curFaceID];
291 
292  DynamicList<label> newFaceLabels(oldFace.size());
293 
294  bool changed = false;
295 
296  forAll(oldFace, pointi)
297  {
298  // Check if the point is removed or retired
299 
300  const label retiredPointi = rpm.lookup(oldFace[pointi], -1);
301 
302  if (retiredPointi != -1)
303  {
304  // Master of retired point; grab its original
305  changed = true;
306 
307  // Pout<< "Reinstating retired point: " << oldFace[pointi]
308  // << " with old: " << retiredPointi
309  // << endl;
310 
311  newFaceLabels.append(retiredPointi);
312  }
313  else if (ref.pointRemoved(oldFace[pointi]))
314  {
315  // Point removed; skip it
316  changed = true;
317  }
318  else if (masterPm.found(oldFace[pointi]))
319  {
320  // Point from master patch only; skip it
321  changed = true;
322  }
323  else
324  {
325  newFaceLabels.append(oldFace[pointi]);
326  }
327  }
328 
329  if (changed)
330  {
331  if (newFaceLabels.size() < 3)
332  {
334  << "Face " << curFaceID << " reduced to less than "
335  << "3 points. Topological/cutting error." << nl
336  << "Old face: " << oldFace << " new face: " << newFaceLabels
337  << abort(FatalError);
338  }
339 
340  // Get face zone and its flip
341  const label modifiedFaceZone =
342  faceZones.whichZone(curFaceID);
343 
344  const bool modifiedFaceZoneFlip =
345  (
346  modifiedFaceZone >= 0
347  ?
348  faceZones[modifiedFaceZone].flipMap()
349  [
350  faceZones[modifiedFaceZone].whichFace(curFaceID)
351  ]
352  : false
353  );
354 
355  face newFace;
356  newFace.transfer(newFaceLabels);
357 
358  // Pout<< "Modifying slave stick-out face " << curFaceID
359  // << " old face: " << oldFace
360  // << " new face: " << newFace
361  // << endl;
362 
363  // Modify the face
364  ref.setAction
365  (
366  polyModifyFace
367  (
368  newFace, // modified face
369  curFaceID, // label of face being modified
370  own[curFaceID], // owner
371  nei[curFaceID], // neighbour
372  false, // face flip
373  mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
374  false, // remove from zone
375  modifiedFaceZone, // zone for face
376  modifiedFaceZoneFlip // face flip in zone
377  )
378  );
379  }
380  }
381 
382  // Bring all slave patch points back to life
383  const labelList& slaveMeshPoints =
384  faceZones[slaveFaceZoneID_.index()]().meshPoints();
385 
386  for (const label slavePointi : slaveMeshPoints)
387  {
388  ref.setAction
389  (
390  polyModifyPoint
391  (
392  slavePointi, // point ID
393  points[slavePointi], // point
394  false, // remove from zone
395  mesh.pointZones().whichZone(slavePointi), // zone
396  true // in a cell
397  )
398  );
399  }
400 
401  // Clear the retired point numbering
402  retiredPointMapPtr_->clear();
403 
404  // Finished decoupling
405  attached_ = false;
406 
407  if (debug)
408  {
409  Pout<< FUNCTION_NAME << nl
410  << ": Finished decoupling sliding interface " << name() << endl;
411  }
412 }
413 
414 
415 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
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
polyTopoChanger.H
polyTopoChange.H
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:65
primitiveMesh.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
ref
rDeltaT ref()
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
polyMesh.H
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
Foam::faceZoneMesh
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
Definition: faceZoneMeshFwd.H:44
polyModifyPoint.H
Foam::cellList
List< cell > cellList
A List of cells.
Definition: cellListFwd.H:47
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
polyModifyFace.H
Foam::polyMeshModifier::name
const word & name() const
Return name of this modifier.
Definition: polyMeshModifier.H:150
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
slidingInterface.H
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::polyTopoChanger::mesh
const polyMesh & mesh() const
Return the mesh reference.
Definition: polyTopoChanger.H:111
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
points
const pointField & points
Definition: gmvOutputHeader.H:1
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
Foam::DynamicID::index
label index() const
The index of the first matching items, -1 if no matches.
Definition: DynamicID.H:123