GTSsurfaceFormat.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-2016 OpenFOAM Foundation
9  Copyright (C) 2016-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 "GTSsurfaceFormat.H"
30 #include "surfaceFormatsCore.H"
31 #include "clock.H"
32 #include "Fstream.H"
33 #include "StringStream.H"
34 #include "faceTraits.H"
35 
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 
38 template<class Face>
40 (
41  const UList<Face>& faceLst
42 )
43 {
44  label nNonTris = 0;
45 
46  if (!faceTraits<Face>::isTri())
47  {
48  for (const auto& f : faceLst)
49  {
50  if (f.size() != 3)
51  {
52  ++nNonTris;
53  }
54  }
55  }
56 
57  if (nNonTris)
58  {
60  << "Surface has " << nNonTris << "/" << faceLst.size()
61  << " non-triangulated faces - not writing!" << endl;
62  }
63 
64  return nNonTris == 0;
65 }
66 
67 
68 
69 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
70 
71 template<class Face>
73 (
74  const fileName& filename
75 )
76 {
77  read(filename);
78 }
79 
80 
81 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
82 
83 template<class Face>
85 (
86  const fileName& filename
87 )
88 {
89  this->clear();
90 
91  IFstream is(filename);
92  if (!is.good())
93  {
95  << "Cannot read file " << filename
96  << exit(FatalError);
97  }
98 
99  // Read header
100  string line = this->getLineNoComment(is);
101 
102  label nPoints, nEdges, nElems;
103  {
104  IStringStream lineStream(line);
105  lineStream
106  >> nPoints
107  >> nEdges
108  >> nElems;
109  }
110 
111 
112  // write directly into the lists:
113  pointField& pointLst = this->storedPoints();
114  List<Face>& faceLst = this->storedFaces();
115  List<label>& zoneIds = this->storedZoneIds();
116 
117  pointLst.setSize(nPoints);
118  faceLst.setSize(nElems);
119  zoneIds.setSize(nElems);
120 
121  // Read points
122  forAll(pointLst, pointi)
123  {
124  scalar x, y, z;
125  line = this->getLineNoComment(is);
126  {
127  IStringStream lineStream(line);
128  lineStream
129  >> x >> y >> z;
130  }
131 
132  pointLst[pointi] = point(x, y, z);
133  }
134 
135  // Read edges (OpenFOAM indexing)
136  edgeList edges(nEdges);
137  forAll(edges, edgei)
138  {
139  label beg, end;
140  line = this->getLineNoComment(is);
141  {
142  IStringStream lineStream(line);
143  lineStream
144  >> beg >> end;
145  }
146  edges[edgei] = edge(beg - 1, end - 1);
147  }
148 
149 
150  // Read triangles. Convert references to edges into pointlabels
151  label maxZone = 0;
152  forAll(faceLst, facei)
153  {
154  label e0Label, e1Label, e2Label;
155  label zoneI = 0;
156 
157  line = this->getLineNoComment(is);
158  {
159  IStringStream lineStream(line);
160  lineStream
161  >> e0Label >> e1Label >> e2Label;
162 
163  // Optional zone number: read first, then check state on stream
164  if (lineStream)
165  {
166  label num;
167  lineStream >> num;
168  if (!lineStream.bad())
169  {
170  zoneI = num;
171  if (maxZone < zoneI)
172  {
173  maxZone = zoneI;
174  }
175  }
176  }
177  }
178 
179  // Determine ordering of edges e0, e1
180  // common: common vertex, shared by e0 and e1
181  // e0Far: vertex on e0 which is not common
182  // e1Far: vertex on e1 which is not common
183  const edge& e0 = edges[e0Label - 1];
184  const edge& e1 = edges[e1Label - 1];
185  const edge& e2 = edges[e2Label - 1];
186 
187  label common01 = e0.commonVertex(e1);
188  if (common01 == -1)
189  {
191  << "Edges 0 and 1 of triangle " << facei
192  << " do not share a point.\n"
193  << " edge0:" << e0 << nl
194  << " edge1:" << e1
195  << exit(FatalError);
196  }
197 
198  const label e0Far = e0.otherVertex(common01);
199  const label e1Far = e1.otherVertex(common01);
200 
201  const label common12 = e1.commonVertex(e2);
202  if (common12 == -1)
203  {
205  << "Edges 1 and 2 of triangle " << facei
206  << " do not share a point.\n"
207  << " edge1:" << e1 << nl
208  << " edge2:" << e2
209  << exit(FatalError);
210  }
211  const label e2Far = e2.otherVertex(common12);
212 
213  // Does edge2 sit between edge1 and 0?
214  if (common12 != e1Far || e2Far != e0Far)
215  {
217  << "Edges of triangle " << facei
218  << " reference more than three points.\n"
219  << " edge0:" << e0 << nl
220  << " edge1:" << e1 << nl
221  << " edge2:" << e2 << nl
222  << exit(FatalError);
223  }
224 
225  faceLst[facei] = Face{e0Far, common01, e1Far};
226  zoneIds[facei] = zoneI;
227  }
228 
229 
230  List<surfZoneIdentifier> newZones(maxZone+1);
231  forAll(newZones, zoneI)
232  {
233  newZones[zoneI] = surfZoneIdentifier
234  (
235  "zone" + ::Foam::name(zoneI),
236  zoneI
237  );
238  }
239 
240  this->storedZoneToc().transfer(newZones);
241  this->addZonesToFaces(); // for labelledTri
242 
243  return true;
244 }
245 
246 
247 template<class Face>
249 (
250  const fileName& filename,
251  const MeshedSurface<Face>& surf,
252  const dictionary&
253 )
254 {
255  const UList<point>& pointLst = surf.points();
256  const UList<Face>& faceLst = surf.surfFaces();
257 
258  const surfZoneList zones =
259  (
260  surf.surfZones().size()
261  ? surf.surfZones()
262  : surfaceFormatsCore::oneZone(faceLst)
263  );
264 
265  checkIfTriangulated(faceLst);
266 
267  OFstream os(filename);
268  if (!os.good())
269  {
271  << "Cannot open file for writing " << filename
272  << exit(FatalError);
273  }
274 
275 
276  // Write header, print zone names as comment
277  os << "# GTS file" << nl
278  << "# Zones:" << nl;
279 
280  forAll(zones, zoneI)
281  {
282  os << "# " << zoneI << " "
283  << zones[zoneI].name() << nl;
284  }
285  os << "#" << nl;
286 
287  os << "# nPoints nEdges nTriangles" << nl
288  << pointLst.size() << ' ' << surf.nEdges() << ' '
289  << surf.size() << nl;
290 
291 
292  // Write vertex coords
293  for (const point& pt : pointLst)
294  {
295  os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
296  }
297 
298 
299  // Write edges.
300  // Note: edges are in local point labels so convert
301  const edgeList& es = surf.edges();
302  const labelList& meshPts = surf.meshPoints();
303 
304  for (const edge& e : es)
305  {
306  os << meshPts[e.start()] + 1 << ' '
307  << meshPts[e.end()] + 1 << nl;
308  }
309 
310  // Write faces in terms of edges.
311  const labelListList& faceEs = surf.faceEdges();
312 
313  label faceIndex = 0;
314  label zoneIndex = 0;
315  for (const surfZone& zone : zones)
316  {
317  const label nLocalFaces = zone.size();
318 
319  for (label i=0; i<nLocalFaces; ++i)
320  {
321  const labelList& fEdges = faceEs[faceIndex++];
322 
323  os << fEdges[0] + 1 << ' '
324  << fEdges[1] + 1 << ' '
325  << fEdges[2] + 1 << ' '
326  << zoneIndex << nl;
327  }
328 
329  ++zoneIndex;
330  }
331 }
332 
333 
334 template<class Face>
336 (
337  const fileName& filename,
338  const UnsortedMeshedSurface<Face>& surf,
339  const dictionary&
340 )
341 {
342  const UList<point>& pointLst = surf.points();
343  const UList<Face>& faceLst = surf.surfFaces();
344  const UList<label>& zoneIds = surf.zoneIds();
345  const UList<surfZoneIdentifier>& zoneToc = surf.zoneToc();
346 
347  checkIfTriangulated(faceLst);
348 
349  OFstream os(filename);
350  if (!os.good())
351  {
353  << "Cannot open file for writing " << filename
354  << exit(FatalError);
355  }
356 
357 
358  // Write header, print zone names as comment
359  os << "# GTS file" << nl
360  << "# Zones:" << nl;
361 
362  forAll(zoneToc, zoneI)
363  {
364  os << "# " << zoneI << " "
365  << zoneToc[zoneI].name() << nl;
366  }
367  os << "#" << nl;
368 
369 
370  os << "# nPoints nEdges nTriangles" << nl
371  << pointLst.size() << ' ' << surf.nEdges() << ' '
372  << surf.size() << nl;
373 
374 
375  // Write vertex coords
376  for (const point& pt : pointLst)
377  {
378  os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
379  }
380 
381 
382  // Write edges.
383  // Note: edges are in local point labels so convert
384  const edgeList& es = surf.edges();
385  const labelList& meshPts = surf.meshPoints();
386 
387  for (const edge& e : es)
388  {
389  os << meshPts[e.start()] + 1 << ' '
390  << meshPts[e.end()] + 1 << nl;
391  }
392 
393  // Write faces in terms of edges.
394  const labelListList& faceEs = surf.faceEdges();
395 
396  forAll(faceLst, facei)
397  {
398  const labelList& fEdges = faceEs[facei];
399 
400  os << fEdges[0] + 1 << ' '
401  << fEdges[1] + 1 << ' '
402  << fEdges[2] + 1 << ' '
403  << zoneIds[facei] << nl;
404  }
405 }
406 
407 
408 // ************************************************************************* //
Foam::MeshedSurface::surfZones
const surfZoneList & surfZones() const
Const access to the surface zones.
Definition: MeshedSurface.H:370
Foam::edge::commonVertex
label commonVertex(const edge &other) const
Return vertex common with other edge or -1 on failure.
Definition: edgeI.H:162
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:97
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::zone
Base class for mesh zones.
Definition: zone.H:63
Foam::MeshedSurface::surfFaces
const List< Face > & surfFaces() const
Return const access to the faces.
Definition: MeshedSurface.H:362
StringStream.H
Input/output from string buffers.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::fileFormats::GTSsurfaceFormat::read
virtual bool read(const fileName &filename)
Read from file.
Definition: GTSsurfaceFormat.C:85
Foam::surfZoneIdentifier
Identifies a surface patch/zone by name, patch index and geometricType.
Definition: surfZoneIdentifier.H:58
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::UnsortedMeshedSurface::zoneIds
virtual const labelList & zoneIds() const
Return const access to the zone ids.
Definition: UnsortedMeshedSurface.H:300
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< vector >
Foam::UnsortedMeshedSurface
A surface geometry mesh, in which the surface zone information is conveyed by the 'zoneId' associated...
Definition: MeshedSurface.H:79
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
clock.H
Foam::UnsortedMeshedSurface::zoneToc
const List< surfZoneIdentifier > & zoneToc() const
Return const access to the zone table-of-contents.
Definition: UnsortedMeshedSurface.H:306
Foam::blockMeshTools::read
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:33
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::IOstream::bad
bool bad() const
Return true if stream is corrupted.
Definition: IOstream.H:234
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:115
Foam::UnsortedMeshedSurface::size
label size() const
The surface size is the number of faces.
Definition: UnsortedMeshedSurface.H:291
Foam::IStringStream
Input from string buffer, using a ISstream.
Definition: StringStream.H:112
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::edge::otherVertex
label otherVertex(const label pointLabel) const
Given the point label for one vertex, return the other one.
Definition: edgeI.H:178
Foam::fileFormats::GTSsurfaceFormat::write
static void write(const fileName &filename, const MeshedSurface< Face > &surf, const dictionary &options=dictionary::null)
Write MeshedSurface.
Definition: GTSsurfaceFormat.C:249
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Fstream.H
Input/output from file streams.
f
labelList f(nPoints)
Foam::fileFormats::GTSsurfaceFormat::GTSsurfaceFormat
GTSsurfaceFormat(const fileName &filename)
Construct from file name.
Definition: GTSsurfaceFormat.C:73
Foam::fileFormats::GTSsurfaceFormat
Read/write GTS format.
Definition: GTSsurfaceFormat.H:59
Foam::Vector< scalar >
Foam::List< Face >
Foam::surfZone
A surface zone on a MeshedSurface.
Definition: surfZone.H:65
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::line
A line primitive.
Definition: line.H:59
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
GTSsurfaceFormat.H
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::IOstream::good
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:216
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::MeshedSurface
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Definition: triSurfaceTools.H:80
faceTraits.H
Foam::MeshedSurface::size
label size() const
The surface size is the number of faces.
Definition: MeshedSurface.H:356
surfaceFormatsCore.H
y
scalar y
Definition: LISASMDCalcMethod1.H:14