splitMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  splitMesh
29 
30 Group
31  grpMeshManipulationUtilities
32 
33 Description
34  Splits mesh by making internal faces external. Uses attachDetach.
35 
36  Generates a meshModifier of the form:
37 
38  Splitter
39  {
40  type attachDetach;
41  faceZoneName membraneFaces;
42  masterPatchName masterPatch;
43  slavePatchName slavePatch;
44  triggerTimes runTime.value();
45  }
46 
47  so will detach at the current time and split all faces in membraneFaces
48  into masterPatch and slavePatch (which have to be present but of 0 size)
49 
50 \*---------------------------------------------------------------------------*/
51 
52 #include "argList.H"
53 #include "polyMesh.H"
54 #include "Time.H"
55 #include "polyTopoChange.H"
56 #include "mapPolyMesh.H"
57 #include "faceSet.H"
58 #include "attachDetach.H"
59 #include "attachPolyTopoChanger.H"
60 #include "regionSide.H"
61 #include "primitivePatch.H"
62 #include "processorMeshes.H"
63 
64 using namespace Foam;
65 
66 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
67 
68 // Find edge between points v0 and v1.
69 label findEdge(const primitiveMesh& mesh, const label v0, const label v1)
70 {
71  const labelList& pEdges = mesh.pointEdges()[v0];
72 
73  forAll(pEdges, pEdgeI)
74  {
75  label edgeI = pEdges[pEdgeI];
76 
77  const edge& e = mesh.edges()[edgeI];
78 
79  if (e.otherVertex(v0) == v1)
80  {
81  return edgeI;
82  }
83  }
84 
86  << "Cannot find edge between mesh points " << v0 << " and " << v1
87  << abort(FatalError);
88 
89  return -1;
90 }
91 
92 
93 // Checks whether patch present
94 void checkPatch(const polyBoundaryMesh& bMesh, const word& name)
95 {
96  const label patchi = bMesh.findPatchID(name);
97 
98  if (patchi == -1)
99  {
101  << "Cannot find patch " << name << nl
102  << "It should be present but of zero size" << endl
103  << "Valid patches are " << bMesh.names()
104  << exit(FatalError);
105  }
106 
107  if (bMesh[patchi].size())
108  {
110  << "Patch " << name << " is present but non-zero size"
111  << exit(FatalError);
112  }
113 }
114 
115 
116 
117 int main(int argc, char *argv[])
118 {
120  (
121  "Splits mesh by making internal faces external at defined faceSet"
122  );
123 
125  argList::noFunctionObjects(); // Never use function objects
126 
127  #include "addOverwriteOption.H"
128 
129  argList::addArgument("faceSet", "The faces used for splitting");
130  argList::addArgument("master", "The master patch name");
131  argList::addArgument("slave", "The slave patch name");
132 
133  #include "setRootCase.H"
134  #include "createTime.H"
135  #include "createPolyMesh.H"
136 
137  const word oldInstance = mesh.pointsInstance();
138 
139  const word setName = args[1];
140  const word masterPatch = args[2];
141  const word slavePatch = args[3];
142  const bool overwrite = args.found("overwrite");
143 
144  // List of faces to split
145  faceSet facesSet(mesh, setName);
146 
147  Info<< "Read " << facesSet.size() << " faces to split" << endl << endl;
148 
149 
150  // Convert into labelList and check
151 
152  labelList faces(facesSet.toc());
153 
154  forAll(faces, i)
155  {
156  if (!mesh.isInternalFace(faces[i]))
157  {
159  << "Face " << faces[i] << " in faceSet " << setName
160  << " is not an internal face."
161  << exit(FatalError);
162  }
163  }
164 
165 
166  // Check for empty master and slave patches
167  checkPatch(mesh.boundaryMesh(), masterPatch);
168  checkPatch(mesh.boundaryMesh(), slavePatch);
169 
170 
171  //
172  // Find 'side' of all faces on splitregion. Uses regionSide which needs
173  // set of edges on side of this region. Use PrimitivePatch to find these.
174  //
175 
176  // Addressing on faces only in mesh vertices.
177  primitiveFacePatch fPatch
178  (
179  faceList(mesh.faces(), faces),
180  mesh.points()
181  );
182 
183  const labelList& meshPoints = fPatch.meshPoints();
184 
185  // Mark all fence edges : edges on boundary of fPatch but not on boundary
186  // of polyMesh
187  labelHashSet fenceEdges(fPatch.size());
188 
189  const labelListList& allEdgeFaces = fPatch.edgeFaces();
190 
191  forAll(allEdgeFaces, patchEdgeI)
192  {
193  if (allEdgeFaces[patchEdgeI].size() == 1)
194  {
195  const edge& e = fPatch.edges()[patchEdgeI];
196 
197  label edgeI =
198  findEdge
199  (
200  mesh,
201  meshPoints[e.start()],
202  meshPoints[e.end()]
203  );
204 
205  fenceEdges.insert(edgeI);
206  }
207  }
208 
209  // Find sides reachable from 0th face of faceSet
210  label startFacei = faces[0];
211 
212  regionSide regionInfo
213  (
214  mesh,
215  facesSet,
216  fenceEdges,
217  mesh.faceOwner()[startFacei],
218  startFacei
219  );
220 
221  // Determine flip state for all faces in faceSet
222  boolList zoneFlip(faces.size());
223 
224  forAll(faces, i)
225  {
226  zoneFlip[i] = !regionInfo.sideOwner().found(faces[i]);
227  }
228 
229 
230  // Create and add face zones and mesh modifiers
231  List<pointZone*> pz(0);
232  List<faceZone*> fz(1);
233  List<cellZone*> cz(0);
234 
235  fz[0] =
236  new faceZone
237  (
238  "membraneFaces",
239  std::move(faces),
240  std::move(zoneFlip),
241  0,
242  mesh.faceZones()
243  );
244 
245  Info<< "Adding point and face zones" << endl;
246  mesh.addZones(pz, fz, cz);
247 
248  attachPolyTopoChanger splitter(mesh);
249  splitter.setSize(1);
250 
251  // Add the sliding interface mesh modifier to start working at current
252  // time
253  splitter.set
254  (
255  0,
256  new attachDetach
257  (
258  "Splitter",
259  0,
260  splitter,
261  "membraneFaces",
262  masterPatch,
263  slavePatch,
265  )
266  );
267 
268  Info<< nl << "Constructed topologyModifier:" << endl;
269  splitter[0].writeDict(Info);
270 
271  if (!overwrite)
272  {
273  ++runTime;
274  }
275 
276  splitter.attach();
277 
278  if (overwrite)
279  {
280  mesh.setInstance(oldInstance);
281  }
282  else
283  {
285  }
286 
287  Info<< "Writing mesh to " << runTime.timeName() << endl;
288  if (!mesh.write())
289  {
291  << "Failed writing polyMesh."
292  << exit(FatalError);
293  }
296 
297 
298  Info<< nl << "End" << nl << endl;
299 
300  return 0;
301 }
302 
303 
304 // ************************************************************************* //
const Type & value() const noexcept
Return const reference to value.
static void noFunctionObjects(bool addWithOption=false)
Remove &#39;-noFunctionObjects&#39; option and ignore any occurrences.
Definition: argList.C:562
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:477
Required Variables.
A list of face labels.
Definition: faceSet.H:47
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:652
const labelListList & pointEdges() const
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:76
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:518
static void noParallel()
Remove the parallel options.
Definition: argList.C:599
label findEdge(const edgeList &edges, const labelList &candidates, const label v0, const label v1)
Return edge among candidates that uses the two vertices.
Definition: meshTools.C:352
bool isInternalFace(const label faceIndex) const noexcept
Return true if given face label is internal to the mesh.
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1063
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:400
List< face > faceList
List of faces.
Definition: faceListFwd.H:39
static void removeFiles(const polyMesh &mesh)
Helper: remove all procAddressing files from mesh instance.
A list of faces which address into the list of points.
Determines the &#39;side&#39; for every face and connected to a singly-connected (through edges) region of fa...
Definition: regionSide.H:59
static void removeFiles(const polyMesh &)
Helper: remove all sets files from mesh instance.
Definition: topoSet.C:693
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:838
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
Definition: edge.H:59
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition: polyMesh.H:611
A class for handling words, derived from Foam::string.
Definition: word.H:63
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
void addZones(PtrList< pointZone > &&pz, PtrList< faceZone > &&fz, PtrList< cellZone > &&cz)
Add mesh zones.
Definition: polyMesh.C:994
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1101
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1088
errorManip< error > abort(error &err)
Definition: errorManip.H:139
virtual bool write(const bool writeOnProc=true) const
Write mesh using IO settings from time.
Definition: fvMesh.C:1068
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh...
This class is derived from polyMesh and serves as a tool for statically connecting pieces of a mesh b...
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition: Time.C:713
Attach/detach boundary mesh modifier. This modifier takes a set of internal faces and converts them i...
Definition: attachDetach.H:58
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:673
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
void setInstance(const fileName &instance, const IOobjectOption::writeOption wOpt=IOobject::AUTO_WRITE)
Set the instance for mesh files.
Definition: polyMeshIO.C:29
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:366
messageStream Info
Information stream (stdout output on master, null elsewhere)
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:60
Foam::argList args(argc, argv)
bool checkPatch(const bool allGeometry, const std::string &name, const polyMesh &mesh, const PatchType &pp, const labelUList &meshEdges, labelHashSet *pointSetPtr=nullptr, labelHashSet *badEdgesPtr=nullptr)
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
Namespace for OpenFOAM.