FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

createBaffles.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Application
00025     createBaffles
00026 
00027 Description
00028     Makes internal faces into boundary faces.
00029 
00030     Does not duplicate points, unlike mergeOrSplitBaffles.
00031 
00032 Note
00033     If any coupled patch face is selected for baffling automatically
00034     the opposite member has to be selected for baffling as well. Note that this
00035     is the same as repatching. This was added only for convenience so
00036     you don't have to filter coupled boundary out of your set.
00037 
00038 Usage
00039 
00040     - createBaffles [OPTIONS] <cellSet name> <patchName>
00041 
00042     @param <cellSet name> \n
00043     @todo Detailed description of argument.
00044 
00045     @param <patchName> \n
00046     @todo Detailed description of argument.
00047 
00048     @param -overwrite \n
00049     Overwrite existing data.
00050 
00051     @param -case <dir>\n
00052     Case directory.
00053 
00054     @param -parallel \n
00055     Run in parallel.
00056 
00057     @param -help \n
00058     Display help message.
00059 
00060     @param -doc \n
00061     Display Doxygen API documentation page for this application.
00062 
00063     @param -srcDoc \n
00064     Display Doxygen source documentation page for this application.
00065 
00066 \*---------------------------------------------------------------------------*/
00067 
00068 #include <OpenFOAM/syncTools.H>
00069 #include <OpenFOAM/argList.H>
00070 #include <OpenFOAM/Time.H>
00071 #include <meshTools/faceSet.H>
00072 #include <dynamicMesh/polyTopoChange.H>
00073 #include <dynamicMesh/polyModifyFace.H>
00074 #include <dynamicMesh/polyAddFace.H>
00075 #include <OpenFOAM/ReadFields.H>
00076 #include <finiteVolume/volFields.H>
00077 #include <finiteVolume/surfaceFields.H>
00078 #include <OpenFOAM/ZoneIDs.H>
00079 
00080 using namespace Foam;
00081 
00082 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00083 
00084 void modifyOrAddFace
00085 (
00086     polyTopoChange& meshMod,
00087     const face& f,
00088     const label faceI,
00089     const label own,
00090     const bool flipFaceFlux,
00091     const label newPatchI,
00092     const label zoneID,
00093     const bool zoneFlip,
00094 
00095     PackedBoolList& modifiedFace
00096 )
00097 {
00098     if (!modifiedFace[faceI])
00099     {
00100         // First usage of face. Modify.
00101         meshMod.setAction
00102         (
00103             polyModifyFace
00104             (
00105                 f,                          // modified face
00106                 faceI,                      // label of face
00107                 own,                        // owner
00108                 -1,                         // neighbour
00109                 flipFaceFlux,               // face flip
00110                 newPatchI,                  // patch for face
00111                 false,                      // remove from zone
00112                 zoneID,                     // zone for face
00113                 zoneFlip                    // face flip in zone
00114             )
00115         );
00116         modifiedFace[faceI] = 1;
00117     }
00118     else
00119     {
00120         // Second or more usage of face. Add.
00121         meshMod.setAction
00122         (
00123             polyAddFace
00124             (
00125                 f,                          // modified face
00126                 own,                        // owner
00127                 -1,                         // neighbour
00128                 -1,                         // master point
00129                 -1,                         // master edge
00130                 faceI,                      // master face
00131                 flipFaceFlux,               // face flip
00132                 newPatchI,                  // patch for face
00133                 zoneID,                     // zone for face
00134                 zoneFlip                    // face flip in zone
00135             )
00136         );
00137     }
00138 }
00139 
00140 
00141 label findPatchID(const polyMesh& mesh, const word& name)
00142 {
00143     label patchI = mesh.boundaryMesh().findPatchID(name);
00144 
00145     if (patchI == -1)
00146     {
00147         FatalErrorIn("findPatchID(const polyMesh&, const word&)")
00148             << "Cannot find patch " << name << endl
00149             << "Valid patches are " << mesh.boundaryMesh().names()
00150             << exit(FatalError);
00151     }
00152     return patchI;
00153 }
00154 
00155 
00156 // Main program:
00157 
00158 int main(int argc, char *argv[])
00159 {
00160 #   include <OpenFOAM/addRegionOption.H>
00161     argList::validArgs.append("faceZone");
00162     argList::validArgs.append("patch");
00163     argList::validOptions.insert("additionalPatches", "(patch2 .. patchN)");
00164     argList::validOptions.insert("internalFacesOnly", "");
00165     argList::validOptions.insert("overwrite", "");
00166 
00167 #   include <OpenFOAM/setRootCase.H>
00168 #   include <OpenFOAM/createTime.H>
00169     runTime.functionObjects().off();
00170 #   include <OpenFOAM/createNamedMesh.H>
00171     const word oldInstance = mesh.pointsInstance();
00172 
00173     const polyBoundaryMesh& patches = mesh.boundaryMesh();
00174     const faceZoneMesh& faceZones = mesh.faceZones();
00175 
00176     // Faces to baffle
00177     faceZoneID zoneID(args.additionalArgs()[0], faceZones);
00178 
00179     Info<< "Converting faces on zone " << zoneID.name()
00180         << " into baffles." << nl << endl;
00181 
00182     if (zoneID.index() == -1)
00183     {
00184         FatalErrorIn(args.executable()) << "Cannot find faceZone "
00185             << zoneID.name() << endl
00186             << "Valid zones are " << faceZones.names()
00187             << exit(FatalError);
00188     }
00189 
00190     const faceZone& fZone = faceZones[zoneID.index()];
00191 
00192     Info<< "Found " << returnReduce(fZone.size(), sumOp<label>())
00193         << " faces on zone " << zoneID.name() << nl << endl;
00194 
00195     // Make sure patches and zoneFaces are synchronised across couples
00196     patches.checkParallelSync(true);
00197     fZone.checkParallelSync(true);
00198 
00199     // Patches to put baffles into
00200     DynamicList<label> newPatches(1);
00201 
00202     word patchName(args.additionalArgs()[1]);
00203     newPatches.append(findPatchID(mesh, patchName));
00204     Info<< "Using patch " << patchName
00205         << " at index " << newPatches[0] << endl;
00206 
00207 
00208     // Additional patches
00209     if (args.optionFound("additionalPatches"))
00210     {
00211         const wordList patchNames
00212         (
00213             args.optionLookup("additionalPatches")()
00214         );
00215 
00216         newPatches.reserve(patchNames.size() + 1);
00217         forAll(patchNames, i)
00218         {
00219             newPatches.append(findPatchID(mesh, patchNames[i]));
00220             Info<< "Using additional patch " << patchNames[i]
00221                 << " at index " << newPatches[newPatches.size()-1] << endl;
00222         }
00223     }
00224 
00225 
00226     bool overwrite = args.optionFound("overwrite");
00227 
00228     bool internalFacesOnly = args.optionFound("internalFacesOnly");
00229 
00230     if (internalFacesOnly)
00231     {
00232         Info<< "Not converting faces on non-coupled patches." << nl << endl;
00233     }
00234 
00235 
00236     // Read objects in time directory
00237     IOobjectList objects(mesh, runTime.timeName());
00238 
00239     // Read vol fields.
00240 
00241     PtrList<volScalarField> vsFlds;
00242     ReadFields(mesh, objects, vsFlds);
00243 
00244     PtrList<volVectorField> vvFlds;
00245     ReadFields(mesh, objects, vvFlds);
00246 
00247     PtrList<volSphericalTensorField> vstFlds;
00248     ReadFields(mesh, objects, vstFlds);
00249 
00250     PtrList<volSymmTensorField> vsymtFlds;
00251     ReadFields(mesh, objects, vsymtFlds);
00252 
00253     PtrList<volTensorField> vtFlds;
00254     ReadFields(mesh, objects, vtFlds);
00255 
00256     // Read surface fields.
00257 
00258     PtrList<surfaceScalarField> ssFlds;
00259     ReadFields(mesh, objects, ssFlds);
00260 
00261     PtrList<surfaceVectorField> svFlds;
00262     ReadFields(mesh, objects, svFlds);
00263 
00264     PtrList<surfaceSphericalTensorField> sstFlds;
00265     ReadFields(mesh, objects, sstFlds);
00266 
00267     PtrList<surfaceSymmTensorField> ssymtFlds;
00268     ReadFields(mesh, objects, ssymtFlds);
00269 
00270     PtrList<surfaceTensorField> stFlds;
00271     ReadFields(mesh, objects, stFlds);
00272 
00273 
00274     // Mesh change container
00275     polyTopoChange meshMod(mesh);
00276 
00277 
00278     // Do the actual changes. Note:
00279     // - loop in incrementing face order (not necessary if faceZone ordered).
00280     //   Preserves any existing ordering on patch faces.
00281     // - two passes, do non-flip faces first and flip faces second. This
00282     //   guarantees that when e.g. creating a cyclic all faces from one
00283     //   side come first and faces from the other side next.
00284 
00285     // Whether first use of face (modify) or consecutive (add)
00286     PackedBoolList modifiedFace(mesh.nFaces());
00287     // Never modify coupled faces
00288     forAll(patches, patchI)
00289     {
00290         const polyPatch& pp = patches[patchI];
00291         if (pp.coupled())
00292         {
00293             forAll(pp, i)
00294             {
00295                 modifiedFace[pp.start()+i] = 1;
00296             }
00297         }
00298     }
00299     label nModified = 0;
00300 
00301     forAll(newPatches, i)
00302     {
00303         label newPatchI = newPatches[i];
00304 
00305         // Pass 1. Do selected side of zone
00306         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00307 
00308         for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
00309         {
00310             label zoneFaceI = fZone.whichFace(faceI);
00311 
00312             if (zoneFaceI != -1)
00313             {
00314                 if (!fZone.flipMap()[zoneFaceI])
00315                 {
00316                     // Use owner side of face
00317                     modifyOrAddFace
00318                     (
00319                         meshMod,
00320                         mesh.faces()[faceI],    // modified face
00321                         faceI,                  // label of face
00322                         mesh.faceOwner()[faceI],// owner
00323                         false,                  // face flip
00324                         newPatchI,              // patch for face
00325                         zoneID.index(),         // zone for face
00326                         false,                  // face flip in zone
00327                         modifiedFace            // modify or add status
00328                     );
00329                 }
00330                 else
00331                 {
00332                     // Use neighbour side of face
00333                     modifyOrAddFace
00334                     (
00335                         meshMod,
00336                         mesh.faces()[faceI].reverseFace(),  // modified face
00337                         faceI,                      // label of face
00338                         mesh.faceNeighbour()[faceI],// owner
00339                         true,                       // face flip
00340                         newPatchI,                  // patch for face
00341                         zoneID.index(),             // zone for face
00342                         true,                       // face flip in zone
00343                         modifiedFace                // modify or add status
00344                     );
00345                 }
00346 
00347                 nModified++;
00348             }
00349         }
00350 
00351 
00352         // Pass 2. Do other side of zone
00353         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00354 
00355         for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
00356         {
00357             label zoneFaceI = fZone.whichFace(faceI);
00358 
00359             if (zoneFaceI != -1)
00360             {
00361                 if (!fZone.flipMap()[zoneFaceI])
00362                 {
00363                     // Use neighbour side of face
00364                     modifyOrAddFace
00365                     (
00366                         meshMod,
00367                         mesh.faces()[faceI].reverseFace(),  // modified face
00368                         faceI,                              // label of face
00369                         mesh.faceNeighbour()[faceI],        // owner
00370                         true,                               // face flip
00371                         newPatchI,                          // patch for face
00372                         zoneID.index(),                     // zone for face
00373                         true,                               // face flip in zone
00374                         modifiedFace                        // modify or add
00375                     );
00376                 }
00377                 else
00378                 {
00379                     // Use owner side of face
00380                     modifyOrAddFace
00381                     (
00382                         meshMod,
00383                         mesh.faces()[faceI],    // modified face
00384                         faceI,                  // label of face
00385                         mesh.faceOwner()[faceI],// owner
00386                         false,                  // face flip
00387                         newPatchI,              // patch for face
00388                         zoneID.index(),         // zone for face
00389                         false,                  // face flip in zone
00390                         modifiedFace            // modify or add status
00391                     );
00392                 }
00393             }
00394         }
00395 
00396 
00397         // Modify any boundary faces
00398         // ~~~~~~~~~~~~~~~~~~~~~~~~~
00399 
00400         // Normal boundary:
00401         // - move to new patch. Might already be back-to-back baffle
00402         // you want to add cyclic to. Do warn though.
00403         //
00404         // Processor boundary:
00405         // - do not move to cyclic
00406         // - add normal patches though.
00407 
00408         // For warning once per patch.
00409         labelHashSet patchWarned;
00410 
00411         forAll(patches, patchI)
00412         {
00413             const polyPatch& pp = patches[patchI];
00414 
00415             if (pp.coupled() && patches[newPatchI].coupled())
00416             {
00417                 // Do not allow coupled faces to be moved to different coupled
00418                 // patches.
00419             }
00420             else if (pp.coupled() || !internalFacesOnly)
00421             {
00422                 forAll(pp, i)
00423                 {
00424                     label faceI = pp.start()+i;
00425 
00426                     label zoneFaceI = fZone.whichFace(faceI);
00427 
00428                     if (zoneFaceI != -1)
00429                     {
00430                         if (patchWarned.insert(patchI))
00431                         {
00432                             WarningIn(args.executable())
00433                                 << "Found boundary face (in patch " << pp.name()
00434                                 << ") in faceZone " << fZone.name()
00435                                 << " to convert to baffle patch "
00436                                 << patches[newPatchI].name()
00437                                 << endl
00438                                 << "    Run with -internalFacesOnly option"
00439                                 << " if you don't wish to convert"
00440                                 << " boundary faces." << endl;
00441                         }
00442 
00443                         modifyOrAddFace
00444                         (
00445                             meshMod,
00446                             mesh.faces()[faceI],        // modified face
00447                             faceI,                      // label of face
00448                             mesh.faceOwner()[faceI],    // owner
00449                             false,                      // face flip
00450                             newPatchI,                  // patch for face
00451                             zoneID.index(),             // zone for face
00452                             fZone.flipMap()[zoneFaceI], // face flip in zone
00453                             modifiedFace                // modify or add status
00454                         );
00455                         nModified++;
00456                     }
00457                 }
00458             }
00459         }
00460     }
00461 
00462 
00463     Info<< "Converted " << returnReduce(nModified, sumOp<label>())
00464         << " faces into boundary faces on patch " << patchName << nl << endl;
00465 
00466     if (!overwrite)
00467     {
00468         runTime++;
00469     }
00470 
00471     // Change the mesh. Change points directly (no inflation).
00472     autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
00473 
00474     // Update fields
00475     mesh.updateMesh(map);
00476 
00477     // Move mesh (since morphing might not do this)
00478     if (map().hasMotionPoints())
00479     {
00480         mesh.movePoints(map().preMotionPoints());
00481     }
00482 
00483     if (overwrite)
00484     {
00485         mesh.setInstance(oldInstance);
00486     }
00487     Info<< "Writing mesh to " << runTime.timeName() << endl;
00488 
00489     mesh.write();
00490 
00491     Info<< "End\n" << endl;
00492 
00493     return 0;
00494 }
00495 
00496 
00497 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines