surfaceToPatch.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
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 Application
25  surfaceToPatch
26 
27 Description
28  Reads surface and applies surface regioning to a mesh. Uses repatchMesh
29  to do the hard work.
30 
31 \*---------------------------------------------------------------------------*/
32 
33 #include "argList.H"
34 #include "Time.H"
35 #include "repatchMesh.H"
36 #include "polyMesh.H"
37 #include "faceSet.H"
38 #include "polyTopoChange.H"
39 #include "globalMeshData.H"
40 
41 using namespace Foam;
42 
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 
45 // Adds empty patch if not yet there. Returns patchID.
46 label addPatch(polyMesh& mesh, const word& patchName)
47 {
48  label patchi = mesh.boundary().findIndex(patchName);
49 
50  if (patchi == -1)
51  {
53 
54  List<polyPatch*> newPatches(patches.size() + 1);
55 
56  patchi = 0;
57 
58  // Copy all old patches
59  forAll(patches, i)
60  {
61  const polyPatch& pp = patches[i];
62 
63  newPatches[patchi] =
64  pp.clone
65  (
66  patches,
67  patchi,
68  pp.size(),
69  pp.start()
70  ).ptr();
71 
72  patchi++;
73  }
74 
75  // Add zero-sized patch
76  newPatches[patchi] =
77  new polyPatch
78  (
79  patchName,
80  0,
81  mesh.nFaces(),
82  patchi,
83  patches
84  );
85 
87  mesh.addPatches(newPatches);
88 
89  Pout<< "Created patch " << patchName << " at " << patchi << endl;
90  }
91  else
92  {
93  Pout<< "Reusing patch " << patchName << " at " << patchi << endl;
94  }
95 
96  return patchi;
97 }
98 
99 
100 // Repatch single face. Return true if patch changed.
101 bool repatchFace
102 (
103  const polyMesh& mesh,
104  const repatchMesh& rMesh,
105  const labelList& nearest,
106  const labelList& surfToMeshPatch,
107  const label facei,
108  polyTopoChange& meshMod
109 )
110 {
111  bool changed = false;
112 
113  label bFacei = facei - mesh.nInternalFaces();
114 
115  if (nearest[bFacei] != -1)
116  {
117  // Use boundary mesh one.
118  const label rMeshPatchID = rMesh.whichPatch(nearest[bFacei]);
119 
120  const label patchID = surfToMeshPatch[rMeshPatchID];
121 
122  if (patchID != mesh.boundary().whichPatch(facei))
123  {
124  const label own = mesh.faceOwner()[facei];
125 
126  meshMod.modifyFace
127  (
128  mesh.faces()[facei],// modified face
129  facei, // label of face being modified
130  own, // owner
131  -1, // neighbour
132  false, // face flip
133  patchID // patch for face
134  );
135 
136  changed = true;
137  }
138  }
139  else
140  {
141  changed = false;
142  }
143 
144  return changed;
145 }
146 
147 
148 
149 int main(int argc, char *argv[])
150 {
152  (
153  "reads surface and applies surface regioning to a mesh"
154  );
155 
157  argList::validArgs.append("surface file");
159  (
160  "faceSet",
161  "name",
162  "only repatch the faces in specified faceSet"
163  );
165  (
166  "tol",
167  "scalar",
168  "search tolerance as fraction of mesh size (default 1e-3)"
169  );
170 
171  #include "setRootCase.H"
172  #include "createTime.H"
173  #include "createPolyMesh.H"
174 
175  const fileName surfName = args[1];
176 
177  Info<< "Reading surface from " << surfName << " ..." << endl;
178 
179  word setName;
180  const bool readSet = args.optionReadIfPresent("faceSet", setName);
181 
182  if (readSet)
183  {
184  Info<< "Repatching only the faces in faceSet " << setName
185  << " according to nearest surface triangle ..." << endl;
186  }
187  else
188  {
189  Info<< "Patching all boundary faces according to nearest surface"
190  << " triangle ..." << endl;
191  }
192 
193  const scalar searchTol = args.optionLookupOrDefault("tol", 1e-3);
194 
195  // Get search box. Anything not within this box will not be considered.
196  const boundBox& meshBb = mesh.bounds();
197  const vector searchSpan = searchTol * meshBb.span();
198 
199  Info<< "All boundary faces further away than " << searchTol
200  << " of mesh bounding box " << meshBb
201  << " will keep their patch label ..." << endl;
202 
203 
204  Info<< "Before patching:" << nl
205  << " patch\tsize" << endl;
206 
208  {
209  Info<< " " << mesh.boundary()[patchi].name() << '\t'
210  << mesh.boundary()[patchi].size() << nl;
211  }
212  Info<< endl;
213 
214 
215  repatchMesh rMesh;
216 
217  // Load in the surface.
218  rMesh.readTriSurface(surfName);
219 
220  // Add all the boundaryMesh patches to the mesh.
221  const PtrList<repatchPatch>& bPatches = rMesh.patches();
222 
223  // Map from surface patch ( = boundaryMesh patch) to polyMesh patch
224  labelList patchMap(bPatches.size());
225 
226  forAll(bPatches, i)
227  {
228  patchMap[i] = addPatch(mesh, bPatches[i].name());
229  }
230 
231  // Obtain nearest face in rMesh for each boundary face in mesh that
232  // is within search span.
233  // Note: should only determine for faceSet if working with that.
234  labelList nearest(rMesh.getNearest(mesh, searchSpan));
235 
236  {
237  // Dump unmatched faces to faceSet for debugging.
238  faceSet unmatchedFaces(mesh, "unmatchedFaces", nearest.size()/100);
239 
240  forAll(nearest, bFacei)
241  {
242  if (nearest[bFacei] == -1)
243  {
244  unmatchedFaces.insert(mesh.nInternalFaces() + bFacei);
245  }
246  }
247 
248  Pout<< "Writing all " << unmatchedFaces.size()
249  << " unmatched faces to faceSet "
250  << unmatchedFaces.name()
251  << endl;
252 
253  unmatchedFaces.write();
254  }
255 
256 
257  polyTopoChange meshMod(mesh);
258 
259  label nChanged = 0;
260 
261  if (readSet)
262  {
263  faceSet faceLabels(mesh, setName);
264  Info<< "Read " << faceLabels.size() << " faces to repatch ..." << endl;
265 
266  forAllConstIter(faceSet, faceLabels, iter)
267  {
268  label facei = iter.key();
269 
270  if (repatchFace(mesh, rMesh, nearest, patchMap, facei, meshMod))
271  {
272  nChanged++;
273  }
274  }
275  }
276  else
277  {
278  forAll(nearest, bFacei)
279  {
280  label facei = mesh.nInternalFaces() + bFacei;
281 
282  if (repatchFace(mesh, rMesh, nearest, patchMap, facei, meshMod))
283  {
284  nChanged++;
285  }
286  }
287  }
288 
289  Pout<< "Changed " << nChanged << " boundary faces." << nl << endl;
290 
291  if (nChanged > 0)
292  {
293  meshMod.changeMesh(mesh);
294 
295  Info<< "After patching:" << nl
296  << " patch\tsize" << endl;
297 
299  {
300  Info<< " " << mesh.boundary()[patchi].name() << '\t'
301  << mesh.boundary()[patchi].size() << endl;
302  }
303  Info<< endl;
304 
305 
306  runTime++;
307 
308  // Write resulting mesh
309  Info<< "Writing modified mesh to time "
310  << runTime.userTimeName() << endl;
311  mesh.write();
312  }
313 
314 
315  Info<< "End\n" << endl;
316 
317  return 0;
318 }
319 
320 
321 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:85
virtual Ostream & write(const token &)
Write token.
Definition: Ostream.C:51
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
static void addOption(const word &opt, const string &param="", const string &usage="")
Add to an option to validOptions with usage information.
Definition: argList.C:121
static void addNote(const string &)
Add extra notes for the usage information.
Definition: argList.C:152
bool optionReadIfPresent(const word &opt, T &) const
Read a value from the named option if present.
Definition: argListI.H:255
static void noParallel()
Remove the parallel options.
Definition: argList.C:168
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:153
T optionLookupOrDefault(const word &opt, const T &deflt) const
Read a value from the named option if present.
Definition: argListI.H:294
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:60
A list of face labels.
Definition: faceSet.H:51
A class for handling file names.
Definition: fileName.H:82
label findIndex(const word &patchName) const
Find patch index given a name.
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:932
Foam::polyBoundaryMesh.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1308
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1321
void addPatches(const List< polyPatch * > &, const bool validBoundary=true)
Add boundary patches.
Definition: polyMesh.C:1091
void removeBoundary()
Remove boundary patches.
Definition: polyMeshClear.C:33
const boundBox & bounds() const
Return mesh bounding box.
Definition: polyMesh.H:399
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:71
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:277
virtual autoPtr< polyPatch > clone(const polyBoundaryMesh &bm) const
Construct and return a clone, resetting the boundary mesh.
Definition: polyPatch.H:212
Direct mesh changes based on v1.3 polyTopoChange syntax.
autoPtr< polyTopoChangeMap > changeMesh(polyMesh &mesh, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
void modifyFace(const face &f, const label facei, const label own, const label nei, const bool flipFaceFlux, const label patchID)
Modify vertices or cell of face.
label nInternalFaces() const
label nFaces() const
virtual bool write(const bool write=true) const
Write using setting from DB.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: repatchMesh.H:58
void readTriSurface(const fileName &)
Read from triSurface.
Definition: repatchMesh.C:474
labelList getNearest(const primitiveMesh &pMesh, const vector &searchSpan) const
Get rMesh index of nearest face for every boundary face in.
Definition: repatchMesh.C:651
label whichPatch(const label facei) const
Get index of patch face is in.
Definition: repatchMesh.C:1106
const PtrList< repatchPatch > & patches() const
Access the patches.
Definition: repatchMesh.H:192
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
int main(int argc, char *argv[])
Definition: financialFoam.C:44
label patchi
const fvPatchList & patches
Namespace for OpenFOAM.
const doubleScalar e
Definition: doubleScalar.H:106
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
static const char nl
Definition: Ostream.H:297
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(1e-3))
Foam::argList args(argc, argv)