1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
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 Makes internal faces into boundary faces. Does not duplicate points, unlike
29 Note: if any coupled patch face is selected for baffling the opposite
30 member has to be selected for baffling as well. Note that this
31 is the same as repatching. This was added only for convenience so
32 you don't have to filter coupled boundary out of your set.
34 \*---------------------------------------------------------------------------*/
36 #include "syncTools.H"
40 #include "polyTopoChange.H"
41 #include "polyModifyFace.H"
42 #include "polyAddFace.H"
43 #include "ReadFields.H"
44 #include "volFields.H"
45 #include "surfaceFields.H"
50 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54 polyTopoChange& meshMod,
58 const bool flipFaceFlux,
59 const label newPatchI,
63 PackedBoolList& modifiedFace
66 if (!modifiedFace[faceI])
68 // First usage of face. Modify.
74 faceI, // label of face
77 flipFaceFlux, // face flip
78 newPatchI, // patch for face
79 false, // remove from zone
80 zoneID, // zone for face
81 zoneFlip // face flip in zone
84 modifiedFace[faceI] = 1;
88 // Second or more usage of face. Add.
99 flipFaceFlux, // face flip
100 newPatchI, // patch for face
101 zoneID, // zone for face
102 zoneFlip // face flip in zone
109 label findPatchID(const polyMesh& mesh, const word& name)
111 label patchI = mesh.boundaryMesh().findPatchID(name);
115 FatalErrorIn("findPatchID(const polyMesh&, const word&)")
116 << "Cannot find patch " << name << endl
117 << "Valid patches are " << mesh.boundaryMesh().names()
126 int main(int argc, char *argv[])
128 argList::validArgs.append("faceZone");
129 argList::validArgs.append("patch");
130 argList::validOptions.insert("additionalPatches", "(patch2 .. patchN)");
131 argList::validOptions.insert("internalFacesOnly", "");
132 argList::validOptions.insert("overwrite", "");
134 # include "setRootCase.H"
135 # include "createTime.H"
136 runTime.functionObjects().off();
137 # include "createMesh.H"
138 const word oldInstance = mesh.pointsInstance();
140 const polyBoundaryMesh& patches = mesh.boundaryMesh();
141 const faceZoneMesh& faceZones = mesh.faceZones();
144 faceZoneID zoneID(args.additionalArgs()[0], faceZones);
146 Info<< "Converting faces on zone " << zoneID.name()
147 << " into baffles." << nl << endl;
149 const faceZone& fZone = faceZones[zoneID.index()];
151 Info<< "Found " << returnReduce(fZone.size(), sumOp<label>())
152 << " faces on zone " << zoneID.name() << nl << endl;
154 // Make sure patches and zoneFaces are synchronised across couples
155 patches.checkParallelSync(true);
156 fZone.checkParallelSync(true);
158 // Patches to put baffles into
159 DynamicList<label> newPatches(1);
161 word patchName(args.additionalArgs()[1]);
162 newPatches.append(findPatchID(mesh, patchName));
163 Info<< "Using patch " << patchName
164 << " at index " << newPatches[0] << endl;
167 // Additional patches
168 if (args.optionFound("additionalPatches"))
170 const wordList patchNames
172 args.optionLookup("additionalPatches")()
175 newPatches.reserve(patchNames.size() + 1);
176 forAll(patchNames, i)
178 newPatches.append(findPatchID(mesh, patchNames[i]));
179 Info<< "Using additional patch " << patchNames[i]
180 << " at index " << newPatches[newPatches.size()-1] << endl;
185 bool overwrite = args.optionFound("overwrite");
187 bool internalFacesOnly = args.optionFound("internalFacesOnly");
189 if (internalFacesOnly)
191 Info<< "Not converting faces on non-coupled patches." << nl << endl;
195 // Read objects in time directory
196 IOobjectList objects(mesh, runTime.timeName());
200 PtrList<volScalarField> vsFlds;
201 ReadFields(mesh, objects, vsFlds);
203 PtrList<volVectorField> vvFlds;
204 ReadFields(mesh, objects, vvFlds);
206 PtrList<volSphericalTensorField> vstFlds;
207 ReadFields(mesh, objects, vstFlds);
209 PtrList<volSymmTensorField> vsymtFlds;
210 ReadFields(mesh, objects, vsymtFlds);
212 PtrList<volTensorField> vtFlds;
213 ReadFields(mesh, objects, vtFlds);
215 // Read surface fields.
217 PtrList<surfaceScalarField> ssFlds;
218 ReadFields(mesh, objects, ssFlds);
220 PtrList<surfaceVectorField> svFlds;
221 ReadFields(mesh, objects, svFlds);
223 PtrList<surfaceSphericalTensorField> sstFlds;
224 ReadFields(mesh, objects, sstFlds);
226 PtrList<surfaceSymmTensorField> ssymtFlds;
227 ReadFields(mesh, objects, ssymtFlds);
229 PtrList<surfaceTensorField> stFlds;
230 ReadFields(mesh, objects, stFlds);
233 // Mesh change container
234 polyTopoChange meshMod(mesh);
237 // Do the actual changes. Note:
238 // - loop in incrementing face order (not necessary if faceZone ordered).
239 // Preserves any existing ordering on patch faces.
240 // - two passes, do non-flip faces first and flip faces second. This
241 // guarantees that when e.g. creating a cyclic all faces from one
242 // side come first and faces from the other side next.
244 // Whether first use of face (modify) or consecutive (add)
245 PackedBoolList modifiedFace(mesh.nFaces());
246 // Never modify coupled faces
247 forAll(patches, patchI)
249 const polyPatch& pp = patches[patchI];
254 modifiedFace[pp.start()+i] = 1;
260 forAll(newPatches, i)
262 label newPatchI = newPatches[i];
264 // Pass 1. Do selected side of zone
265 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
267 for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
269 label zoneFaceI = fZone.whichFace(faceI);
273 if (!fZone.flipMap()[zoneFaceI])
275 // Use owner side of face
279 mesh.faces()[faceI], // modified face
280 faceI, // label of face
281 mesh.faceOwner()[faceI],// owner
283 newPatchI, // patch for face
284 zoneID.index(), // zone for face
285 false, // face flip in zone
286 modifiedFace // modify or add status
291 // Use neighbour side of face
295 mesh.faces()[faceI].reverseFace(), // modified face
296 faceI, // label of face
297 mesh.faceNeighbour()[faceI],// owner
299 newPatchI, // patch for face
300 zoneID.index(), // zone for face
301 true, // face flip in zone
302 modifiedFace // modify or add status
311 // Pass 2. Do other side of zone
312 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
314 for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
316 label zoneFaceI = fZone.whichFace(faceI);
320 if (!fZone.flipMap()[zoneFaceI])
322 // Use neighbour side of face
326 mesh.faces()[faceI].reverseFace(), // modified face
327 faceI, // label of face
328 mesh.faceNeighbour()[faceI], // owner
330 newPatchI, // patch for face
331 zoneID.index(), // zone for face
332 true, // face flip in zone
333 modifiedFace // modify or add
338 // Use owner side of face
342 mesh.faces()[faceI], // modified face
343 faceI, // label of face
344 mesh.faceOwner()[faceI],// owner
346 newPatchI, // patch for face
347 zoneID.index(), // zone for face
348 false, // face flip in zone
349 modifiedFace // modify or add status
356 // Modify any boundary faces
357 // ~~~~~~~~~~~~~~~~~~~~~~~~~
360 // - move to new patch. Might already be back-to-back baffle
361 // you want to add cyclic to. Do warn though.
363 // Processor boundary:
364 // - do not move to cyclic
365 // - add normal patches though.
367 // For warning once per patch.
368 labelHashSet patchWarned;
370 forAll(patches, patchI)
372 const polyPatch& pp = patches[patchI];
374 if (pp.coupled() && patches[newPatchI].coupled())
376 // Do not allow coupled faces to be moved to different coupled
379 else if (pp.coupled() || !internalFacesOnly)
383 label faceI = pp.start()+i;
385 label zoneFaceI = fZone.whichFace(faceI);
389 if (patchWarned.insert(patchI))
391 WarningIn(args.executable())
392 << "Found boundary face (in patch " << pp.name()
393 << ") in faceZone " << fZone.name()
394 << " to convert to baffle patch "
395 << patches[newPatchI].name()
397 << " Run with -internalFacesOnly option"
398 << " if you don't wish to convert"
399 << " boundary faces." << endl;
405 mesh.faces()[faceI], // modified face
406 faceI, // label of face
407 mesh.faceOwner()[faceI], // owner
409 newPatchI, // patch for face
410 zoneID.index(), // zone for face
411 fZone.flipMap()[zoneFaceI], // face flip in zone
412 modifiedFace // modify or add status
422 Info<< "Converted " << returnReduce(nModified, sumOp<label>())
423 << " faces into boundary faces on patch " << patchName << nl << endl;
430 // Change the mesh. Change points directly (no inflation).
431 autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
434 mesh.updateMesh(map);
436 // Move mesh (since morphing might not do this)
437 if (map().hasMotionPoints())
439 mesh.movePoints(map().preMotionPoints());
444 mesh.setInstance(oldInstance);
446 Info<< "Writing mesh to " << runTime.timeName() << endl;
450 Info<< "End\n" << endl;
456 // ************************************************************************* //