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-2022 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 (Pstream::master() || !parallel_)
66  {
67  if (!isDir(outputDir))
68  {
69  mkDir(outputDir);
70  }
71 
72  ensightGeoFile osGeom
73  (
74  outputDir,
75  baseName + ".00000000.mesh",
76  writeFormat_
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);
89  osCase
90  << "FORMAT" << nl
91  << "type: ensight gold" << nl
92  << nl
93  << "GEOMETRY" << nl
94  << "model: 1 " << osGeom.name().name() << nl
95  << nl
96  << "TIME" << nl;
97 
98  ensightCase::printTimeset(osCase, 1, scalar(0));
99  }
100 
101  wroteGeom_ = true;
102  return outputFile;
103 }
104 
105 
106 template<class Type>
107 Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated
108 (
109  const word& fieldName,
110  const Field<Type>& localValues
111 )
112 {
113  checkOpen();
114 
115  const ensight::FileName baseName(outputPath_.name());
116  const ensight::VarName varName(fieldName);
117 
118 
119  // Uncollated
120  // ==========
121  // CaseFile: rootdir/time/<field>/NAME.case
122  // Geometry: rootdir/time/<field>/NAME.<index>.mesh
123  // Field: rootdir/time/<field>/NAME.<index>.<field>
124 
125  // Variable name as sub-directory for results. Eg,
126  // - VAR1/NAME1.case
127  // - VAR1/NAME1.00000000.mesh
128  // - VAR1/NAME1.00000001.VAR1
129  // and
130  // - VAR2/NAME1.case
131  // - VAR2/NAME1.00000000.mesh
132  // - VAR2/NAME1.00000001.VAR2
133 
134  fileName outputDir;
135  if (useTimeDir() && !timeName().empty())
136  {
137  // Splice in time-directory
138  outputDir = outputPath_.path() / timeName();
139  }
140  else
141  {
142  outputDir = outputPath_.path();
143  }
144 
145  const fileName baseDir = outputDir / varName;
146  const word timeDir = timeName();
147  const scalar timeValue = currTime_.value();
148 
149  const fileName outputFile = baseDir / baseName + ".case";
150 
151  if (verbose_)
152  {
153  Info<< "Writing case file to " << outputFile << nl;
154  }
155 
156  // Implicit geometry merge()
157  tmp<Field<Type>> tfield = adjustField(fieldName, mergeField(localValues));
158 
159  if (verbose_)
160  {
161  Info<< endl;
162  }
163 
164  // const meshedSurf& surf = surface();
165  const meshedSurfRef& surf = adjustSurface();
166 
167  if (Pstream::master() || !parallel_)
168  {
169  if (!isDir(outputFile.path()))
170  {
171  mkDir(outputFile.path());
172  }
173 
174  // Two-argument form for path-name to avoid validating base-dir
175  ensightGeoFile osGeom
176  (
177  baseDir,
178  baseName + ".00000000.mesh",
179  writeFormat_
180  );
181  ensightFile osField
182  (
183  baseDir,
184  baseName + ".00000000." + varName,
185  writeFormat_
186  );
187 
188  // Ensight Geometry
189  ensightOutputSurface part
190  (
191  surf.points(),
192  surf.faces(),
193  osGeom.name().name()
194  );
195  part.write(osGeom); // serial
196 
197  // Write field (serial)
198  osField.write(ensightPTraits<Type>::typeName);
199  osField.newline();
200  part.writeData(osField, tfield(), this->isPointData());
201 
202 
203  // Update case file
204  {
205  OFstream osCase(outputFile, IOstreamOption::ASCII);
206 
207  // Format options
208  osCase.setf(ios_base::left);
209  osCase.setf(ios_base::scientific, ios_base::floatfield);
210  osCase.precision(5);
211 
212  osCase
213  << "FORMAT" << nl
214  << "type: ensight gold" << nl
215  << nl
216  << "GEOMETRY" << nl
217  << "model: 1 " << osGeom.name().name() << nl
218  << nl
219  << "VARIABLE" << nl
221  <<
222  (
223  this->isPointData()
224  ? " per node: 1 " // time-set 1
225  : " per element: 1 " // time-set 1
226  )
227  << setw(15) << varName << ' '
228  << baseName.c_str() << ".********."
229  << ensight::FileName(varName).c_str() << nl;
230 
231  osCase
232  << nl
233  << "TIME" << nl;
234 
235  ensightCase::printTimeset(osCase, 1, timeValue);
236  osCase << "# end" << nl;
237  }
238  }
239 
240  wroteGeom_ = true;
241  return outputFile;
242 }
243 
244 
245 // ************************************************************************* //
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:53
A class for handling file names.
Definition: fileName.H:71
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:49
"ascii" (normal default)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
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:1037
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
IOstream & scientific(IOstream &io)
Definition: IOstream.H:563