autoPatch.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 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Application
27  autoPatch
28 
29 Group
30  grpMeshManipulationUtilities
31 
32 Description
33  Divides external faces into patches based on (user supplied) feature
34  angle.
35 
36 \*---------------------------------------------------------------------------*/
37 
38 #include "argList.H"
39 #include "polyMesh.H"
40 #include "Time.H"
41 #include "boundaryMesh.H"
42 #include "repatchPolyTopoChanger.H"
43 #include "unitConversion.H"
44 #include "OFstream.H"
45 #include "ListOps.H"
46 
47 using namespace Foam;
48 
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 
51 // Get all feature edges.
52 void collectFeatureEdges(const boundaryMesh& bMesh, labelList& markedEdges)
53 {
54  markedEdges.setSize(bMesh.mesh().nEdges());
55 
56  label markedI = 0;
57 
58  forAll(bMesh.featureSegments(), i)
59  {
60  const labelList& segment = bMesh.featureSegments()[i];
61 
62  forAll(segment, j)
63  {
64  label featEdgeI = segment[j];
65 
66  label meshEdgeI = bMesh.featureToEdge()[featEdgeI];
67 
68  markedEdges[markedI++] = meshEdgeI;
69  }
70  }
71  markedEdges.setSize(markedI);
72 }
73 
74 
75 
76 int main(int argc, char *argv[])
77 {
79  (
80  "Divides external faces into patches based on feature angle"
81  );
82 
83  #include "addOverwriteOption.H"
84 
86  argList::noFunctionObjects(); // Never use function objects
87 
88  argList::addArgument("featureAngle", "in degrees [0-180]");
89 
90  #include "setRootCase.H"
91  #include "createTime.H"
92  #include "createPolyMesh.H"
93 
94  const word oldInstance = mesh.pointsInstance();
95 
96  Info<< "Mesh read in = "
98  << " s\n" << endl << endl;
99 
100 
101  const scalar featureAngle = args.get<scalar>(1);
102  const bool overwrite = args.found("overwrite");
103 
104  const scalar minCos = Foam::cos(degToRad(featureAngle));
105 
106  Info<< "Feature:" << featureAngle << endl
107  << "minCos :" << minCos << endl
108  << endl;
109 
110  //
111  // Use boundaryMesh to reuse all the featureEdge stuff in there.
112  //
113 
115  bMesh.read(mesh);
116 
117  // Set feature angle (calculate feature edges)
118  bMesh.setFeatureEdges(minCos);
119 
120  // Collect all feature edges as edge labels
121  labelList markedEdges;
122 
123  collectFeatureEdges(bMesh, markedEdges);
124 
125 
126 
127  // (new) patch ID for every face in mesh.
128  labelList patchIDs(bMesh.mesh().size(), -1);
129 
130  //
131  // Fill patchIDs with values for every face by floodfilling without
132  // crossing feature edge.
133  //
134 
135  // Current patch number.
136  label newPatchi = bMesh.patches().size();
137 
138  label suffix = 0;
139 
140  while (true)
141  {
142  // Find first unset face.
143  label unsetFacei = patchIDs.find(-1);
144 
145  if (unsetFacei == -1)
146  {
147  // All faces have patchID set. Exit.
148  break;
149  }
150 
151  // Found unset face. Create patch for it.
152  word patchName;
153  do
154  {
155  patchName = "auto" + name(suffix++);
156  }
157  while (bMesh.findPatchID(patchName) != -1);
158 
159  bMesh.addPatch(patchName);
160 
161  bMesh.changePatchType(patchName, "patch");
162 
163 
164  // Fill visited with all faces reachable from unsetFacei.
165  boolList visited(bMesh.mesh().size());
166 
167  bMesh.markFaces(markedEdges, unsetFacei, visited);
168 
169 
170  // Assign all visited faces to current patch
171  label nVisited = 0;
172 
173  forAll(visited, facei)
174  {
175  if (visited[facei])
176  {
177  nVisited++;
178 
179  patchIDs[facei] = newPatchi;
180  }
181  }
182 
183  Info<< "Assigned " << nVisited << " faces to patch " << patchName
184  << endl << endl;
185 
186  newPatchi++;
187  }
188 
189 
190 
191  const PtrList<boundaryPatch>& patches = bMesh.patches();
192 
193  // Create new list of patches with old ones first
194  polyPatchList newPatches(patches.size());
195 
196  newPatchi = 0;
197 
198  // Copy old patches
199  forAll(mesh.boundaryMesh(), patchi)
200  {
201  const polyPatch& patch = mesh.boundaryMesh()[patchi];
202 
203  newPatches.set
204  (
205  newPatchi,
206  patch.clone
207  (
208  mesh.boundaryMesh(),
209  newPatchi,
210  patch.size(),
211  patch.start()
212  )
213  );
214 
215  ++newPatchi;
216  }
217 
218  // Add new ones with empty size.
219  for (label patchi = newPatchi; patchi < patches.size(); patchi++)
220  {
221  const word& patchName = patches[patchi].name();
222 
223  newPatches.set
224  (
225  newPatchi,
227  (
228  polyPatch::typeName,
229  patchName,
230  0,
231  mesh.nFaces(),
232  newPatchi,
234  )
235  );
236 
237  ++newPatchi;
238  }
239 
240  if (!overwrite)
241  {
242  ++runTime;
243  }
244 
245 
246  // Change patches
247  repatchPolyTopoChanger polyMeshRepatcher(mesh);
248  polyMeshRepatcher.changePatches(newPatches);
249 
250 
251  // Change face ordering
252 
253  // Since bMesh read from mesh there is one to one mapping so we don't
254  // have to do the geometric stuff.
255  const labelList& meshFace = bMesh.meshFace();
256 
257  forAll(patchIDs, facei)
258  {
259  label meshFacei = meshFace[facei];
260 
261  polyMeshRepatcher.changePatchID(meshFacei, patchIDs[facei]);
262  }
263 
264  polyMeshRepatcher.repatch();
265 
266  // Write resulting mesh
267  if (overwrite)
268  {
269  mesh.setInstance(oldInstance);
270  }
271 
272  // Set the precision of the points data to 10
274 
275  mesh.write();
276 
277  Info<< "End\n" << endl;
278 
279  return 0;
280 }
281 
282 
283 // ************************************************************************* //
static void noFunctionObjects(bool addWithOption=false)
Remove &#39;-noFunctionObjects&#39; option and ignore any occurrences.
Definition: argList.C:547
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:462
Required Variables.
const labelList patchIDs(pbm.patchSet(polyPatchNames, false, true).sortedToc())
label find(const T &val, label pos=0) const
Find index of the first occurrence of the value.
Definition: UList.C:204
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:162
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
Unit conversion functions.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
Definition: boundaryMesh.H:58
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:423
static void noParallel()
Remove the parallel options.
Definition: argList.C:584
label nFaces() const noexcept
Number of mesh faces.
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
A list of faces which address into the list of points.
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:848
void setSize(const label n)
Alias for resize()
Definition: List.H:289
dynamicFvMesh & mesh
dimensionedScalar cos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
A mesh which allows changes in the patch distribution of the boundary faces. The change in patching i...
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition: polyMesh.H:584
A class for handling words, derived from Foam::string.
Definition: word.H:63
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:113
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: PtrList.H:159
virtual bool write(const bool writeOnProc=true) const
Write mesh using IO settings from time.
Definition: fvMesh.C:1069
label nEdges() const
Number of edges in patch.
double cpuTimeIncrement() const
Return CPU time (in seconds) since last call to cpuTimeIncrement()
Definition: cpuTimePosix.C:80
T get(const label index) const
Get a value from the argument at index.
Definition: argListI.H:271
void setInstance(const fileName &instance, const IOobjectOption::writeOption wOpt=IOobject::AUTO_WRITE)
Set the instance for mesh files.
Definition: polyMeshIO.C:29
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
const polyBoundaryMesh & patches
const std::string patch
OpenFOAM patch number as a std::string.
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:351
messageStream Info
Information stream (stdout output on master, null elsewhere)
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return pointer to a new patch created on freestore from components.
Definition: polyPatchNew.C:28
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
Foam::argList args(argc, argv)
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
PrimitivePatch< List< face >, const pointField > bMesh
Holder of faceList and points. (v.s. e.g. primitivePatch which references points) ...
Definition: bMesh.H:39
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
Namespace for OpenFOAM.