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 Splits mesh by making internal faces external. Uses attachDetach.
28 Generates a meshModifier of the form:
33 faceZoneName membraneFaces;
34 masterPatchName masterPatch;
35 slavePatchName slavePatch;
36 triggerTimes runTime.value();
39 so will detach at the current time and split all faces in membraneFaces
40 into masterPatch and slavePatch (which have to be present but of 0 size)
42 \*---------------------------------------------------------------------------*/
47 #include "polyTopoChange.H"
48 #include "mapPolyMesh.H"
50 #include "attachDetach.H"
51 #include "polyTopoChanger.H"
52 #include "regionSide.H"
53 #include "primitiveFacePatch.H"
57 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
59 // Find edge between points v0 and v1.
60 label findEdge(const primitiveMesh& mesh, const label v0, const label v1)
62 const labelList& pEdges = mesh.pointEdges()[v0];
64 forAll(pEdges, pEdgeI)
66 label edgeI = pEdges[pEdgeI];
68 const edge& e = mesh.edges()[edgeI];
70 if (e.otherVertex(v0) == v1)
78 "findEdge(const primitiveMesh&, const label, const label)"
79 ) << "Cannot find edge between mesh points " << v0 << " and " << v1
86 // Checks whether patch present
87 void checkPatch(const polyBoundaryMesh& bMesh, const word& name)
89 label patchI = bMesh.findPatchID(name);
93 FatalErrorIn("checkPatch(const polyBoundaryMesh&, const word&)")
94 << "Cannot find patch " << name << endl
95 << "It should be present but of zero size" << endl
96 << "Valid patches are " << bMesh.names()
100 if (bMesh[patchI].size())
102 FatalErrorIn("checkPatch(const polyBoundaryMesh&, const word&)")
103 << "Patch " << name << " is present but non-zero size"
111 int main(int argc, char *argv[])
113 Foam::argList::noParallel();
115 Foam::argList::validArgs.append("faceSet");
116 Foam::argList::validArgs.append("masterPatch");
117 Foam::argList::validArgs.append("slavePatch");
118 Foam::argList::validOptions.insert("overwrite", "");
120 # include "setRootCase.H"
121 # include "createTime.H"
122 runTime.functionObjects().off();
123 # include "createPolyMesh.H"
124 const word oldInstance = mesh.pointsInstance();
126 word setName(args.additionalArgs()[0]);
127 word masterPatch(args.additionalArgs()[1]);
128 word slavePatch(args.additionalArgs()[2]);
129 bool overwrite = args.optionFound("overwrite");
131 // List of faces to split
132 faceSet facesSet(mesh, setName);
134 Info<< "Read " << facesSet.size() << " faces to split" << endl << endl;
137 // Convert into labelList and check
139 labelList faces(facesSet.toc());
143 if (!mesh.isInternalFace(faces[i]))
145 FatalErrorIn(args.executable())
146 << "Face " << faces[i] << " in faceSet " << setName
147 << " is not an internal face."
153 // Check for empty master and slave patches
154 checkPatch(mesh.boundaryMesh(), masterPatch);
155 checkPatch(mesh.boundaryMesh(), slavePatch);
159 // Find 'side' of all faces on splitregion. Uses regionSide which needs
160 // set of edges on side of this region. Use PrimitivePatch to find these.
163 IndirectList<face> zoneFaces(mesh.faces(), faces);
165 // Calculation engine for set of faces in a mesh
166 typedef PrimitivePatch<face, List, const pointField&> facePatch;
169 // Addressing on faces only in mesh vertices.
170 facePatch fPatch(zoneFaces(), mesh.points());
172 const labelList& meshPoints = fPatch.meshPoints();
174 // Mark all fence edges : edges on boundary of fPatch but not on boundary
176 labelHashSet fenceEdges(fPatch.size());
178 const labelListList& allEdgeFaces = fPatch.edgeFaces();
180 forAll(allEdgeFaces, patchEdgeI)
182 if (allEdgeFaces[patchEdgeI].size() == 1)
184 const edge& e = fPatch.edges()[patchEdgeI];
190 meshPoints[e.start()],
194 fenceEdges.insert(edgeI);
198 // Find sides reachable from 0th face of faceSet
199 label startFaceI = faces[0];
201 regionSide regionInfo
206 mesh.faceOwner()[startFaceI],
210 // Determine flip state for all faces in faceSet
211 boolList zoneFlip(faces.size());
215 zoneFlip[i] = !regionInfo.sideOwner().found(faces[i]);
219 // Create and add face zones and mesh modifiers
220 List<pointZone*> pz(0);
221 List<faceZone*> fz(1);
222 List<cellZone*> cz(0);
234 Info << "Adding point and face zones" << endl;
235 mesh.addZones(pz, fz, cz);
237 polyTopoChanger splitter(mesh);
240 // Add the sliding interface mesh modifier to start working at current
253 scalarField(1, runTime.value())
257 Info<< nl << "Constructed topologyModifier:" << endl;
258 splitter[0].writeDict(Info);
265 splitter.changeMesh();
267 Info<< "Writing mesh to " << runTime.timeName() << endl;
270 FatalErrorIn(args.executable())
271 << "Failed writing polyMesh."
275 Info<< nl << "end" << endl;
280 // ************************************************************************* //