surfaceToPatch.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  Copyright (C) 2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  surfaceToPatch
29 
30 Group
31  grpSurfaceUtilities
32 
33 Description
34  Reads surface and applies surface regioning to a mesh. Uses boundaryMesh
35  to do the hard work.
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #include "argList.H"
40 #include "Time.H"
41 #include "boundaryMesh.H"
42 #include "polyMesh.H"
43 #include "faceSet.H"
44 #include "polyTopoChange.H"
45 #include "polyModifyFace.H"
46 #include "globalMeshData.H"
47 
48 using namespace Foam;
49 
50 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51 
52 // Adds empty patch if not yet there. Returns patchID.
53 label addPatch(polyMesh& mesh, const word& patchName)
54 {
55  label patchi = mesh.boundaryMesh().findPatchID(patchName);
56 
57  if (patchi == -1)
58  {
60 
61  List<polyPatch*> newPatches(patches.size() + 1);
62 
63  patchi = 0;
64 
65  // Copy all old patches
66  forAll(patches, i)
67  {
68  const polyPatch& pp = patches[i];
69 
70  newPatches[patchi] =
71  pp.clone
72  (
73  patches,
74  patchi,
75  pp.size(),
76  pp.start()
77  ).ptr();
78 
79  patchi++;
80  }
81 
82  // Add zero-sized patch
83  newPatches[patchi] =
84  new polyPatch
85  (
86  patchName,
87  0,
88  mesh.nFaces(),
89  patchi,
90  patches,
91  polyPatch::typeName
92  );
93 
95  mesh.addPatches(newPatches);
96 
97  Pout<< "Created patch " << patchName << " at " << patchi << endl;
98  }
99  else
100  {
101  Pout<< "Reusing patch " << patchName << " at " << patchi << endl;
102  }
103 
104  return patchi;
105 }
106 
107 
108 // Repatch single face. Return true if patch changed.
109 bool repatchFace
110 (
111  const polyMesh& mesh,
112  const boundaryMesh& bMesh,
113  const labelList& nearest,
114  const labelList& surfToMeshPatch,
115  const label facei,
116  polyTopoChange& meshMod
117 )
118 {
119  bool changed = false;
120 
121  label bFacei = facei - mesh.nInternalFaces();
122 
123  if (nearest[bFacei] != -1)
124  {
125  // Use boundary mesh one.
126  label bMeshPatchID = bMesh.whichPatch(nearest[bFacei]);
127 
128  label patchID = surfToMeshPatch[bMeshPatchID];
129 
130  if (patchID != mesh.boundaryMesh().whichPatch(facei))
131  {
132  label own = mesh.faceOwner()[facei];
133 
134  label zoneID = mesh.faceZones().whichZone(facei);
135 
136  bool zoneFlip = false;
137 
138  if (zoneID >= 0)
139  {
140  const faceZone& fZone = mesh.faceZones()[zoneID];
141 
142  zoneFlip = fZone.flipMap()[fZone.whichFace(facei)];
143  }
144 
145  meshMod.setAction
146  (
148  (
149  mesh.faces()[facei],// modified face
150  facei, // label of face being modified
151  own, // owner
152  -1, // neighbour
153  false, // face flip
154  patchID, // patch for face
155  false, // remove from zone
156  zoneID, // zone for face
157  zoneFlip // face flip in zone
158  )
159  );
160 
161  changed = true;
162  }
163  }
164  else
165  {
166  changed = false;
167  }
168  return changed;
169 }
170 
171 
172 
173 int main(int argc, char *argv[])
174 {
176  (
177  "Reads surface and applies surface regioning to a mesh"
178  );
179 
181  argList::addArgument("surfaceFile");
183  (
184  "faceSet",
185  "name",
186  "Only repatch the faces in specified faceSet"
187  );
189  (
190  "tol",
191  "scalar",
192  "Search tolerance as fraction of mesh size (default 1e-3)"
193  );
194 
195  #include "setRootCase.H"
196  #include "createTime.H"
197  #include "createPolyMesh.H"
198 
199  const fileName surfName = args[1];
200 
201  Info<< "Reading surface from " << surfName << " ..." << endl;
202 
203  word setName;
204  const bool readSet = args.readIfPresent("faceSet", setName);
205 
206  if (readSet)
207  {
208  Info<< "Repatching only the faces in faceSet " << setName
209  << " according to nearest surface triangle ..." << endl;
210  }
211  else
212  {
213  Info<< "Patching all boundary faces according to nearest surface"
214  << " triangle ..." << endl;
215  }
216 
217  const scalar searchTol = args.getOrDefault<scalar>("tol", 1e-3);
218 
219  // Get search box. Anything not within this box will not be considered.
220  const boundBox& meshBb = mesh.bounds();
221  const vector searchSpan = searchTol * meshBb.span();
222 
223  Info<< "All boundary faces further away than " << searchTol
224  << " of mesh bounding box " << meshBb
225  << " will keep their patch label ..." << endl;
226 
227 
228  Info<< "Before patching:" << nl
229  << " patch\tsize" << endl;
230 
231  forAll(mesh.boundaryMesh(), patchi)
232  {
233  Info<< " " << mesh.boundaryMesh()[patchi].name() << '\t'
234  << mesh.boundaryMesh()[patchi].size() << nl;
235  }
236  Info<< endl;
237 
238 
240 
241  // Load in the surface.
242  bMesh.readTriSurface(surfName);
243 
244  // Add all the boundaryMesh patches to the mesh.
245  const PtrList<boundaryPatch>& bPatches = bMesh.patches();
246 
247  // Map from surface patch ( = boundaryMesh patch) to polyMesh patch
248  labelList patchMap(bPatches.size());
249 
250  forAll(bPatches, i)
251  {
252  patchMap[i] = addPatch(mesh, bPatches[i].name());
253  }
254 
255  // Obtain nearest face in bMesh for each boundary face in mesh that
256  // is within search span.
257  // Note: should only determine for faceSet if working with that.
258  labelList nearest(bMesh.getNearest(mesh, searchSpan));
259 
260  {
261  // Dump unmatched faces to faceSet for debugging.
262  faceSet unmatchedFaces(mesh, "unmatchedFaces", nearest.size()/100);
263 
264  forAll(nearest, bFacei)
265  {
266  if (nearest[bFacei] == -1)
267  {
268  unmatchedFaces.insert(mesh.nInternalFaces() + bFacei);
269  }
270  }
271 
272  Pout<< "Writing all " << unmatchedFaces.size()
273  << " unmatched faces to faceSet "
274  << unmatchedFaces.name()
275  << endl;
276 
277  unmatchedFaces.write();
278  }
279 
280 
281  polyTopoChange meshMod(mesh);
282 
283  label nChanged = 0;
284 
285  if (readSet)
286  {
287  faceSet faceLabels(mesh, setName);
288  Info<< "Read " << faceLabels.size() << " faces to repatch ..." << endl;
289 
290  for (const label facei : faceLabels)
291  {
292  if (repatchFace(mesh, bMesh, nearest, patchMap, facei, meshMod))
293  {
294  nChanged++;
295  }
296  }
297  }
298  else
299  {
300  forAll(nearest, bFacei)
301  {
302  const label facei = mesh.nInternalFaces() + bFacei;
303 
304  if (repatchFace(mesh, bMesh, nearest, patchMap, facei, meshMod))
305  {
306  ++nChanged;
307  }
308  }
309  }
310 
311  Pout<< "Changed " << nChanged << " boundary faces." << nl << endl;
312 
313  if (nChanged > 0)
314  {
315  meshMod.changeMesh(mesh, false);
316 
317  Info<< "After patching:" << nl
318  << " patch\tsize" << endl;
319 
320  forAll(mesh.boundaryMesh(), patchi)
321  {
322  Info<< " " << mesh.boundaryMesh()[patchi].name() << '\t'
323  << mesh.boundaryMesh()[patchi].size() << endl;
324  }
325  Info<< endl;
326 
327 
328  ++runTime;
329 
330  // Write resulting mesh
331  Info<< "Writing modified mesh to time " << runTime.value() << endl;
332  mesh.write();
333  }
334 
335 
336  Info<< "End\n" << endl;
337 
338  return 0;
339 }
340 
341 
342 // ************************************************************************* //
Foam::polyMesh::addPatches
void addPatches(PtrList< polyPatch > &plist, const bool validBoundary=true)
Add boundary patches.
Definition: polyMesh.C:930
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:70
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::fvMesh::write
virtual bool write(const bool valid=true) const
Write mesh using IO settings from time.
Definition: fvMesh.C:895
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:286
Foam::polyTopoChange::changeMesh
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, const bool inflate, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
Definition: polyTopoChange.C:2955
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const
Number of internal faces.
Definition: primitiveMeshI.H:78
globalMeshData.H
Foam::primitiveMesh::nFaces
label nFaces() const
Number of mesh faces.
Definition: primitiveMeshI.H:90
polyTopoChange.H
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:99
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
Foam::faceSet
A list of face labels.
Definition: faceSet.H:51
Foam::polyModifyFace
Class describing modification of a face.
Definition: polyModifyFace.H:50
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:435
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:434
meshBb
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(rndGen, 1e-3))
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
polyMesh.H
Foam::argList::readIfPresent
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:302
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const
Return face zone mesh.
Definition: polyMesh.H:477
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:302
Foam::faceZone
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:65
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:67
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::OSstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:107
Foam::bMesh
PrimitivePatch< List< face >, const pointField > bMesh
Holder of faceList and points. (v.s. e.g. primitivePatch which references points)
Definition: bMesh.H:48
argList.H
patchID
label patchID
Definition: boundaryProcessorFaPatchPoints.H:5
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1076
faceSet.H
Foam::polyBoundaryMesh::whichPatch
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Definition: polyBoundaryMesh.C:805
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:62
Foam::polyBoundaryMesh::findPatchID
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
Definition: polyBoundaryMesh.C:766
Foam::ZoneMesh::whichZone
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition: ZoneMesh.C:315
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
zoneID
const labelIOList & zoneID
Definition: interpolatedFaces.H:22
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::faceZone::whichFace
label whichFace(const label globalCellID) const
Helper function to re-direct to zone::localID(...)
Definition: faceZone.C:379
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:312
polyModifyFace.H
Foam::polyPatch::clone
virtual autoPtr< polyPatch > clone(const polyBoundaryMesh &bm) const
Construct and return a clone, resetting the boundary mesh.
Definition: polyPatch.H:232
Foam::polyMesh::removeBoundary
void removeBoundary()
Remove boundary patches.
Definition: polyMeshClear.C:39
Foam::polyMesh::bounds
const boundBox & bounds() const
Return mesh bounding box.
Definition: polyMesh.H:441
Time.H
setRootCase.H
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1063
Foam::polyTopoChange::setAction
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.
Definition: polyTopoChange.C:2456
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
createTime.H
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
boundaryMesh.H
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:62
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:491
Foam::argList::addOption
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:336
args
Foam::argList args(argc, argv)
Foam::faceZone::flipMap
const boolList & flipMap() const
Return face flip map.
Definition: faceZone.H:271
createPolyMesh.H
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:85