polyMeshIO.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) 2011-2013 OpenFOAM Foundation
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 "polyMesh.H"
27 #include "Time.H"
28 #include "cellIOList.H"
29 
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
31 
33 {
34  if (debug)
35  {
36  Info<< "void polyMesh::setInstance(const fileName& inst) : "
37  << "Resetting file instance to " << inst << endl;
38  }
39 
40  points_.writeOpt() = IOobject::AUTO_WRITE;
41  points_.instance() = inst;
42 
43  faces_.writeOpt() = IOobject::AUTO_WRITE;
44  faces_.instance() = inst;
45 
46  owner_.writeOpt() = IOobject::AUTO_WRITE;
47  owner_.instance() = inst;
48 
49  neighbour_.writeOpt() = IOobject::AUTO_WRITE;
50  neighbour_.instance() = inst;
51 
52  boundary_.writeOpt() = IOobject::AUTO_WRITE;
53  boundary_.instance() = inst;
54 
55  pointZones_.writeOpt() = IOobject::AUTO_WRITE;
56  pointZones_.instance() = inst;
57 
58  faceZones_.writeOpt() = IOobject::AUTO_WRITE;
59  faceZones_.instance() = inst;
60 
61  cellZones_.writeOpt() = IOobject::AUTO_WRITE;
62  cellZones_.instance() = inst;
63 }
64 
65 
67 {
68  if (debug)
69  {
70  Info<< "polyMesh::readUpdateState polyMesh::readUpdate() : "
71  << "Updating mesh based on saved data." << endl;
72  }
73 
74  // Find the point and cell instance
75  fileName pointsInst(time().findInstance(meshDir(), "points"));
76  fileName facesInst(time().findInstance(meshDir(), "faces"));
77  //fileName boundaryInst(time().findInstance(meshDir(), "boundary"));
78 
79  if (debug)
80  {
81  Info<< "Faces instance: old = " << facesInstance()
82  << " new = " << facesInst << nl
83  //<< "Boundary instance: old = " << boundary_.instance()
84  //<< " new = " << boundaryInst << nl
85  << "Points instance: old = " << pointsInstance()
86  << " new = " << pointsInst << endl;
87  }
88 
89  if (facesInst != facesInstance())
90  {
91  // Topological change
92  if (debug)
93  {
94  Info<< "Topological change" << endl;
95  }
96 
97  clearOut();
98 
99  // Set instance to new instance. Note that points instance can differ
100  // from from faces instance.
101  setInstance(facesInst);
102  points_.instance() = pointsInst;
103 
104  points_ = pointIOField
105  (
106  IOobject
107  (
108  "points",
109  pointsInst,
110  meshSubDir,
111  *this,
114  false
115  )
116  );
117 
118  faces_ = faceCompactIOList
119  (
120  IOobject
121  (
122  "faces",
123  facesInst,
124  meshSubDir,
125  *this,
128  false
129  )
130  );
131 
132  owner_ = labelIOList
133  (
134  IOobject
135  (
136  "owner",
137  facesInst,
138  meshSubDir,
139  *this,
142  false
143  )
144  );
145 
146  neighbour_ = labelIOList
147  (
148  IOobject
149  (
150  "neighbour",
151  facesInst,
152  meshSubDir,
153  *this,
156  false
157  )
158  );
159 
160  // Reset the boundary patches
161  polyBoundaryMesh newBoundary
162  (
163  IOobject
164  (
165  "boundary",
166  facesInst,
167  meshSubDir,
168  *this,
171  false
172  ),
173  *this
174  );
175 
176  // Check that patch types and names are unchanged
177  bool boundaryChanged = false;
178 
179  if (newBoundary.size() != boundary_.size())
180  {
181  boundaryChanged = true;
182  }
183  else
184  {
185  wordList newTypes = newBoundary.types();
186  wordList newNames = newBoundary.names();
187 
188  wordList oldTypes = boundary_.types();
189  wordList oldNames = boundary_.names();
190 
191  forAll(oldTypes, patchI)
192  {
193  if
194  (
195  oldTypes[patchI] != newTypes[patchI]
196  || oldNames[patchI] != newNames[patchI]
197  )
198  {
199  boundaryChanged = true;
200  break;
201  }
202  }
203  }
204 
205  if (boundaryChanged)
206  {
207  WarningIn("polyMesh::readUpdateState polyMesh::readUpdate()")
208  << "Number of patches has changed. This may have "
209  << "unexpected consequences. Proceed with care." << endl;
210 
211  boundary_.clear();
212  boundary_.setSize(newBoundary.size());
213 
214  forAll(newBoundary, patchI)
215  {
216  boundary_.set(patchI, newBoundary[patchI].clone(boundary_));
217  }
218  }
219  else
220  {
221  forAll(boundary_, patchI)
222  {
223  boundary_[patchI] = polyPatch
224  (
225  newBoundary[patchI].name(),
226  newBoundary[patchI].size(),
227  newBoundary[patchI].start(),
228  patchI,
229  boundary_,
230  newBoundary[patchI].type()
231  );
232  }
233  }
234 
235 
236  // Boundary is set so can use initMesh now (uses boundary_ to
237  // determine internal and active faces)
238 
239  if (exists(owner_.objectPath()))
240  {
241  initMesh();
242  }
243  else
244  {
246  (
247  IOobject
248  (
249  "cells",
250  facesInst,
251  meshSubDir,
252  *this,
255  false
256  )
257  );
258 
259  // Recalculate the owner/neighbour addressing and reset the
260  // primitiveMesh
261  initMesh(cells);
262  }
263 
264 
265  // Even if number of patches stayed same still recalculate boundary
266  // data.
267 
268  // Calculate topology for the patches (processor-processor comms etc.)
269  boundary_.updateMesh();
270 
271  // Calculate the geometry for the patches (transformation tensors etc.)
272  boundary_.calcGeometry();
273 
274  // Derived info
275  bounds_ = boundBox(points_);
276  geometricD_ = Vector<label>::zero;
277  solutionD_ = Vector<label>::zero;
278 
279  // Zones
280  pointZoneMesh newPointZones
281  (
282  IOobject
283  (
284  "pointZones",
285  facesInst,
286  meshSubDir,
287  *this,
290  false
291  ),
292  *this
293  );
294 
295  label oldSize = pointZones_.size();
296 
297  if (newPointZones.size() <= pointZones_.size())
298  {
299  pointZones_.setSize(newPointZones.size());
300  }
301 
302  // Reset existing ones
303  forAll(pointZones_, czI)
304  {
305  pointZones_[czI] = newPointZones[czI];
306  }
307 
308  // Extend with extra ones
309  pointZones_.setSize(newPointZones.size());
310 
311  for (label czI = oldSize; czI < newPointZones.size(); czI++)
312  {
313  pointZones_.set(czI, newPointZones[czI].clone(pointZones_));
314  }
315 
316 
317  faceZoneMesh newFaceZones
318  (
319  IOobject
320  (
321  "faceZones",
322  facesInst,
323  meshSubDir,
324  *this,
327  false
328  ),
329  *this
330  );
331 
332  oldSize = faceZones_.size();
333 
334  if (newFaceZones.size() <= faceZones_.size())
335  {
336  faceZones_.setSize(newFaceZones.size());
337  }
338 
339  // Reset existing ones
340  forAll(faceZones_, fzI)
341  {
342  faceZones_[fzI].resetAddressing
343  (
344  newFaceZones[fzI],
345  newFaceZones[fzI].flipMap()
346  );
347  }
348 
349  // Extend with extra ones
350  faceZones_.setSize(newFaceZones.size());
351 
352  for (label fzI = oldSize; fzI < newFaceZones.size(); fzI++)
353  {
354  faceZones_.set(fzI, newFaceZones[fzI].clone(faceZones_));
355  }
356 
357 
358  cellZoneMesh newCellZones
359  (
360  IOobject
361  (
362  "cellZones",
363  facesInst,
364  meshSubDir,
365  *this,
368  false
369  ),
370  *this
371  );
372 
373  oldSize = cellZones_.size();
374 
375  if (newCellZones.size() <= cellZones_.size())
376  {
377  cellZones_.setSize(newCellZones.size());
378  }
379 
380  // Reset existing ones
381  forAll(cellZones_, czI)
382  {
383  cellZones_[czI] = newCellZones[czI];
384  }
385 
386  // Extend with extra ones
387  cellZones_.setSize(newCellZones.size());
388 
389  for (label czI = oldSize; czI < newCellZones.size(); czI++)
390  {
391  cellZones_.set(czI, newCellZones[czI].clone(cellZones_));
392  }
393 
394 
395  if (boundaryChanged)
396  {
398  }
399  else
400  {
401  return polyMesh::TOPO_CHANGE;
402  }
403  }
404  else if (pointsInst != pointsInstance())
405  {
406  // Points moved
407  if (debug)
408  {
409  Info<< "Point motion" << endl;
410  }
411 
412  clearGeom();
413 
414 
415  label nOldPoints = points_.size();
416 
417  points_.clear();
418 
419  pointIOField newPoints
420  (
421  IOobject
422  (
423  "points",
424  pointsInst,
425  meshSubDir,
426  *this,
429  false
430  )
431  );
432 
433  if (nOldPoints != 0 && nOldPoints != newPoints.size())
434  {
435  FatalErrorIn("polyMesh::readUpdate()")
436  << "Point motion detected but number of points "
437  << newPoints.size() << " in "
438  << newPoints.objectPath() << " does not correspond to "
439  << " current " << nOldPoints
440  << exit(FatalError);
441  }
442 
443  points_.transfer(newPoints);
444  points_.instance() = pointsInst;
445 
446  // Derived info
447  bounds_ = boundBox(points_);
448 
449  // Rotation can cause direction vector to change
450  geometricD_ = Vector<label>::zero;
451  solutionD_ = Vector<label>::zero;
452 
453 
454  //if (boundaryInst != boundary_.instance())
455  //{
456  // // Boundary file but no topology change
457  // if (debug)
458  // {
459  // Info<< "Boundary state change" << endl;
460  // }
461  //
462  // // Reset the boundary patches
463  // polyBoundaryMesh newBoundary
464  // (
465  // IOobject
466  // (
467  // "boundary",
468  // facesInst,
469  // meshSubDir,
470  // *this,
471  // IOobject::MUST_READ,
472  // IOobject::NO_WRITE,
473  // false
474  // ),
475  // *this
476  // );
477  //
478  //
479  //
480  //
481  // boundary_.clear();
482  // boundary_.setSize(newBoundary.size());
483  //
484  // forAll(newBoundary, patchI)
485  // {
486  // boundary_.set(patchI, newBoundary[patchI].clone(boundary_));
487  // }
488  // // Calculate topology for the patches (processor-processor comms
489  // // etc.)
490  // boundary_.updateMesh();
491  //
492  // // Calculate the geometry for the patches (transformation tensors
493  // // etc.)
494  // boundary_.calcGeometry();
495  //}
496 
497  return polyMesh::POINTS_MOVED;
498  }
499  else
500  {
501  if (debug)
502  {
503  Info<< "No change" << endl;
504  }
505 
506  return polyMesh::UNCHANGED;
507  }
508 }
509 
510 
511 // ************************************************************************* //
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:309
A List of objects of type <T> with automated input and output using a compact storage. Behaves like IOList except when binary output in case it writes a CompactListList.
Definition: CompactIOList.H:53
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:142
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
bool set(const label) const
Is element set.
Definition: PtrListI.H:107
Foam::autoPtr< IOobject > clone() const
Clone.
Definition: IOobject.H:239
void setInstance(const fileName &)
Set the instance for mesh files.
Definition: polyMeshIO.C:32
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in.
Definition: polyMeshIO.C:66
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:390
void clear()
Clear the PtrList, i.e. set size to zero deleting all the.
Definition: PtrList.C:185
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const fileName & instance() const
Definition: IOobject.H:337
void updateMesh()
Correct polyBoundaryMesh after topology update.
const cellList & cells() const
vectorIOField pointIOField
pointIOField is a vectorIOField.
Definition: pointIOField.H:42
bool exists(const fileName &, const bool checkGzip=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:609
messageStream Info
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:818
Templated 3D Vector derived from VectorSpace adding construction from 3 components, element access using x(), y() and z() member functions and the inner-product (dot-product) and cross product operators.
Definition: Vector.H:57
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
wordList names() const
Return a list of patch names.
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:379
static const char nl
Definition: Ostream.H:260
wordList types() const
Return a list of patch types.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
#define WarningIn(functionName)
Report a warning using Foam::Warning.
Foam::polyBoundaryMesh.
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:88
#define forAll(list, i)
Definition: UList.H:421
writeOption writeOpt() const
Definition: IOobject.H:314
fileName objectPath() const
Return complete path + object name.
Definition: IOobject.H:363
label size() const
Return number of elements in table.
const word & name() const
Return name.
Definition: IOobject.H:260
void clearOut()
Clear all geometry and addressing unnecessary for CFD.
fileName::Type type(const fileName &)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:589
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:55
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:824
error FatalError
A class for handling file names.
Definition: fileName.H:69
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:812
const Time & time() const
Return time.
void clearGeom()
Clear geometry.
Definition: polyMeshClear.C:55
CompactIOList< face, label > faceCompactIOList
Definition: faceIOList.H:43
IOList< label > labelIOList
Label container classes.
Definition: labelIOList.H:42