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

splitMesh.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     splitMesh
00026 
00027 Description
00028     Splits mesh by making internal faces external.
00029 
00030     Uses attachDetach. Generates a meshModifier of the form:
00031 
00032     Splitter
00033     {
00034         type                       attachDetach;
00035         faceZoneName               membraneFaces;
00036         masterPatchName            masterPatch;
00037         slavePatchName             slavePatch;
00038         triggerTimes               runTime.value();
00039     }
00040 
00041     so will detach at the current time and split all faces in membraneFaces
00042     into masterPatch and slavePatch (which have to be present but of 0 size)
00043 
00044 Usage
00045 
00046     - splitMesh [OPTIONS] <face set> <masterPatch> <slavePatch>
00047 
00048     @param <face set> \n
00049     @todo Detailed description of argument.
00050 
00051     @param <masterPatch> \n
00052     @todo Detailed description of argument.
00053 
00054     @param <slavePatch> \n
00055     @todo Detailed description of argument.
00056 
00057     @param -overwrite \n
00058     Overwrite existing data.
00059 
00060     @param -case <dir>\n
00061     Case directory.
00062 
00063     @param -help \n
00064     Display help message.
00065 
00066     @param -doc \n
00067     Display Doxygen API documentation page for this application.
00068 
00069     @param -srcDoc \n
00070     Display Doxygen source documentation page for this application.
00071 
00072 \*---------------------------------------------------------------------------*/
00073 
00074 #include <OpenFOAM/argList.H>
00075 #include <OpenFOAM/polyMesh.H>
00076 #include <OpenFOAM/Time.H>
00077 #include <dynamicMesh/polyTopoChange.H>
00078 #include <OpenFOAM/mapPolyMesh.H>
00079 #include <meshTools/faceSet.H>
00080 #include <dynamicMesh/attachDetach.H>
00081 #include <dynamicMesh/attachPolyTopoChanger.H>
00082 #include "regionSide.H"
00083 #include <OpenFOAM/primitiveFacePatch.H>
00084 
00085 using namespace Foam;
00086 
00087 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00088 
00089 // Find edge between points v0 and v1.
00090 label findEdge(const primitiveMesh& mesh, const label v0, const label v1)
00091 {
00092     const labelList& pEdges = mesh.pointEdges()[v0];
00093 
00094     forAll(pEdges, pEdgeI)
00095     {
00096         label edgeI = pEdges[pEdgeI];
00097 
00098         const edge& e = mesh.edges()[edgeI];
00099 
00100         if (e.otherVertex(v0) == v1)
00101         {
00102             return edgeI;
00103         }
00104     }
00105 
00106     FatalErrorIn
00107     (
00108         "findEdge(const primitiveMesh&, const label, const label)"
00109     )   << "Cannot find edge between mesh points " << v0 << " and " << v1
00110         << abort(FatalError);
00111 
00112     return -1;
00113 }
00114 
00115 
00116 // Checks whether patch present
00117 void checkPatch(const polyBoundaryMesh& bMesh, const word& name)
00118 {
00119     label patchI = bMesh.findPatchID(name);
00120 
00121     if (patchI == -1)
00122     {
00123         FatalErrorIn("checkPatch(const polyBoundaryMesh&, const word&)")
00124             << "Cannot find patch " << name << endl
00125             << "It should be present but of zero size" << endl
00126             << "Valid patches are " << bMesh.names()
00127             << exit(FatalError);
00128     }
00129 
00130     if (bMesh[patchI].size())
00131     {
00132         FatalErrorIn("checkPatch(const polyBoundaryMesh&, const word&)")
00133             << "Patch " << name << " is present but non-zero size"
00134             << exit(FatalError);
00135     }
00136 }
00137 
00138 
00139 // Main program:
00140 
00141 int main(int argc, char *argv[])
00142 {
00143     Foam::argList::noParallel();
00144 
00145     Foam::argList::validArgs.append("faceSet");
00146     Foam::argList::validArgs.append("masterPatch");
00147     Foam::argList::validArgs.append("slavePatch");
00148     Foam::argList::validOptions.insert("overwrite", "");
00149 
00150 #   include <OpenFOAM/setRootCase.H>
00151 #   include <OpenFOAM/createTime.H>
00152     runTime.functionObjects().off();
00153 #   include <OpenFOAM/createPolyMesh.H>
00154     const word oldInstance = mesh.pointsInstance();
00155 
00156     word setName(args.additionalArgs()[0]);
00157     word masterPatch(args.additionalArgs()[1]);
00158     word slavePatch(args.additionalArgs()[2]);
00159     bool overwrite = args.optionFound("overwrite");
00160 
00161     // List of faces to split
00162     faceSet facesSet(mesh, setName);
00163 
00164     Info<< "Read " << facesSet.size() << " faces to split" << endl << endl;
00165 
00166 
00167     // Convert into labelList and check
00168 
00169     labelList faces(facesSet.toc());
00170 
00171     forAll(faces, i)
00172     {
00173         if (!mesh.isInternalFace(faces[i]))
00174         {
00175             FatalErrorIn(args.executable())
00176             << "Face " << faces[i] << " in faceSet " << setName
00177             << " is not an internal face."
00178             << exit(FatalError);
00179         }
00180     }
00181 
00182 
00183     // Check for empty master and slave patches
00184     checkPatch(mesh.boundaryMesh(), masterPatch);
00185     checkPatch(mesh.boundaryMesh(), slavePatch);
00186 
00187 
00188     //
00189     // Find 'side' of all faces on splitregion. Uses regionSide which needs
00190     // set of edges on side of this region. Use PrimitivePatch to find these.
00191     //
00192 
00193     // Addressing on faces only in mesh vertices.
00194     primitiveFacePatch fPatch
00195     (
00196         UIndirectList<face>
00197         (
00198             mesh.faces(),
00199             faces
00200         ),
00201         mesh.points()
00202     );
00203 
00204     const labelList& meshPoints = fPatch.meshPoints();
00205 
00206     // Mark all fence edges : edges on boundary of fPatch but not on boundary
00207     // of polyMesh
00208     labelHashSet fenceEdges(fPatch.size());
00209 
00210     const labelListList& allEdgeFaces = fPatch.edgeFaces();
00211 
00212     forAll(allEdgeFaces, patchEdgeI)
00213     {
00214         if (allEdgeFaces[patchEdgeI].size() == 1)
00215         {
00216             const edge& e = fPatch.edges()[patchEdgeI];
00217 
00218             label edgeI =
00219                 findEdge
00220                 (
00221                     mesh,
00222                     meshPoints[e.start()],
00223                     meshPoints[e.end()]
00224                 );
00225 
00226             fenceEdges.insert(edgeI);
00227         }
00228     }
00229 
00230     // Find sides reachable from 0th face of faceSet
00231     label startFaceI = faces[0];
00232 
00233     regionSide regionInfo
00234     (
00235         mesh,
00236         facesSet,
00237         fenceEdges,
00238         mesh.faceOwner()[startFaceI],
00239         startFaceI
00240     );
00241 
00242     // Determine flip state for all faces in faceSet
00243     boolList zoneFlip(faces.size());
00244 
00245     forAll(faces, i)
00246     {
00247         zoneFlip[i] = !regionInfo.sideOwner().found(faces[i]);
00248     }
00249 
00250 
00251     // Create and add face zones and mesh modifiers
00252     List<pointZone*> pz(0);
00253     List<faceZone*> fz(1);
00254     List<cellZone*> cz(0);
00255 
00256     fz[0] =
00257         new faceZone
00258         (
00259             "membraneFaces",
00260             faces,
00261             zoneFlip,
00262             0,
00263             mesh.faceZones()
00264         );
00265 
00266     Info << "Adding point and face zones" << endl;
00267     mesh.addZones(pz, fz, cz);
00268 
00269     attachPolyTopoChanger splitter(mesh);
00270     splitter.setSize(1);
00271 
00272     // Add the sliding interface mesh modifier to start working at current
00273     // time
00274     splitter.set
00275     (
00276         0,
00277         new attachDetach
00278         (
00279             "Splitter",
00280             0,
00281             splitter,
00282             "membraneFaces",
00283             masterPatch,
00284             slavePatch,
00285             scalarField(1, runTime.value())
00286         )
00287     );
00288 
00289     Info<< nl << "Constructed topologyModifier:" << endl;
00290     splitter[0].writeDict(Info);
00291 
00292     if (!overwrite)
00293     {
00294         runTime++;
00295     }
00296 
00297     splitter.attach();
00298 
00299     if (overwrite)
00300     {
00301         mesh.setInstance(oldInstance);
00302     }
00303 
00304     Info<< "Writing mesh to " << runTime.timeName() << endl;
00305     if (!mesh.write())
00306     {
00307         FatalErrorIn(args.executable())
00308             << "Failed writing polyMesh."
00309             << exit(FatalError);
00310     }
00311 
00312     Info<< nl << "end" << endl;
00313     return 0;
00314 }
00315 
00316 
00317 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines