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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "polyMesh.H"
30 #include "Time.H"
31 #include "cellIOList.H"
32 
33 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
34 
36 (
37  const fileName& inst,
39 )
40 {
41  DebugInFunction << "Resetting file instance to " << inst << endl;
42 
43  points_.writeOpt(wOpt);
44  points_.instance() = inst;
45 
46  faces_.writeOpt(wOpt);
47  faces_.instance() = inst;
48 
49  owner_.writeOpt(wOpt);
50  owner_.instance() = inst;
51 
52  neighbour_.writeOpt(wOpt);
53  neighbour_.instance() = inst;
54 
55  boundary_.writeOpt(wOpt);
56  boundary_.instance() = inst;
57 
58  pointZones_.writeOpt(wOpt);
59  pointZones_.instance() = inst;
60 
61  faceZones_.writeOpt(wOpt);
62  faceZones_.instance() = inst;
63 
64  cellZones_.writeOpt(wOpt);
65  cellZones_.instance() = inst;
66 
67  if (tetBasePtIsPtr_)
68  {
69  tetBasePtIsPtr_->writeOpt(wOpt);
70  tetBasePtIsPtr_->instance() = inst;
71  }
72 }
73 
74 
76 {
77  DebugInFunction << "Updating mesh based on saved data." << endl;
78 
79  // Find point/faces instances
80  const fileName pointsInst(time().findInstance(meshDir(), "points"));
81  const fileName facesInst(time().findInstance(meshDir(), "faces"));
82  //const fileName boundInst
83  //(time().findInstance(meshDir(), "boundary", IOobject::MUST_READ, facesInst));
84 
85  if (debug)
86  {
87  Info<< "Faces instance: old = " << facesInstance()
88  << " new = " << facesInst << nl
89  << "Points instance: old = " << pointsInstance()
90  << " new = " << pointsInst << endl;
91  }
92 
93  if (facesInst != facesInstance())
94  {
95  // Topological change
96  if (debug)
97  {
98  Info<< "Topological change" << endl;
99  }
100 
101  clearOut();
102 
103  // Set instance to new instance. Note that points instance can differ
104  // from from faces instance.
105  setInstance(facesInst);
106  points_.instance() = pointsInst;
107 
108  points_.clear();
109  points_ = pointIOField
110  (
111  IOobject
112  (
113  "points",
114  pointsInst,
115  meshSubDir,
116  *this,
120  )
121  );
122 
123  faces_.clear();
124  faces_ = faceCompactIOList
125  (
126  IOobject
127  (
128  "faces",
129  facesInst,
130  meshSubDir,
131  *this,
135  )
136  );
137 
138  // owner
139  {
140  owner_.clear();
141 
142  labelIOList list
143  (
144  IOobject
145  (
146  "owner",
147  facesInst,
148  meshSubDir,
149  *this,
153  )
154  );
155 
156  // Update owner headerClassName.
157  // The "cells" logic below may rely on it!
158 
159  owner_ = std::move(static_cast<labelList&>(list));
160  owner_.headerClassName() = std::move(list.headerClassName());
161  owner_.note() = std::move(list.note());
162  }
163 
164  // neighbour
165  {
166  neighbour_.clear();
167 
168  labelIOList list
169  (
170  IOobject
171  (
172  "neighbour",
173  facesInst,
174  meshSubDir,
175  *this,
179  )
180  );
181 
182  // Update neighbour headerClassName.
183  // - not currently needed, but for symmetry with owner
184  // The "cells" logic below may rely on it!
185 
186  neighbour_ = std::move(static_cast<labelList&>(list));
187  neighbour_.headerClassName() = std::move(list.headerClassName());
188  neighbour_.note() = std::move(list.note());
189  }
190 
191  // Reset the boundary patches
192  polyBoundaryMesh newBoundary
193  (
194  IOobject
195  (
196  "boundary",
197  facesInst,
198  meshSubDir,
199  *this,
203  ),
204  *this
205  );
206 
207  // Check that patch types and names are unchanged
208  bool boundaryChanged = false;
209 
210  if (newBoundary.size() != boundary_.size())
211  {
212  boundaryChanged = true;
213  }
214  else
215  {
216  forAll(boundary_, patchi)
217  {
218  const auto& oldPatch = boundary_[patchi];
219  const auto& newPatch = newBoundary[patchi];
220 
221  if
222  (
223  (oldPatch.name() != newPatch.name())
224  || (oldPatch.type() != newPatch.type())
225  )
226  {
227  boundaryChanged = true;
228  break;
229  }
230  }
231  }
232 
233  if (boundaryChanged)
234  {
236  << "Number of patches has changed. This may have "
237  << "unexpected consequences. Proceed with care." << endl;
238 
239  boundary_.resize_null(newBoundary.size());
240 
241  forAll(newBoundary, patchi)
242  {
243  boundary_.set(patchi, newBoundary[patchi].clone(boundary_));
244  }
245  }
246  else
247  {
248  forAll(boundary_, patchi)
249  {
250  boundary_[patchi] = polyPatch
251  (
252  newBoundary[patchi].name(),
253  newBoundary[patchi].size(),
254  newBoundary[patchi].start(),
255  patchi,
256  boundary_,
257  newBoundary[patchi].physicalType(),
258  newBoundary[patchi].inGroups()
259  );
260  }
261  }
262 
263 
264  // Boundary is set so can use initMesh now (uses boundary_ to
265  // determine internal and active faces)
266 
267  if (owner_.hasHeaderClass())
268  {
269  initMesh();
270  }
271  else
272  {
274  (
275  IOobject
276  (
277  "cells",
278  facesInst,
279  meshSubDir,
280  *this,
284  )
285  );
286 
287  // Recalculate the owner/neighbour addressing and reset the
288  // primitiveMesh
289  initMesh(cells);
290  }
291 
292 
293  // Even if number of patches stayed same still recalculate boundary
294  // data.
295 
296  // Calculate topology for the patches (processor-processor comms etc.)
297  boundary_.updateMesh();
298 
299  // Calculate the geometry for the patches (transformation tensors etc.)
300  boundary_.calcGeometry();
301 
302  // Derived info
303  bounds_ = boundBox(points_);
304  geometricD_ = Zero;
305  solutionD_ = Zero;
306 
307 
308  // Update point/face/cell zones, but primarily just the addressing.
309  // - this will be extremely fragile (not just here) if the names
310  // or the order of the zones also change
311 
312  #undef update_meshZones
313  #define update_meshZones(DataMember) \
314  { \
315  (DataMember).clearAddressing(); \
316  (DataMember).clearPrimitives(); \
317  \
318  decltype(DataMember) newZones \
319  ( \
320  IOobject \
321  ( \
322  (DataMember).name(), \
323  facesInst, \
324  meshSubDir, \
325  *this, \
326  IOobject::READ_IF_PRESENT, \
327  IOobject::NO_WRITE, \
328  IOobject::NO_REGISTER \
329  ), \
330  *this, \
331  PtrList<entry>() \
332  ); \
333  const label numZones = newZones.size(); \
334  (DataMember).resize(numZones); \
335  \
336  for (label zonei = 0; zonei < numZones; ++zonei) \
337  { \
338  /* Existing or new empty zone */ \
339  auto& zn = (DataMember).try_emplace \
340  ( \
341  zonei, \
342  newZones[zonei], Foam::zero{}, (DataMember) \
343  ); \
344  \
345  /* Set addressing */ \
346  zn.resetAddressing(std::move(newZones[zonei])); \
347  } \
348  }
349 
350  update_meshZones(pointZones_);
351  update_meshZones(faceZones_);
352  update_meshZones(cellZones_);
353  #undef update_meshZones
354 
355 
356  // Re-read tet base points
357  tetBasePtIsPtr_ = readTetBasePtIs();
358 
359 
360  if (boundaryChanged)
361  {
363  }
364  else
365  {
366  return polyMesh::TOPO_CHANGE;
367  }
368  }
369  else if (pointsInst != pointsInstance())
370  {
371  // Points moved
372  if (debug)
373  {
374  Info<< "Point motion" << endl;
375  }
376 
377  pointIOField newPoints
378  (
379  IOobject
380  (
381  "points",
382  pointsInst,
383  meshSubDir,
384  *this,
388  )
389  );
390 
391  // Re-read tet base points
392  autoPtr<labelIOList> newTetBasePtIsPtr = readTetBasePtIs();
393 
394  // Update all geometry
395  updateGeomPoints(std::move(newPoints), newTetBasePtIsPtr);
396 
397  return polyMesh::POINTS_MOVED;
398  }
399  else
400  {
401  if (debug)
402  {
403  Info<< "No change" << endl;
404  }
405 
406  return polyMesh::UNCHANGED;
407  }
408 }
409 
410 
411 // ************************************************************************* //
writeOption
Enumeration defining write preferences.
A class for handling file names.
Definition: fileName.H:72
vectorIOField pointIOField
pointIOField is a vectorIOField.
Definition: pointIOField.H:38
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Ignore writing from objectRegistry::writeObject()
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
#define update_meshZones(DataMember)
CompactIOList< face, label > faceCompactIOList
Compact IO for a List of face.
Definition: faceIOList.H:35
writeOption writeOpt() const noexcept
Get the write option.
IOList< label > labelIOList
IO for a List of label.
Definition: labelIOList.H:32
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
const cellShapeList & cells
#define DebugInFunction
Report an information message using Foam::Info.
Reading is optional [identical to LAZY_READ].
int debug
Static debugging option.
CompactIOList< cell, label > cellCompactIOList
Compact IO for a List of cell.
Definition: cellIOList.H:35
const fileName & instance() const noexcept
Read access to instance path component.
Definition: IOobjectI.H:266
void setInstance(const fileName &instance, const IOobjectOption::writeOption wOpt=IOobject::AUTO_WRITE)
Set the instance for mesh files.
Definition: polyMeshIO.C:29
#define WarningInFunction
Report a warning using Foam::Warning.
messageStream Info
Information stream (stdout output on master, null elsewhere)
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:90
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in.
Definition: polyMeshIO.C:68
Do not request registration (bool: false)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127