1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Reads surface and applies surface regioning to a mesh. Uses boundaryMesh
29 \*---------------------------------------------------------------------------*/
32 #include "objectRegistry.H"
34 #include "boundaryMesh.H"
37 #include "directTopoChange.H"
38 #include "polyModifyFace.H"
39 #include "globalMeshData.H"
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 // Adds empty patch if not yet there. Returns patchID.
46 label addPatch(polyMesh& mesh, const word& patchName)
48 label patchI = mesh.boundaryMesh().findPatchID(patchName);
52 const polyBoundaryMesh& patches = mesh.boundaryMesh();
54 List<polyPatch*> newPatches(patches.size() + 1);
58 // Copy all old patches
61 const polyPatch& pp = patches[i];
75 // Add zero-sized patch
86 mesh.removeBoundary();
87 mesh.addPatches(newPatches);
89 Pout<< "Created patch " << patchName << " at " << patchI << endl;
93 Pout<< "Reusing patch " << patchName << " at " << patchI << endl;
100 // Repatch single face. Return true if patch changed.
103 const polyMesh& mesh,
104 const boundaryMesh& bMesh,
105 const labelList& nearest,
106 const labelList& surfToMeshPatch,
108 directTopoChange& meshMod
111 bool changed = false;
113 label bFaceI = faceI - mesh.nInternalFaces();
115 if (nearest[bFaceI] != -1)
117 // Use boundary mesh one.
118 label bMeshPatchID = bMesh.whichPatch(nearest[bFaceI]);
120 label patchID = surfToMeshPatch[bMeshPatchID];
122 if (patchID != mesh.boundaryMesh().whichPatch(faceI))
124 label own = mesh.faceOwner()[faceI];
126 label zoneID = mesh.faceZones().whichZone(faceI);
128 bool zoneFlip = false;
132 const faceZone& fZone = mesh.faceZones()[zoneID];
134 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
141 mesh.faces()[faceI],// modified face
142 faceI, // label of face being modified
146 patchID, // patch for face
147 false, // remove from zone
148 zoneID, // zone for face
149 zoneFlip // face flip in zone
166 int main(int argc, char *argv[])
168 argList::noParallel();
169 argList::validArgs.append("surface file");
170 argList::validOptions.insert("faceSet", "faceSet name");
171 argList::validOptions.insert("tol", "fraction of mesh size");
173 # include "setRootCase.H"
174 # include "createTime.H"
175 # include "createPolyMesh.H"
177 fileName surfName(args.additionalArgs()[0]);
179 Info<< "Reading surface from " << surfName << " ..." << endl;
181 bool readSet = args.optionFound("faceSet");
186 setName = args.option("faceSet");
188 Info<< "Repatching only the faces in faceSet " << setName
189 << " according to nearest surface triangle ..." << endl;
193 Info<< "Patching all boundary faces according to nearest surface"
194 << " triangle ..." << endl;
197 scalar searchTol = 1e-3;
198 args.optionReadIfPresent("tol", searchTol);
200 // Get search box. Anything not within this box will not be considered.
201 const boundBox& meshBb = mesh.globalData().bb();
202 const vector searchSpan = searchTol*meshBb.span();
204 Info<< "All boundary faces further away than " << searchTol
205 << " of mesh bounding box " << meshBb
206 << " will keep their patch label ..." << endl;
209 Info<< "Before patching:" << nl
210 << " patch\tsize" << endl;
212 forAll(mesh.boundaryMesh(), patchI)
214 Info<< " " << mesh.boundaryMesh()[patchI].name() << '\t'
215 << mesh.boundaryMesh()[patchI].size() << endl;
223 // Load in the surface.
224 bMesh.readTriSurface(surfName);
226 // Add all the boundaryMesh patches to the mesh.
227 const PtrList<boundaryPatch>& bPatches = bMesh.patches();
229 // Map from surface patch ( = boundaryMesh patch) to polyMesh patch
230 labelList patchMap(bPatches.size());
234 patchMap[i] = addPatch(mesh, bPatches[i].name());
237 // Obtain nearest face in bMesh for each boundary face in mesh that
238 // is within search span.
239 // Note: should only determine for faceSet if working with that.
240 labelList nearest(bMesh.getNearest(mesh, searchSpan));
243 // Dump unmatched faces to faceSet for debugging.
244 faceSet unmatchedFaces(mesh, "unmatchedFaces", nearest.size()/100);
246 forAll(nearest, bFaceI)
248 if (nearest[bFaceI] == -1)
250 unmatchedFaces.insert(mesh.nInternalFaces() + bFaceI);
254 Pout<< "Writing all " << unmatchedFaces.size()
255 << " unmatched faces to faceSet "
256 << unmatchedFaces.name()
259 unmatchedFaces.write();
263 directTopoChange meshMod(mesh);
269 faceSet faceLabels(mesh, setName);
270 Info<< "Read " << faceLabels.size() << " faces to repatch ..." << endl;
272 forAllConstIter(faceSet, faceLabels, iter)
274 label faceI = iter.key();
276 if (repatchFace(mesh, bMesh, nearest, patchMap, faceI, meshMod))
284 forAll(nearest, bFaceI)
286 label faceI = mesh.nInternalFaces() + bFaceI;
288 if (repatchFace(mesh, bMesh, nearest, patchMap, faceI, meshMod))
295 Pout<< "Changed " << nChanged << " boundary faces." << nl << endl;
299 meshMod.changeMesh(mesh, false);
301 Info<< "After patching:" << nl
302 << " patch\tsize" << endl;
304 forAll(mesh.boundaryMesh(), patchI)
306 Info<< " " << mesh.boundaryMesh()[patchI].name() << '\t'
307 << mesh.boundaryMesh()[patchI].size() << endl;
314 // Write resulting mesh
315 Info << "Writing modified mesh to time " << runTime.value() << endl;
320 Info<< "End\n" << endl;
326 // ************************************************************************* //