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