polyMeshIO.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2022 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 
32 void Foam::polyMesh::setPointsWrite(const Foam::IOobject::writeOption wo)
33 {
34  points_.writeOpt() = wo;
35 
36  if (tetBasePtIsPtr_.valid())
37  {
38  tetBasePtIsPtr_->writeOpt() = wo;
39  }
40 }
41 
42 
43 void Foam::polyMesh::setTopologyWrite(const Foam::IOobject::writeOption wo)
44 {
45  setPointsWrite(wo);
46 
47  faces_.writeOpt() = wo;
48  owner_.writeOpt() = wo;
49  neighbour_.writeOpt() = wo;
50  boundary_.writeOpt() = wo;
51  pointZones_.writeOpt() = wo;
52  faceZones_.writeOpt() = wo;
53  cellZones_.writeOpt() = wo;
54 }
55 
56 
58 {
59  if (debug)
60  {
61  InfoInFunction << "Resetting points instance to " << inst << endl;
62  }
63 
64  points_.instance() = inst;
65  points_.eventNo() = getEvent();
66 
67  if (tetBasePtIsPtr_.valid())
68  {
69  tetBasePtIsPtr_->instance() = inst;
70  tetBasePtIsPtr_().eventNo() = getEvent();
71  }
72 
73  setPointsWrite(IOobject::AUTO_WRITE);
74 }
75 
76 
78 {
79  if (debug)
80  {
81  InfoInFunction << "Resetting topology instance to " << inst << endl;
82  }
83 
84  setPointsInstance(inst);
85 
86  faces_.instance() = inst;
87  owner_.instance() = inst;
88  neighbour_.instance() = inst;
89  boundary_.instance() = inst;
90  pointZones_.instance() = inst;
91  faceZones_.instance() = inst;
92  cellZones_.instance() = inst;
93 
94  setTopologyWrite(IOobject::AUTO_WRITE);
95 }
96 
97 
99 {
100  if (debug)
101  {
102  InfoInFunction << "Updating mesh based on saved data." << endl;
103  }
104 
105  // Find the points and faces instance
106  fileName pointsInst(time().findInstance(meshDir(), "points"));
107  fileName facesInst(time().findInstance(meshDir(), "faces"));
108 
109  if (debug)
110  {
111  Info<< "Faces instance: old = " << facesInstance()
112  << " new = " << facesInst << nl
113  << "Points instance: old = " << pointsInstance()
114  << " new = " << pointsInst << endl;
115  }
116 
117  if (facesInst != facesInstance())
118  {
119  // Topological change
120  if (debug)
121  {
122  Info<< "Topological change" << endl;
123  }
124 
125  clearOut();
126 
127  // Set instance to new instance. Note that points instance can differ
128  // from from faces instance.
129  setInstance(facesInst);
130  points_.instance() = pointsInst;
131 
132  points_ = pointIOField
133  (
134  IOobject
135  (
136  "points",
137  pointsInst,
138  meshSubDir,
139  *this,
142  false
143  )
144  );
145 
146  faces_ = faceCompactIOList
147  (
148  IOobject
149  (
150  "faces",
151  facesInst,
152  meshSubDir,
153  *this,
156  false
157  )
158  );
159 
160  owner_ = labelIOList
161  (
162  IOobject
163  (
164  "owner",
165  facesInst,
166  meshSubDir,
167  *this,
170  false
171  )
172  );
173 
174  neighbour_ = labelIOList
175  (
176  IOobject
177  (
178  "neighbour",
179  facesInst,
180  meshSubDir,
181  *this,
184  false
185  )
186  );
187 
188  // Reset the boundary patches
189  polyBoundaryMesh newBoundary
190  (
191  IOobject
192  (
193  "boundary",
194  facesInst,
195  meshSubDir,
196  *this,
199  false
200  ),
201  *this
202  );
203 
204  // Check that patch types and names are unchanged
205  bool boundaryChanged = false;
206 
207  if (newBoundary.size() != boundary_.size())
208  {
209  boundaryChanged = true;
210  }
211  else
212  {
213  wordList newTypes = newBoundary.types();
214  wordList newNames = newBoundary.names();
215 
216  wordList oldTypes = boundary_.types();
217  wordList oldNames = boundary_.names();
218 
219  forAll(oldTypes, patchi)
220  {
221  if
222  (
223  oldTypes[patchi] != newTypes[patchi]
224  || oldNames[patchi] != newNames[patchi]
225  )
226  {
227  boundaryChanged = true;
228  break;
229  }
230  }
231  }
232 
233  if (boundaryChanged)
234  {
235  boundary_.clear();
236  boundary_.setSize(newBoundary.size());
237 
238  forAll(newBoundary, patchi)
239  {
240  boundary_.set(patchi, newBoundary[patchi].clone(boundary_));
241  }
242  }
243  else
244  {
245  forAll(boundary_, patchi)
246  {
247  boundary_[patchi] = polyPatch
248  (
249  newBoundary[patchi].name(),
250  newBoundary[patchi].size(),
251  newBoundary[patchi].start(),
252  patchi,
253  boundary_,
254  newBoundary[patchi].type()
255  );
256  }
257  }
258 
259 
260  // Boundary is set so can use initMesh now (uses boundary_ to
261  // determine internal and active faces)
262 
263  if (!owner_.headerClassName().empty())
264  {
265  initMesh();
266  }
267  else
268  {
270  (
271  IOobject
272  (
273  "cells",
274  facesInst,
275  meshSubDir,
276  *this,
279  false
280  )
281  );
282 
283  // Recalculate the owner/neighbour addressing and reset the
284  // primitiveMesh
285  initMesh(cells);
286  }
287 
288 
289  // Even if number of patches stayed same still recalculate boundary
290  // data.
291 
292  // Calculate topology for the patches (processor-processor comms etc.)
293  boundary_.topoChange();
294 
295  // Calculate the geometry for the patches (transformation tensors etc.)
296  boundary_.calcGeometry();
297 
298  // Derived info
299  bounds_ = boundBox(points_);
300  geometricD_ = Zero;
301  solutionD_ = Zero;
302 
303  // Zones
304  meshPointZones newPointZones
305  (
306  IOobject
307  (
308  "pointZones",
309  facesInst,
310  meshSubDir,
311  *this,
314  false
315  ),
316  *this
317  );
318 
319  label oldSize = pointZones_.size();
320 
321  if (newPointZones.size() <= pointZones_.size())
322  {
323  pointZones_.setSize(newPointZones.size());
324  }
325 
326  // Reset existing ones
327  forAll(pointZones_, czI)
328  {
329  pointZones_[czI] = newPointZones[czI];
330  }
331 
332  // Extend with extra ones
333  pointZones_.setSize(newPointZones.size());
334 
335  for (label czI = oldSize; czI < newPointZones.size(); czI++)
336  {
337  pointZones_.set(czI, newPointZones[czI].clone(pointZones_));
338  }
339 
340 
341  meshFaceZones newFaceZones
342  (
343  IOobject
344  (
345  "faceZones",
346  facesInst,
347  meshSubDir,
348  *this,
351  false
352  ),
353  *this
354  );
355 
356  oldSize = faceZones_.size();
357 
358  if (newFaceZones.size() <= faceZones_.size())
359  {
360  faceZones_.setSize(newFaceZones.size());
361  }
362 
363  // Reset existing ones
364  forAll(faceZones_, fzI)
365  {
366  faceZones_[fzI].resetAddressing
367  (
368  newFaceZones[fzI],
369  newFaceZones[fzI].flipMap()
370  );
371  }
372 
373  // Extend with extra ones
374  faceZones_.setSize(newFaceZones.size());
375 
376  for (label fzI = oldSize; fzI < newFaceZones.size(); fzI++)
377  {
378  faceZones_.set(fzI, newFaceZones[fzI].clone(faceZones_));
379  }
380 
381 
382  meshCellZones newCellZones
383  (
384  IOobject
385  (
386  "cellZones",
387  facesInst,
388  meshSubDir,
389  *this,
392  false
393  ),
394  *this
395  );
396 
397  oldSize = cellZones_.size();
398 
399  if (newCellZones.size() <= cellZones_.size())
400  {
401  cellZones_.setSize(newCellZones.size());
402  }
403 
404  // Reset existing ones
405  forAll(cellZones_, czI)
406  {
407  cellZones_[czI] = newCellZones[czI];
408  }
409 
410  // Extend with extra ones
411  cellZones_.setSize(newCellZones.size());
412 
413  for (label czI = oldSize; czI < newCellZones.size(); czI++)
414  {
415  cellZones_.set(czI, newCellZones[czI].clone(cellZones_));
416  }
417 
418  // Re-read tet base points
419  tetBasePtIsPtr_ = readTetBasePtIs();
420 
421 
422  if (boundaryChanged)
423  {
425  }
426  else
427  {
428  return polyMesh::TOPO_CHANGE;
429  }
430  }
431  else if (pointsInst != pointsInstance())
432  {
433  // Points moved
434  if (debug)
435  {
436  Info<< "Point motion" << endl;
437  }
438 
439  clearGeom();
440 
441 
442  label nOldPoints = points_.size();
443 
444  points_.clear();
445 
446  pointIOField newPoints
447  (
448  IOobject
449  (
450  "points",
451  pointsInst,
452  meshSubDir,
453  *this,
456  false
457  )
458  );
459 
460  if (nOldPoints != 0 && nOldPoints != newPoints.size())
461  {
463  << "Point motion detected but number of points "
464  << newPoints.size() << " in "
465  << newPoints.objectPath() << " does not correspond to "
466  << " current " << nOldPoints
467  << exit(FatalError);
468  }
469 
470  points_.transfer(newPoints);
471  points_.instance() = pointsInst;
472 
473  // Re-read tet base points
474  autoPtr<labelIOList> newTetBasePtIsPtr = readTetBasePtIs();
475  if (newTetBasePtIsPtr.valid())
476  {
477  tetBasePtIsPtr_ = newTetBasePtIsPtr;
478  }
479 
480  // Calculate the geometry for the patches (transformation tensors etc.)
481  boundary_.calcGeometry();
482 
483  // Derived info
484  bounds_ = boundBox(points_);
485 
486  // Rotation can cause direction vector to change
487  geometricD_ = Zero;
488  solutionD_ = Zero;
489 
490  return polyMesh::POINTS_MOVED;
491  }
492  else
493  {
494  if (debug)
495  {
496  Info<< "No change" << endl;
497  }
498 
499  return polyMesh::UNCHANGED;
500  }
501 }
502 
503 
505 (
509  const bool write
510 ) const
511 {
512  const bool written = objectRegistry::writeObject(fmt, ver, cmp, write);
513 
514  const_cast<polyMesh&>(*this).setTopologyWrite(IOobject::NO_WRITE);
515 
516  return written;
517 }
518 
519 
520 // ************************************************************************* //
autoPtr< IOobject > clone() const
Clone.
Definition: IOobject.H:288
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
writeOption
Enumeration defining the write options.
Definition: IOobject.H:125
const word & name() const
Return name.
Definition: IOobject.H:315
A class for handling file names.
Definition: fileName.H:79
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:888
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
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:328
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
fileName objectPath() const
Return complete path + object name.
Definition: regIOobject.H:159
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:58
void setPointsInstance(const fileName &)
Set the instance for the points files.
Definition: polyMeshIO.C:57
const cellList & cells() const
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write=true) const
Write the underlying polyMesh.
Definition: polyMeshIO.C:505
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:44
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:882
void topoChange()
Correct polyBoundaryMesh after topology update.
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
wordList names() const
Return a list of patch names.
label getEvent() const
Return new event number.
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:86
label eventNo() const
Event number at last update.
Definition: regIOobjectI.H:89
static const zero Zero
Definition: zero.H:97
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.
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:193
void clearGeom()
Clear geometry.
Definition: polyMeshClear.C:53
static const char nl
Definition: Ostream.H:260
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:54
void setInstance(const fileName &)
Set the instance for mesh files.
Definition: polyMeshIO.C:77
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
writeOption writeOpt() const
Definition: IOobject.H:375
label patchi
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:876
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
Version number type.
Definition: IOstream.H:96
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
fileName & instance() const
Return the instance directory, constant, system, <time> etc.
Definition: IOobject.C:355
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:76
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:90
readUpdateState readUpdate()
Update the mesh based on the mesh files saved in.
Definition: polyMeshIO.C:98
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:321
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:98
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write) const
Write the objects.
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.