FreeFOAM The Cross-Platform CFD Toolkit
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 | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "slidingInterface.H"
27 #include <OpenFOAM/polyMesh.H>
28 #include <OpenFOAM/primitiveMesh.H>
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 void Foam::slidingInterface::decoupleInterface
37 (
38  polyTopoChange& ref
39 ) const
40 {
41  if (debug)
42  {
43  Pout<< "void slidingInterface::decoupleInterface("
44  << "polyTopoChange& ref) const : "
45  << "Decoupling sliding interface " << name() << endl;
46  }
47 
48  if (!attached_)
49  {
50  if (debug)
51  {
52  Pout<< "void slidingInterface::decoupleInterface("
53  << "polyTopoChange& ref) const : "
54  << "Interface already decoupled." << endl;
55  }
56 
57  return;
58  }
59 
60  // Clear previous couple
61  clearCouple(ref);
62 
63  const polyMesh& mesh = topoChanger().mesh();
64  const faceList& faces = mesh.faces();
65  const cellList& cells = mesh.cells();
66 
67  const labelList& own = mesh.faceOwner();
68  const labelList& nei = mesh.faceNeighbour();
69 
70  // Master side
71 
72  const primitiveFacePatch& masterPatch =
73  mesh.faceZones()[masterFaceZoneID_.index()]();
74 
75  const labelList& masterPatchAddr =
76  mesh.faceZones()[masterFaceZoneID_.index()];
77 
78  const boolList& masterPatchFlip =
79  mesh.faceZones()[masterFaceZoneID_.index()].flipMap();
80 
81  const labelList& masterFc = masterFaceCells();
82 
83  // Recover faces in master patch
84 
85  forAll (masterPatchAddr, faceI)
86  {
87  // Make a copy of the face and turn it if necessary
88  face newFace = faces[masterPatchAddr[faceI]];
89 
90  if (masterPatchFlip[faceI])
91  {
92  newFace = newFace.reverseFace();
93  }
94 
95  ref.setAction
96  (
97  polyModifyFace
98  (
99  newFace, // new face
100  masterPatchAddr[faceI], // master face index
101  masterFc[faceI], // owner
102  -1, // neighbour
103  false, // flux flip
104  masterPatchID_.index(), // patch ID
105  false, // remove from zone
106  masterFaceZoneID_.index(), // zone ID
107  false // zone flip. Face corrected
108  )
109  );
110 // Pout << "Modifying master patch face no " << masterPatchAddr[faceI] << " face: " << faces[masterPatchAddr[faceI]] << " old owner: " << own[masterPatchAddr[faceI]] << " new owner: " << masterFc[faceI] << endl;
111  }
112 
113  // Slave side
114 
115  const primitiveFacePatch& slavePatch =
116  mesh.faceZones()[slaveFaceZoneID_.index()]();
117 
118  const labelList& slavePatchAddr =
119  mesh.faceZones()[slaveFaceZoneID_.index()];
120 
121  const boolList& slavePatchFlip =
122  mesh.faceZones()[slaveFaceZoneID_.index()].flipMap();
123 
124  const labelList& slaveFc = slaveFaceCells();
125 
126  // Grab retired point mapping
127  const Map<label>& rpm = retiredPointMap();
128 
129  // Recover faces in slave patch
130 
131  forAll (slavePatchAddr, faceI)
132  {
133  // Make a copy of face and turn it if necessary
134  face newFace = faces[slavePatchAddr[faceI]];
135 
136  if (slavePatchFlip[faceI])
137  {
138  newFace = newFace.reverseFace();
139  }
140 
141  // Recover retired points on the slave side
142  forAll (newFace, pointI)
143  {
144  Map<label>::const_iterator rpmIter = rpm.find(newFace[pointI]);
145  if (rpmIter != rpm.end())
146  {
147  // Master of retired point; grab its original
148 // Pout << "Reinstating retired point: " << newFace[pointI] << " with old: " << rpm.find(newFace[pointI])() << endl;
149  newFace[pointI] = rpmIter();
150  }
151  }
152 
153  ref.setAction
154  (
155  polyModifyFace
156  (
157  newFace, // new face
158  slavePatchAddr[faceI], // master face index
159  slaveFc[faceI], // owner
160  -1, // neighbour
161  false, // flux flip
162  slavePatchID_.index(), // patch ID
163  false, // remove from zone
164  slaveFaceZoneID_.index(), // zone ID
165  false // zone flip. Face corrected
166  )
167  );
168  }
169 
170  // Re-create the master stick-out faces
171 
172  // Grab the list of faces in the layer
173  const labelList& masterStickOuts = masterStickOutFaces();
174 
175  forAll (masterStickOuts, faceI)
176  {
177  // Renumber the face and remove additional points
178 
179  const label curFaceID = masterStickOuts[faceI];
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  (
207  "void slidingInterface::decoupleInterface("
208  "polyTopoChange& ref) const"
209  ) << "Face " << curFaceID << " reduced to less than "
210  << "3 points. Topological/cutting error." << nl
211  << "Old face: " << oldFace << " new face: " << newFaceLabels
212  << abort(FatalError);
213  }
214 
215  // Get face zone and its flip
216  label modifiedFaceZone = mesh.faceZones().whichZone(curFaceID);
217  bool modifiedFaceZoneFlip = false;
218 
219  if (modifiedFaceZone >= 0)
220  {
221  modifiedFaceZoneFlip =
222  mesh.faceZones()[modifiedFaceZone].flipMap()
223  [
224  mesh.faceZones()[modifiedFaceZone].whichFace(curFaceID)
225  ];
226  }
227 
228  face newFace;
229  newFace.transfer(newFaceLabels);
230 
231 // Pout << "Modifying master stick-out face " << curFaceID << " old face: " << oldFace << " new face: " << newFace << endl;
232 
233  // Modify the face
234  ref.setAction
235  (
236  polyModifyFace
237  (
238  newFace, // modified face
239  curFaceID, // label of face being modified
240  own[curFaceID], // owner
241  nei[curFaceID], // neighbour
242  false, // face flip
243  mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
244  false, // remove from zone
245  modifiedFaceZone, // zone for face
246  modifiedFaceZoneFlip // face flip in zone
247  )
248  );
249  }
250  }
251 
252  // Re-create the slave stick-out faces
253 
254  labelHashSet slaveLayerCellFaceMap
255  (
256  primitiveMesh::facesPerCell_*(masterPatch.size() + slavePatch.size())
257  );
258 
259  forAll (slaveFc, faceI)
260  {
261  const labelList& curFaces = cells[slaveFc[faceI]];
262 
263  forAll (curFaces, faceI)
264  {
265  // Check if the face belongs to the slave face zone; and
266  // if it has been removed; if not add it
267  if
268  (
269  mesh.faceZones().whichZone(curFaces[faceI])
270  != slaveFaceZoneID_.index()
271  && !ref.faceRemoved(curFaces[faceI])
272 
273  )
274  {
275  slaveLayerCellFaceMap.insert(curFaces[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  forAll (slaveStickOuts, faceI)
287  {
288  // Renumber the face and remove additional points
289 
290  const label curFaceID = slaveStickOuts[faceI];
291 
292  const face& oldFace = faces[curFaceID];
293 
294  DynamicList<label> newFaceLabels(oldFace.size());
295 
296  bool changed = false;
297 
298  forAll (oldFace, pointI)
299  {
300  // Check if the point is removed or retired
301  if (rpm.found(oldFace[pointI]))
302  {
303  // Master of retired point; grab its original
304  changed = true;
305 // Pout << "Reinstating retired point: " << oldFace[pointI] << " with old: " << rpm.find(oldFace[pointI])() << endl;
306  newFaceLabels.append(rpm.find(oldFace[pointI])());
307  }
308  else if (ref.pointRemoved(oldFace[pointI]))
309  {
310  // Point removed; skip it
311  changed = true;
312  }
313  else if (masterPm.found(oldFace[pointI]))
314  {
315  // Point from master patch only; skip it
316  changed = true;
317  }
318  else
319  {
320  newFaceLabels.append(oldFace[pointI]);
321  }
322  }
323 
324  if (changed)
325  {
326  if (newFaceLabels.size() < 3)
327  {
329  (
330  "void slidingInterface::decoupleInterface("
331  "polyTopoChange& ref) const"
332  ) << "Face " << curFaceID << " reduced to less than "
333  << "3 points. Topological/cutting error." << nl
334  << "Old face: " << oldFace << " new face: " << newFaceLabels
335  << abort(FatalError);
336  }
337 
338  // Get face zone and its flip
339  label modifiedFaceZone = mesh.faceZones().whichZone(curFaceID);
340  bool modifiedFaceZoneFlip = false;
341 
342  if (modifiedFaceZone >= 0)
343  {
344  modifiedFaceZoneFlip =
345  mesh.faceZones()[modifiedFaceZone].flipMap()
346  [
347  mesh.faceZones()[modifiedFaceZone].whichFace(curFaceID)
348  ];
349  }
350 
351  face newFace;
352  newFace.transfer(newFaceLabels);
353 
354 // Pout << "Modifying slave stick-out face " << curFaceID << " old face: " << oldFace << " new face: " << newFace << endl;
355 
356  // Modify the face
357  ref.setAction
358  (
359  polyModifyFace
360  (
361  newFace, // modified face
362  curFaceID, // label of face being modified
363  own[curFaceID], // owner
364  nei[curFaceID], // neighbour
365  false, // face flip
366  mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
367  false, // remove from zone
368  modifiedFaceZone, // zone for face
369  modifiedFaceZoneFlip // face flip in zone
370  )
371  );
372  }
373  }
374 
375  // Bring all slave patch points back to life
376  const pointField& points = mesh.points();
377 
378  const labelList& slaveMeshPoints =
379  mesh.faceZones()[slaveFaceZoneID_.index()]().meshPoints();
380 
381  forAll (slaveMeshPoints, pointI)
382  {
383  ref.setAction
384  (
385  polyModifyPoint
386  (
387  slaveMeshPoints[pointI], // point ID
388  points[slaveMeshPoints[pointI]], // point
389  false, // remove from zone
390  mesh.pointZones().whichZone(slaveMeshPoints[pointI]), // zone
391  true // in a cell
392  )
393  );
394  }
395 
396  // Clear the retired point numbering
397  retiredPointMapPtr_->clear();
398 
399  // Finished decoupling
400  attached_ = false;
401 
402  if (debug)
403  {
404  Pout<< "void slidingInterface::coupleInterface("
405  << "polyTopoChange& ref) const : "
406  << "Finished decoupling sliding interface " << name() << endl;
407  }
408 }
409 
410 
411 // ************************ vim: set sw=4 sts=4 et: ************************ //