tecplotWriter.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "tecplotWriter.H"
27 #include "fvMesh.H"
28 
29 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
30 
31 // Construct from components
33 :
34  runTime_(runTime)
35 {}
36 
37 
38 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
39 
41 (
42  const word& name,
43  const string& varNames,
44  const fileName& fName,
45  INTEGER4 tecplotFileType
46 ) const
47 {
48 Pout<< endl
49  << endl
50  << "Name:" << name
51  << " varNames:" << varNames
52  << " to file:" << fName
53  << " of type:" << tecplotFileType
54  << endl;
55 
56  INTEGER4 IsDouble = 0; // float
57  INTEGER4 Debug = 0; // nodebug
58  if
59  (
60  !TECINI112
61  (
62  const_cast<char*>(name.c_str()), /* Data Set Title */
63  const_cast<char*>(varNames.c_str()), /* Variable List */
64  const_cast<char*>(fName.c_str()), /* File Name */
65  const_cast<char*>(runTime_.path().c_str()), /* Scratch Directory */
66  &tecplotFileType,
67  &Debug,
68  &IsDouble
69  )
70  )
71  {
72 // FatalErrorInFunction
73 // << "Error in TECINI112." << exit(FatalError);
74  }
75 }
76 
77 
79 (
80  const word& zoneName,
81  INTEGER4 strandID,
82  const fvMesh& mesh,
83  const List<INTEGER4>& varLocArray,
84  INTEGER4 nFaceNodes
85 ) const
86 {
87  /* Call TECZNE112 */
88  INTEGER4 NumNodes = mesh.nPoints(); /* number of unique nodes */
89  INTEGER4 NumElems = mesh.nCells(); /* number of elements */
90  INTEGER4 NumFaces = mesh.nFaces(); /* number of unique faces */
91 
92  INTEGER4 ICellMax = 0; /* Not Used, set to zero */
93  INTEGER4 JCellMax = 0; /* Not Used, set to zero */
94  INTEGER4 KCellMax = 0; /* Not Used, set to zero */
95 
96  double SolTime = runTime_.value(); /* solution time */
97  INTEGER4 ParentZone = 0; /* no parent zone */
98 
99  INTEGER4 IsBlock = 1; /* block format */
100 
101  INTEGER4 NFConns = 0; /* not used for FEPolyhedron
102  * zones
103  */
104  INTEGER4 FNMode = 0; /* not used for FEPolyhedron
105  * zones
106  */
107 Pout<< "zoneName:" << zoneName
108  //<< " varLocArray:" << varLocArray
109  << " solTime:" << SolTime
110  << endl;
111 
112 
113 
114  INTEGER4 *PassiveVarArray = nullptr;
115  INTEGER4 *VarShareArray = nullptr;
116  INTEGER4 ShrConn = 0;
117 
118  INTEGER4 NumBConns = 0; /* No Boundary Connections */
119  INTEGER4 NumBItems = 0; /* No Boundary Items */
120 
121  INTEGER4 ZoneType = ZoneType_FEPolyhedron;
122 
123  if
124  (
125  !TECZNE112
126  (
127  const_cast<char*>(zoneName.c_str()),
128  &ZoneType,
129  &NumNodes,
130  &NumElems,
131  &NumFaces,
132  &ICellMax,
133  &JCellMax,
134  &KCellMax,
135  &SolTime,
136  &strandID,
137  &ParentZone,
138  &IsBlock,
139  &NFConns,
140  &FNMode,
141  &nFaceNodes,
142  &NumBConns,
143  &NumBItems,
144  PassiveVarArray,
145  const_cast<INTEGER4*>(varLocArray.begin()),
146  VarShareArray,
147  &ShrConn
148  )
149  )
150  {
151 // FatalErrorInFunction
152 // << "Error in TECZNE112." << exit(FatalError);
153  }
154 }
155 
156 
158 (
159  const word& zoneName,
160  INTEGER4 strandID,
161  const indirectPrimitivePatch& pp,
162  const List<INTEGER4>& varLocArray
163 ) const
164 {
165  /* Call TECZNE112 */
166  INTEGER4 NumNodes = pp.nPoints(); /* number of unique nodes */
167  INTEGER4 NumElems = pp.size(); /* number of elements */
168  INTEGER4 NumFaces = pp.nEdges(); /* number of unique faces */
169 
170  INTEGER4 ICellMax = 0; /* Not Used, set to zero */
171  INTEGER4 JCellMax = 0; /* Not Used, set to zero */
172  INTEGER4 KCellMax = 0; /* Not Used, set to zero */
173 
174  double SolTime = runTime_.value(); /* solution time */
175  INTEGER4 ParentZone = 0; /* no parent zone */
176 
177  INTEGER4 IsBlock = 1; /* block format */
178 
179  INTEGER4 NFConns = 0; /* not used for FEPolyhedron
180  * zones
181  */
182  INTEGER4 FNMode = 0; /* not used for FEPolyhedron
183  * zones
184  */
185  INTEGER4 NumFaceNodes = 2*pp.nEdges();
186 
187 Pout<< "zoneName:" << zoneName
188  << " strandID:" << strandID
189  //<< " varLocArray:" << varLocArray
190  << " solTime:" << SolTime
191  << endl;
192 
193 
194  INTEGER4 *PassiveVarArray = nullptr;
195  INTEGER4 *VarShareArray = nullptr;
196  INTEGER4 ShrConn = 0;
197 
198  INTEGER4 NumBConns = 0; /* No Boundary Connections */
199  INTEGER4 NumBItems = 0; /* No Boundary Items */
200 
201  INTEGER4 ZoneType = ZoneType_FEPolygon;
202 
203  if
204  (
205  !TECZNE112
206  (
207  const_cast<char*>(zoneName.c_str()),
208  &ZoneType,
209  &NumNodes,
210  &NumElems,
211  &NumFaces,
212  &ICellMax,
213  &JCellMax,
214  &KCellMax,
215  &SolTime,
216  &strandID,
217  &ParentZone,
218  &IsBlock,
219  &NFConns,
220  &FNMode,
221  &NumFaceNodes,
222  &NumBConns,
223  &NumBItems,
224  PassiveVarArray,
225  const_cast<INTEGER4*>(varLocArray.begin()),
226  VarShareArray,
227  &ShrConn
228  )
229  )
230  {
231 // FatalErrorInFunction
232 // << "Error in TECZNE112." << exit(FatalError);
233  }
234 }
235 
236 
238 (
239  const word& zoneName,
240  INTEGER4 strandID,
241  const label n,
242  const List<INTEGER4>& varLocArray
243 ) const
244 {
245  /* Call TECZNE112 */
246  INTEGER4 IMax = n; /* number of unique nodes */
247  INTEGER4 JMax = 1; /* number of elements */
248  INTEGER4 KMax = 1; /* number of unique faces */
249 
250  INTEGER4 ICellMax = 0; /* Not Used, set to zero */
251  INTEGER4 JCellMax = 0; /* Not Used, set to zero */
252  INTEGER4 KCellMax = 0; /* Not Used, set to zero */
253 
254  double SolTime = runTime_.value(); /* solution time */
255  INTEGER4 ParentZone = 0; /* no parent zone */
256 
257  INTEGER4 IsBlock = 1; /* block format */
258 
259  INTEGER4 NFConns = 0; /* not used for FEPolyhedron
260  * zones
261  */
262  INTEGER4 FNMode = 0; /* not used for FEPolyhedron
263  * zones
264  */
265  INTEGER4 NumFaceNodes = 1;
266  INTEGER4 NumBConns = 1; /* No Boundary Connections */
267  INTEGER4 NumBItems = 1; /* No Boundary Items */
268 
269 Pout<< "zoneName:" << zoneName
270  << " strandID:" << strandID
271  //<< " varLocArray:" << varLocArray
272  << " solTime:" << SolTime
273  << endl;
274 
275 
276  INTEGER4 *PassiveVarArray = nullptr;
277  INTEGER4 *VarShareArray = nullptr;
278  INTEGER4 ShrConn = 0;
279 
280 
281  INTEGER4 ZoneType = ZoneType_Ordered;
282 
283  if
284  (
285  !TECZNE112
286  (
287  const_cast<char*>(zoneName.c_str()),
288  &ZoneType,
289  &IMax,
290  &JMax,
291  &KMax,
292  &ICellMax,
293  &JCellMax,
294  &KCellMax,
295  &SolTime,
296  &strandID,
297  &ParentZone,
298  &IsBlock,
299  &NFConns,
300  &FNMode,
301  &NumFaceNodes,
302  &NumBConns,
303  &NumBItems,
304  PassiveVarArray,
305  const_cast<INTEGER4*>(varLocArray.begin()),
306  VarShareArray,
307  &ShrConn
308  )
309  )
310  {
311 // FatalErrorInFunction
312 // << "Error in TECZNE112." << exit(FatalError);
313  }
314 }
315 
316 
317 void Foam::tecplotWriter::writeConnectivity(const fvMesh& mesh) const
318 {
319  List<INTEGER4> FaceNodeCounts(mesh.nFaces());
320 
321  forAll(mesh.faces(), facei)
322  {
323  const face& f = mesh.faces()[facei];
324  FaceNodeCounts[facei] = INTEGER4(f.size());
325  }
326 
327 
328  INTEGER4 nFaceNodes = 0;
329  forAll(mesh.faces(), facei)
330  {
331  nFaceNodes += mesh.faces()[facei].size();
332  }
333 
334 
335  List<INTEGER4> FaceNodes(nFaceNodes);
336  label nodeI = 0;
337  forAll(mesh.faces(), facei)
338  {
339  const face& f = mesh.faces()[facei];
340  forAll(f, fp)
341  {
342  FaceNodes[nodeI++] = INTEGER4(f[fp]+1);
343  }
344  }
345 
346 
347  List<INTEGER4> FaceLeftElems(mesh.nFaces());
348  forAll(mesh.faceOwner(), facei)
349  {
350  FaceLeftElems[facei] = mesh.faceOwner()[facei]+1;
351  }
352 
353  List<INTEGER4> FaceRightElems(mesh.nFaces());
354  forAll(mesh.faceNeighbour(), facei)
355  {
356  FaceRightElems[facei] = mesh.faceNeighbour()[facei]+1;
357  }
358  for
359  (
360  label facei = mesh.nInternalFaces();
361  facei < mesh.nFaces();
362  facei++
363  )
364  {
365  FaceRightElems[facei] = 0;
366  }
367 
368  if
369  (
370  !TECPOLY112
371  (
372  FaceNodeCounts.begin(), /* The face node counts array */
373  FaceNodes.begin(), /* The face nodes array */
374  FaceLeftElems.begin(), /* The left elements array */
375  FaceRightElems.begin(), /* The right elements array */
376  nullptr, /* No boundary connection counts */
377  nullptr, /* No boundary connection elements */
378  nullptr /* No boundary connection zones */
379  )
380  )
381  {
382 // FatalErrorInFunction
383 // << "Error in TECPOLY112." << exit(FatalError);
384  }
385 }
386 
388 (
389  const indirectPrimitivePatch& pp
390 ) const
391 {
392  INTEGER4 NumFaces = pp.nEdges(); /* number of unique faces */
393  INTEGER4 NumFaceNodes = 2*pp.nEdges();
394 
395  // All faces (=edges) have 2 nodes
396  List<INTEGER4> FaceNodeCounts(NumFaces);
397  FaceNodeCounts = 2;
398 
399  List<INTEGER4> FaceNodes(NumFaceNodes);
400  label nodeI = 0;
401  forAll(pp.edges(), edgeI)
402  {
403  edge e = pp.edges()[edgeI];
404  if (e[0] > e[1])
405  {
406  e.flip();
407  }
408 
409  FaceNodes[nodeI++] = INTEGER4(e[0]+1);
410  FaceNodes[nodeI++] = INTEGER4(e[1]+1);
411  }
412 
413  /* Define the right and left elements of each face.
414  *
415  * The last step for writing out the polyhedral data is to
416  * define the right and left neighboring elements for each
417  * face. The neighboring elements can be determined using the
418  * right-hand rule. For each face, place your right-hand along
419  * the face which your fingers pointing the direction of
420  * incrementing node numbers (i.e. from node 1 to node 2).
421  * Your right thumb will point towards the right element; the
422  * element on the other side of your hand is the left element.
423  *
424  * The number zero is used to indicate that there isn't an
425  * element on that side of the face.
426  *
427  * Because of the way we numbered the nodes and faces, the
428  * right element for every face is the element itself
429  * (element 1) and the left element is "no-neighboring element"
430  * (element 0).
431  */
432 
433  List<INTEGER4> FaceLeftElems(NumFaces);
434  List<INTEGER4> FaceRightElems(NumFaces);
435 
436  const labelListList& edgeFaces = pp.edgeFaces();
437  forAll(edgeFaces, edgeI)
438  {
439  const labelList& eFaces = edgeFaces[edgeI];
440 
441  if (eFaces.size() == 1)
442  {
443  FaceLeftElems[edgeI] = 0;
444  FaceRightElems[edgeI] = eFaces[0]+1;
445  }
446  else if (eFaces.size() == 2)
447  {
448  edge e = pp.edges()[edgeI];
449  if (e[0] > e[1])
450  {
451  e.flip();
452  }
453 
454  const face& f0 = pp.localFaces()[eFaces[0]];
455 
456  // The face that uses the vertices of e in increasing order
457  // is the left face.
458 
459  label fp = findIndex(f0, e[0]);
460  bool f0IsLeft = (f0.nextLabel(fp) == e[1]);
461 
462  if (f0IsLeft)
463  {
464  FaceLeftElems[edgeI] = eFaces[0]+1;
465  FaceRightElems[edgeI] = eFaces[1]+1;
466  }
467  else
468  {
469  FaceLeftElems[edgeI] = eFaces[1]+1;
470  FaceRightElems[edgeI] = eFaces[0]+1;
471  }
472  }
473  else
474  {
475  // non-manifold. Treat as if open.
476  FaceLeftElems[edgeI] = 0;
477  FaceRightElems[edgeI] = eFaces[0]+1;
478  }
479  }
480 
481  /* Write the face map (created above) using TECPOLY112. */
482  if
483  (
484  !TECPOLY112
485  (
486  FaceNodeCounts.begin(), /* The face node counts array */
487  FaceNodes.begin(), /* The face nodes array */
488  FaceLeftElems.begin(), /* The left elements array */
489  FaceRightElems.begin(), /* The right elements array */
490  nullptr, /* No boundary connection counts */
491  nullptr, /* No boundary connection elements */
492  nullptr /* No boundary connection zones */
493  )
494  )
495  {
496 // FatalErrorInFunction
497 // << "Error in TECPOLY112." << exit(FatalError);
498  }
499 }
500 
501 
503 {
504 Pout<< "writeEnd" << endl;
505 
506  if (!TECEND112())
507  {
508 // FatalErrorInFunction
509 // << "Error in TECEND112." << exit(FatalError);
510  }
511 
512 }
513 
514 
515 // ************************************************************************* //
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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:59
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
void writeConnectivity(const fvMesh &mesh) const
Write mesh.
const Type & value() const
Return const reference to value.
void writePolyhedralZone(const word &zoneName, const INTEGER4 strandID, const fvMesh &mesh, const List< INTEGER4 > &varLocArray, INTEGER4 nFaceNodes) const
Write mesh as polyhedral zone.
List< label > labelList
A List of labels.
Definition: labelList.H:56
void writeEnd() const
labelList f(nPoints)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
void writeInit(const word &name, const string &varNames, const fileName &, INTEGER4 tecplotFileType) const
void writePolygonalZone(const word &zoneName, const INTEGER4 strandID, const indirectPrimitivePatch &pp, const List< INTEGER4 > &varLocArray) const
Write surface as polygonal zone.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
void writeOrderedZone(const word &zoneName, INTEGER4 strandID, const label n, const List< INTEGER4 > &varLocArray) const
Write unordered data (or rather 1D ordered)
label n
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:105
fileName path() const
Return path.
Definition: TimePaths.H:139
tecplotWriter(const Time &)
Construct from components.