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-2021 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 auto surfName = args.get<fileName>(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)
Definition: polyMesh.C:954
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:63
Foam::fileName
A class for handling file names.
Definition: fileName.H:71
Foam::faceZone::flipMap
const boolList & flipMap() const noexcept
Definition: faceZone.H:268
Foam::fvMesh::write
virtual bool write(const bool valid=true) const
Definition: fvMesh.C:1034
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:59
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Definition: argListI.H:300
globalMeshData.H
polyTopoChange.H
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:95
Foam::argList::addNote
static void addNote(const string &note)
Definition: argList.C:405
Foam::faceSet
A list of face labels.
Definition: faceSet.H:47
Foam::polyModifyFace
Class describing modification of a face.
Definition: polyModifyFace.H:44
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Definition: polyMesh.H:440
Foam::endl
Ostream & endl(Ostream &os)
Definition: Ostream.H:381
Foam::dimensioned::value
const Type & value() const
Definition: dimensionedType.C:427
meshBb
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(rndGen, 1e-3))
Foam::Pout
prefixOSstream Pout
polyMesh.H
Foam::argList::get
T get(const label index) const
Definition: argListI.H:271
Foam::argList::readIfPresent
bool readIfPresent(const word &optName, T &val) const
Definition: argListI.H:316
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:73
forAll
#define forAll(list, i)
Definition: stdFoam.H:349
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Definition: argList.C:294
Foam::faceZone
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:60
Foam::Info
messageStream Info
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:64
Foam::OSstream::name
virtual const fileName & name() const
Definition: OSstream.H:103
Foam::bMesh
PrimitivePatch< List< face >, const pointField > bMesh
Holder of faceList and points. (v.s. e.g. primitivePatch which references points)
Definition: bMesh.H:42
argList.H
patchID
label patchID
Definition: boundaryProcessorFaPatchPoints.H:5
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Definition: polyMesh.C:1100
faceSet.H
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const noexcept
Definition: polyMesh.H:482
Foam::polyBoundaryMesh::whichPatch
label whichPatch(const label faceIndex) const
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:55
Foam::polyBoundaryMesh::findPatchID
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Definition: polyBoundaryMesh.C:758
Foam::polyTopoChange::changeMesh
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, const labelUList &patchMap, const bool inflate, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Definition: polyTopoChange.C:2973
Foam::ZoneMesh::whichZone
label whichZone(const label objectIndex) const
Definition: ZoneMesh.C:282
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
Foam
Definition: atmBoundaryLayer.C:26
Foam::faceZone::whichFace
label whichFace(const label globalCellID) const
Definition: faceZone.C:365
Foam::polyPatch::start
label start() const
Definition: polyPatch.H:357
polyModifyFace.H
Foam::polyMesh::removeBoundary
void removeBoundary()
Definition: polyMeshClear.C:32
Foam::polyMesh::bounds
const boundBox & bounds() const
Definition: polyMesh.H:446
Foam::IOobject::name
const word & name() const noexcept
Definition: IOobjectI.H:58
Time.H
setRootCase.H
Foam::polyMesh::faces
virtual const faceList & faces() const
Definition: polyMesh.C:1087
Foam::polyTopoChange::setAction
label setAction(const topoAction &action)
Definition: polyTopoChange.C:2474
Foam::nl
constexpr char nl
Definition: Ostream.H:424
Foam::Vector< scalar >
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const noexcept
Definition: primitiveMeshI.H:71
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:58
Foam::constant::electromagnetic::e
const dimensionedScalar e
Definition: createFields.H:11
createTime.H
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:59
Foam::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:57
Foam::polyPatch::clone
virtual autoPtr< polyPatch > clone(const labelList &faceCells) const
Definition: polyPatch.H:231
Foam::name
word name(const expressions::valueTypeCode typeCode)
Definition: exprTraits.C:52
boundaryMesh.H
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:58
Foam::primitiveMesh::nFaces
label nFaces() const noexcept
Definition: primitiveMeshI.H:83
Foam::argList::noParallel
static void noParallel()
Definition: argList.C:503
Foam::argList::addOption
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Definition: argList.C:328
args
Foam::argList args(argc, argv)
createPolyMesh.H
Required Variables.
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:75