nastranSurfaceWriterImpl.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) 2012-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2019 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 "OFstream.H"
30 #include "IOmanip.H"
31 #include "OSspecific.H"
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 template<class Type>
36 Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeValue
37 (
38  Ostream& os,
39  const Type& value
40 ) const
41 {
42  switch (writeFormat_)
43  {
44  case fieldFormat::SHORT :
45  {
46  os << setw(8) << value;
47  break;
48  }
49 
50  case fieldFormat::LONG :
51  {
52  os << setw(16) << value;
53  break;
54  }
55 
56  case fieldFormat::FREE :
57  {
58  os << value;
59  break;
60  }
61  }
62 
63  return os;
64 }
65 
66 
67 template<class Type>
68 Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFaceValue
69 (
70  Ostream& os,
71  const loadFormat format,
72  const Type& value,
73  const label EID
74 ) const
75 {
76  // Fixed short/long formats supporting PLOAD2 and PLOAD4:
77 
78  // PLOAD2:
79  // 1 descriptor : PLOAD2
80  // 2 SID : load set ID
81  // 3 data value : load value - MUST be singular
82  // 4 EID : element ID
83 
84  // PLOAD4:
85  // 1 descriptor : PLOAD4
86  // 2 SID : load set ID
87  // 3 EID : element ID
88  // 4 onwards : load values
89 
90  label SID = 1;
91 
92  Type scaledValue = scale_*value;
93 
94  // Write keyword
95  writeKeyword(os, fileFormats::NASCore::loadFormatNames[format])
96  << separator_;
97 
98  // Write load set ID
99  os.setf(std::ios_base::right);
100 
101  writeValue(os, SID) << separator_;
102 
103  switch (format)
104  {
105  case loadFormat::PLOAD2 :
106  {
108  {
109  writeValue(os, scaledValue) << separator_;
110  }
111  else
112  {
114  << fileFormats::NASCore::loadFormatNames[format]
115  << " requires scalar values"
116  << " - it cannot be used for higher rank values"
117  << endl;
118 
119  writeValue(os, scalar(0)) << separator_;
120  }
121 
122  writeValue(os, EID);
123  break;
124  }
125 
126  case loadFormat::PLOAD4 :
127  {
128  writeValue(os, EID);
129 
130  for (direction d = 0; d < pTraits<Type>::nComponents; ++d)
131  {
132  os << separator_;
133  writeValue(os, component(scaledValue, d));
134  }
135  break;
136  }
137  }
138 
139  os.unsetf(std::ios_base::right);
140 
141  os << nl;
142 
143  return os;
144 }
145 
146 
147 template<class Type>
148 Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
149 (
150  const word& fieldName,
151  const Field<Type>& localValues
152 )
153 {
154  checkOpen();
155 
156  if (!fieldMap_.found(fieldName))
157  {
159  << "No mapping found between field " << fieldName
160  << " and corresponding Nastran field. Available types are:"
161  << fieldMap_
162  << exit(FatalError);
163 
164  return fileName::null;
165  }
166 
167  const loadFormat& format(fieldMap_[fieldName]);
168 
169  // Field: rootdir/<TIME>/field/surfaceName.nas
170 
171  fileName outputFile = outputPath_.path();
172  if (useTimeDir() && !timeName().empty())
173  {
174  // Splice in time-directory
175  outputFile /= timeName();
176  }
177  outputFile /= fieldName / outputPath_.name();
178  outputFile.ext("nas");
179 
180  if (verbose_)
181  {
182  Info<< "Writing field " << fieldName << " to " << outputFile << endl;
183  }
184 
185 
186  // geometry merge() implicit
187  tmp<Field<Type>> tfield = mergeField(localValues);
188 
189  const meshedSurf& surf = surface();
190 
191  if (Pstream::master() || !parallel_)
192  {
193  const auto& values = tfield();
194 
195  if (!isDir(outputFile.path()))
196  {
197  mkDir(outputFile.path());
198  }
199 
200  const scalar timeValue = 0.0;
201 
202  OFstream os(outputFile);
203  fileFormats::NASCore::setPrecision(os, writeFormat_);
204 
205  if (verbose_)
206  {
207  Info<< "Writing nastran file to " << os.name() << endl;
208  }
209 
210  os << "TITLE=OpenFOAM " << outputFile.name()
211  << " " << fieldName << " data" << nl
212  << "$" << nl
213  << "TIME " << timeValue << nl
214  << "$" << nl
215  << "BEGIN BULK" << nl;
216 
217  List<DynamicList<face>> decomposedFaces;
218  writeGeometry(os, surf, decomposedFaces);
219 
220  os << "$" << nl
221  << "$ Field data" << nl
222  << "$" << nl;
223 
224  label elemId = 0;
225 
226  if (this->isPointData())
227  {
228  for (const DynamicList<face>& dFaces : decomposedFaces)
229  {
230  for (const face& f : dFaces)
231  {
232  Type v = Zero;
233 
234  for (const label verti : f)
235  {
236  v += values[verti];
237  }
238  v /= f.size();
239 
240  writeFaceValue(os, format, v, ++elemId);
241  }
242  }
243  }
244  else
245  {
246  for (const DynamicList<face>& dFaces : decomposedFaces)
247  {
248  forAll(dFaces, facei)
249  {
250  writeFaceValue(os, format, values[facei], ++elemId);
251  }
252  }
253  }
254 
255  writeFooter(os, surf)
256  << "ENDDATA" << endl;
257  }
258 
259  wroteGeom_ = true;
260  return outputFile;
261 }
262 
263 
264 // ************************************************************************* //
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::component
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
Definition: FieldFieldFunctions.C:44
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::OFstream::name
virtual const fileName & name() const
Read/write access to the name of the stream.
Definition: OSstream.H:91
Foam::fileName::path
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:186
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:57
Foam::HashTableOps::values
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:149
Foam::fileName::name
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:209
Foam::meshedSurf
Abstract definition of a meshed surface defined by faces and points.
Definition: meshedSurf.H:49
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
OFstream.H
format
word format(conversionProperties.get< word >("format"))
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
IOmanip.H
Istream and Ostream manipulators taking arguments.
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::FatalError
error FatalError
Foam::fileName::ext
word ext() const
Return file name extension (part after last .)
Definition: fileNameI.H:228
Foam::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:99
Foam::IOstream::setf
ios_base::fmtflags setf(const ios_base::fmtflags f)
Set flags of stream.
Definition: IOstream.H:361
Foam::fileFormats::NASCore::loadFormat
loadFormat
Output load format.
Definition: NASCore.H:74
Foam::IOstream::unsetf
void unsetf(const ios_base::fmtflags f)
Unset flags of stream.
Definition: IOstream.H:377
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::nl
constexpr char nl
Definition: Ostream.H:372
f
labelList f(nPoints)
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::pTraits
Traits class for primitives.
Definition: pTraits.H:52
Foam::direction
uint8_t direction
Definition: direction.H:47
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:74
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
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
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:294
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