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-2017 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  InfoInFunction << "Resetting file instance to " << inst << endl;
37  }
38 
39  points_.writeOpt() = IOobject::AUTO_WRITE;
40  points_.instance() = inst;
41 
42  faces_.writeOpt() = IOobject::AUTO_WRITE;
43  faces_.instance() = inst;
44 
45  owner_.writeOpt() = IOobject::AUTO_WRITE;
46  owner_.instance() = inst;
47 
48  neighbour_.writeOpt() = IOobject::AUTO_WRITE;
49  neighbour_.instance() = inst;
50 
51  boundary_.writeOpt() = IOobject::AUTO_WRITE;
52  boundary_.instance() = inst;
53 
54  pointZones_.writeOpt() = IOobject::AUTO_WRITE;
55  pointZones_.instance() = inst;
56 
57  faceZones_.writeOpt() = IOobject::AUTO_WRITE;
58  faceZones_.instance() = inst;
59 
60  cellZones_.writeOpt() = IOobject::AUTO_WRITE;
61  cellZones_.instance() = inst;
62 
63  if (tetBasePtIsPtr_.valid())
64  {
65  tetBasePtIsPtr_->writeOpt() = IOobject::AUTO_WRITE;
66  tetBasePtIsPtr_->instance() = inst;
67  }
68 }
69 
70 
72 {
73  if (debug)
74  {
75  InfoInFunction << "Updating mesh based on saved data." << endl;
76  }
77 
78  // Find the point and cell instance
79  fileName pointsInst(time().findInstance(meshDir(), "points"));
80  fileName facesInst(time().findInstance(meshDir(), "faces"));
81  //fileName boundaryInst(time().findInstance(meshDir(), "boundary"));
82 
83  if (debug)
84  {
85  Info<< "Faces instance: old = " << facesInstance()
86  << " new = " << facesInst << nl
87  << "Points instance: old = " << pointsInstance()
88  << " new = " << pointsInst << endl;
89  }
90 
91  if (facesInst != facesInstance())
92  {
93  // Topological change
94  if (debug)
95  {
96  Info<< "Topological change" << endl;
97  }
98 
99  clearOut();
100 
101  // Set instance to new instance. Note that points instance can differ
102  // from from faces instance.
103  setInstance(facesInst);
104  points_.instance() = pointsInst;
105 
106  points_ = pointIOField
107  (
108  IOobject
109  (
110  "points",
111  pointsInst,
112  meshSubDir,
113  *this,
116  false
117  )
118  );
119 
120  faces_ = faceCompactIOList
121  (
122  IOobject
123  (
124  "faces",
125  facesInst,
126  meshSubDir,
127  *this,
130  false
131  )
132  );
133 
134  owner_ = labelIOList
135  (
136  IOobject
137  (
138  "owner",
139  facesInst,
140  meshSubDir,
141  *this,
144  false
145  )
146  );
147 
148  neighbour_ = labelIOList
149  (
150  IOobject
151  (
152  "neighbour",
153  facesInst,
154  meshSubDir,
155  *this,
158  false
159  )
160  );
161 
162  // Reset the boundary patches
163  polyBoundaryMesh newBoundary
164  (
165  IOobject
166  (
167  "boundary",
168  facesInst,
169  meshSubDir,
170  *this,
173  false
174  ),
175  *this
176  );
177 
178  // Check that patch types and names are unchanged
179  bool boundaryChanged = false;
180 
181  if (newBoundary.size() != boundary_.size())
182  {
183  boundaryChanged = true;
184  }
185  else
186  {
187  wordList newTypes = newBoundary.types();
188  wordList newNames = newBoundary.names();
189 
190  wordList oldTypes = boundary_.types();
191  wordList oldNames = boundary_.names();
192 
193  forAll(oldTypes, patchi)
194  {
195  if
196  (
197  oldTypes[patchi] != newTypes[patchi]
198  || oldNames[patchi] != newNames[patchi]
199  )
200  {
201  boundaryChanged = true;
202  break;
203  }
204  }
205  }
206 
207  if (boundaryChanged)
208  {
210  << "unexpected consequences. Proceed with care." << endl;
211 
212  boundary_.clear();
213  boundary_.setSize(newBoundary.size());
214 
215  forAll(newBoundary, patchi)
216  {
217  boundary_.set(patchi, newBoundary[patchi].clone(boundary_));
218  }
219  }
220  else
221  {
222  forAll(boundary_, patchi)
223  {
224  boundary_[patchi] = polyPatch
225  (
226  newBoundary[patchi].name(),
227  newBoundary[patchi].size(),
228  newBoundary[patchi].start(),
229  patchi,
230  boundary_,
231  newBoundary[patchi].type()
232  );
233  }
234  }
235 
236 
237  // Boundary is set so can use initMesh now (uses boundary_ to
238  // determine internal and active faces)
239 
240  if (!owner_.headerClassName().empty())
241  {
242  initMesh();
243  }
244  else
245  {
247  (
248  IOobject
249  (
250  "cells",
251  facesInst,
252  meshSubDir,
253  *this,
256  false
257  )
258  );
259 
260  // Recalculate the owner/neighbour addressing and reset the
261  // primitiveMesh
262  initMesh(cells);
263  }
264 
265 
266  // Even if number of patches stayed same still recalculate boundary
267  // data.
268 
269  // Calculate topology for the patches (processor-processor comms etc.)
270  boundary_.updateMesh();
271 
272  // Calculate the geometry for the patches (transformation tensors etc.)
273  boundary_.calcGeometry();
274 
275  // Derived info
276  bounds_ = boundBox(points_);
277  geometricD_ = Zero;
278  solutionD_ = Zero;
279 
280  // Zones
281  pointZoneMesh newPointZones
282  (
283  IOobject
284  (
285  "pointZones",
286  facesInst,
287  meshSubDir,
288  *this,
291  false
292  ),
293  *this
294  );
295 
296  label oldSize = pointZones_.size();
297 
298  if (newPointZones.size() <= pointZones_.size())
299  {
300  pointZones_.setSize(newPointZones.size());
301  }
302 
303  // Reset existing ones
304  forAll(pointZones_, czI)
305  {
306  pointZones_[czI] = newPointZones[czI];
307  }
308 
309  // Extend with extra ones
310  pointZones_.setSize(newPointZones.size());
311 
312  for (label czI = oldSize; czI < newPointZones.size(); czI++)
313  {
314  pointZones_.set(czI, newPointZones[czI].clone(pointZones_));
315  }
316 
317 
318  faceZoneMesh newFaceZones
319  (
320  IOobject
321  (
322  "faceZones",
323  facesInst,
324  meshSubDir,
325  *this,
328  false
329  ),
330  *this
331  );
332 
333  oldSize = faceZones_.size();
334 
335  if (newFaceZones.size() <= faceZones_.size())
336  {
337  faceZones_.setSize(newFaceZones.size());
338  }
339 
340  // Reset existing ones
341  forAll(faceZones_, fzI)
342  {
343  faceZones_[fzI].resetAddressing
344  (
345  newFaceZones[fzI],
346  newFaceZones[fzI].flipMap()
347  );
348  }
349 
350  // Extend with extra ones
351  faceZones_.setSize(newFaceZones.size());
352 
353  for (label fzI = oldSize; fzI < newFaceZones.size(); fzI++)
354  {
355  faceZones_.set(fzI, newFaceZones[fzI].clone(faceZones_));
356  }
357 
358 
359  cellZoneMesh newCellZones
360  (
361  IOobject
362  (
363  "cellZones",
364  facesInst,
365  meshSubDir,
366  *this,
369  false
370  ),
371  *this
372  );
373 
374  oldSize = cellZones_.size();
375 
376  if (newCellZones.size() <= cellZones_.size())
377  {
378  cellZones_.setSize(newCellZones.size());
379  }
380 
381  // Reset existing ones
382  forAll(cellZones_, czI)
383  {
384  cellZones_[czI] = newCellZones[czI];
385  }
386 
387  // Extend with extra ones
388  cellZones_.setSize(newCellZones.size());
389 
390  for (label czI = oldSize; czI < newCellZones.size(); czI++)
391  {
392  cellZones_.set(czI, newCellZones[czI].clone(cellZones_));
393  }
394 
395  // Re-read tet base points
396  tetBasePtIsPtr_ = readTetBasePtIs();
397 
398 
399  if (boundaryChanged)
400  {
402  }
403  else
404  {
405  return polyMesh::TOPO_CHANGE;
406  }
407  }
408  else if (pointsInst != pointsInstance())
409  {
410  // Points moved
411  if (debug)
412  {
413  Info<< "Point motion" << endl;
414  }
415 
416  clearGeom();
417 
418 
419  label nOldPoints = points_.size();
420 
421  points_.clear();
422 
423  pointIOField newPoints
424  (
425  IOobject
426  (
427  "points",
428  pointsInst,
429  meshSubDir,
430  *this,
433  false
434  )
435  );
436 
437  if (nOldPoints != 0 && nOldPoints != newPoints.size())
438  {
440  << "Point motion detected but number of points "
441  << newPoints.size() << " in "
442  << newPoints.objectPath() << " does not correspond to "
443  << " current " << nOldPoints
444  << exit(FatalError);
445  }
446 
447  points_.transfer(newPoints);
448  points_.instance() = pointsInst;
449 
450  // Re-read tet base points
451  autoPtr<labelIOList> newTetBasePtIsPtr = readTetBasePtIs();
452  if (newTetBasePtIsPtr.valid())
453  {
454  tetBasePtIsPtr_ = newTetBasePtIsPtr;
455  }
456 
457  // Calculate the geometry for the patches (transformation tensors etc.)
458  boundary_.calcGeometry();
459 
460  // Derived info
461  bounds_ = boundBox(points_);
462 
463  // Rotation can cause direction vector to change
464  geometricD_ = Zero;
465  solutionD_ = Zero;
466 
467  return polyMesh::POINTS_MOVED;
468  }
469  else
470  {
471  if (debug)
472  {
473  Info<< "No change" << endl;
474  }
475 
476  return polyMesh::UNCHANGED;
477  }
478 }
479 
480 
481 // ************************************************************************* //
autoPtr< IOobject > clone() const
Clone.
Definition: IOobject.H:264
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
const word & name() const
Return name.
Definition: IOobject.H:291
A class for handling file names.
Definition: fileName.H:69
bool set(const label) const
Is element set.
Definition: PtrListI.H:65
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:801
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
vectorIOField pointIOField
pointIOField is a vectorIOField.
Definition: pointIOField.H:42
void clearOut()
Clear all geometry and addressing unnecessary for CFD.
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:312
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:58
const cellList & cells() const
wordList types() const
Return a list of patch types.
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
CompactIOList< face, label > faceCompactIOList
Definition: faceIOList.H:43
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:795
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:124
wordList names() const
Return a list of patch names.
static const zero Zero
Definition: zero.H:91
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set)
Definition: autoPtrI.H:83
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:131
Foam::polyBoundaryMesh.
void clearGeom()
Clear geometry.
Definition: polyMeshClear.C:53
static const char nl
Definition: Ostream.H:262
void updateMesh()
Correct polyBoundaryMesh after topology update.
const Time & time() const
Return time.
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
fileName::Type type(const fileName &, const bool followLink=true)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:485
void setInstance(const fileName &)
Set the instance for mesh files.
Definition: polyMeshIO.C:32
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
writeOption writeOpt() const
Definition: IOobject.H:363
const fileName & instance() const
Definition: IOobject.H:386
label patchi
#define WarningInFunction
Report a warning using Foam::Warning.
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:789
void clear()
Clear the PtrList, i.e. set size to zero deleting all the.
Definition: PtrList.C:174
messageStream Info
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:88
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in.
Definition: polyMeshIO.C:71
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:297
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:92
fileName objectPath() const
Return complete path + object name.
Definition: IOobject.H:412
A primitive field of type <T> with automated input and output.
Definition: IOField.H:50
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
IOList< label > labelIOList
Label container classes.
Definition: labelIOList.H:42
#define InfoInFunction
Report an information message using Foam::Info.