Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
11License
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\*---------------------------------------------------------------------------*/
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 (
112 (
113 "points",
114 pointsInst,
115 meshSubDir,
116 *this,
120 )
121 );
122
123 faces_.clear();
124 faces_ = faceCompactIOList
125 (
127 (
128 "faces",
129 facesInst,
130 meshSubDir,
131 *this,
135 )
136 );
137
138 // owner
139 {
140 owner_.clear();
141
142 labelIOList list
143 (
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 (
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 (
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 (
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 {
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 (
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
398 }
399 else
400 {
401 if (debug)
402 {
403 Info<< "No change" << endl;
404 }
405
406 return polyMesh::UNCHANGED;
407 }
408}
409
410
411// ************************************************************************* //
label size() const noexcept
Definition HashTable.H:358
@ NO_REGISTER
Do not request registration (bool: false).
@ READ_IF_PRESENT
Reading is optional [identical to LAZY_READ].
@ MUST_READ
Reading required.
writeOption
Enumeration defining write preferences.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
const word & headerClassName() const noexcept
Return name of the class name read from header.
Definition IOobjectI.H:223
autoPtr< IOobject > clone() const
Clone.
Definition IOobject.H:641
const string & note() const noexcept
Return the optional note.
Definition IOobjectI.H:235
label size() const noexcept
The number of entries in the list.
Definition UPtrListI.H:106
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
A bounding box defined in terms of min/max extrema points.
Definition boundBox.H:71
A class for handling file names.
Definition fileName.H:75
const Time & time() const noexcept
Return time registry.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
void setInstance(const fileName &instance, const IOobjectOption::writeOption wOpt=IOobject::AUTO_WRITE)
Set the instance for mesh files.
Definition polyMeshIO.C:29
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition polyMesh.C:844
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir).
Definition polyMesh.C:826
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition polyMesh.H:92
void updateGeomPoints(pointIOField &&newPoints, autoPtr< labelIOList > &newTetBasePtIsPtr)
Update geometry points; keep topology. Optionally with new face decomposition.
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition polyMesh.C:838
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in.
Definition polyMeshIO.C:68
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh").
Definition polyMesh.H:411
void clearOut(const bool isMeshUpdate=false)
Clear all geometry and addressing.
A patch is a list of labels that address the faces in the global face list.
Definition polyPatch.H:73
const cellList & cells() const
auto & name
const cellShapeList & cells
#define WarningInFunction
Report a warning using Foam::Warning.
#define DebugInFunction
Report an information message using Foam::Info.
Namespace for handling debugging switches.
Definition debug.C:45
List< label > labelList
A List of labels.
Definition List.H:62
IOList< label > labelIOList
IO for a List of label.
Definition labelIOList.H:32
CompactIOList< face > faceCompactIOList
Compact IO for a List of face.
Definition faceIOList.H:35
messageStream Info
Information stream (stdout output on master, null elsewhere).
vectorIOField pointIOField
pointIOField is a vectorIOField.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
CompactIOList< cell > cellCompactIOList
Compact IO for a List of cell.
Definition cellIOList.H:35
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
#define update_meshZones(DataMember)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299