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-------------------------------------------------------------------------------
11License
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
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// ************************************************************************* //
scalar y
Input/output from string buffers.
label size_type
The type to represent the size of a buffer.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
DynamicList< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:434
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:503
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:398
bool set(const Key &key, const T &obj)
Copy assign a new entry, overwriting existing entries.
Definition: HashTableI.H:202
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:180
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
Definition: HashTable.C:719
void clear()
Clear all entries from table.
Definition: HashTable.C:678
Input from file stream, using an ISstream.
Definition: IFstream.H:57
virtual const fileName & name() const
Read/write access to the name of the stream.
Definition: ISstream.H:113
label lineNumber() const noexcept
Const access to the current stream line number.
Definition: IOstream.H:318
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:76
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
virtual bool read()
Re-read model coefficients if they have changed.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:66
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:590
bool all() const
True if all bits in this bitset are set or if the set is empty.
Definition: bitSetI.H:461
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:66
virtual bool read(const fileName &filename)
Read from a file.
Definition: NASedgeFormat.C:45
A class for handling file names.
Definition: fileName.H:76
virtual void validate()
Validate the turbulence fields after construction.
Definition: kkLOmega.C:597
A line primitive.
Definition: line.H:68
A class for handling words, derived from Foam::string.
Definition: word.H:68
patchWriters clear()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
const pointField & points
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
vector point
Point is a vector.
Definition: point.H:43
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
volScalarField & b
Definition: createFields.H:27
volScalarField & e
Definition: createFields.H:11
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333