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-2020 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 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 
31 int Foam::surfaceWriters::ensightWriter::geometryTimeset() const
32 {
33  const scalarList& times = caching_.times();
34  const bitSet& geoms = caching_.geometries();
35 
36  if (geoms.count() <= 1)
37  {
38  // Static
39  return 0;
40  }
41 
42  if (geoms.size() == times.size() && geoms.all())
43  {
44  // Geometry changing is the same as fields changing
45  return 1;
46  }
47 
48  // Geometry changing differently from fields
49  return 2;
50 }
51 
52 
53 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
54 
55 Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated()
56 {
57  // Collated?
58  // ========
59  // CaseFile: rootdir/surfaceName/surfaceName.case
60  // Geometry: rootdir/surfaceName/surfaceName.mesh
61 
62  wroteGeom_ = true;
63  return fileName::null;
64 }
65 
66 
67 template<class Type>
68 Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
69 (
70  const word& fieldName,
71  const Field<Type>& localValues
72 )
73 {
74  // Geometry changed since last output? Capture now before any merging.
75  const bool geomChanged = (!upToDate_);
76 
77  checkOpen();
78 
79  const ensight::FileName surfName(outputPath_.name());
80  const ensight::VarName varName(fieldName);
81 
82 
83  // Collated
84  // ========
85  // CaseFile: rootdir/surfaceName/surfaceName.case
86  // Geometry: rootdir/surfaceName/data/<index>/geometry
87  // Field: rootdir/surfaceName/data/<index>/field
88 
89  // Use surface name as sub-directory for results. Eg,
90  // - SURF1/SURF1.case
91  // - SURF1/data/00000000/geometry
92  // - SURF1/data/00000000/VAR1
93  // - SURF1/data/00000000/VAR2
94 
95  // Names "data" and "geometry" as per ensightCase:
96  const char* fmt = "%08d";
97  const char* mask = "data/********/";
98 
99 
100  // Ignore the useTimeDir setting - manage ourselves
101  const fileName baseDir = outputPath_;
102 
103  const word timeDir = timeName();
104  const scalar timeValue = currTime_.value();
105 
106  const fileName outputFile = baseDir / surfName + ".case";
107 
108  if (verbose_)
109  {
110  Info<< "Writing case file to " << outputFile << endl;
111  }
112 
113 
114 
115  // Implicit geometry merge()
116  tmp<Field<Type>> tfield = mergeField(localValues);
117 
118  const meshedSurf& surf = surface();
119 
120  if (Pstream::master() || !parallel_)
121  {
122  if (!isDir(outputFile.path()))
123  {
124  mkDir(outputFile.path());
125  }
126 
127  const bool stateChanged =
128  caching_.update
129  (
130  baseDir,
131  timeValue,
132  geomChanged,
133  fieldName,
135  varName
136  );
137 
138 
139  // The most current time and geometry indices
140  const label timeIndex = caching_.latestTimeIndex();
141  const label geomIndex = caching_.latestGeomIndex();
142 
143 
144  // This will be used for the name of a static geometry,
145  // or just the masking part for moving geometries.
146  const fileName geometryName
147  (
148  "data"/word::printf(fmt, geomIndex)/ensightCase::geometryName
149  );
150 
151 
152  // Do case file
153  if (stateChanged)
154  {
155  OFstream osCase(outputFile, IOstream::ASCII);
156 
157  // Format options
158  osCase.setf(ios_base::left);
159  osCase.setf(ios_base::scientific, ios_base::floatfield);
160  osCase.precision(5);
161 
162  if (verbose_)
163  {
164  Info<< "Writing case file to " << osCase.name() << endl;
165  }
166 
167  // The geometry can be any of the following:
168  // 0: constant/static
169  // 1: moving, with the same frequency as the data
170  // 2: moving, with different frequency as the data
171 
172  const label tsGeom = geometryTimeset();
173 
174  osCase
175  << "FORMAT" << nl
176  << "type: ensight gold" << nl
177  << nl
178  << "GEOMETRY" << nl;
179 
180 
181  if (tsGeom)
182  {
183  // moving
184  osCase
185  << "model: " << tsGeom << " " // time-set (1|2)
186  << mask << geometryName.name() << nl;
187  }
188  else
189  {
190  // steady
191  osCase
192  << "model: "
193  << geometryName.c_str() << nl;
194  }
195 
196  osCase
197  << nl
198  << "VARIABLE" << nl;
199 
200 
201  for (const entry& dEntry : caching_.fieldsDict())
202  {
203  const dictionary& subDict = dEntry.dict();
204 
205  const word varType(subDict.get<word>("type"));
206  const word varName
207  (
208  subDict.getOrDefault<word>
209  (
210  "name",
211  dEntry.keyword() // fieldName as fallback
212  )
213  );
214 
215  osCase
216  << varType
217  <<
218  (
219  this->isPointData()
220  ? " per node: 1 " // time-set 1
221  : " per element: 1 " // time-set 1
222  )
223  << setw(15) << varName << ' '
224  << mask << varName << nl;
225  }
226 
227  osCase
228  << nl
229  << "TIME" << nl;
230 
231  printTimeset(osCase, 1, caching_.times());
232  if (tsGeom == 2)
233  {
234  printTimeset
235  (
236  osCase,
237  tsGeom,
238  caching_.times(),
239  caching_.geometries()
240  );
241  }
242 
243  osCase << "# end" << nl;
244  }
245 
246 
247  // Location for data (and possibly the geometry as well)
248  fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex);
249 
250  // As per mkdir -p "data/00000000"
251  mkDir(dataDir);
252 
253 
254  const fileName geomFile(baseDir/geometryName);
255 
256  // Ensight Geometry
258  (
259  surf.points(),
260  surf.faces(),
261  geomFile.name()
262  );
263 
264  if (!exists(geomFile))
265  {
266  if (verbose_)
267  {
268  Info<< "Writing geometry to " << geomFile.name() << endl;
269  }
270 
271  // Two-argument form for path-name to avoid validating base-dir
272  ensightGeoFile osGeom
273  (
274  geomFile.path(),
275  geomFile.name(),
276  writeFormat_
277  );
278  part.write(osGeom); // serial
279  }
280 
281  // Write field
282  ensightFile osField
283  (
284  dataDir,
285  varName,
286  writeFormat_
287  );
288 
289  if (verbose_)
290  {
291  Info<< "Writing field file to " << osField.name() << endl;
292  }
293 
294  // Write field (serial only)
296  part.writeData(osField, tfield(), this->isPointData());
297 
298  // Timestamp in the directory for future reference
299  {
300  OFstream timeStamp(dataDir/"time");
301  timeStamp
302  << "# timestep time" << nl
303  << dataDir.name() << ' ' << timeValue << nl;
304  }
305  }
306 
307  wroteGeom_ = true;
308  return outputFile;
309 }
310 
311 
312 // ************************************************************************* //
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::scalarList
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:64
Foam::exists
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: MSwindows.C:625
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::OFstream::name
virtual const fileName & name() const
Read/write access to the name of the stream.
Definition: OSstream.H:107
Foam::fileName::path
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:176
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::ensightPTraits
Ensight names and component order for base types.
Definition: ensightPTraits.H:53
Foam::fileName::name
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:199
Foam::meshedSurf::faces
virtual const faceList & faces() const =0
The faces used for the surface.
Foam::meshedSurf
Abstract definition of a meshed surface defined by faces and points.
Definition: meshedSurf.H:49
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::ensightFile::writeKeyword
virtual Ostream & writeKeyword(const keyType &key)
Definition: ensightFile.C:320
Foam::ensightGeoFile
Specialized Ensight output with extra geometry file header.
Definition: ensightGeoFile.H:48
Foam::ensight::FileName
Specification of a valid Ensight file-name.
Definition: ensightFileName.H:60
Foam::ensight::VarName
Specification of a valid Ensight variable-name.
Definition: ensightVarName.H:59
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::meshedSurf::points
virtual const pointField & points() const =0
The points used for the surface.
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::ensightFile::write
virtual bool write(const token &)
Writing token does not make sense.
Definition: ensightFile.H:176
Foam::surfaceWriters::writerCaching::geometries
const bitSet & geometries() const
Indices in times() when geometry (mesh) has been written.
Definition: surfaceWriterCaching.H:114
Foam::ensightFile
Ensight output with specialized write() for strings, integers and floats. Correctly handles binary wr...
Definition: ensightFile.H:52
Foam::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::scientific
IOstream & scientific(IOstream &io)
Definition: IOstream.H:464
Foam::fileName::null
static const fileName null
An empty fileName.
Definition: fileName.H:101
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::IOstream::setf
ios_base::fmtflags setf(const ios_base::fmtflags f)
Set flags of stream.
Definition: IOstream.H:378
Foam::OSstream::precision
virtual int precision() const
Get precision of output field.
Definition: OSstream.C:326
Foam::ensightOutputSurface
A variant of ensightFaces that holds references to contiguous points/faces with its own encapsulated ...
Definition: ensightOutputSurface.H:58
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
Foam::surfaceWriters::writerCaching::times
const scalarList & times() const
The output times for fields.
Definition: surfaceWriterCaching.H:108
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::word::printf
static word printf(const char *fmt, const PrimitiveType &val)
Use a printf-style formatter for a primitive.
timeIndex
label timeIndex
Definition: getTimeIndex.H:30
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
Foam::ensightCase::geometryName
static const char * geometryName
The name for geometry files: "geometry".
Definition: ensightCase.H:80
Foam::isDir
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:643