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-2020 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  // Clear everything
90  this->clear();
91 
92  IFstream is(filename);
93  if (!is.good())
94  {
96  << "Cannot read file " << filename << nl
97  << exit(FatalError);
98  }
99 
100  // Read header
101  string line = this->getLineNoComment(is);
102 
103  label nPoints, nEdges, nElems;
104  {
105  IStringStream lineStream(line);
106  lineStream
107  >> nPoints
108  >> nEdges
109  >> nElems;
110  }
111 
112 
113  // Write directly into the lists
114  auto& pointLst = this->storedPoints();
115  auto& faceLst = this->storedFaces();
116  auto& zoneIds = this->storedZoneIds();
117 
118  pointLst.resize(nPoints);
119  faceLst.resize(nElems);
120  zoneIds.resize(nElems);
121 
122  // Read points
123  forAll(pointLst, pointi)
124  {
125  scalar x, y, z;
126  line = this->getLineNoComment(is);
127  {
128  IStringStream lineStream(line);
129  lineStream
130  >> x >> y >> z;
131  }
132 
133  pointLst[pointi] = point(x, y, z);
134  }
135 
136  // Read edges (OpenFOAM indexing)
137  edgeList edges(nEdges);
138  forAll(edges, edgei)
139  {
140  label beg, end;
141  line = this->getLineNoComment(is);
142  {
143  IStringStream lineStream(line);
144  lineStream
145  >> beg >> end;
146  }
147  edges[edgei] = edge(beg - 1, end - 1);
148  }
149 
150 
151  // Read triangles. Convert references to edges into pointlabels
152  label maxZone = 0;
153  forAll(faceLst, facei)
154  {
155  label e0Label, e1Label, e2Label;
156  label zoneI = 0;
157 
158  line = this->getLineNoComment(is);
159  {
160  IStringStream lineStream(line);
161  lineStream
162  >> e0Label >> e1Label >> e2Label;
163 
164  // Optional zone number: read first, then check stream state
165  if (lineStream)
166  {
167  label num;
168  lineStream >> num;
169  if (!lineStream.bad())
170  {
171  zoneI = num;
172  if (maxZone < zoneI)
173  {
174  maxZone = zoneI;
175  }
176  }
177  }
178  }
179 
180  // Determine ordering of edges e0, e1
181  // common: common vertex, shared by e0 and e1
182  // e0Far: vertex on e0 which is not common
183  // e1Far: vertex on e1 which is not common
184  const edge& e0 = edges[e0Label - 1];
185  const edge& e1 = edges[e1Label - 1];
186  const edge& e2 = edges[e2Label - 1];
187 
188  label common01 = e0.commonVertex(e1);
189  if (common01 == -1)
190  {
192  << "Edges 0 and 1 of triangle " << facei
193  << " do not share a point.\n"
194  << " edge0:" << e0 << nl
195  << " edge1:" << e1
196  << exit(FatalError);
197  }
198 
199  const label e0Far = e0.otherVertex(common01);
200  const label e1Far = e1.otherVertex(common01);
201 
202  const label common12 = e1.commonVertex(e2);
203  if (common12 == -1)
204  {
206  << "Edges 1 and 2 of triangle " << facei
207  << " do not share a point.\n"
208  << " edge1:" << e1 << nl
209  << " edge2:" << e2
210  << exit(FatalError);
211  }
212  const label e2Far = e2.otherVertex(common12);
213 
214  // Does edge2 sit between edge1 and 0?
215  if (common12 != e1Far || e2Far != e0Far)
216  {
218  << "Edges of triangle " << facei
219  << " reference more than three points.\n"
220  << " edge0:" << e0 << nl
221  << " edge1:" << e1 << nl
222  << " edge2:" << e2 << nl
223  << exit(FatalError);
224  }
225 
226  faceLst[facei] = Face{e0Far, common01, e1Far};
227  zoneIds[facei] = zoneI;
228  }
229 
230 
231  List<surfZoneIdentifier> newZones(maxZone+1);
232  forAll(newZones, zonei)
233  {
234  newZones[zonei] = surfZoneIdentifier
235  (
236  surfZoneIdentifier::defaultName(zonei),
237  zonei
238  );
239  }
240 
241  this->storedZoneToc().transfer(newZones);
242  this->addZonesToFaces(); // for labelledTri
243 
244  return true;
245 }
246 
247 
248 template<class Face>
250 (
251  const fileName& filename,
252  const MeshedSurface<Face>& surf,
253  IOstreamOption streamOpt,
254  const dictionary&
255 )
256 {
257  // ASCII only, allow output compression
258  streamOpt.format(IOstream::ASCII);
259 
260  const UList<point>& pointLst = surf.points();
261  const UList<Face>& faceLst = surf.surfFaces();
262 
263  const surfZoneList zones =
264  (
265  surf.surfZones().size()
266  ? surf.surfZones()
267  : surfaceFormatsCore::oneZone(faceLst)
268  );
269 
270  checkIfTriangulated(faceLst);
271 
272  OFstream os(filename, streamOpt);
273  if (!os.good())
274  {
276  << "Cannot write file " << filename << nl
277  << exit(FatalError);
278  }
279 
280 
281  // Write header, print zone names as comment
282  os << "# GTS file" << nl
283  << "# Zones:" << nl;
284 
285  forAll(zones, zonei)
286  {
287  os << "# " << zonei << " "
288  << zones[zonei].name() << nl;
289  }
290  os << "#" << nl;
291 
292  os << "# nPoints nEdges nTriangles" << nl
293  << pointLst.size() << ' ' << surf.nEdges() << ' '
294  << surf.size() << nl;
295 
296 
297  // Write vertex coords
298  for (const point& pt : pointLst)
299  {
300  os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
301  }
302 
303 
304  // Write edges.
305  // Note: edges are in local point labels so convert
306  const edgeList& es = surf.edges();
307  const labelList& meshPts = surf.meshPoints();
308 
309  for (const edge& e : es)
310  {
311  os << meshPts[e.start()] + 1 << ' '
312  << meshPts[e.end()] + 1 << nl;
313  }
314 
315  // Write faces in terms of edges
316  const labelListList& faceEs = surf.faceEdges();
317 
318  label faceIndex = 0;
319  label zoneIndex = 0;
320 
321  for (const surfZone& zone : zones)
322  {
323  for (label nLocal = zone.size(); nLocal--; ++faceIndex)
324  {
325  const label facei = faceIndex;
326 
327  const labelList& fEdges = faceEs[facei];
328 
329  os << fEdges[0] + 1 << ' '
330  << fEdges[1] + 1 << ' '
331  << fEdges[2] + 1 << ' '
332  << zoneIndex << nl;
333  }
334 
335  ++zoneIndex;
336  }
337 }
338 
339 
340 template<class Face>
342 (
343  const fileName& filename,
344  const UnsortedMeshedSurface<Face>& surf,
345  IOstreamOption streamOpt,
346  const dictionary&
347 )
348 {
349  // ASCII only, allow output compression
350  streamOpt.format(IOstream::ASCII);
351 
352  const UList<point>& pointLst = surf.points();
353  const UList<Face>& faceLst = surf.surfFaces();
354  const UList<label>& zoneIds = surf.zoneIds();
355  const UList<surfZoneIdentifier>& zoneToc = surf.zoneToc();
356 
357  checkIfTriangulated(faceLst);
358 
359  OFstream os(filename, streamOpt);
360  if (!os.good())
361  {
363  << "Cannot write file " << filename << nl
364  << exit(FatalError);
365  }
366 
367 
368  // Write header, print zone names as comment
369  os << "# GTS file" << nl
370  << "# Zones:" << nl;
371 
372  forAll(zoneToc, zonei)
373  {
374  os << "# " << zonei << " "
375  << zoneToc[zonei].name() << nl;
376  }
377  os << "#" << nl;
378 
379  os << "# nPoints nEdges nTriangles" << nl
380  << pointLst.size() << ' ' << surf.nEdges() << ' '
381  << surf.size() << nl;
382 
383 
384  // Write vertex coords
385  for (const point& pt : pointLst)
386  {
387  os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
388  }
389 
390 
391  // Write edges.
392  // Note: edges are in local point labels so convert
393  const edgeList& es = surf.edges();
394  const labelList& meshPts = surf.meshPoints();
395 
396  for (const edge& e : es)
397  {
398  os << meshPts[e.start()] + 1 << ' '
399  << meshPts[e.end()] + 1 << nl;
400  }
401 
402  // Write faces in terms of edges.
403  const labelListList& faceEs = surf.faceEdges();
404 
405  forAll(faceLst, facei)
406  {
407  const labelList& fEdges = faceEs[facei];
408 
409  os << fEdges[0] + 1 << ' '
410  << fEdges[1] + 1 << ' '
411  << fEdges[2] + 1 << ' '
412  << zoneIds[facei] << nl;
413  }
414 }
415 
416 
417 // ************************************************************************* //
Foam::MeshedSurface::surfZones
const surfZoneList & surfZones() const
Const access to the surface zones.
Definition: MeshedSurface.H:429
Foam::edge::commonVertex
label commonVertex(const edge &other) const
Return vertex common with other edge or -1 on failure.
Definition: edgeI.H:172
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:53
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::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:286
Foam::MeshedSurface::surfFaces
const List< Face > & surfFaces() const
Return const access to the faces.
Definition: MeshedSurface.H:413
Foam::fileFormats::GTSsurfaceFormat::write
static void write(const fileName &filename, const MeshedSurface< Face > &surf, IOstreamOption streamOpt=IOstreamOption(), const dictionary &=dictionary::null)
Write MeshedSurface.
Definition: GTSsurfaceFormat.C:250
StringStream.H
Input/output from string buffers.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
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 and index, with optional geometric type.
Definition: surfZoneIdentifier.H:59
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
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::blockMeshTools::read
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:57
Foam::UnsortedMeshedSurface::zoneIds
virtual const labelList & zoneIds() const
Return const access to the zone ids.
Definition: UnsortedMeshedSurface.H:336
Foam::UnsortedMeshedSurface
A surface geometry mesh, in which the surface zone information is conveyed by the 'zoneId' associated...
Definition: MeshedSurface.H:83
clock.H
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::UnsortedMeshedSurface::zoneToc
const List< surfZoneIdentifier > & zoneToc() const
Return const access to the zone table-of-contents.
Definition: UnsortedMeshedSurface.H:342
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:123
os
OBJstream os(runTime.globalPath()/outputName)
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::IOstream::bad
bool bad() const noexcept
True if stream is corrupted.
Definition: IOstream.H:251
Foam::UnsortedMeshedSurface::size
label size() const
The surface size is the number of faces.
Definition: UnsortedMeshedSurface.H:327
Foam::IStringStream
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
Definition: StringStream.H:108
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:53
Foam::edge::otherVertex
label otherVertex(const label pointLabel) const
Given the point label for one vertex, return the other one.
Definition: edgeI.H:188
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
Fstream.H
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:65
Foam::Vector< scalar >
Foam::List< edge >
Foam::surfZone
A surface zone on a MeshedSurface.
Definition: surfZone.H:56
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:53
GTSsurfaceFormat.H
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::point
vector point
Point is a vector.
Definition: point.H:43
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:407
surfaceFormatsCore.H
y
scalar y
Definition: LISASMDCalcMethod1.H:14