vtkPV3FoamMeshVolume.C 9.96 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
Mark Olesen's avatar
Mark Olesen committed
5
    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM; if not, write to the Free Software Foundation,
    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Description

\*---------------------------------------------------------------------------*/

#include "vtkPV3Foam.H"

// Foam includes
#include "fvMesh.H"
#include "cellModeller.H"
Mark Olesen's avatar
Mark Olesen committed
34
#include "vtkOpenFOAMPoints.H"
35
36
37
38
39
40
41

// VTK includes
#include "vtkCellArray.h"
#include "vtkUnstructuredGrid.h"

// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

Mark Olesen's avatar
Mark Olesen committed
42
vtkUnstructuredGrid* Foam::vtkPV3Foam::volumeVTKMesh
43
44
(
    const fvMesh& mesh,
Mark Olesen's avatar
Mark Olesen committed
45
    polyDecomp& decompInfo
46
47
)
{
Mark Olesen's avatar
Mark Olesen committed
48
49
    vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New();

50
51
    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
52
        Info<< "<beg> Foam::vtkPV3Foam::volumeVTKMesh" << endl;
Mark Olesen's avatar
Mark Olesen committed
53
        printMemory();
54
55
56
57
58
59
60
61
    }

    // Number of additional points needed by the decomposition of polyhedra
    label nAddPoints = 0;

    // Number of additional cells generated by the decomposition of polyhedra
    label nAddCells = 0;

Mark Olesen's avatar
Mark Olesen committed
62
63
64
    labelList& superCells = decompInfo.superCells();
    labelList& addPointCellLabels = decompInfo.addPointCellLabels();

65
66
67
68
69
70
71
72
73
74
75
    const cellModel& tet = *(cellModeller::lookup("tet"));
    const cellModel& pyr = *(cellModeller::lookup("pyr"));
    const cellModel& prism = *(cellModeller::lookup("prism"));
    const cellModel& wedge = *(cellModeller::lookup("wedge"));
    const cellModel& tetWedge = *(cellModeller::lookup("tetWedge"));
    const cellModel& hex = *(cellModeller::lookup("hex"));

    // Scan for cells which need to be decomposed and count additional points
    // and cells
    if (debug)
    {
76
        Info<< "... building cell-shapes" << endl;
77
78
79
80
81
    }
    const cellShapeList& cellShapes = mesh.cellShapes();

    if (debug)
    {
82
        Info<< "... scanning" << endl;
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
    }
    forAll(cellShapes, cellI)
    {
        const cellModel& model = cellShapes[cellI].model();

        if
        (
            model != hex
         && model != wedge
         && model != prism
         && model != pyr
         && model != tet
         && model != tetWedge
        )
        {
            const cell& cFaces = mesh.cells()[cellI];

            forAll(cFaces, cFaceI)
            {
                const face& f = mesh.faces()[cFaces[cFaceI]];

                label nFacePoints = f.size();

                label nQuads = (nFacePoints - 2)/2;
                label nTris = (nFacePoints - 2)%2;
                nAddCells += nQuads + nTris;
            }

            nAddCells--;
            nAddPoints++;
        }
    }

    // Set size of additional point addressing array
    // (from added point to original cell)
Mark Olesen's avatar
Mark Olesen committed
118
    addPointCellLabels.setSize(nAddPoints);
119
120
121
122
123
124

    // Set size of additional cells mapping array
    // (from added cell to original cell)

    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
125
126
127
128
        Info<<" mesh nCells     = " << mesh.nCells() << nl
            <<"      nPoints    = " << mesh.nPoints() << nl
            <<"      nAddCells  = " << nAddCells << nl
            <<"      nAddPoints = " << nAddPoints << endl;
129
130
131
132
133
134
    }

    superCells.setSize(mesh.nCells() + nAddCells);

    if (debug)
    {
135
        Info<< "... converting points" << endl;
136
137
138
139
    }

    // Convert Foam mesh vertices to VTK
    vtkPoints *vtkpoints = vtkPoints::New();
Mark Olesen's avatar
Mark Olesen committed
140
    vtkpoints->Allocate( mesh.nPoints() + nAddPoints );
141
142
143
144
145

    const Foam::pointField& points = mesh.points();

    forAll(points, i)
    {
Mark Olesen's avatar
Mark Olesen committed
146
        vtkInsertNextOpenFOAMPoint(vtkpoints, points[i]);
147
148
149
150
151
    }


    if (debug)
    {
152
        Info<< "... converting cells" << endl;
153
154
    }

Mark Olesen's avatar
Mark Olesen committed
155
    vtkmesh->Allocate( mesh.nCells() + nAddCells );
156
157

    // Set counters for additional points and additional cells
Mark Olesen's avatar
Mark Olesen committed
158
    label addPointI = 0, addCellI = 0;
159
160
161
162
163

    // Create storage for points - needed for mapping from Foam to VTK
    // data types - max 'order' = hex = 8 points
    vtkIdType nodeIds[8];

Mark Olesen's avatar
Mark Olesen committed
164
    forAll(cellShapes, cellI)
165
    {
Mark Olesen's avatar
Mark Olesen committed
166
        const cellShape& cellShape = cellShapes[cellI];
167
168
        const cellModel& cellModel = cellShape.model();

Mark Olesen's avatar
Mark Olesen committed
169
        superCells[addCellI++] = cellI;
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

        if (cellModel == tet)
        {
            for (int j = 0; j < 4; j++)
            {
                nodeIds[j] = cellShape[j];
            }
            vtkmesh->InsertNextCell
            (
                VTK_TETRA,
                4,
                nodeIds
            );
        }
        else if (cellModel == pyr)
        {
            for (int j = 0; j < 5; j++)
            {
                nodeIds[j] = cellShape[j];
            }
            vtkmesh->InsertNextCell
            (
                VTK_PYRAMID,
                5,
                nodeIds
            );
        }
        else if (cellModel == prism)
        {
            for (int j = 0; j < 6; j++)
            {
                nodeIds[j] = cellShape[j];
            }
            vtkmesh->InsertNextCell
            (
                VTK_WEDGE,
                6,
                nodeIds
            );
        }
        else if (cellModel == tetWedge)
        {
            // Treat as squeezed prism

            nodeIds[0] = cellShape[0];
            nodeIds[1] = cellShape[2];
            nodeIds[2] = cellShape[1];
            nodeIds[3] = cellShape[3];
            nodeIds[4] = cellShape[4];
            nodeIds[5] = cellShape[4];

            vtkmesh->InsertNextCell
            (
                VTK_WEDGE,
                6,
                nodeIds
            );
        }
        else if (cellModel == wedge)
        {
            // Treat as squeezed hex

            nodeIds[0] = cellShape[0];
            nodeIds[1] = cellShape[1];
            nodeIds[2] = cellShape[2];
            nodeIds[3] = cellShape[2];
            nodeIds[4] = cellShape[3];
            nodeIds[5] = cellShape[4];
            nodeIds[6] = cellShape[5];
            nodeIds[7] = cellShape[6];

            vtkmesh->InsertNextCell
            (
                VTK_HEXAHEDRON,
                8,
                nodeIds
            );
        }
        else if (cellModel == hex)
        {
            for (int j = 0; j < 8; j++)
            {
                nodeIds[j] = cellShape[j];
            }
            vtkmesh->InsertNextCell
            (
                VTK_HEXAHEDRON,
                8,
                nodeIds
            );
        }
        else
        {
            // Polyhedral cell. Decompose into tets + prisms.

            // Mapping from additional point to cell
Mark Olesen's avatar
Mark Olesen committed
266
            addPointCellLabels[addPointI] = cellI;
267
268

            // Insert the new vertex from the cell-centre
Mark Olesen's avatar
Mark Olesen committed
269
            label newVertexLabel = mesh.nPoints() + addPointI;
Mark Olesen's avatar
Mark Olesen committed
270
            vtkInsertNextOpenFOAMPoint(vtkpoints, mesh.C()[cellI]);
271
272
273
274

            // Whether to insert cell in place of original or not.
            bool substituteCell = true;

Mark Olesen's avatar
Mark Olesen committed
275
            const labelList& cFaces = mesh.cells()[cellI];
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

            forAll(cFaces, cFaceI)
            {
                const face& f = mesh.faces()[cFaces[cFaceI]];

                label nFacePoints = f.size();

                label nQuads = (nFacePoints - 2)/2;
                label nTris = (nFacePoints - 2)%2;

                label qpi = 0;

                for (label quadi=0; quadi<nQuads; quadi++)
                {
                    label thisCellI = -1;

                    if (substituteCell)
                    {
Mark Olesen's avatar
Mark Olesen committed
294
                        thisCellI = cellI;
295
296
297
298
                        substituteCell = false;
                    }
                    else
                    {
Mark Olesen's avatar
Mark Olesen committed
299
300
                        thisCellI = mesh.nCells() + addCellI;
                        superCells[addCellI++] = cellI;
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
                    }

                    nodeIds[0] = f[0];
                    nodeIds[1] = f[qpi + 1];
                    nodeIds[2] = f[qpi + 2];
                    nodeIds[3] = f[qpi + 3];
                    nodeIds[4] = newVertexLabel;
                    vtkmesh->InsertNextCell
                    (
                        VTK_PYRAMID,
                        5,
                        nodeIds
                    );

                    qpi += 2;
                }

                if (nTris)
                {
                    label thisCellI = -1;

                    if (substituteCell)
                    {
Mark Olesen's avatar
Mark Olesen committed
324
                        thisCellI = cellI;
325
326
327
328
                        substituteCell = false;
                    }
                    else
                    {
Mark Olesen's avatar
Mark Olesen committed
329
330
                        thisCellI = mesh.nCells() + addCellI;
                        superCells[addCellI++] = cellI;
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
                    }

                    nodeIds[0] = f[0];
                    nodeIds[1] = f[qpi + 1];
                    nodeIds[2] = f[qpi + 2];
                    nodeIds[3] = newVertexLabel;
                    vtkmesh->InsertNextCell
                    (
                        VTK_TETRA,
                        4,
                        nodeIds
                    );
                }
            }

Mark Olesen's avatar
Mark Olesen committed
346
            addPointI++;
347
348
349
350
351
        }
    }

    vtkmesh->SetPoints(vtkpoints);
    vtkpoints->Delete();
352
353
354

    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
355
        Info<< "<end> Foam::vtkPV3Foam::volumeVTKMesh" << endl;
Mark Olesen's avatar
Mark Olesen committed
356
        printMemory();
357
    }
358

Mark Olesen's avatar
Mark Olesen committed
359
360
    return vtkmesh;
}
361

362

363
// ************************************************************************* //