NASedgeFormat.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-2017 OpenFOAM Foundation
9  Copyright (C) 2017 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 "NASedgeFormat.H"
30 #include "IFstream.H"
31 #include "StringStream.H"
32 #include "bitSet.H"
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
36 Foam::fileFormats::NASedgeFormat::NASedgeFormat(const fileName& filename)
37 {
38  read(filename);
39 }
40 
41 
42 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
43 
45 (
46  const fileName& filename
47 )
48 {
49  clear();
50 
51  IFstream is(filename);
52  if (!is.good())
53  {
55  << "Cannot read file " << filename
56  << exit(FatalError);
57  }
58 
59  DynamicList<point> dynPoints;
60  DynamicList<edge> dynEdges;
61  DynamicList<label> pointId; // Nastran index of points
62 
63  while (is.good())
64  {
65  string::size_type linei = 0; // parsing position within current line
66  string line;
67  is.getLine(line);
68 
69  if (line.empty() || line[0] == '$')
70  {
71  continue; // Skip empty or comment
72  }
73 
74  // Check if character 72 is continuation
75  if (line.size() > 72 && line[72] == '+')
76  {
77  line.resize(72);
78 
79  while (true)
80  {
81  string buf;
82  is.getLine(buf);
83 
84  if (buf.size() > 72 && buf[72] == '+')
85  {
86  line += buf.substr(8, 64);
87  }
88  else
89  {
90  line += buf.substr(8);
91  break;
92  }
93  }
94  }
95 
96 
97  // First word (column 0-8)
98  const word cmd(word::validate(nextNasField(line, linei, 8)));
99 
100  if (cmd == "CBEAM" || cmd == "CROD")
101  {
102  // discard elementId (8-16)
103  (void) nextNasField(line, linei, 8); // 8-16
104  // discard groupId (16-24)
105  (void) nextNasField(line, linei, 8); // 16-24
106 
107  label a = readLabel(nextNasField(line, linei, 8)); // 24-32
108  label b = readLabel(nextNasField(line, linei, 8)); // 32-40
109 
110  dynEdges.append(edge(a,b));
111  }
112  else if (cmd == "PLOTEL")
113  {
114  // discard elementId (8-16)
115  (void) nextNasField(line, linei, 8); // 8-16
116 
117  label a = readLabel(nextNasField(line, linei, 8)); // 16-24
118  label b = readLabel(nextNasField(line, linei, 8)); // 24-32
119 
120  dynEdges.append(edge(a,b));
121  }
122  else if (cmd == "GRID")
123  {
124  label index = readLabel(nextNasField(line, linei, 8)); // 8-16
125  (void) nextNasField(line, linei, 8); // 16-24
126  scalar x = readNasScalar(nextNasField(line, linei, 8)); // 24-32
127  scalar y = readNasScalar(nextNasField(line, linei, 8)); // 32-40
128  scalar z = readNasScalar(nextNasField(line, linei, 8)); // 40-48
129 
130  pointId.append(index);
131  dynPoints.append(point(x, y, z));
132  }
133  else if (cmd == "GRID*")
134  {
135  // Long format is on two lines with '*' continuation symbol
136  // on start of second line.
137  // Typical line (spaces compacted)
138  // GRID* 126 0 -5.55999875E+02 -5.68730474E+02
139  // * 2.14897901E+02
140 
141  label index = readLabel(nextNasField(line, linei, 16)); // 8-24
142  (void) nextNasField(line, linei, 16); // 24-40
143  scalar x = readNasScalar(nextNasField(line, linei, 16)); // 40-56
144  scalar y = readNasScalar(nextNasField(line, linei, 16)); // 56-72
145 
146  linei = 0; // restart at index 0
147  is.getLine(line);
148  if (line[0] != '*')
149  {
151  << "Expected continuation symbol '*' when reading GRID*"
152  << " (double precision coordinate) format" << nl
153  << "Read:" << line << nl
154  << "File:" << is.name() << " line:" << is.lineNumber()
155  << exit(FatalError);
156  }
157  (void) nextNasField(line, linei, 8); // 0-8
158  scalar z = readNasScalar(nextNasField(line, linei, 16)); // 8-16
159 
160  pointId.append(index);
161  dynPoints.append(point(x, y, z));
162  }
163  }
164 
165  // transfer to normal lists
166  storedPoints().transfer(dynPoints);
167 
168  pointId.shrink();
169  dynEdges.shrink();
170 
171  // Build inverse mapping (NASTRAN pointId -> index)
172  Map<label> mapPointId(2*pointId.size());
173  forAll(pointId, i)
174  {
175  mapPointId.insert(pointId[i], i);
176  }
177 
178  // note which points were really used and which can be culled
179  bitSet usedPoints(points().size());
180 
181 
182  // Pass1: relabel edges
183  // ~~~~~~~~~~~~~~~~~~~~
184  for (edge& e : dynEdges)
185  {
186  e[0] = mapPointId[e[0]];
187  e[1] = mapPointId[e[1]];
188 
189  usedPoints.set(e[0]);
190  usedPoints.set(e[1]);
191  }
192  pointId.clearStorage();
193  mapPointId.clear();
194 
195  // Not all points were used, subset/cull them accordingly
196  if (!usedPoints.all())
197  {
198  label nUsed = 0;
199 
200  pointField& pts = storedPoints();
201  for (const label pointi : usedPoints)
202  {
203  if (nUsed != pointi)
204  {
205  pts[nUsed] = pts[pointi];
206  }
207 
208  // map prev -> new id
209  mapPointId.set(pointi, nUsed);
210 
211  ++nUsed;
212  }
213  pts.resize(nUsed);
214 
215  // Renumber edge vertices
216  for (edge& e : dynEdges)
217  {
218  e[0] = mapPointId[e[0]];
219  e[1] = mapPointId[e[1]];
220  }
221  }
222 
223  storedEdges().transfer(dynEdges);
224 
225  return true;
226 }
227 
228 
229 // ************************************************************************* //
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::ISstream::getLine
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:76
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::bitSet::all
bool all() const
True if all bits in this bitset are set or if the set is empty.
Definition: bitSetI.H:460
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:53
Foam::DynamicList< point >
Foam::IFstream::name
virtual const fileName & name() const
Read/write access to the name of the stream.
Definition: ISstream.H:113
NASedgeFormat.H
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::bitSet::set
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:574
Foam::Map< label >
Foam::word::validate
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition: word.C:45
Foam::IOstream::lineNumber
label lineNumber() const noexcept
Const access to the current stream line number.
Definition: IOstream.H:318
StringStream.H
Input/output from string buffers.
Foam::DynamicList::shrink
DynamicList< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:434
bitSet.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::Field< vector >
Foam::fileFormats::NASedgeFormat::read
virtual bool read(const fileName &filename)
Read from a file.
Definition: NASedgeFormat.C:45
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:76
IFstream.H
Foam::FatalError
error FatalError
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::readLabel
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::DynamicList::clearStorage
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:398
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::line
A line primitive.
Definition: line.H:53
Foam::point
vector point
Point is a vector.
Definition: point.H:43
y
scalar y
Definition: LISASMDCalcMethod1.H:14