FreeFOAM The Cross-Platform CFD Toolkit
blockMeshApp.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 | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
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
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Application
25  blockMesh
26 
27 Description
28  A multi-block mesh generator.
29 
30  Uses the block mesh description found in
31  @a constant/polyMesh/blockMeshDict
32  (or @a constant/<region>/polyMesh/blockMeshDict).
33 
34 Usage
35 
36  - blockMesh [OPTION]
37 
38  @param -blockTopology \n
39  Write the topology as a set of edges in OBJ format.
40 
41  @param -region <name> \n
42  Specify an alternative mesh region.
43 
44  @param -dict <dictionary> \n
45  Specify an alternative dictionary for the block mesh description.
46 
47  @param -case <dir> \n
48  Case directory.
49 
50  @param -help \n
51  Display help message.
52 
53  @param -doc \n
54  Display Doxygen API documentation page for this application.
55 
56  @param -srcDoc \n
57  Display Doxygen source documentation page for this application.
58 
59 \*---------------------------------------------------------------------------*/
60 
61 #include <OpenFOAM/Time.H>
62 #include <OpenFOAM/IOdictionary.H>
63 #include <OpenFOAM/IOPtrList.H>
64 
65 #include "blockMesh.H"
69 #include <meshTools/cellSet.H>
70 
71 #include <OpenFOAM/argList.H>
72 #include <OpenFOAM/OSspecific.H>
73 #include <OpenFOAM/OFstream.H>
74 
75 #include <OpenFOAM/Pair.H>
77 
78 using namespace Foam;
79 
80 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
81 // Main program:
82 
83 int main(int argc, char *argv[])
84 {
86  argList::validOptions.insert("blockTopology", "");
87  argList::validOptions.insert("dict", "dictionary");
89 # include <OpenFOAM/setRootCase.H>
90 # include <OpenFOAM/createTime.H>
91 
92  const word dictName("blockMeshDict");
93 
95  fileName polyMeshDir;
96 
97  if (args.optionFound("region"))
98  {
99  // constant/<region>/polyMesh/blockMeshDict
100  regionName = args.option("region");
101  polyMeshDir = regionName/polyMesh::meshSubDir;
102 
103  Info<< nl << "Generating mesh for region " << regionName << endl;
104  }
105  else
106  {
107  // constant/polyMesh/blockMeshDict
108  regionName = polyMesh::defaultRegion;
109  polyMeshDir = polyMesh::meshSubDir;
110  }
111 
112  autoPtr<IOobject> meshDictIoPtr;
113 
114  if (args.optionFound("dict"))
115  {
116  fileName dictPath(args.option("dict"));
117 
118  meshDictIoPtr.set
119  (
120  new IOobject
121  (
122  (
123  isDir(dictPath)
124  ? dictPath/dictName
125  : dictPath
126  ),
127  runTime,
130  false
131  )
132  );
133  }
134  else
135  {
136  meshDictIoPtr.set
137  (
138  new IOobject
139  (
140  dictName,
141  runTime.constant(),
142  polyMeshDir,
143  runTime,
146  false
147  )
148  );
149  }
150 
151  if (!meshDictIoPtr->headerOk())
152  {
154  << "Cannot open mesh description file\n "
155  << meshDictIoPtr->objectPath()
156  << nl
157  << exit(FatalError);
158  }
159 
160  Info<< nl << "Creating block mesh from\n "
161  << meshDictIoPtr->objectPath() << nl << endl;
162 
163  IOdictionary meshDict(meshDictIoPtr());
164  blockMesh blocks(meshDict);
165 
166 
167  if (args.optionFound("blockTopology"))
168  {
169  // Write mesh as edges.
170  {
171  fileName objMeshFile("blockTopology.obj");
172 
173  OFstream str(runTime.path()/objMeshFile);
174 
175  Info<< nl << "Dumping block structure as Lightwave obj format"
176  << " to " << objMeshFile << endl;
177 
178  blocks.writeTopology(str);
179  }
180 
181  // Write centres of blocks
182  {
183  fileName objCcFile("blockCentres.obj");
184 
185  OFstream str(runTime.path()/objCcFile);
186 
187  Info<< nl << "Dumping block centres as Lightwave obj format"
188  << " to " << objCcFile << endl;
189 
190  const polyMesh& topo = blocks.topology();
191 
192  const pointField& cellCentres = topo.cellCentres();
193 
194  forAll(cellCentres, cellI)
195  {
196  //point cc = b.blockShape().centre(b.points());
197  const point& cc = cellCentres[cellI];
198 
199  str << "v " << cc.x() << ' ' << cc.y() << ' ' << cc.z() << nl;
200  }
201  }
202 
203  Info<< nl << "end" << endl;
204 
205  return 0;
206  }
207 
208 
209 
210  Info<< nl << "Creating mesh from block mesh" << endl;
211 
212  wordList patchNames = blocks.patchNames();
213  wordList patchTypes = blocks.patchTypes();
214  word defaultFacesName = "defaultFaces";
215  word defaultFacesType = emptyPolyPatch::typeName;
216  wordList patchPhysicalTypes = blocks.patchPhysicalTypes();
217 
219  (
220  runTime,
221  runTime.constant(),
222  polyMeshDir,
223  patchNames,
224  patchTypes,
228  );
229 
230  polyMesh mesh
231  (
232  IOobject
233  (
234  regionName,
235  runTime.constant(),
236  runTime
237  ),
238  xferCopy(blocks.points()), // could we re-use space?
239  blocks.cells(),
240  blocks.patches(),
241  patchNames,
242  patchTypes,
246  );
247 
248 
249  // Read in a list of dictionaries for the merge patch pairs
250  if (meshDict.found("mergePatchPairs"))
251  {
252  List<Pair<word> > mergePatchPairs
253  (
254  meshDict.lookup("mergePatchPairs")
255  );
256 
257 # include "mergePatchPairs.H"
258  }
259  else
260  {
261  Info<< nl << "There are no merge patch pairs edges" << endl;
262  }
263 
264 
265  // Set any cellZones (note: cell labelling unaffected by above
266  // mergePatchPairs)
267 
268  label nZones = blocks.numZonedBlocks();
269 
270  if (nZones > 0)
271  {
272  Info<< nl << "Adding cell zones" << endl;
273 
274  // Map from zoneName to cellZone index
275  HashTable<label> zoneMap(nZones);
276 
277  // Cells per zone.
278  List<DynamicList<label> > zoneCells(nZones);
279 
280  // Running cell counter
281  label cellI = 0;
282 
283  // Largest zone so far
284  label freeZoneI = 0;
285 
286  forAll(blocks, blockI)
287  {
288  const block& b = blocks[blockI];
289  const labelListList& blockCells = b.cells();
290  const word& zoneName = b.blockDef().zoneName();
291 
292  if (zoneName.size())
293  {
294  HashTable<label>::const_iterator iter = zoneMap.find(zoneName);
295 
296  label zoneI;
297 
298  if (iter == zoneMap.end())
299  {
300  zoneI = freeZoneI++;
301 
302  Info<< " " << zoneI << '\t' << zoneName << endl;
303 
304  zoneMap.insert(zoneName, zoneI);
305  }
306  else
307  {
308  zoneI = iter();
309  }
310 
311  forAll(blockCells, i)
312  {
313  zoneCells[zoneI].append(cellI++);
314  }
315  }
316  else
317  {
318  cellI += b.cells().size();
319  }
320  }
321 
322 
323  List<cellZone*> cz(zoneMap.size());
324 
325  Info<< nl << "Writing cell zones as cellSets" << endl;
326 
327  forAllConstIter(HashTable<label>, zoneMap, iter)
328  {
329  label zoneI = iter();
330 
331  cz[zoneI] = new cellZone
332  (
333  iter.key(),
334  zoneCells[zoneI].shrink(),
335  zoneI,
336  mesh.cellZones()
337  );
338 
339  // Write as cellSet for ease of processing
340  cellSet cset(mesh, iter.key(), zoneCells[zoneI].shrink());
341  cset.write();
342  }
343 
344  mesh.pointZones().setSize(0);
345  mesh.faceZones().setSize(0);
346  mesh.cellZones().setSize(0);
348  }
349 
350  // Set the precision of the points data to 10
352 
353  Info << nl << "Writing polyMesh" << endl;
354  mesh.removeFiles();
355  if (!mesh.write())
356  {
358  << "Failed writing polyMesh."
359  << exit(FatalError);
360  }
361 
362  Info<< nl << "End" << endl;
363 
364  return 0;
365 }
366 
367 
368 // ************************ vim: set sw=4 sts=4 et: ************************ //