FreeFOAM The Cross-Platform CFD Toolkit
meshRefinementMerge.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 "meshRefinement.H"
30 
31 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
32 
33 // Merge faces that are in-line.
35 (
36  const scalar minCos,
37  const scalar concaveCos,
38  const labelList& patchIDs
39 )
40 {
41  // Patch face merging engine
42  combineFaces faceCombiner(mesh_);
43 
44  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
45 
46  // Pick up all candidate cells on boundary
47  labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
48 
49  forAll(patchIDs, i)
50  {
51  label patchI = patchIDs[i];
52 
53  const polyPatch& patch = patches[patchI];
54 
55  if (!patch.coupled())
56  {
57  forAll(patch, i)
58  {
59  boundaryCells.insert(mesh_.faceOwner()[patch.start()+i]);
60  }
61  }
62  }
63 
64  // Get all sets of faces that can be merged
65  labelListList mergeSets
66  (
67  faceCombiner.getMergeSets
68  (
69  minCos,
70  concaveCos,
71  boundaryCells
72  )
73  );
74 
75  label nFaceSets = returnReduce(mergeSets.size(), sumOp<label>());
76 
77  Info<< "mergePatchFaces : Merging " << nFaceSets
78  << " sets of faces." << endl;
79 
80  if (nFaceSets > 0)
81  {
82  // Topology changes container
83  polyTopoChange meshMod(mesh_);
84 
85  // Merge all faces of a set into the first face of the set. Remove
86  // unused points.
87  faceCombiner.setRefinement(mergeSets, meshMod);
88 
89  // Change the mesh (no inflation)
90  autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh_, false, true);
91 
92  // Update fields
93  mesh_.updateMesh(map);
94 
95  // Move mesh (since morphing does not do this)
96  if (map().hasMotionPoints())
97  {
98  mesh_.movePoints(map().preMotionPoints());
99  }
100  else
101  {
102  // Delete mesh volumes. No other way to do this?
103  mesh_.clearOut();
104  }
105 
106  if (overwrite())
107  {
108  mesh_.setInstance(oldInstance());
109  }
110 
111  faceCombiner.updateMesh(map);
112 
113  // Get the kept faces that need to be recalculated.
114  // Merging two boundary faces might shift the cell centre
115  // (unless the faces are absolutely planar)
116  labelHashSet retestFaces(6*mergeSets.size());
117 
118  forAll(mergeSets, setI)
119  {
120  label oldMasterI = mergeSets[setI][0];
121 
122  label faceI = map().reverseFaceMap()[oldMasterI];
123 
124  // faceI is always uncoupled boundary face
125  const cell& cFaces = mesh_.cells()[mesh_.faceOwner()[faceI]];
126 
127  forAll(cFaces, i)
128  {
129  retestFaces.insert(cFaces[i]);
130  }
131  }
132  updateMesh(map, retestFaces.toc());
133  }
134 
135 
136  return nFaceSets;
137 }
138 
139 
140 // Remove points not used by any face or points used by only two faces where
141 // the edges are in line
143 (
144  const scalar minCos
145 )
146 {
147  // Point removal analysis engine
148  removePoints pointRemover(mesh_);
149 
150  // Count usage of points
151  boolList pointCanBeDeleted;
152  label nRemove = pointRemover.countPointUsage(minCos, pointCanBeDeleted);
153 
154  Info<< "Removing " << nRemove
155  << " straight edge points." << endl;
156 
158 
159  if (nRemove > 0)
160  {
161  // Save my local faces that will change. These changed faces might
162  // cause a shift in the cell centre which needs to be retested.
163  // Have to do this before changing mesh since point will be removed.
164  labelHashSet retestOldFaces(nRemove / Pstream::nProcs());
165 
166  {
167  const faceList& faces = mesh_.faces();
168 
169  forAll(faces, faceI)
170  {
171  const face& f = faces[faceI];
172 
173  forAll(f, fp)
174  {
175  if (pointCanBeDeleted[f[fp]])
176  {
177  retestOldFaces.insert(faceI);
178  break;
179  }
180  }
181  }
182  }
183 
184  // Topology changes container
185  polyTopoChange meshMod(mesh_);
186 
187  pointRemover.setRefinement(pointCanBeDeleted, meshMod);
188 
189  // Change the mesh (no inflation)
190  map = meshMod.changeMesh(mesh_, false, true);
191 
192  // Update fields
193  mesh_.updateMesh(map);
194 
195  // Move mesh (since morphing does not do this)
196  if (map().hasMotionPoints())
197  {
198  mesh_.movePoints(map().preMotionPoints());
199  }
200  else
201  {
202  // Delete mesh volumes. No other way to do this?
203  mesh_.clearOut();
204  }
205 
206  if (overwrite())
207  {
208  mesh_.setInstance(oldInstance());
209  }
210 
211  pointRemover.updateMesh(map);
212 
213  // Get the kept faces that need to be recalculated.
214  labelHashSet retestFaces(6*retestOldFaces.size());
215 
216  const cellList& cells = mesh_.cells();
217 
218  forAllConstIter(labelHashSet, retestOldFaces, iter)
219  {
220  label faceI = map().reverseFaceMap()[iter.key()];
221 
222  const cell& ownFaces = cells[mesh_.faceOwner()[faceI]];
223 
224  forAll(ownFaces, i)
225  {
226  retestFaces.insert(ownFaces[i]);
227  }
228 
229  if (mesh_.isInternalFace(faceI))
230  {
231  const cell& neiFaces = cells[mesh_.faceNeighbour()[faceI]];
232 
233  forAll(neiFaces, i)
234  {
235  retestFaces.insert(neiFaces[i]);
236  }
237  }
238  }
239  updateMesh(map, retestFaces.toc());
240  }
241 
242  return map;
243 }
244 
245 
246 // ************************ vim: set sw=4 sts=4 et: ************************ //