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 // ************************************************************************* //
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition: word.C:39
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
A line primitive.
Definition: line.H:52
A class for handling file names.
Definition: fileName.H:72
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
Input/output from string buffers.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:63
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
virtual bool read(const fileName &filename)
Read from a file.
Definition: NASedgeFormat.C:38
scalar y
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
const pointField & points
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
patchWriters clear()
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicList.H:584
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:68
DynamicList< T, SizeMin > & shrink()
Calls shrink_to_fit() and returns a reference to the DynamicList.
Definition: DynamicListI.H:447
Input from file stream, using an ISstream.
Definition: IFstream.H:49
vector point
Point is a vector.
Definition: point.H:37
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:412
const pointField & pts