Loading...
Searching...
No Matches
ensightSurfaceWriterCollated.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-2014 OpenFOAM Foundation
9 Copyright (C) 2015-2024 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
29// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
30
31Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated()
32{
33 // Collated?
34 // ========
35 // CaseFile: rootdir/surfaceName/surfaceName.case
36 // Geometry: rootdir/surfaceName/surfaceName.mesh
38 wroteGeom_ = true;
39 return fileName::null;
40}
41
42
43template<class Type>
44Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
45(
46 const word& fieldName,
47 const Field<Type>& localValues
48)
49{
50 // Geometry changed since last output? Capture now before any merging.
51 const bool geomChanged = (!upToDate_);
52
53 checkOpen();
54
55 const ensight::FileName surfName(outputPath_.name());
56 const ensight::VarName varName(fieldName);
57
58
59 // Collated
60 // ========
61 // CaseFile: rootdir/surfaceName/surfaceName.case
62 // Geometry: rootdir/surfaceName/data/<index>/geometry
63 // Field: rootdir/surfaceName/data/<index>/field
64
65 // Use surface name as sub-directory for results. Eg,
66 // - SURF1/SURF1.case
67 // - SURF1/data/00000000/geometry
68 // - SURF1/data/00000000/VAR1
69 // - SURF1/data/00000000/VAR2
70
71 // Names "data" and "geometry" as per ensightCase:
72 const int maskWidth = 8;
73 const char* mask = "data/********/";
74
75
76 // Ignore the useTimeDir setting - manage ourselves
77 const fileName baseDir = outputPath_;
78
79 const word timeDir = timeName();
80 const scalar timeValue = currTime_.value();
81
82 const fileName outputFile = baseDir / surfName + ".case";
83
84 if (verbose_)
85 {
86 Info<< "Writing case file to " << outputFile << nl;
87 }
88
89 // Implicit geometry merge()
90 tmp<Field<Type>> tfield = adjustField(fieldName, mergeField(localValues));
91
92 if (verbose_)
93 {
94 Info<< endl;
95 }
96
97 // const meshedSurf& surf = surface();
98 const meshedSurfRef& surf = adjustSurface();
99
100 if (UPstream::master() || !parallel_)
101 {
102 if (!Foam::isDir(outputFile.path()))
103 {
104 Foam::mkDir(outputFile.path());
105 }
106
107 const bool stateChanged =
108 caching_.update
109 (
110 baseDir,
111 timeValue,
112 geomChanged,
113 fieldName,
115 varName
116 );
117
118
119 // The most current time and geometry indices
120 const label timeIndex = caching_.latestTimeIndex();
121 const label geomIndex = caching_.latestGeomIndex();
122
123
124 // This will be used for the name of a static geometry,
125 // or just the masking part for moving geometries.
126 const fileName geometryName
127 (
128 "data"
129 / ensightCase::padded(maskWidth, geomIndex)
131 );
132
133
134 // Location for data (and possibly the geometry as well)
135 const fileName dataDir
136 (
137 baseDir/"data"/ensightCase::padded(maskWidth, timeIndex)
138 );
139
140 // As per mkdir -p "data/00000000"
141 Foam::mkDir(dataDir);
142
143
144 const fileName geomFile(baseDir/geometryName);
145
146 // Ensight Geometry
147 ensightOutputSurface part
148 (
149 surf.points(),
150 surf.faces(),
151 geomFile.name()
152 );
153
154 if (!Foam::exists(geomFile))
155 {
156 if (verbose_)
157 {
158 Info<< "Writing geometry to " << geomFile.name() << endl;
159 }
160
161 // Two-argument form for path-name to avoid validating base-dir
162 ensightGeoFile osGeom
163 (
164 geomFile.path(),
165 geomFile.name(),
166 caseOpts_.format()
167 );
168
169 osGeom.beginGeometry();
170 part.write(osGeom); // serial
171 }
172
173 // Write field
174 ensightFile osField
175 (
176 dataDir,
177 varName,
178 caseOpts_.format()
179 );
180
181 if (verbose_)
182 {
183 Info<< "Writing field file to " << osField.name() << endl;
184 }
185
186 // Write field (serial only)
187 osField.write(ensightPTraits<Type>::typeName);
188 osField.newline();
189 part.writeData(osField, tfield(), this->isPointData());
190
191
192 // Update case file
193 if (stateChanged)
194 {
195 OFstream osCase
196 (
198 outputFile,
200 );
201 ensightCase::setTimeFormat(osCase, caseOpts_); // time-format
202
203 if (verbose_)
204 {
205 Info<< "Writing case file to " << osCase.name() << endl;
206 }
207
208 // The geometry can be any of the following:
209 // 0: constant/static
210 // 1: moving, with the same frequency as the data
211 // 2: moving, with different frequency as the data
212
213 const label tsGeom = caching_.geometryTimeset();
214
215 osCase
216 << "FORMAT" << nl
217 << "type: ensight gold" << nl
218 << nl
219 << "GEOMETRY" << nl;
220
221
222 if (tsGeom)
223 {
224 // moving
225 osCase
226 << "model: " << tsGeom << " " // time-set (1|2)
227 << mask << geometryName.name() << nl;
228 }
229 else
230 {
231 // steady
232 osCase
233 << "model: "
234 << geometryName.c_str() << nl;
235 }
236
237 osCase
238 << nl
239 << "VARIABLE" << nl;
240
241
242 for (const entry& dEntry : caching_.fieldsDict())
243 {
244 const dictionary& subDict = dEntry.dict();
245
246 const string varType(subDict.get<string>("type"));
247 const word varName
248 (
249 subDict.getOrDefault<word>
250 (
251 "name",
252 dEntry.keyword() // fieldName as fallback
253 )
254 );
255
256 osCase
257 << varType.c_str()
258 <<
259 (
260 this->isPointData()
261 ? " per node: 1 " // time-set 1
262 : " per element: 1 " // time-set 1
263 )
264 << setw(15) << varName << ' '
265 << mask << ensight::FileName(varName).c_str() << nl;
266 }
267
268 osCase
269 << nl
270 << "TIME" << nl;
271
272 ensightCase::printTimeset(osCase, 1, caching_.times());
273 if (tsGeom == 2)
274 {
276 (
277 osCase,
278 tsGeom,
279 caching_.times(),
280 caching_.geometries()
281 );
282 }
283
284 osCase << "# end" << nl;
285 }
286
287 // Timestamp in the directory for future reference
288 {
289 OFstream timeStamp(dataDir/"time");
290 timeStamp
291 << "# timestep time" << nl
292 << dataDir.name() << ' ' << timeValue << nl;
293 }
294 }
295
296 wroteGeom_ = true;
297 return outputFile;
298}
299
300
301// ************************************************************************* //
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
@ ASCII
"ascii" (normal default)
@ ATOMIC
atomic = true
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
Definition OFstream.H:75
virtual const fileName & name() const override
Read/write access to the name of the stream.
Definition OSstream.H:134
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
bool wroteGeom_
Track if geometry has been written since the last open.
void checkOpen() const
Verify that the outputPath_ has been set or FatalError.
bool upToDate_
The content is up-to-date?
bool verbose_
Additional output verbosity.
instant currTime_
The current time value/name.
scalar timeValue() const
The current time value/name.
fileName outputPath_
The full output directory and file (coords) name.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
static const char * geometryName
The name for geometry files: "geometry".
Definition ensightCase.H:80
static void setTimeFormat(OSstream &os, IOstreamOption::floatFormat timeFmt, const int timePrec)
Set output time format for ensight case file.
Definition ensightCase.C:63
static word padded(const int nwidth, const label index)
Stringified zero-padded integer value of specified width.
Definition ensightCase.C:48
static void printTimeset(OSstream &os, const label ts, const scalar timeValue)
Print time-set for ensight case file with a single time.
A variant of OFstream with specialised handling for Ensight writing of strings, integers and floats (...
Definition ensightFile.H:50
virtual bool write(const token &) override
Writing token does not make sense.
void newline()
Add carriage return to ascii stream.
A variant of ensightFile (Ensight writing) that includes the extra geometry file header information.
void beginGeometry()
Start of geometry information.
A variant of ensightFaces that holds references to contiguous points/faces with its own encapsulated ...
void write(ensightGeoFile &os) const
Write processor-local geometry (serial-only). No beginGeometry() marker.
void writeData(ensightFile &os, const Field< Type > &fld, const bool isPointData=false) const
Write a field of face or point values (serial-only).
Specification of a valid Ensight file-name.
Specification of a valid Ensight variable-name.
A keyword and a list of tokens is an 'entry'.
Definition entry.H:66
A class for handling file names.
Definition fileName.H:75
static const fileName null
An empty fileName.
Definition fileName.H:111
static std::string path(const std::string &str)
Return directory path name (part before last /).
Definition fileNameI.H:169
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition fileNameI.H:192
Implements a meshed surface by referencing another meshed surface or faces/points components.
virtual const pointField & points() const
The points used for the surface.
virtual const faceList & faces() const
The faces used for the surface.
bool wroteGeom_
Track if geometry has been written since the last open.
A class for managing temporary objects.
Definition tmp.H:75
A class for handling words, derived from Foam::string.
Definition word.H:66
word timeName
Definition getTimeIndex.H:3
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition POSIX.C:837
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).
Omanip< int > setw(const int i)
Definition IOmanip.H:199
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition POSIX.C:862
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
label timeIndex
static const char *const typeName
The type name used in ensight case files.