1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
25 Reads surface and applies surface regioning to a mesh. Uses boundaryMesh
28 \*---------------------------------------------------------------------------*/
32 #include "boundaryMesh.H"
35 #include "polyTopoChange.H"
36 #include "polyModifyFace.H"
37 #include "globalMeshData.H"
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 // Adds empty patch if not yet there. Returns patchID.
44 label addPatch(polyMesh& mesh, const word& patchName)
46 label patchI = mesh.boundaryMesh().findPatchID(patchName);
50 const polyBoundaryMesh& patches = mesh.boundaryMesh();
52 List<polyPatch*> newPatches(patches.size() + 1);
56 // Copy all old patches
59 const polyPatch& pp = patches[i];
73 // Add zero-sized patch
84 mesh.removeBoundary();
85 mesh.addPatches(newPatches);
87 Pout<< "Created patch " << patchName << " at " << patchI << endl;
91 Pout<< "Reusing patch " << patchName << " at " << patchI << endl;
98 // Repatch single face. Return true if patch changed.
101 const polyMesh& mesh,
102 const boundaryMesh& bMesh,
103 const labelList& nearest,
104 const labelList& surfToMeshPatch,
106 polyTopoChange& meshMod
109 bool changed = false;
111 label bFaceI = faceI - mesh.nInternalFaces();
113 if (nearest[bFaceI] != -1)
115 // Use boundary mesh one.
116 label bMeshPatchID = bMesh.whichPatch(nearest[bFaceI]);
118 label patchID = surfToMeshPatch[bMeshPatchID];
120 if (patchID != mesh.boundaryMesh().whichPatch(faceI))
122 label own = mesh.faceOwner()[faceI];
124 label zoneID = mesh.faceZones().whichZone(faceI);
126 bool zoneFlip = false;
130 const faceZone& fZone = mesh.faceZones()[zoneID];
132 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
139 mesh.faces()[faceI],// modified face
140 faceI, // label of face being modified
144 patchID, // patch for face
145 false, // remove from zone
146 zoneID, // zone for face
147 zoneFlip // face flip in zone
164 int main(int argc, char *argv[])
168 "reads surface and applies surface regioning to a mesh"
171 argList::noParallel();
172 argList::validArgs.append("surfaceFile");
177 "only repatch the faces in specified faceSet"
183 "search tolerance as fraction of mesh size (default 1e-3)"
186 #include "setRootCase.H"
187 #include "createTime.H"
188 #include "createPolyMesh.H"
190 const fileName surfName = args[1];
192 Info<< "Reading surface from " << surfName << " ..." << endl;
195 const bool readSet = args.optionReadIfPresent("faceSet", setName);
199 Info<< "Repatching only the faces in faceSet " << setName
200 << " according to nearest surface triangle ..." << endl;
204 Info<< "Patching all boundary faces according to nearest surface"
205 << " triangle ..." << endl;
208 const scalar searchTol = args.optionLookupOrDefault("tol", 1e-3);
210 // Get search box. Anything not within this box will not be considered.
211 const boundBox& meshBb = mesh.bounds();
212 const vector searchSpan = searchTol * meshBb.span();
214 Info<< "All boundary faces further away than " << searchTol
215 << " of mesh bounding box " << meshBb
216 << " will keep their patch label ..." << endl;
219 Info<< "Before patching:" << nl
220 << " patch\tsize" << endl;
222 forAll(mesh.boundaryMesh(), patchI)
224 Info<< " " << mesh.boundaryMesh()[patchI].name() << '\t'
225 << mesh.boundaryMesh()[patchI].size() << nl;
232 // Load in the surface.
233 bMesh.readTriSurface(surfName);
235 // Add all the boundaryMesh patches to the mesh.
236 const PtrList<boundaryPatch>& bPatches = bMesh.patches();
238 // Map from surface patch ( = boundaryMesh patch) to polyMesh patch
239 labelList patchMap(bPatches.size());
243 patchMap[i] = addPatch(mesh, bPatches[i].name());
246 // Obtain nearest face in bMesh for each boundary face in mesh that
247 // is within search span.
248 // Note: should only determine for faceSet if working with that.
249 labelList nearest(bMesh.getNearest(mesh, searchSpan));
252 // Dump unmatched faces to faceSet for debugging.
253 faceSet unmatchedFaces(mesh, "unmatchedFaces", nearest.size()/100);
255 forAll(nearest, bFaceI)
257 if (nearest[bFaceI] == -1)
259 unmatchedFaces.insert(mesh.nInternalFaces() + bFaceI);
263 Pout<< "Writing all " << unmatchedFaces.size()
264 << " unmatched faces to faceSet "
265 << unmatchedFaces.name()
268 unmatchedFaces.write();
272 polyTopoChange meshMod(mesh);
278 faceSet faceLabels(mesh, setName);
279 Info<< "Read " << faceLabels.size() << " faces to repatch ..." << endl;
281 forAllConstIter(faceSet, faceLabels, iter)
283 label faceI = iter.key();
285 if (repatchFace(mesh, bMesh, nearest, patchMap, faceI, meshMod))
293 forAll(nearest, bFaceI)
295 label faceI = mesh.nInternalFaces() + bFaceI;
297 if (repatchFace(mesh, bMesh, nearest, patchMap, faceI, meshMod))
304 Pout<< "Changed " << nChanged << " boundary faces." << nl << endl;
308 meshMod.changeMesh(mesh, false);
310 Info<< "After patching:" << nl
311 << " patch\tsize" << endl;
313 forAll(mesh.boundaryMesh(), patchI)
315 Info<< " " << mesh.boundaryMesh()[patchI].name() << '\t'
316 << mesh.boundaryMesh()[patchI].size() << endl;
323 // Write resulting mesh
324 Info<< "Writing modified mesh to time " << runTime.value() << endl;
329 Info<< "End\n" << endl;
335 // ************************************************************************* //