BUGFIX: Uninitialised member variables
[foam-extend-3.2.git] / applications / utilities / surface / surfaceToPatch / surfaceToPatch.C
blobbcf0a934ec0ce5912ccd6e4da4d0eea3b58d8363
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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
25 Description
26     Reads surface and applies surface regioning to a mesh. Uses boundaryMesh
27     to do the hard work.
29 \*---------------------------------------------------------------------------*/
31 #include "argList.H"
32 #include "objectRegistry.H"
33 #include "Time.H"
34 #include "boundaryMesh.H"
35 #include "polyMesh.H"
36 #include "faceSet.H"
37 #include "directTopoChange.H"
38 #include "polyModifyFace.H"
39 #include "globalMeshData.H"
41 using namespace Foam;
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);
50     if (patchI == -1)
51     {
52         const polyBoundaryMesh& patches = mesh.boundaryMesh();
54         List<polyPatch*> newPatches(patches.size() + 1);
56         patchI = 0;
58         // Copy all old patches
59         forAll(patches, i)
60         {
61             const polyPatch& pp = patches[i];
63             newPatches[patchI] =
64                 pp.clone
65                 (
66                     patches,
67                     patchI,
68                     pp.size(),
69                     pp.start()
70                 ).ptr();
72             patchI++;
73         }
75         // Add zero-sized patch
76         newPatches[patchI] =
77             new polyPatch
78             (
79                 patchName,
80                 0,
81                 mesh.nFaces(),
82                 patchI,
83                 patches
84             );
86         mesh.removeBoundary();
87         mesh.addPatches(newPatches);
89         Pout<< "Created patch " << patchName << " at " << patchI << endl;
90     }
91     else
92     {
93         Pout<< "Reusing patch " << patchName << " at " << patchI << endl;
94     }
96     return patchI;
100 // Repatch single face. Return true if patch changed.
101 bool repatchFace
103     const polyMesh& mesh,
104     const boundaryMesh& bMesh,
105     const labelList& nearest,
106     const labelList& surfToMeshPatch,
107     const label faceI,
108     directTopoChange& meshMod
111     bool changed = false;
113     label bFaceI = faceI - mesh.nInternalFaces();
115     if (nearest[bFaceI] != -1)
116     {
117         // Use boundary mesh one.
118         label bMeshPatchID = bMesh.whichPatch(nearest[bFaceI]);
120         label patchID = surfToMeshPatch[bMeshPatchID];
122         if (patchID != mesh.boundaryMesh().whichPatch(faceI))
123         {
124             label own = mesh.faceOwner()[faceI];
126             label zoneID = mesh.faceZones().whichZone(faceI);
128             bool zoneFlip = false;
130             if (zoneID >= 0)
131             {
132                 const faceZone& fZone = mesh.faceZones()[zoneID];
134                 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
135             }
137             meshMod.setAction
138             (
139                 polyModifyFace
140                 (
141                     mesh.faces()[faceI],// modified face
142                     faceI,              // label of face being modified
143                     own,                // owner
144                     -1,                 // neighbour
145                     false,              // face flip
146                     patchID,            // patch for face
147                     false,              // remove from zone
148                     zoneID,             // zone for face
149                     zoneFlip            // face flip in zone
150                 )
151             );
153             changed = true;
154         }
155     }
156     else
157     {
158         changed = false;
159     }
160     return changed;
164 // Main program:
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");
182     word setName;
184     if (readSet)
185     {
186         setName = args.option("faceSet");
188         Info<< "Repatching only the faces in faceSet " << setName
189             << " according to nearest surface triangle ..." << endl;
190     }
191     else
192     {
193         Info<< "Patching all boundary faces according to nearest surface"
194             << " triangle ..." << endl;
195     }
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)
213     {
214         Info<< "    " << mesh.boundaryMesh()[patchI].name() << '\t'
215             << mesh.boundaryMesh()[patchI].size() << endl;
216     }
217     Info<< endl;
221     boundaryMesh bMesh;
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());
232     forAll(bPatches, i)
233     {
234         patchMap[i] = addPatch(mesh, bPatches[i].name());
235     }
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));
242     {
243         // Dump unmatched faces to faceSet for debugging.
244         faceSet unmatchedFaces(mesh, "unmatchedFaces", nearest.size()/100);
246         forAll(nearest, bFaceI)
247         {
248             if (nearest[bFaceI] == -1)
249             {
250                 unmatchedFaces.insert(mesh.nInternalFaces() + bFaceI);
251             }
252         }
254         Pout<< "Writing all " << unmatchedFaces.size()
255             << " unmatched faces to faceSet "
256             << unmatchedFaces.name()
257             << endl;
259         unmatchedFaces.write();
260     }
263     directTopoChange meshMod(mesh);
265     label nChanged = 0;
267     if (readSet)
268     {
269         faceSet faceLabels(mesh, setName);
270         Info<< "Read " << faceLabels.size() << " faces to repatch ..." << endl;
272         forAllConstIter(faceSet, faceLabels, iter)
273         {
274             label faceI = iter.key();
276             if (repatchFace(mesh, bMesh, nearest, patchMap, faceI, meshMod))
277             {
278                 nChanged++;
279             }
280         }
281     }
282     else
283     {
284         forAll(nearest, bFaceI)
285         {
286             label faceI = mesh.nInternalFaces() + bFaceI;
288             if (repatchFace(mesh, bMesh, nearest, patchMap, faceI, meshMod))
289             {
290                 nChanged++;
291             }
292         }
293     }
295     Pout<< "Changed " << nChanged << " boundary faces." << nl << endl;
297     if (nChanged > 0)
298     {
299         meshMod.changeMesh(mesh, false);
301         Info<< "After patching:" << nl
302             << "    patch\tsize" << endl;
304         forAll(mesh.boundaryMesh(), patchI)
305         {
306             Info<< "    " << mesh.boundaryMesh()[patchI].name() << '\t'
307                 << mesh.boundaryMesh()[patchI].size() << endl;
308         }
309         Info<< endl;
312         runTime++;
314         // Write resulting mesh
315         Info << "Writing modified mesh to time " << runTime.value() << endl;
316         mesh.write();
317     }
320     Info<< "End\n" << endl;
322     return 0;
326 // ************************************************************************* //