FreeFOAM The Cross-Platform CFD Toolkit
repatchPolyTopoChanger.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 Description
25  A mesh which allows changes in the patch distribution of the
26  faces. The change in patching is set using changePatchID. For a
27  boundary face, a new patch ID is given. If the face is internal,
28  it will be added to the first patch and its opposite to the second
29  patch (take care with face orientation!).
30 
31 \*---------------------------------------------------------------------------*/
32 
33 #include "repatchPolyTopoChanger.H"
35 #include <OpenFOAM/mapPolyMesh.H>
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 Foam::polyTopoChange& Foam::repatchPolyTopoChanger::meshMod()
41 {
42  if (meshModPtr_.empty())
43  {
44  meshModPtr_.reset(new polyTopoChange(mesh_));
45  }
46  return meshModPtr_();
47 }
48 
49 
50 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
51 
52 Foam::repatchPolyTopoChanger::repatchPolyTopoChanger(polyMesh& mesh)
53 :
54  mesh_(mesh),
55  meshModPtr_(NULL)
56 {}
57 
58 
59 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
60 
62 (
64 )
65 {
66  if (meshModPtr_.valid())
67  {
69  (
70  "repatchPolyTopoChanger::changePatches(const List<polyPatch*>&)"
71  ) << "Cannot change patches after having changed faces. " << nl
72  << "Please call changePatches first."
73  << exit(FatalError);
74  }
75  meshModPtr_.clear();
76  mesh_.removeBoundary();
77  mesh_.addPatches(patches);
78 }
79 
80 
82 (
83  const label faceID,
84  const label patchID
85 )
86 {
87  if (polyTopoChanger::debug)
88  {
89  // Check that the request is possible
90  if
91  (
92  faceID >= mesh_.faces().size()
93  || patchID >= mesh_.boundaryMesh().size()
94  || mesh_.isInternalFace(faceID)
95  )
96  {
98  (
99  "void Foam::repatchPolyTopoChanger::changePatchID\n"
100  "(\n"
101  " const label faceID,\n"
102  " const label patchID\n"
103  ")\n"
104  ) << "Error in definition. faceID: " << faceID
105  << " patchID: " << patchID << ". "
106  << "Labels out of range or internal face."
107  << abort(FatalError);
108  }
109  }
110 
111  const label zoneID = mesh_.faceZones().whichZone(faceID);
112 
113  bool zoneFlip = false;
114 
115  if (zoneID >= 0)
116  {
117  const faceZone& fZone = mesh_.faceZones()[zoneID];
118 
119  zoneFlip = fZone.flipMap()[fZone.whichFace(faceID)];
120  }
121 
122  meshMod().setAction
123  (
125  (
126  mesh_.faces()[faceID], // face
127  faceID, // face ID
128  mesh_.faceOwner()[faceID], // owner
129  -1, // neighbour
130  false, // flip flux
131  patchID, // patch ID
132  false, // remove from zone
133  zoneID, // zone ID
134  zoneFlip // zone flip
135  )
136  );
137 }
138 
139 
141 (
142  const label faceID,
143  const label zoneID,
144  const bool zoneFlip
145 )
146 {
147  if (polyTopoChanger::debug)
148  {
149  // Check that the request is possible
150  if (faceID > mesh_.faces().size())
151  {
153  (
154  "void Foam::repatchPolyTopoChanger::setFaceZone"
155  "(\n"
156  " const label faceID,\n"
157  " const label zoneID,\n"
158  " const bool flip\n"
159  ")\n"
160  ) << "Error in definition. faceID: " << faceID
161  << "out of range."
162  << abort(FatalError);
163  }
164  }
165 
166  meshMod().setAction
167  (
169  (
170  mesh_.faces()[faceID], // face
171  faceID, // face ID
172  mesh_.faceOwner()[faceID], // owner
173  mesh_.faceNeighbour()[faceID], // neighbour
174  false, // flip flux
175  mesh_.boundaryMesh().whichPatch(faceID), // patch ID
176  true, // remove from zone
177  zoneID, // zone ID
178  zoneFlip // zone flip
179  )
180  );
181 }
182 
183 
185 (
186  const label faceID,
187  const label fp
188 )
189 {
190  if (polyTopoChanger::debug)
191  {
192  // Check that the request is possible
193  if (faceID > mesh_.faces().size())
194  {
196  (
197  "void Foam::repatchPolyTopoChanger::setFaceZone"
198  "(\n"
199  " const label faceID,\n"
200  " const label zoneID,\n"
201  " const bool flip\n"
202  ")\n"
203  ) << "Error in definition. faceID: " << faceID
204  << "out of range."
205  << abort(FatalError);
206  }
207  }
208 
209  const face& f = mesh_.faces()[faceID];
210 
211  if ((fp < 0) || (fp >= f.size()))
212  {
214  (
215  "void Foam::repatchPolyTopoChanger::changeAnchorPoint"
216  "(\n"
217  " const label faceID,\n"
218  " const label fp\n"
219  ")\n"
220  ) << "Error in definition. Face point: " << fp
221  << "indexes out of face " << f
222  << abort(FatalError);
223  }
224 
225  label patchID = mesh_.boundaryMesh().whichPatch(faceID);
226 
227  const label zoneID = mesh_.faceZones().whichZone(faceID);
228 
229  bool zoneFlip = false;
230 
231  if (zoneID >= 0)
232  {
233  const faceZone& fZone = mesh_.faceZones()[zoneID];
234 
235  zoneFlip = fZone.flipMap()[fZone.whichFace(faceID)];
236  }
237 
238  if (fp == 0)
239  {
240  // Do dummy modify to keep patch ordering.
241  meshMod().setAction
242  (
244  (
245  f, // face
246  faceID, // face ID
247  mesh_.faceOwner()[faceID], // owner
248  -1, // neighbour
249  false, // flip flux
250  patchID, // patch ID
251  false, // remove from zone
252  zoneID, // zone ID
253  zoneFlip // zone flip
254  )
255  );
256  }
257  else
258  {
259  // Construct new face with fp as first point.
260 
261  face newFace(f.size());
262 
263  label fVert = fp;
264 
265  for (label i = 0; i < f.size(); i++)
266  {
267  newFace[i] = f[fVert++];
268 
269  if (fVert == f.size())
270  {
271  fVert = 0;
272  }
273  }
274 
275 
276  meshMod().setAction
277  (
279  (
280  newFace, // face
281  faceID, // face ID
282  mesh_.faceOwner()[faceID], // owner
283  -1, // neighbour
284  false, // flip flux
285  patchID, // patch ID
286  false, // remove from zone
287  zoneID, // zone ID
288  zoneFlip // zone flip
289  )
290  );
291  }
292 }
293 
294 
296 {
297  // Change mesh, no inflation
298  meshMod().changeMesh(mesh_, false);
299 
300  // Clear topo change for the next operation
301  meshModPtr_.clear();
302 }
303 
304 
305 // ************************ vim: set sw=4 sts=4 et: ************************ //