ensightCoordSetWriter.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-2016 OpenFOAM Foundation
9  Copyright (C) 2021-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 "ensightCoordSetWriter.H"
30 #include "coordSet.H"
31 #include "IOmanip.H"
32 #include "ensightCase.H"
33 #include "ensightGeoFile.H"
34 #include "ensightOutput.H"
35 #include "ensightPTraits.H"
36 #include "coordSetWriterMethods.H"
38 
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
43 namespace coordSetWriters
44 {
45  defineTypeName(ensightWriter);
46  addToRunTimeSelectionTable(coordSetWriter, ensightWriter, word);
47  addToRunTimeSelectionTable(coordSetWriter, ensightWriter, wordDict);
48 }
49 }
50 
51 
52 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
53 
54 namespace Foam
55 {
56 
57 template<class Type>
58 static void writeTrackField
59 (
60  ensightFile& os,
61  const UPtrList<const Field<Type>>& fieldPtrs
62 )
63 {
64  // Write field (serial only)
66  os.newline();
67 
68  forAll(fieldPtrs, tracki)
69  {
70  const Field<Type>& fld = fieldPtrs[tracki];
71 
72  os.beginPart(tracki); // Part index (0-based)
73 
74  // Skip if empty. This check is probably redundant
75  if (fld.empty())
76  {
77  continue;
78  }
79 
80  // Write as coordinates data
82  (
83  os,
85  fld,
86  false /* serial only! */
87  );
88  }
89 }
90 
91 } // End namespace Foam
92 
93 
94 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
95 
96 void Foam::coordSetWriters::ensightWriter::writeGeometry
97 (
98  ensightGeoFile& os,
99  elemOutputType elemOutput
100 ) const
101 {
102  // Writing tracks as x/y/z coordinates, optionally with points
103  // or points/lines as elements.
104  //
105  // The requirements are so basic that they do not warrant an
106  // ensightPart treatment at all.
107 
108  forAll(coords_, tracki)
109  {
110  const auto& coords = coords_[tracki];
111  const label nPoints = coords.size();
112 
113  word partName("track" + Foam::name(tracki));
114  if (coords_.size() == 1 && elemOutputType::WRITE_LINES != elemOutput)
115  {
116  partName = "sampled";
117  }
118 
120  (
121  os,
122  tracki, // Part index (0-based)
123  partName,
124  nPoints,
125  static_cast<const pointField&>(coords),
126  false /* serial only! */
127  );
128 
129  if (elemOutputType::WRITE_POINTS == elemOutput)
130  {
131  if (nPoints)
132  {
133  os.writeKeyword("point");
134  os.write(nPoints);
135  os.newline();
136  for (label pointi = 0; pointi < nPoints; ++pointi)
137  {
138  os.write(pointi+1); // From 0-based to 1-based index
139  os.newline();
140  }
141  }
142  }
143  if (elemOutputType::WRITE_LINES == elemOutput)
144  {
145  const label nLines = (nPoints-1);
146  if (nPoints == 1)
147  {
148  os.writeKeyword("point");
149  os.write(nPoints);
150  os.newline();
151  for (label pointi = 0; pointi < nPoints; ++pointi)
152  {
153  os.write(pointi+1); // From 0-based to 1-based index
154  os.newline();
155  }
156  }
157  else if (nLines > 0)
158  {
159  os.writeKeyword("bar2");
160  os.write(nLines);
161  os.newline();
162  for (label pointi = 0; pointi < nLines; ++pointi)
163  {
164  os.write(pointi+1); // From 0-based to 1-based index
165  os.write(pointi+2);
166  os.newline();
167  }
168  }
169  }
170  }
171 }
172 
173 
174 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
175 
177 :
179  caseOpts_(IOstreamOption::BINARY),
180  collateTimes_(true),
181  caching_("fieldsDict") // Historic name
182 {}
183 
184 
186 :
187  coordSetWriter(options),
188  caseOpts_("format", options, IOstreamOption::BINARY),
189  collateTimes_(options.getOrDefault("collateTimes", true)),
190  caching_("fieldsDict") // Historic name
191 {
192  caseOpts_.timeFormat("timeFormat", options);
193  caseOpts_.timePrecision("timePrecision", options);
194 }
195 
196 
198 (
199  const coordSet& coords,
200  const fileName& outputPath,
201  const dictionary& options
202 )
203 :
204  ensightWriter(options)
205 {
206  open(coords, outputPath);
207 }
208 
209 
211 (
212  const UPtrList<coordSet>& tracks,
213  const fileName& outputPath,
214  const dictionary& options
215 )
216 :
217  ensightWriter(options)
218 {
219  open(tracks, outputPath);
220 }
221 
222 
223 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
224 
226 {
227  close();
228 }
229 
230 
231 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
232 
234 {
235  // Assume collateTimes == true, otherwise too fragile
236 
237  // Collated
238  // ========
239  // CaseFile: rootdir/NAME/NAME.case
240  // Geometry: rootdir/NAME/data/<index>/geometry
241  // Field: rootdir/NAME/data/<index>/field
242 
243  if (!outputPath_.empty())
244  {
245  return outputPath_ / (ensight::FileName(outputPath_.name()) + ".case");
246  }
247 
248  return fileName();
249 }
250 
251 
252 void Foam::coordSetWriters::ensightWriter::close(const bool force)
253 {
254  caching_.clear();
255  coordSetWriter::close(force);
256 }
257 
258 
259 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
260 // Field writing implementations
261 
264 
265 template<class Type>
266 Foam::fileName Foam::coordSetWriters::ensightWriter::writeTemplate
267 (
268  const word& fieldName,
269  const Field<Type>& values
270 )
271 {
272  checkOpen();
273  if (coords_.empty())
274  {
275  return fileName::null;
276  }
277  if (coords_.size() != 1)
278  {
280  << "Attempted to write field: " << fieldName
281  << " (" << 1 << " entries) for "
282  << coords_.size() << " sets" << nl
283  << exit(FatalError);
284  }
285 
286  UPtrList<const Field<Type>> fieldPtrs(repackageFields(values));
287 
288  elemOutputType elemOutput =
289  (
290  useTracks_
291  ? elemOutputType::WRITE_LINES
292  : elemOutputType::NO_ELEMENTS
293  );
294 
295  if (collateTimes_)
296  {
297  return writeCollated(fieldName, fieldPtrs, elemOutput);
298  }
299  else
300  {
301  return writeUncollated(fieldName, fieldPtrs, elemOutput);
302  }
303 }
304 
305 
306 template<class Type>
307 Foam::fileName Foam::coordSetWriters::ensightWriter::writeTemplate
308 (
309  const word& fieldName,
310  const List<Field<Type>>& fieldValues
311 )
312 {
313  checkOpen();
314  if (coords_.empty())
315  {
316  return fileName::null;
317  }
318  if (coords_.size() != fieldValues.size())
319  {
321  << "Attempted to write field: " << fieldName
322  << " (" << fieldValues.size() << " entries) for "
323  << coords_.size() << " sets" << nl
324  << exit(FatalError);
325  }
326 
327  UPtrList<const Field<Type>> fieldPtrs(repackageFields(fieldValues));
328 
329  if (collateTimes_)
330  {
331  return writeCollated
332  (
333  fieldName,
334  fieldPtrs,
335  elemOutputType::WRITE_LINES
336  );
337  }
338  else
339  {
340  return writeUncollated
341  (
342  fieldName,
343  fieldPtrs,
344  elemOutputType::WRITE_LINES
345  );
346  }
347 }
348 
349 
350 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
351 
352 // Field writing methods
354 
355 
356 // ************************************************************************* //
Ensight output with specialized write() for strings, integers and floats. Correctly handles binary wr...
Definition: ensightFile.H:46
addToRunTimeSelectionTable(coordSetWriter, abaqusWriter, word)
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
A class for handling file names.
Definition: fileName.H:72
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
virtual Ostream & write(const char c) override
Write character.
Definition: OBJstream.C:69
Ensight names and component order for base types.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
Specification of a valid Ensight file-name.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
static const fileName null
An empty fileName.
Definition: fileName.H:111
defineTypeName(abaqusWriter)
A simple container for options an IOstream can normally have.
static const char *const coordinates
The keyword "coordinates".
Definition: ensightFile.H:96
Macros for easy insertion into run-time selection tables.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
Convenience macros for instantiating coordSetWriter methods.
Holds list of sampling positions.
Definition: coordSet.H:49
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
void writeFieldComponents(ensightOutput::floatBufferType &scratch, ensightFile &os, const char *key, const FieldContainer< Type > &fld, bool parallel)
Write field content (component-wise) for the given ensight element type.
Generic templated field type.
Definition: Field.H:62
A class for handling words, derived from Foam::string.
Definition: word.H:63
label nPoints
Base class for writing coordSet(s) and tracks with fields.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
Istream and Ostream manipulators taking arguments.
OBJstream os(runTime.globalPath()/outputName)
UPtrList< const coordSet > coords_
Reference to coordinate set(s)
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
defineCoordSetWriterWriteFields(Foam::coordSetWriters::ensightWriter)
virtual void close(bool force=false)
Finish output, clears output times.
static void writeTrackField(ensightFile &os, const UPtrList< const Field< Type >> &fieldPtrs)
virtual void close(bool force=false)
Finish output, performing any necessary cleanup.
virtual fileName path() const
Expected (characteristic) output file name - information only.
virtual ~ensightWriter()
Destructor. Calls close()
Namespace for OpenFOAM.
bool writeCoordinates(ensightGeoFile &os, const label partId, const word &partName, const label nPoints, const FieldContainer< Foam::point > &fld, bool parallel)
Write coordinates (component-wise) for the given part.