ensightSurfaceWriterUncollated.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-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 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
30 
31 Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated()
32 {
33  checkOpen();
34 
35  const ensight::FileName baseName(outputPath_.name());
36 
37 
38  // Uncollated
39  // ==========
40  // CaseFile: rootdir/<TIME>/NAME.case
41  // Geometry: rootdir/<TIME>/NAME.00000000.mesh
42 
43  fileName outputDir;
44  if (useTimeDir() && !timeName().empty())
45  {
46  // Splice in time-directory
47  outputDir = outputPath_.path() / timeName();
48  }
49  else
50  {
51  outputDir = outputPath_.path();
52  }
53 
54  const fileName outputFile = outputDir / baseName + ".case";
55 
56  if (verbose_)
57  {
58  Info<< "Writing case file to " << outputFile << endl;
59  }
60 
61 
62  // const meshedSurf& surf = surface();
63  const meshedSurfRef& surf = adjustSurface();
64 
65  if (UPstream::master() || !parallel_)
66  {
67  if (!isDir(outputDir))
68  {
69  mkDir(outputDir);
70  }
71 
72  ensightGeoFile osGeom
73  (
74  outputDir,
75  baseName + ".00000000.mesh",
76  caseOpts_.format()
77  );
78 
79  ensightOutputSurface part
80  (
81  surf.points(),
82  surf.faces(),
83  osGeom.name().name()
84  );
85  part.write(osGeom); // serial
86 
87  // Update case file
88  OFstream osCase(outputFile, IOstreamOption::ASCII);
89  ensightCase::setTimeFormat(osCase, caseOpts_); // time-format
90 
91  osCase
92  << "FORMAT" << nl
93  << "type: ensight gold" << nl
94  << nl
95  << "GEOMETRY" << nl
96  << "model: 1 " << osGeom.name().name() << nl
97  << nl
98  << "TIME" << nl;
99 
100  ensightCase::printTimeset(osCase, 1, scalar(0));
101  }
102 
103  wroteGeom_ = true;
104  return outputFile;
105 }
106 
107 
108 template<class Type>
109 Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated
110 (
111  const word& fieldName,
112  const Field<Type>& localValues
113 )
114 {
115  checkOpen();
116 
117  const ensight::FileName baseName(outputPath_.name());
118  const ensight::VarName varName(fieldName);
119 
120 
121  // Uncollated
122  // ==========
123  // CaseFile: rootdir/time/<field>/NAME.case
124  // Geometry: rootdir/time/<field>/NAME.<index>.mesh
125  // Field: rootdir/time/<field>/NAME.<index>.<field>
126 
127  // Variable name as sub-directory for results. Eg,
128  // - VAR1/NAME1.case
129  // - VAR1/NAME1.00000000.mesh
130  // - VAR1/NAME1.00000001.VAR1
131  // and
132  // - VAR2/NAME1.case
133  // - VAR2/NAME1.00000000.mesh
134  // - VAR2/NAME1.00000001.VAR2
135 
136  fileName outputDir;
137  if (useTimeDir() && !timeName().empty())
138  {
139  // Splice in time-directory
140  outputDir = outputPath_.path() / timeName();
141  }
142  else
143  {
144  outputDir = outputPath_.path();
145  }
146 
147  const fileName baseDir = outputDir / varName;
148  const word timeDir = timeName();
149  const scalar timeValue = currTime_.value();
150 
151  const fileName outputFile = baseDir / baseName + ".case";
152 
153  if (verbose_)
154  {
155  Info<< "Writing case file to " << outputFile << nl;
156  }
157 
158  // Implicit geometry merge()
159  tmp<Field<Type>> tfield = adjustField(fieldName, mergeField(localValues));
160 
161  if (verbose_)
162  {
163  Info<< endl;
164  }
165 
166  // const meshedSurf& surf = surface();
167  const meshedSurfRef& surf = adjustSurface();
168 
169  if (UPstream::master() || !parallel_)
170  {
171  if (!isDir(outputFile.path()))
172  {
173  mkDir(outputFile.path());
174  }
175 
176  // Two-argument form for path-name to avoid validating base-dir
177  ensightGeoFile osGeom
178  (
179  baseDir,
180  baseName + ".00000000.mesh",
181  caseOpts_.format()
182  );
183  ensightFile osField
184  (
185  baseDir,
186  baseName + ".00000000." + varName,
187  caseOpts_.format()
188  );
189 
190  // Ensight Geometry
191  ensightOutputSurface part
192  (
193  surf.points(),
194  surf.faces(),
195  osGeom.name().name()
196  );
197  part.write(osGeom); // serial
198 
199  // Write field (serial)
200  osField.write(ensightPTraits<Type>::typeName);
201  osField.newline();
202  part.writeData(osField, tfield(), this->isPointData());
203 
204 
205  // Update case file
206  {
207  OFstream osCase(outputFile, IOstreamOption::ASCII);
208  ensightCase::setTimeFormat(osCase, caseOpts_); // time-format
209 
210  osCase
211  << "FORMAT" << nl
212  << "type: ensight gold" << nl
213  << nl
214  << "GEOMETRY" << nl
215  << "model: 1 " << osGeom.name().name() << nl
216  << nl
217  << "VARIABLE" << nl
219  <<
220  (
221  this->isPointData()
222  ? " per node: 1 " // time-set 1
223  : " per element: 1 " // time-set 1
224  )
225  << setw(15) << varName << ' '
226  << baseName.c_str() << ".********."
227  << ensight::FileName(varName).c_str() << nl;
228 
229  osCase
230  << nl
231  << "TIME" << nl;
232 
233  ensightCase::printTimeset(osCase, 1, timeValue);
234  osCase << "# end" << nl;
235  }
236  }
237 
238  wroteGeom_ = true;
239  return outputFile;
240 }
241 
242 
243 // ************************************************************************* //
static void printTimeset(OSstream &os, const label ts, const scalar timeValue)
Print time-set for ensight case file with a single time.
Definition: ensightCase.C:91
A class for handling file names.
Definition: fileName.H:72
static void setTimeFormat(OSstream &os, IOstreamOption::floatFormat timeFmt, const int timePrec)
Set output time format for ensight case file.
Definition: ensightCase.C:53
IOstreamOption::streamFormat format() const noexcept
The output file format (ascii/binary)
Definition: ensightCase.H:613
Specification of a valid Ensight file-name.
void checkOpen() const
Verify that the outputPath_ has been set or FatalError.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
"ascii" (normal default)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
const meshedSurfRef & adjustSurface() const
Merge surfaces (if not upToDate) and return merged (parallel) or regular surface (non-parallel) and a...
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:169
bool parallel_
Writing in parallel (via master)
bool wroteGeom_
Track if geometry has been written since the last open.
const word & timeName() const
The current time value/name.
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:860
word timeName
Definition: getTimeIndex.H:3
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:614
Generic templated field type.
Definition: Field.H:62
A class for handling words, derived from Foam::string.
Definition: word.H:63
const char *const typeName
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:192
Specification of a valid Ensight variable-name.
bool useTimeDir() const noexcept
Should a time directory be spliced into the output path?
fileName outputPath_
The full output directory and file (surface) name.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
messageStream Info
Information stream (stdout output on master, null elsewhere)
bool verbose_
Additional output verbosity.
Omanip< int > setw(const int i)
Definition: IOmanip.H:199