ce08c9a8bff50ef37a691c783d13d5bffe9c3277
[OpenFOAM-1.5.x.git] / src / dynamicMesh / slidingInterface / decoupleSlidingInterface.C
blobce08c9a8bff50ef37a691c783d13d5bffe9c3277
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "slidingInterface.H"
28 #include "polyMesh.H"
29 #include "primitiveMesh.H"
30 #include "polyTopoChange.H"
31 #include "polyTopoChanger.H"
32 #include "polyModifyFace.H"
33 #include "polyModifyPoint.H"
35 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
37 void Foam::slidingInterface::decoupleInterface
39     polyTopoChange& ref
40 ) const
42     if (debug)
43     {
44         Pout<< "void slidingInterface::decoupleInterface("
45             << "polyTopoChange& ref) const : "
46             << "Decoupling sliding interface " << name() << endl;
47     }
49     if (!attached_)
50     {
51         if (debug)
52         {
53             Pout<< "void slidingInterface::decoupleInterface("
54                 << "polyTopoChange& ref) const : "
55                 << "Interface already decoupled." << endl;
56         }
58         return;
59     }
61     // Clear previous couple
62     clearCouple(ref);
64     const polyMesh& mesh = topoChanger().mesh();
65     const faceList& faces = mesh.faces();
66     const cellList& cells = mesh.cells();
68     const labelList& own = mesh.faceOwner();
69     const labelList& nei = mesh.faceNeighbour();
71     // Master side
73     const primitiveFacePatch& masterPatch =
74         mesh.faceZones()[masterFaceZoneID_.index()]();
76     const labelList& masterPatchAddr =
77         mesh.faceZones()[masterFaceZoneID_.index()];
79     const boolList& masterPatchFlip =
80         mesh.faceZones()[masterFaceZoneID_.index()].flipMap();
82     const labelList& masterFc = masterFaceCells();
84     // Recover faces in master patch
86     forAll (masterPatchAddr, faceI)
87     {
88         // Make a copy of the face and turn it if necessary
89         face newFace = faces[masterPatchAddr[faceI]];
91         if (masterPatchFlip[faceI])
92         {
93             newFace = newFace.reverseFace();
94         }
96         ref.setAction
97         (
98             polyModifyFace
99             (
100                 newFace,                         // new face
101                 masterPatchAddr[faceI],          // master face index
102                 masterFc[faceI],                 // owner
103                 -1,                              // neighbour
104                 false,                           // flux flip
105                 masterPatchID_.index(),          // patch ID
106                 false,                           // remove from zone
107                 masterFaceZoneID_.index(),       // zone ID
108                 false                            // zone flip.  Face corrected
109             )
110         );
111 //         Pout << "Modifying master patch face no " << masterPatchAddr[faceI] << " face: " << faces[masterPatchAddr[faceI]] << " old owner: " << own[masterPatchAddr[faceI]] << " new owner: " << masterFc[faceI] << endl;
112     }
114     // Slave side
116     const primitiveFacePatch& slavePatch =
117         mesh.faceZones()[slaveFaceZoneID_.index()]();
119     const labelList& slavePatchAddr =
120         mesh.faceZones()[slaveFaceZoneID_.index()];
122     const boolList& slavePatchFlip =
123         mesh.faceZones()[slaveFaceZoneID_.index()].flipMap();
125     const labelList& slaveFc = slaveFaceCells();
127     // Grab retired point mapping
128     const Map<label>& rpm = retiredPointMap();
130     // Recover faces in slave patch
132     forAll (slavePatchAddr, faceI)
133     {
134         // Make a copy of face and turn it if necessary
135         face newFace = faces[slavePatchAddr[faceI]];
137         if (slavePatchFlip[faceI])
138         {
139             newFace = newFace.reverseFace();
140         }
142         // Recover retired points on the slave side
143         forAll (newFace, pointI)
144         {
145             Map<label>::const_iterator rpmIter = rpm.find(newFace[pointI]);
146             if (rpmIter != rpm.end())
147             {
148                 // Master of retired point; grab its original
149 //                 Pout << "Reinstating retired point: " << newFace[pointI] << " with old: " << rpm.find(newFace[pointI])() << endl;
150                 newFace[pointI] = rpmIter();
151             }
152         }
154         ref.setAction
155         (
156             polyModifyFace
157             (
158                 newFace,                         // new face
159                 slavePatchAddr[faceI],           // master face index
160                 slaveFc[faceI],                  // owner
161                 -1,                              // neighbour
162                 false,                           // flux flip
163                 slavePatchID_.index(),           // patch ID
164                 false,                           // remove from zone
165                 slaveFaceZoneID_.index(),        // zone ID
166                 false                            // zone flip.  Face corrected
167             )
168         );
169     }
171     // Re-create the master stick-out faces
173     // Grab the list of faces in the layer
174     const labelList& masterStickOuts = masterStickOutFaces();
176     forAll (masterStickOuts, faceI)
177     {
178         // Renumber the face and remove additional points
180         const label curFaceID = masterStickOuts[faceI];
182         const face& oldFace = faces[curFaceID];
184         DynamicList<label> newFaceLabels(oldFace.size());
186         bool changed = false;
188         forAll (oldFace, pointI)
189         {
190             // Check if the point is removed
191             if (ref.pointRemoved(oldFace[pointI]))
192             {
193                 // Point removed; skip it
194                 changed = true;
195             }
196             else
197             {
198                 newFaceLabels.append(oldFace[pointI]);
199             }
200         }
202         if (changed)
203         {
204             if (newFaceLabels.size() < 3)
205             {
206                 FatalErrorIn
207                 (
208                     "void slidingInterface::decoupleInterface("
209                     "polyTopoChange& ref) const"
210                 )   << "Face " << curFaceID << " reduced to less than "
211                     << "3 points.  Topological/cutting error." << nl
212                     << "Old face: " << oldFace << " new face: " << newFaceLabels
213                     << abort(FatalError);
214             }
216             // Get face zone and its flip
217             label modifiedFaceZone = mesh.faceZones().whichZone(curFaceID);
218             bool modifiedFaceZoneFlip = false;
220             if (modifiedFaceZone >= 0)
221             {
222                 modifiedFaceZoneFlip =
223                     mesh.faceZones()[modifiedFaceZone].flipMap()
224                     [
225                         mesh.faceZones()[modifiedFaceZone].whichFace(curFaceID)
226                     ];
227             }
229             face newFace;
230             newFace.transfer(newFaceLabels.shrink());
232 //             Pout << "Modifying master stick-out face " << curFaceID << " old face: " << oldFace << " new face: " << newFace << endl;
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     }
253     // Re-create the slave stick-out faces
255     labelHashSet slaveLayerCellFaceMap
256     (
257         primitiveMesh::facesPerCell_*(masterPatch.size() + slavePatch.size())
258     );
260     forAll (slaveFc, faceI)
261     {
262         const labelList& curFaces = cells[slaveFc[faceI]];
264         forAll (curFaces, faceI)
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                 mesh.faceZones().whichZone(curFaces[faceI])
271              != slaveFaceZoneID_.index()
272              && !ref.faceRemoved(curFaces[faceI])
274             )
275             {
276                 slaveLayerCellFaceMap.insert(curFaces[faceI]);
277             }
278         }
279     }
281     // Grab the list of faces in the layer
282     const labelList& slaveStickOuts = slaveStickOutFaces();
284     // Grab master point mapping
285     const Map<label>& masterPm = masterPatch.meshPointMap();
287     forAll (slaveStickOuts, faceI)
288     {
289         // Renumber the face and remove additional points
291         const label curFaceID = slaveStickOuts[faceI];
293         const face& oldFace = faces[curFaceID];
295         DynamicList<label> newFaceLabels(oldFace.size());
297         bool changed = false;
299         forAll (oldFace, pointI)
300         {
301             // Check if the point is removed or retired
302             if (rpm.found(oldFace[pointI]))
303             {
304                 // Master of retired point; grab its original
305                 changed = true;
306 //                 Pout << "Reinstating retired point: " << oldFace[pointI] << " with old: " << rpm.find(oldFace[pointI])() << endl;
307                 newFaceLabels.append(rpm.find(oldFace[pointI])());
308             }
309             else if (ref.pointRemoved(oldFace[pointI]))
310             {
311                 // Point removed; skip it
312                 changed = true;
313             }
314             else if (masterPm.found(oldFace[pointI]))
315             {
316                 // Point from master patch only; skip it
317                 changed = true;
318             }
319             else
320             {
321                 newFaceLabels.append(oldFace[pointI]);
322             }
323         }
325         if (changed)
326         {
327             if (newFaceLabels.size() < 3)
328             {
329                 FatalErrorIn
330                 (
331                     "void slidingInterface::decoupleInterface("
332                     "polyTopoChange& ref) const"
333                 )   << "Face " << curFaceID << " reduced to less than "
334                     << "3 points.  Topological/cutting error." << nl
335                     << "Old face: " << oldFace << " new face: " << newFaceLabels
336                     << abort(FatalError);
337             }
339             // Get face zone and its flip
340             label modifiedFaceZone = mesh.faceZones().whichZone(curFaceID);
341             bool modifiedFaceZoneFlip = false;
343             if (modifiedFaceZone >= 0)
344             {
345                 modifiedFaceZoneFlip =
346                     mesh.faceZones()[modifiedFaceZone].flipMap()
347                     [
348                         mesh.faceZones()[modifiedFaceZone].whichFace(curFaceID)
349                     ];
350             }
352             face newFace;
353             newFace.transfer(newFaceLabels.shrink());
355 //             Pout << "Modifying slave stick-out face " << curFaceID << " old face: " << oldFace << " new face: " << newFace << endl;
357             // Modify the face
358             ref.setAction
359             (
360                 polyModifyFace
361                 (
362                     newFace,                // modified face
363                     curFaceID,              // label of face being modified
364                     own[curFaceID],         // owner
365                     nei[curFaceID],         // neighbour
366                     false,                  // face flip
367                     mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
368                     false,                  // remove from zone
369                     modifiedFaceZone,       // zone for face
370                     modifiedFaceZoneFlip    // face flip in zone
371                 )
372             );
373         }
374     }
376     // Bring all slave patch points back to life
377     const pointField& points = mesh.points();
379     const labelList& slaveMeshPoints =
380         mesh.faceZones()[slaveFaceZoneID_.index()]().meshPoints();
382     forAll (slaveMeshPoints, pointI)
383     {
384         ref.setAction
385         (
386             polyModifyPoint
387             (
388                 slaveMeshPoints[pointI],             // point ID
389                 points[slaveMeshPoints[pointI]],     // point
390                 false,                               // remove from zone
391                 mesh.pointZones().whichZone(slaveMeshPoints[pointI]), // zone
392                 true                                // in a cell
393             )
394         );
395     }
397     // Clear the retired point numbering
398     retiredPointMapPtr_->clear();
400     // Finished decoupling
401     attached_ = false;
403     if (debug)
404     {
405         Pout<< "void slidingInterface::coupleInterface("
406             << "polyTopoChange& ref) const : "
407             << "Finished decoupling sliding interface " << name() << endl;
408     }
412 // ************************************************************************* //