abaqusCoordSetWriter.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) 2023 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "abaqusCoordSetWriter.H"
29 #include "coordSet.H"
30 #include "IOmanip.H"
31 #include "OFstream.H"
32 #include "OSspecific.H"
33 #include "stringOps.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 namespace coordSetWriters
42 {
46 }
47 }
48 
50 Foam::coordSetWriters::abaqusWriter::timeBaseNames_
51 ({
52  { timeBase::time, "time" },
53  { timeBase::iter, "iteration" },
54 });
55 
56 
57 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
58 
59 namespace Foam
60 {
61 template<class Type>
62 static inline void putValue(Ostream& os, const Type& value, const int width)
63 {
64  if (width) os << setw(width);
65  os << value;
66 }
67 }
68 
69 
70 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
71 
72 Foam::string Foam::coordSetWriters::abaqusWriter::replaceUserEntries
73 (
74  const string& str,
75  const dictionary& vars
76 ) const
77 {
78  string result = str;
79 
80  const bool allowEnv = true;
81  const bool allowEmpty = false;
82 
83  stringOps::inplaceExpand(result, vars, allowEnv, allowEmpty);
84 
85  return result;
86 }
87 
88 
89 void Foam::coordSetWriters::abaqusWriter::appendTimeName
90 (
91  const word& fieldName,
92  fileName& fName
93 ) const
94 {
95  if (useTimeDir())
96  {
97  return;
98  }
99 
100  switch (timeBase_)
101  {
102  case timeBase::time:
103  {
104  fName.ext(timeName());
105  break;
106  }
107  case timeBase::iter:
108  {
109  fName.ext(Foam::name(writeIndex_[fieldName]));
110  break;
111  }
112  default:
113  {
115  << "Unhandled enumeration " << timeBaseNames_[timeBase_]
116  << ". Available options: " << timeBaseNames_.sortedToc()
117  << abort(FatalError);
118  }
119  }
120 }
121 
122 
123 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
124 
126 :
127  coordSetWriter(),
128  outputHeader_(),
129  writeGeometry_(false),
130  nullValue_(pTraits<scalar>::min),
131  useLocalTimeDir_(coordSetWriter::useTimeDir()),
132  timeBase_(timeBase::time),
133  writeIndex_(0)
134 {}
135 
136 
138 :
139  coordSetWriter(options),
140  outputHeader_(),
141  writeGeometry_(false),
142  nullValue_(pTraits<scalar>::min),
143  useLocalTimeDir_(coordSetWriter::useTimeDir()),
144  timeBase_(timeBase::time),
145  writeIndex_(0)
146 {
147  options.readIfPresent("header", outputHeader_);
148 
149  options.readIfPresent("useTimeDir", useLocalTimeDir_);
150 
151  if (!useLocalTimeDir_)
152  {
153  timeBaseNames_.readIfPresent("timeBase", options, timeBase_);
154  options.readIfPresent("writeIndex", writeIndex_);
155  }
156 
157  options.readIfPresent("writeGeometry", writeGeometry_);
158 
159  options.readIfPresent("nullValue", nullValue_);
160 }
161 
162 
164 (
165  const coordSet& coords,
166  const fileName& outputPath,
167  const dictionary& options
168 )
169 :
170  abaqusWriter(options)
171 {
172  open(coords, outputPath);
173 }
174 
175 
177 (
178  const UPtrList<coordSet>& tracks,
179  const fileName& outputPath,
180  const dictionary& options
181 )
182 :
183  abaqusWriter(options)
184 {
185  open(tracks, outputPath);
186 }
187 
188 
189 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
190 
192 {
193  close();
194 }
195 
196 
197 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
198 
200 {
201  // 1) rootdir/<TIME>/setName.{inp}
202  // 2) rootdir/setName.{inp}
203 
204  return getExpectedPath("inp");
205 }
206 
207 
208 void Foam::coordSetWriters::abaqusWriter::writeGeometry
209 (
210  Ostream& os,
211  label nTracks
212 ) const
213 {
214  if (!writeGeometry_ || coords_.empty())
215  {
216  return;
217  }
218 
219  os << "** Geometry" << nl
220  << "**" << nl
221  << "** Points" << nl
222  << "**" << nl;
223 
224  // Write points
225  label globalPointi = 1;
226  for (const coordSet& coords : coords_)
227  {
228  for (const point& p : coords)
229  {
230  const point tp = p*geometryScale_;
231 
232  os << globalPointi << ", "
233  << tp[0] << ", " << tp[1] << ", " << tp[2] << nl;
234 
235  ++globalPointi;
236  }
237  }
238 
239  if (nTracks)
240  {
242  << "Tracks not implemented for " << typeName << endl;
243  }
245  wroteGeom_ = true;
246 }
247 
248 
249 template<class Type>
250 Foam::fileName Foam::coordSetWriters::abaqusWriter::writeTemplate
251 (
252  const word& fieldName,
253  const Field<Type>& values
254 )
255 {
256  // useTimeDir(options.getOrDefault("useTimeDir", true));
257  useTimeDir(useLocalTimeDir_);
258 
259  // Note - invalid samples are set to pTraits<Type>::max in sampledSetsImpl.C
260 
261  checkOpen();
262  if (coords_.empty())
263  {
264  return fileName::null;
265  }
266 
267  fileName outputFile = path();
268 
269  if (!wroteGeom_)
270  {
271  if (!writeIndex_.insert(fieldName, 0))
272  {
273  ++writeIndex_[fieldName];
274  }
275 
276  if (!isDir(outputFile.path()))
277  {
278  mkDir(outputFile.path());
279  }
280 
281  if (writeGeometry_)
282  {
283  const word geomName("geometry");
284  if (!writeIndex_.insert(geomName, 0))
285  {
286  ++writeIndex_[geomName];
287  }
288 
289  fileName geomFileName(outputFile.lessExt() + ".inp");
290 
291  appendTimeName("geometry", geomFileName);
292 
293  if (verbose_)
294  {
295  Info<< "Writing abaqus geometry to " << geomFileName << endl;
296  }
297 
298  OFstream osGeom(geomFileName);
299 
300  writeGeometry(osGeom, (useTracks_ ? coords_.size() : 0));
301  }
302 
303  fileName fieldFileName(outputFile.lessExt() + ".inp_" + fieldName);
304  appendTimeName(fieldName, fieldFileName);
305 
306  if (verbose_)
307  {
308  Info<< "Writing field data to " << fieldFileName << endl;
309  }
310 
311  OFstream os(fieldFileName);
312 
313  if (!outputHeader_.empty())
314  {
315  dictionary vars;
316  vars.add("TIME", timeName());
317  vars.add("FIELD_NAME", fieldName);
318  vars.add("FILE_NAME", fieldFileName);
319 
320  for (const auto& s : outputHeader_)
321  {
322  os << replaceUserEntries(s, vars).c_str() << nl;
323  }
324  }
325  else
326  {
327  os << "** OpenFOAM " << fieldFileName.nameLessExt() << nl
328  << "** Project " << outputFile << nl
329  << "** Field=" << fieldName << " Time=" << timeName() << nl;
330  }
331 
332  tmp<Field<Type>> tfield(values);
333  tfield = adjustFieldTemplate(fieldName, tfield);
334  const auto& field = tfield();
335 
336  forAll(field, samplei)
337  {
338  os << (samplei+1);
339  for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; ++cmpt)
340  {
341  // Work-around to set null values - set to pTraits<Type>::max
342  // by default
343  scalar s = component(field[samplei], cmpt);
344  if (s > 0.5*pTraits<scalar>::max)
345  {
346  s = nullValue_;
347  }
348 
349  os << ", " << s;
350  }
351  os << nl;
352  }
353  }
355  return outputFile;
356 }
357 
358 
359 template<class Type>
360 Foam::fileName Foam::coordSetWriters::abaqusWriter::writeTemplate
361 (
362  const word& fieldName,
363  const List<Field<Type>>& fieldValues
364 )
365 {
366  // Track writing
367 
368  checkOpen();
369  if (coords_.empty())
370  {
371  return fileName::null;
372  }
373 
374  fileName outputFile = path();
375 
376  if (!wroteGeom_)
377  {
378  if (verbose_)
379  {
380  Info<< "Writing abaqus geometry to " << outputFile << endl;
381  }
382 
383  if (!isDir(outputFile.path()))
384  {
385  mkDir(outputFile.path());
386  }
387 
388  OFstream osGeom(outputFile.lessExt() + "." + fieldName + ".inp");
389 
390  osGeom
391  << "** Geometry" << nl
392  << "**" << nl
393  << "** Points" << nl
394  << "**" << nl;
395 
396  writeGeometry(osGeom, coords_.size());
397  }
398 
399  return outputFile;
400 }
401 
402 
403 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
404 
405 // Field writing methods
407 
408 
409 // ************************************************************************* //
addToRunTimeSelectionTable(coordSetWriter, abaqusWriter, word)
rDeltaTY field()
uint8_t direction
Definition: direction.H:46
A class for handling file names.
Definition: fileName.H:72
writer writeGeometry()
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
virtual fileName path() const
Characteristic output file name - information only.
bool readIfPresent(const word &key, const dictionary &dict, EnumType &val, const bool warnOnly=false) const
Find an entry if present, and assign to T val.
Definition: EnumI.H:111
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
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
A traits class, which is primarily used for primitives and vector-space.
Definition: pTraits.H:75
defineTypeName(abaqusWriter)
Write coordSet(s) as Abaqus point fields.
::Foam::direction nComponents(const expressions::valueTypeCode) noexcept
The number of components associated with given valueTypeCode.
Definition: exprTraits.C:40
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:169
Macros for easy insertion into run-time selection tables.
static void putValue(Ostream &os, const Type &value, const int width)
Definition: NASCore.C:71
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:860
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
word timeName
Definition: getTimeIndex.H:3
Convenience macros for instantiating coordSetWriter methods.
Holds list of sampling positions.
Definition: coordSet.H:49
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
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
Generic templated field type.
Definition: Field.H:62
A class for handling words, derived from Foam::string.
Definition: word.H:63
Base class for writing coordSet(s) and tracks with fields.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
errorManip< error > abort(error &err)
Definition: errorManip.H:139
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
void inplaceExpand(std::string &s, const HashTable< string > &mapping, const char sigil='$')
Inplace expand occurrences of variables according to the mapping. Does not use environment values...
Definition: stringOps.C:718
Istream and Ostream manipulators taking arguments.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
OBJstream os(runTime.globalPath()/outputName)
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
defineCoordSetWriterWriteFields(Foam::coordSetWriters::abaqusWriter)
vector point
Point is a vector.
Definition: point.H:37
#define WarningInFunction
Report a warning using Foam::Warning.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: error.H:64
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileNameI.H:238
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual ~abaqusWriter()
Destructor. Calls close()
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
volScalarField & p
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;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
A class for handling character strings derived from std::string.
Definition: string.H:72
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
Namespace for OpenFOAM.