STARCDedgeFormat.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) 2016-2024 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 "STARCDedgeFormat.H"
30 #include "ListOps.H"
31 #include "clock.H"
32 #include "bitSet.H"
33 #include "StringStream.H"
34 
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
36 
37 inline void Foam::fileFormats::STARCDedgeFormat::writeLines
38 (
39  Ostream& os,
40  const edgeList& edges,
41  label starCellId
42 )
43 {
44  starCellId = max(1, starCellId); // Enforce 1-based cellId
45 
46  for (const edge& e : edges)
47  {
48  os << starCellId
49  << ' ' << starcdLine // 2(line) shape
50  << ' ' << e.size()
51  << ' ' << 401 // arbitrary value
52  << ' ' << starcdLineType; // 5(line)
53 
54  os << nl
55  << " " << starCellId << " "
56  << (e[0]+1) << " " << (e[1]+1) << nl;
57 
58  ++starCellId;
59  }
60 }
61 
62 
63 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
64 
66 (
67  Ostream& os,
68  const pointField& pointLst,
69  const label nEdges
70 )
71 {
72  const word caseName = os.name().stem();
73 
74  os << "! STARCD file written " << clock::dateTime().c_str() << nl
75  << "! " << pointLst.size() << " points, " << nEdges << " lines" << nl
76  << "! case " << caseName << nl
77  << "! ------------------------------" << nl;
78 
79 // forAll(zoneLst, zoneI)
80 // {
81 // os << "ctable " << zoneI + 1 << " line" << nl
82 // << "ctname " << zoneI + 1 << " "
83 // << zoneLst[zoneI].name() << nl;
84 // }
85 
86  os << "! ------------------------------" << nl
87  << "*set icvo mxv - 1" << nl
88  << "vread " << caseName << ".vrt icvo,,,coded" << nl
89  << "cread " << caseName << ".cel icvo,,,add,coded" << nl
90  << "*set icvo" << nl
91  << "! end" << nl;
92 
93  os.flush();
94 }
95 
96 
97 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
98 
100 (
101  const fileName& filename
102 )
103 {
104  read(filename);
105 }
106 
107 
108 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
109 
111 (
112  const fileName& filename
113 )
114 {
115  clear();
116 
117  const fileName prefix(filename.lessExt());
118 
119  // STARCD index of points
120  List<label> pointId;
121 
122  // Read points from .vrt file
123  readPoints
124  (
125  IFstream(starFileName(prefix, STARCDCore::VRT_FILE))(),
126  storedPoints(),
127  pointId
128  );
129 
130  // Build inverse mapping (STARCD pointId -> index)
131  Map<label> mapPointId(invertToMap(pointId));
132  pointId.clear();
133 
134  // Note which points were really used and which can be culled
135  bitSet usedPoints(points().size());
136 
137 
138  // Read .cel file
139  // ~~~~~~~~~~~~~~
140  IFstream is(starFileName(prefix, STARCDCore::CEL_FILE));
141  if (!is.good())
142  {
144  << "Cannot read file " << is.name()
145  << exit(FatalError);
146  }
147 
148  readHeader(is, STARCDCore::HEADER_CEL);
149 
150  DynamicList<edge> dynEdges;
151 
152  label ignoredLabel, shapeId, nLabels, cellTableId, typeId;
153  DynamicList<label> vertexLabels(64);
154 
155  token tok;
156 
157  while (is.read(tok).good() && tok.isLabel())
158  {
159  // const label starCellId = tok.labelToken();
160  is >> shapeId
161  >> nLabels
162  >> cellTableId
163  >> typeId;
164 
165  vertexLabels.clear();
166  vertexLabels.reserve(nLabels);
167 
168  // Read indices - max 8 per line
169  for (label i = 0; i < nLabels; ++i)
170  {
171  label vrtId;
172  if ((i % 8) == 0)
173  {
174  is >> ignoredLabel; // Skip cellId for continuation lines
175  }
176  is >> vrtId;
177 
178  // Convert original vertex id to point label
179  vertexLabels.append(mapPointId[vrtId]);
180  }
181 
182  if (typeId == starcdLineType)
183  {
184  if (vertexLabels.size() >= 2)
185  {
186  dynEdges.append(edge(vertexLabels[0], vertexLabels[1]));
187 
188  usedPoints.set(vertexLabels[0]);
189  usedPoints.set(vertexLabels[1]);
190  }
191  }
192  }
193 
194  mapPointId.clear();
195 
196  // Not all points were used, subset/cull them accordingly
197  if (!usedPoints.all())
198  {
199  label nUsed = 0;
200 
201  pointField& pts = storedPoints();
202  for (const label pointi : usedPoints)
203  {
204  if (nUsed != pointi)
205  {
206  pts[nUsed] = pts[pointi];
207  }
208 
209  // Map prev -> new id
210  mapPointId.set(pointi, nUsed);
211 
212  ++nUsed;
213  }
214  pts.resize(nUsed);
215 
216  // Renumber edge vertices
217  for (edge& e : dynEdges)
218  {
219  e[0] = mapPointId[e[0]];
220  e[1] = mapPointId[e[1]];
221  }
222  }
223 
224  storedEdges().transfer(dynEdges);
225 
226  return true;
227 }
228 
229 
231 (
232  const fileName& filename,
233  const edgeMesh& mesh,
234  IOstreamOption streamOpt,
235  const dictionary&
236 )
237 {
238  // ASCII only, allow output compression
239  streamOpt.format(IOstreamOption::ASCII);
240 
241  const pointField& pointLst = mesh.points();
242  const edgeList& edgeLst = mesh.edges();
243 
244  const fileName prefix(filename.lessExt());
245 
246  // The .vrt file
247  {
248  OFstream os(starFileName(prefix, STARCDCore::VRT_FILE), streamOpt);
249  writePoints(os, pointLst);
250  }
251 
252  // The .cel file
253  {
254  OFstream os(starFileName(prefix, STARCDCore::CEL_FILE), streamOpt);
256  writeLines(os, edgeLst);
257  }
258 
259  // Write a simple .inp file. Never compressed
260  writeCase
261  (
262  OFstream(starFileName(prefix, STARCDCore::INP_FILE))(),
263  pointLst,
264  edgeLst.size()
265  );
266 }
267 
268 
269 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
virtual bool read(const fileName &name) override
Read from file.
A class for handling file names.
Definition: fileName.H:72
static void writeHeader(Ostream &os, const word &fieldName)
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...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
Input/output from string buffers.
List< edge > edgeList
List of edge.
Definition: edgeList.H:32
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
Output to file stream as an OSstream, normally using std::ofstream for the actual output...
Definition: OFstream.H:71
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
"ascii" (normal default)
A token holds an item read from Istream.
Definition: token.H:65
A simple container for options an IOstream can normally have.
Various functions to operate on Lists.
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:127
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
dynamicFvMesh & mesh
const pointField & points
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
A class for handling words, derived from Foam::string.
Definition: word.H:63
static std::string dateTime()
The current wall-clock date/time (in local time) as a string in ISO-8601 format (yyyy-mm-ddThh:mm:ss)...
Definition: clock.C:53
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicList.H:584
STARCDedgeFormat(const fileName &filename)
Construct from file name.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
OBJstream os(runTime.globalPath()/outputName)
Mesh data needed to do the Finite Area discretisation.
Definition: edgeFaMesh.H:47
Input from file stream as an ISstream, normally using std::ifstream for the actual input...
Definition: IFstream.H:51
static void writeCase(Ostream &os, const pointField &pointLst, const label nEdges)
static void write(const fileName &filename, const edgeMesh &mesh, IOstreamOption streamOpt=IOstreamOption(), const dictionary &options=dictionary::null)
Write edge mesh to file in STARCD format.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
surface1 clear()
const edgeList & edges() const noexcept
Return edges.
Definition: edgeMeshI.H:98
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileNameI.H:238
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:599
Map< label > invertToMap(const labelUList &values)
Create inverse mapping, which is a lookup table into the given list.
Definition: ListOps.C:107
streamFormat format() const noexcept
Get the current stream format.
const pointField & pts