Loading...
Searching...
No Matches
boundaryDataSurfaceWriter.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) 2015 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\*---------------------------------------------------------------------------*/
28
30#include "OFstream.H"
31#include "OSspecific.H"
32#include "IOmanip.H"
33#include "Time.H"
34#include "pointIOField.H"
35#include "primitivePatch.H"
39// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41namespace Foam
42{
43namespace surfaceWriters
44{
48}
49}
50
51
52// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
53
55:
57 streamOpt_(),
58 header_(true),
59 writeNormal_(false)
60{}
61
62
64(
65 const dictionary& options
66)
67:
68 surfaceWriter(options),
69 streamOpt_
70 (
71 IOstreamOption::formatEnum("format", options, IOstreamOption::ASCII),
72 IOstreamOption::compressionEnum("compression", options)
73 ),
74 header_(options.getOrDefault("header", true)),
75 writeNormal_(options.getOrDefault("normal", false))
76{}
77
78
80(
81 const meshedSurf& surf,
82 const fileName& outputPath,
83 bool parallel,
84 const dictionary& options
85)
87 boundaryDataWriter(options)
88{
89 open(surf, outputPath, parallel);
90}
91
92
94(
95 const pointField& points,
96 const faceList& faces,
97 const fileName& outputPath,
98 bool parallel,
99 const dictionary& options
100)
101:
102 boundaryDataWriter(options)
103{
104 open(points, faces, outputPath, parallel);
105}
106
107
108// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
109
110void Foam::surfaceWriters::boundaryDataWriter::serialWriteGeometry
111(
112 const regIOobject& iopts,
113 const meshedSurf& surf
114)
115{
116 const pointField& points = surf.points();
117 const faceList& faces = surf.faces();
118
119 if (verbose_)
120 {
121 if (this->isPointData())
122 {
123 Info<< "Writing points: " << iopts.objectPath() << endl;
124 }
125 else
126 {
127 Info<< "Writing face centres: " << iopts.objectPath() << endl;
128 }
129 }
130
131 // Like regIOobject::writeObject without instance() adaptation
132 // since this would write to e.g. 0/ instead of postProcessing/
133
134 autoPtr<primitivePatch> ppPtr;
135
136 {
137 OFstream os(iopts.objectPath(), streamOpt_);
138
139 if (header_)
140 {
141 iopts.writeHeader(os);
142 }
143
144 if (this->isPointData())
145 {
146 // Just like writeData, but without copying beforehand
147 os << points;
148 }
149 else
150 {
151 ppPtr.reset(new primitivePatch(SubList<face>(faces), points));
152
153 // Just like writeData, but without copying beforehand
154 os << ppPtr().faceCentres();
155 }
156
157 if (header_)
158 {
160 }
161 }
162
163 if (writeNormal_ && !this->isPointData())
164 {
165 vectorIOField iofld
166 (
167 IOobject
168 (
169 iopts.objectPath().path()/"normal",
170 iopts.db(),
174 )
175 );
176 iofld.note() = "face data";
177
178 OFstream os(iofld.objectPath(), streamOpt_);
179
180 if (header_)
181 {
182 iofld.writeHeader(os);
183 }
184
185 os << ppPtr().faceNormals();
186
187 if (header_)
190 }
191 }
192}
193
194
196{
197 checkOpen();
198
199 // Geometry: rootdir/surfaceName/"points"
200 // Field: rootdir/surfaceName/<TIME>/field
201
202 fileName surfaceDir = outputPath_;
203
204 // Dummy Time to use as objectRegistry
205 refPtr<Time> timePtr(Time::NewGlobalTime());
206
207 // const meshedSurf& surf = surface();
208 const meshedSurfRef& surf = adjustSurface();
209
210 if (UPstream::master() || !parallel_)
211 {
212 if (!isDir(surfaceDir))
213 {
214 mkDir(surfaceDir);
215 }
216
217 // Write sample locations
218 pointIOField iopts
219 (
220 IOobject
221 (
222 surfaceDir/"points",
223 *timePtr,
227 )
228 );
229 iopts.note() = (this->isPointData() ? "point data" : "face data");
230
231 serialWriteGeometry(iopts, surf);
232 }
233
234 wroteGeom_ = true;
235 return surfaceDir;
236}
237
238
239// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
240
241template<class Type>
242Foam::fileName Foam::surfaceWriters::boundaryDataWriter::writeTemplate
243(
244 const word& fieldName,
245 const Field<Type>& localValues
246)
247{
248 checkOpen();
249
250 // Geometry: rootdir/surfaceName/"points"
251 // Field: rootdir/surfaceName/<TIME>/field
252
253 fileName surfaceDir = outputPath_;
254
255 const fileName outputFile(surfaceDir/timeName()/fieldName);
256
257 // Implicit geometry merge()
258 tmp<Field<Type>> tfield = adjustField(fieldName, mergeField(localValues));
259
260 if (verbose_)
261 {
262 Info<< " to " << outputFile << endl;
263 }
264
265
266 // Dummy Time to use as objectRegistry
268
269 // const meshedSurf& surf = surface();
270 const meshedSurfRef& surf = adjustSurface();
271
272 if (UPstream::master() || !parallel_)
273 {
274 if (!isDir(outputFile.path()))
275 {
276 mkDir(outputFile.path());
277 }
278
279 // Write sample locations
280 {
281 pointIOField iopts
282 (
283 IOobject
284 (
285 surfaceDir/"points",
286 *timePtr,
290 )
291 );
292 iopts.note() = (this->isPointData() ? "point data" : "face data");
293
294 serialWriteGeometry(iopts, surf);
295 }
296
297 // Write field
298 {
299 IOField<Type> iofld
300 (
301 IOobject
302 (
303 outputFile,
304 *timePtr,
308 )
309 );
310 iofld.note() = (this->isPointData() ? "point data" : "face data");
311
312 OFstream os(iofld.objectPath(), streamOpt_);
313
314 if (header_)
315 {
316 iofld.writeHeader(os);
317 }
318
319 // Just like writeData, but without copying beforehand
320 os << tfield();
321
322 if (header_)
323 {
325 }
326 }
327 }
328
329 wroteGeom_ = true;
330 return surfaceDir;
331}
332
333
334// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
335
336// Field writing methods
337defineSurfaceWriterWriteFields(Foam::surfaceWriters::boundaryDataWriter);
338
339
340// ************************************************************************* //
Istream and Ostream manipulators taking arguments.
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
A primitive field of type <T> with automated input and output.
Definition IOField.H:53
@ NO_REGISTER
Do not request registration (bool: false).
@ NO_READ
Nothing to be read.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
static Ostream & writeEndDivider(Ostream &os)
Write the standard end file divider.
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition IOobject.C:450
const string & note() const noexcept
Return the optional note.
Definition IOobjectI.H:235
fileName objectPath() const
The complete path + object name.
Definition IOobjectI.H:313
bool writeHeader(Ostream &os) const
Write header with current type().
A simple container for options an IOstream can normally have.
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
Definition OFstream.H:75
static autoPtr< Time > NewGlobalTime()
Construct (dummy) global Time - no functionObjects or libraries, using the global path information st...
Definition TimeNew.C:78
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
A class for handling file names.
Definition fileName.H:75
static std::string path(const std::string &str)
Return directory path name (part before last /).
Definition fileNameI.H:169
Implements a meshed surface by referencing another meshed surface or faces/points components.
Abstract definition of a meshed surface defined by faces and points.
Definition meshedSurf.H:44
virtual const faceList & faces() const =0
The faces used for the surface.
virtual const pointField & points() const =0
The points used for the surface.
A class for managing references or pointers (no reference counting).
Definition refPtr.H:54
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition regIOobject.H:71
Base class for surface writers.
surfaceWriter()
Default construct.
virtual void open(const fileName &outputPath)
Open for output on specified path, using existing surface.
bool wroteGeom_
Track if geometry has been written since the last open.
bool isPointData() const noexcept
Are the field data to be treated as point data?
void checkOpen() const
Verify that the outputPath_ has been set or FatalError.
bool parallel_
Writing in parallel (via master).
tmp< Field< label > > adjustField(const word &fieldName, const tmp< Field< label > > &tfield) const
bool verbose_
Additional output verbosity.
const meshedSurfRef & adjustSurface() const
Merge surfaces (if not upToDate) and return merged (parallel) or regular surface (non-parallel) and a...
tmp< Field< label > > mergeField(const Field< label > &fld) const
fileName outputPath_
The full output directory and file (surface) name.
A surfaceWriter for outputting to a form usable for the timeVaryingMapped boundary condition....
virtual fileName write()
Write surface geometry to file.
A class for managing temporary objects.
Definition tmp.H:75
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeName(Type)
Define the typeName.
Definition className.H:113
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
word timeName
Definition getTimeIndex.H:3
Namespace for surface writers.
Namespace for OpenFOAM.
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition POSIX.C:616
messageStream Info
Information stream (stdout output on master, null elsewhere).
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
List< face > faceList
List of faces.
Definition faceListFwd.H:41
vectorIOField pointIOField
pointIOField is a vectorIOField.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
vectorField pointField
pointField is a vectorField.
IOField< vector > vectorIOField
IO for a Field of vector.
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition POSIX.C:862
Convenience macros for instantiating surfaceWriter methods.
#define defineSurfaceWriterWriteFields(ThisClass)