FreeFOAM The Cross-Platform CFD Toolkit
createTopology.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 \*---------------------------------------------------------------------------*/
25 
26 #include "blockMesh.H"
27 #include <OpenFOAM/Time.H>
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 bool Foam::blockMesh::blockLabelsOK
34 (
35  const label blockLabel,
36  const pointField& points,
37  const cellShape& blockShape
38 )
39 {
40  bool ok = true;
41 
42  forAll(blockShape, blockI)
43  {
44  if (blockShape[blockI] < 0)
45  {
46  ok = false;
47 
48  WarningIn
49  (
50  "bool Foam::blockMesh::blockLabelsOK"
51  "(const label blockLabel, const pointField& points, "
52  "const cellShape& blockShape)"
53  ) << "block " << blockLabel
54  << " point label " << blockShape[blockI]
55  << " less than zero" << endl;
56  }
57  else if (blockShape[blockI] >= points.size())
58  {
59  ok = false;
60 
61  WarningIn
62  (
63  "bool Foam::blockMesh::blockLabelsOK"
64  "(const label blockLabel, const pointField& points, "
65  "const cellShape& blockShape)"
66  ) << "block " << blockLabel
67  << " point label " << blockShape[blockI]
68  << " larger than " << points.size() - 1
69  << " the largest defined point label" << endl;
70  }
71  }
72 
73  return ok;
74 }
75 
76 
77 bool Foam::blockMesh::patchLabelsOK
78 (
79  const label patchLabel,
80  const pointField& points,
81  const faceList& patchFaces
82 )
83 {
84  bool ok = true;
85 
86  forAll(patchFaces, faceI)
87  {
88  const labelList& f = patchFaces[faceI];
89 
90  forAll(f, fp)
91  {
92  if (f[fp] < 0)
93  {
94  ok = false;
95 
96  WarningIn
97  (
98  "bool Foam::blockMesh::patchLabelsOK(...)"
99  ) << "patch " << patchLabel
100  << " face " << faceI
101  << " point label " << f[fp]
102  << " less than zero" << endl;
103  }
104  else if (f[fp] >= points.size())
105  {
106  ok = false;
107 
108  WarningIn
109  (
110  "bool Foam::blockMesh::patchLabelsOK(...)"
111  ) << "patch " << patchLabel
112  << " face " << faceI
113  << " point label " << f[fp]
114  << " larger than " << points.size() - 1
115  << " the largest defined point label" << endl;
116  }
117  }
118  }
119 
120  return ok;
121 }
122 
123 
124 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
125 
126 Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription)
127 {
128  bool topologyOK = true;
129 
130  blockMesh& blocks = *this;
131 
132  word defaultPatchName = "defaultFaces";
133  word defaultPatchType = emptyPolyPatch::typeName;
134 
135  // get names/types for the unassigned patch faces
136  // this is a bit heavy handed (and ugly), but there is currently
137  // no easy way to rename polyMesh patches subsequently
138  if (const dictionary* dictPtr = meshDescription.subDictPtr("defaultPatch"))
139  {
140  dictPtr->readIfPresent("name", defaultPatchName);
141  dictPtr->readIfPresent("type", defaultPatchType);
142  }
143 
144  Info<< nl << "Creating blockCorners" << endl;
145 
146  // create blockCorners
147  pointField tmpBlockPoints(meshDescription.lookup("vertices"));
148 
149  if (meshDescription.found("edges"))
150  {
151  // read number of non-linear edges in mesh
152  Info<< nl << "Creating curved edges" << endl;
153 
154  ITstream& edgesStream(meshDescription.lookup("edges"));
155 
156  label nEdges = 0;
157 
158  token firstToken(edgesStream);
159 
160  if (firstToken.isLabel())
161  {
162  nEdges = firstToken.labelToken();
163  edges_.setSize(nEdges);
164  }
165  else
166  {
167  edgesStream.putBack(firstToken);
168  }
169 
170  // Read beginning of edges
171  edgesStream.readBegin("edges");
172 
173  nEdges = 0;
174 
175  token lastToken(edgesStream);
176  while
177  (
178  !(
179  lastToken.isPunctuation()
180  && lastToken.pToken() == token::END_LIST
181  )
182  )
183  {
184  if (edges_.size() <= nEdges)
185  {
186  edges_.setSize(nEdges + 1);
187  }
188 
189  edgesStream.putBack(lastToken);
190 
191  edges_.set
192  (
193  nEdges,
194  curvedEdge::New(tmpBlockPoints, edgesStream)
195  );
196 
197  nEdges++;
198 
199  edgesStream >> lastToken;
200  }
201  edgesStream.putBack(lastToken);
202 
203  // Read end of edges
204  edgesStream.readEnd("edges");
205  }
206  else
207  {
208  Info<< nl << "There are no non-linear edges" << endl;
209  }
210 
211 
212  Info<< nl << "Creating blocks" << endl;
213  {
214  ITstream& blockDescriptorStream(meshDescription.lookup("blocks"));
215 
216  // read number of blocks in mesh
217  label nBlocks = 0;
218 
219  token firstToken(blockDescriptorStream);
220 
221  if (firstToken.isLabel())
222  {
223  nBlocks = firstToken.labelToken();
224  blocks.setSize(nBlocks);
225  }
226  else
227  {
228  blockDescriptorStream.putBack(firstToken);
229  }
230 
231  // Read beginning of blocks
232  blockDescriptorStream.readBegin("blocks");
233 
234  nBlocks = 0;
235 
236  token lastToken(blockDescriptorStream);
237  while
238  (
239  !(
240  lastToken.isPunctuation()
241  && lastToken.pToken() == token::END_LIST
242  )
243  )
244  {
245  if (blocks.size() <= nBlocks)
246  {
247  blocks.setSize(nBlocks + 1);
248  }
249 
250  blockDescriptorStream.putBack(lastToken);
251 
252  blocks.set
253  (
254  nBlocks,
255  new block
256  (
257  blockDescriptor
258  (
259  tmpBlockPoints,
260  edges_,
261  blockDescriptorStream
262  )
263  )
264  );
265 
266  topologyOK = topologyOK && blockLabelsOK
267  (
268  nBlocks,
269  tmpBlockPoints,
270  blocks[nBlocks].blockDef().blockShape()
271  );
272 
273  nBlocks++;
274 
275  blockDescriptorStream >> lastToken;
276  }
277  blockDescriptorStream.putBack(lastToken);
278 
279  // Read end of blocks
280  blockDescriptorStream.readEnd("blocks");
281  }
282 
283 
284  Info<< nl << "Creating patches" << endl;
285 
286  faceListList tmpBlocksPatches;
289 
290  {
291  ITstream& patchStream(meshDescription.lookup("patches"));
292 
293  // read number of patches in mesh
294  label nPatches = 0;
295 
296  token firstToken(patchStream);
297 
298  if (firstToken.isLabel())
299  {
300  nPatches = firstToken.labelToken();
301 
302  tmpBlocksPatches.setSize(nPatches);
303  patchNames.setSize(nPatches);
304  patchTypes.setSize(nPatches);
305  }
306  else
307  {
308  patchStream.putBack(firstToken);
309  }
310 
311  // Read beginning of blocks
312  patchStream.readBegin("patches");
313 
314  nPatches = 0;
315 
316  token lastToken(patchStream);
317  while
318  (
319  !(
320  lastToken.isPunctuation()
321  && lastToken.pToken() == token::END_LIST
322  )
323  )
324  {
325  if (tmpBlocksPatches.size() <= nPatches)
326  {
327  tmpBlocksPatches.setSize(nPatches + 1);
328  patchNames.setSize(nPatches + 1);
329  patchTypes.setSize(nPatches + 1);
330  }
331 
332  patchStream.putBack(lastToken);
333 
334  patchStream
335  >> patchTypes[nPatches]
336  >> patchNames[nPatches]
337  >> tmpBlocksPatches[nPatches];
338 
339 
340  // Catch multiple patches asap.
341  for (label i = 0; i < nPatches; i++)
342  {
343  if (patchNames[nPatches] == patchNames[i])
344  {
346  (
347  "blockMesh::createTopology(IOdictionary&)"
348  ) << "Duplicate patch " << patchNames[nPatches]
349  << " at line " << patchStream.lineNumber()
350  << ". Exiting !" << nl
351  << exit(FatalError);
352  }
353  }
354 
355  topologyOK = topologyOK && patchLabelsOK
356  (
357  nPatches,
358  tmpBlockPoints,
359  tmpBlocksPatches[nPatches]
360  );
361 
362  nPatches++;
363 
364  patchStream >> lastToken;
365  }
366  patchStream.putBack(lastToken);
367 
368  // Read end of blocks
369  patchStream.readEnd("patches");
370  }
371 
372 
373  if (!topologyOK)
374  {
375  FatalErrorIn("blockMesh::createTopology(IOdictionary&)")
376  << "Cannot create mesh due to errors in topology, exiting !" << nl
377  << exit(FatalError);
378  }
379 
380 
381  Info<< nl << "Creating block mesh topology" << endl;
382 
383  PtrList<cellShape> tmpBlockCells(blocks.size());
384  forAll(blocks, blockLabel)
385  {
386  tmpBlockCells.set
387  (
388  blockLabel,
389  new cellShape(blocks[blockLabel].blockDef().blockShape())
390  );
391 
392  if (tmpBlockCells[blockLabel].mag(tmpBlockPoints) < 0.0)
393  {
394  WarningIn
395  (
396  "blockMesh::createTopology(IOdictionary&)"
397  ) << "negative volume block : " << blockLabel
398  << ", probably defined inside-out" << endl;
399  }
400  }
401 
402  wordList patchPhysicalTypes(tmpBlocksPatches.size());
403 
405  (
406  meshDescription.time(),
407  meshDescription.time().constant(),
409  patchNames,
410  patchTypes,
411  defaultPatchName,
412  defaultPatchType,
414  );
415 
416  polyMesh* blockMeshPtr = new polyMesh
417  (
418  IOobject
419  (
420  "blockMesh",
421  meshDescription.time().constant(),
422  meshDescription.time(),
425  false
426  ),
427  xferMove(tmpBlockPoints),
428  tmpBlockCells,
429  tmpBlocksPatches,
430  patchNames,
431  patchTypes,
432  defaultPatchName,
433  defaultPatchType,
435  );
436 
437  checkBlockMesh(*blockMeshPtr);
438 
439  return blockMeshPtr;
440 }
441 
442 
443 // ************************ vim: set sw=4 sts=4 et: ************************ //